This is an old revision of the document!


PHP's gd library is missing or unable to create PNG images

Type System

Overview

Every port in the engine has a type, and a port accepts a value if it's exactly that type — or if some path leads from the value's actual type to the port's. That path is usually a registered conversion, but not always: a few types are subtypes of another, and a value of the subtype is already a value of the parent, with nothing to convert at all. This page covers both — the full set of registered conversions, and the handful of places where none exists because none is needed.

Each type here is implemented by a dedicated type class, named after the data it represents with a Type suffix: Region Manager Type is the class backing the region manager data, Table Type the class backing tables, and so on. This page refers to every type by that full class name and links each one to its own page.

See Ports on the EGO Script page for how a port's type governs what it can receive, and Basic Data Flow for the general rule this page's conversions follow.

How automatic conversion works

Automatic type conversion only happens when a value is connected from one port to another — a variable reference, or a functor call inlined directly into an argument. It never applies to a constant written directly into a port; a constant is instead parsed by the receiving port's own type-specific literal syntax, which accepts only that type's own literal form. See Constants for this rule in full.

Conditional conversions. A handful of conversions only succeed if the source value actually holds data compatible with the target type at runtime, raising an error otherwise — converting an already-typed, known value never fails, but converting a generic holder type (such as Table Value Type) does depend on what it actually contains. Table Value TypeString Type and Table Value TypeReal Value Type are the clearest examples: each only succeeds if the Table Value Type value actually holds that type. Wrapping such a conversion in Skip On Error turns the failure into a type test — see Manipulating Tables and Lookup Tables for a full worked example of this pattern. The same conditional logic governs every type that converts to or from Table Type itself — see Table format of table-shaped types below for the exact column layout each one expects.

Sequencing. A conversion to None Type is registered for almost every type in the system. This isn't meant to transform data — it's what lets sequence ports accept a connection from any container's output regardless of what that container actually produces: connecting an output to a None Type-typed input creates a dependency edge without needing the value itself, so the engine schedules the connected functor to run after the one that produced it. The types that support this are listed separately in Sequencing below, rather than repeated in every table.

Subtyping instead of conversion

Not every compatible pair of types shows up as a registered conversion, because not every relationship between two types is a conversion in the first place. Some types are subtypes of another — a value of the subtype already is a value of the parent type, so a port declared for the parent accepts it directly, with nothing to register and nothing to run at connection time. Three relationships in this system work this way:

Value types

The chain running through Positive Integer Value Type, Non Negative Integer Value Type, and Integer Value Type described in Subtyping instead of conversion above is the backbone of this table: most of the entries below are the narrowing, runtime-checked half of that relationship, alongside conversions into more permissive types like String Type and Real Value Type that never fail.

Filename and text types

Table and Lookup Table types

Table Type sits at the center of this group. As Subtyping instead of conversion above describes, it and Lookup Table Type are both subtypes of Base Table Type, so only the narrowing direction back down to a specific shape needs a registered conversion. The rest of the table is more ordinary conversion territory: Table Value Type moving to and from the scalar types a table cell can actually hold, and the individual value types converting into Tuple Type and Table Cell Type for use as keys and column declarations.

Map and raster types

One conversion is conspicuously absent from this table: nothing converts Categorical Map Type to or from Map Type directly. Subtyping instead of conversion above explains why: a Categorical Map Type value converts automatically wherever a Map Type is expected, keeping its cells and null value intact and dropping only the guarantee that a categorization is attached; the reverse never happens automatically, since an arbitrary Map Type value isn't guaranteed to carry one. What's left below is Cell Type's round trip with the numeric value types, and the two paths a categorical map takes toward its supporting data: its legend, as a Categorization Type, and its spatial reference, as a Projection Type.

Simulation types

Calibration types

The one conversion pair here follows the same table-shaped logic as the simulation types above, though its exact column layout isn't confirmed — see the note in Table format of table-shaped types below.

Table format of table-shaped types

Several of the types above are really Table Type (or Lookup Table Type) under one particular, expected column layout: converting to Table Type keeps the same rows but drops the type's special meaning, and converting from Table Type checks that the table actually has this shape — the same conditional-conversion pattern described above. The engine registers an exact default format for most of these; key columns are marked * the way Table Type itself marks them. Table Type's own Automatic Conversions section and Manipulating Tables and Lookup Tables both describe the Lookup Table Type row below in those same terms — its *#real, #real shape already matching what a single-value table needs.

Type Direction Table format
Lookup Table Type ↔ Table Type Key* (Real), Value (Real)
Categorization Type ↔ Table Type Value* (Real), Name (String), Color_Red (Real), Color_Green (Real), Color_Blue (Real)
Change Matrix Type ↔ Table Type From* (Real), To* (Real), Cells (Real)
Percent Matrix Type ↔ Table Type From* (Real), To* (Real), Percent (Real)
Transition Matrix Type ↔ Table Type From* (Real), To* (Real), Rate (Real)
Transition Function Parameter Matrix Type ↔ Table Type From* (Real), To* (Real), Mean_Patch_Size (Real), Patch_Size_Variance (Real), Patch_Isometry (Real)
Neighborhood Table Type ↔ Table Type Neighbor1* (Real), Neighbor2* (Real), Weight (Real)
Weights Type ↔ Table Type From* (Real), To* (Real), Variable* (String), Range_Lower_Limit* (Real), Range_Upper_Limit* (Real), Weight (Real)
Weights Of Evidence Skeleton Type ↔ Table Type No default format registered alongside the others — shape not confirmed.
Base Table Type → Table Type only Not a fixed shape but a generic container — accepts anything already shaped like Table Type or Lookup Table Type. The registered conversion only runs in the narrowing direction, checking a generic value against Table Type's shape; the reverse needs no conversion at all, since Table Type is a subtype of Base Table Type to begin with — see Subtyping instead of conversion above.
Lookup Table Group Type ↔ Table Type Generic collection of Lookup Table Type values, not a single fixed shape.
Note: Transition Set Type is left out of this table on purpose — it converts one-way from Lookup Table Type but never to or from Table Type directly, so it has no registered table format either.

Region types

Region Manager Type stands apart from every other type on this page: it has no automatic conversions to or from anything else. The only conversion registered for it at all is the sequencing conversion to None Type described below.

Sequencing