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 works one of two ways: most of the time it's a registered conversion, actual logic that runs when the connection is made; a few times it's subtyping instead, where the source type is already, structurally, a value of the target type and nothing needs to run at all. This page lists both together in the same tables — see Converters and subtyping below for how the two are told apart.

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. Some conversions can fail outright, for two different reasons. The first is a mismatch between a generic holder's declared type and what it actually contains: 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.

The second reason is content validation: the source value's type is compatible, but its actual content doesn't satisfy the target type's constraints. String TypeReal Value Type is the clearest example — connecting the string “test” to a Real Value Type port fails outright, since “test” isn't parseable as a number, while “3.14” succeeds. The same content-validation governs every conversion that narrows the numeric chain in Value types below: Integer Value TypeNon Negative Integer Value Type fails for any negative input, for instance, since there's no way to represent it in the narrower type at all. The named filename converters (String TypeMap Filename Type and similar) very likely apply the same extension-checking rule Constants documents for literal filenames — that's inferred from the dedicated converter classes registered for them rather than confirmed directly, since this page has no visibility into their implementation.

Information loss. Failing outright and losing information are two different things — a conversion that never fails can still be irreversible. Real Value TypeInteger Value Type is the clearest example: it never fails, since every real number truncates to some integer, but the fractional part is simply dropped — 3.9 and 3.1 both become 3, and neither the original value nor the fact that something was lost survives the conversion. The opposite case — guaranteed to succeed *and* fully recoverable — describes the widening direction of that same numeric chain instead; see Value types below for exactly which steps are which. Beyond this numeric chain and the holder-type pattern above, this page doesn't have visibility into which of the other conversions here are lossy versus lossless, so it doesn't attempt to mark every row — treat any conversion not discussed here as unconfirmed on that question.

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.

Converters and subtyping

A path from one type to another works one of two ways. Most entries in the tables below are registered converters — real conversion logic that runs when the connection is made, subject to the conditional-failure pattern above. A few are subtyping instead: the source type is already, structurally, a value of the target type, so a port declared for the target accepts it directly, with nothing to register and nothing to run. Both kinds appear together in the same tables from here on; subtyping-based entries are set in italics to keep the distinction visible without splitting them into a separate list.

Three relationships in this system work through subtyping:

Value types

The chain running through Positive Integer Value Type, Non Negative Integer Value Type, Integer Value Type, and Real Value Type behaves differently depending on direction. Widening — positive to non-negative to integer to real — only relaxes which values are allowed; the number itself never changes, so every registered step is both guaranteed to succeed and fully recoverable. (Non Negative Integer Value Type's own step to Integer Value Type isn't among these registered steps at all — it's the italicized subtyping entry from Converters and subtyping above, so the question of failing or losing information doesn't apply to it; nothing runs.) Narrowing the other way splits into two different behaviors: Integer Value TypeNon Negative Integer Value Type and Non Negative Integer Value TypePositive Integer Value Type both fail outright if the value falls outside the narrower range — negative, or zero, respectively — since there's no way to represent those values in the target type at all. Real Value TypeInteger Value Type is different again: it never fails, but it's lossy — the fractional part is simply truncated and can't be recovered. See How automatic conversion works above for these two dimensions — failure and information loss — stated generally.

Five of these types also converge on Null Value Type — not to be confused with None Type above. Where None Type is the sequencing mechanism, Null Value Type is an ordinary type in its own right; converting to it always succeeds, and it converts onward only to None Type, nowhere else.

Filename and text types

Filenames largely behave like String Type with an extra validation step on the way in — see Constants for the extension-checking rules each filename type applies to its text. Every filename type here converts to and from String Type; most of them — Generic, Map, Table, Lookup Table, and Weights Filename Type — also convert to and from a generic Table Value Type holder, the same generic-holder role Table Value Type plays for the table-shaped types further down this page. Folder Type, Kmz Filename Type, and Projection Type are the exceptions: they connect only to String Type, not to Table Value Type.

Table and Lookup Table types

Table Type sits at the center of this group. It and Lookup Table Type are both subtypes of Base Table Type — see Converters and subtyping above — so their path back to Base Table Type, set in italics below, needs no conversion at all, while the narrowing direction the other way round is an ordinary registered check against a specific shape. 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

Categorical Map Type's path to Map Type, set in italics below, is the clearest example of subtyping on this page — see Converters and subtyping above. 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 — which is why there's no corresponding Map Type → Categorical Map Type entry at all. The rest of the table 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, → Lookup Table Type Not a fixed shape but a generic container — accepts anything already shaped like Table Type or Lookup Table Type. Both directions shown here are the narrowing, format-checking half of the relationship. The reverse — Table Type or Lookup Table Type back to Base Table Type — needs no format at all, since it's subtyping rather than a conversion; it's shown in italics in Table and Lookup Table types above rather than repeated here.
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