Prelude constants

The suffete::prelude module exposes well-known constants. Importing it gives you the common-case Elements and Types without going through the interner.

use suffete::prelude::*;

Elements (ElementId)

Landmarks

ConstantElementNotes
NEVERNever$\bot$.
MIXEDMixed (vanilla)$\top$.
NULLNullThe value null.
VOIDVoidThe PHP void.
PLACEHOLDERPlaceholderInference hole.

Booleans

ConstantElement
TRUETrue
FALSEFalse
BOOLBool

Scalars (unrefined)

ConstantElement
INTInt (unspecified)
FLOATFloat (unspecified)
STRINGString (unspecified, no flags)
NUMERICNumeric (true union)
SCALARScalar (true union)
ARRAY_KEYArrayKey (true union)

Common refinements

ConstantElement
NUMERIC_STRINGString (unspecified, with is_numeric=true)
NON_EMPTY_STRINGString (unspecified, with is_non_empty=true)
EMPTY_STRINGString (literal "")
INT_ZEROInt (literal 0)

Object family

ConstantElement
OBJECT_ANYObjectAny

Iterable / callable

ConstantElement
ITERABLE_MIXED_MIXEDIterable<mixed, mixed>
CALLABLECallable (bare form, no signature)

Resources

ConstantElement
RESOURCEResource (unrefined)
OPEN_RESOURCEResource (state = Open, no kind)
CLOSED_RESOURCEResource (state = Closed, no kind)

Arrays

ConstantElement
EMPTY_ARRAYarray{} (the empty sealed shape)

Types (TypeId)

Each TYPE_* constant is the singleton type wrapping the corresponding Element. Use these when you need a TypeId for a single Element ; it saves the construction call.

ConstantTypeEquivalent
TYPE_NEVERneverTypeBuilder::new().push(NEVER).build()
TYPE_MIXEDmixedTypeBuilder::new().push(MIXED).build()
TYPE_NULLnull...
TYPE_VOIDvoid...
TYPE_TRUEtrue...
TYPE_FALSEfalse...
TYPE_BOOLbool...
TYPE_INTint...
TYPE_FLOATfloat...
TYPE_STRINGstring...
TYPE_NUMERICnumeric...
TYPE_SCALARscalar...
TYPE_ARRAY_KEYarray-key...
TYPE_NUMERIC_STRINGnumeric-string...
TYPE_NON_EMPTY_STRINGnon-empty-string...
TYPE_OBJECT_ANYobject...
TYPE_RESOURCEresource...
TYPE_OPEN_RESOURCEopen-resource...
TYPE_CLOSED_RESOURCEclosed-resource...
TYPE_EMPTY_ARRAYarray{}...

The TYPE_* constants are computed at boot time and exposed as consts. Comparing t == TYPE_INT is a single u64 compare ; faster than constructing a TypeBuilder and calling build.

When to use the prelude

For the trivial cases:

use suffete::prelude::*;

// Use the Element constant when constructing a union:
let t = TypeBuilder::new().push(INT).push(STRING).build();

// Use the Type constant when you need a TypeId directly:
let int_only: TypeId = TYPE_INT;

// Use the Type constant in operations:
let result = lattice::refines(some_t, TYPE_MIXED, &world, opts, &mut report);

For non-trivial Elements (named objects, sealed shapes, callable signatures), use the ElementId constructors or the interner directly. The prelude only covers the well-known singletons.

Naming conventions

  • UPPER_SNAKE_CASE for ElementId constants.
  • TYPE_UPPER_SNAKE_CASE for TypeId constants.
  • The element name matches the PHP-side name, lowercased and snake-cased: INT, STRING, OBJECT_ANY, EMPTY_ARRAY, NUMERIC_STRING.

Adding to the prelude

The prelude is the place for frequently-needed constants. New entries should:

  • Have a clearly-defined PHP-side meaning (so the name is unambiguous).
  • Be a singleton (one canonical Element / Type per name).
  • Get used often enough that an analyser shouldn't have to construct it inline.

Refinement variants that can be expressed as flag combinations on the basic kinds (e.g. truthy-string) are typically not in the prelude ; they are constructed via the interner with a StringInfo carrying the flags.

See also: Constructing types: TypeBuilder and prelude for the broader construction API; Element kinds for the full kind list.