Skip to content

Release 2.4.0

Latest

Choose a tag to compare

@reid-spencer reid-spencer released this 07 Oct 23:56
· 1 commit to main since this release

What's New

RIDDL has always required every value to be typed. 2.4.0 enforces that rule for the two values
whose spelling carries no type of their own: empty/none and prompt(…). A bare empty takes
the type of its position. Where nothing supplies a type, you write empty T, and T is a
type NAME
, never a type expression. Declare type MaybeRecipe is Recipe? and write empty MaybeRecipe. See the Computational Model §0.3, ruling 6.

Features

  • empty is checked at every position that types it. A bare empty is now held to the
    minimum-cardinality rule at every position that supplies a type:

    • set, append/remove and let
    • constructor, call, initiate and terminate arguments
    • put, return, require … with
    • store/upsert and update … set
    • comparison operands

    Fields typed inline (note: String?) are checked too. Before this release only four of those
    positions checked anything, and the rest accepted empty against types that cannot be empty.

  • x == empty. empty can now be a comparison operand. The operand opposite it supplies its
    type.

  • EmptyValue.typeRef and PromptValue.typeRef. A value's ascription is carried as the
    TypeRef it names. New non-deprecated readers: ascribedType and expressionAscription.
    A bare predefined type (Real, Boolean, TimeStamp) counts as a name; a parameterized one
    (String(1,30)) does not.

  • Three new Errors:

    • value-ascription-not-a-name: empty String? or prompt(…) as T*. The 2.0 spelling was
      admitted by mistake; it still parses, so the message names the fix.
    • value-empty-untyped: a bare empty where nothing supplies a type, such as an untyped
      let, log empty or empty == empty.
    • value-empty-ascription-contradicts: an ascription that is not, syntactically, the
      position's declared type. A field typed inline takes a bare empty.

Bug Fixes

  • update T set f = empty where … failed to parse. empty's optional ascription read the
    next word as a type name. put empty to …, append empty to … and store empty in … failed
    the same way. The guard after empty is now a word category rather than a list, and the EBNF
    carries the same rule.
  • empty with an alias type was refused. empty MaybeNote with type MaybeNote is String?
    reported "requires at least one value", and so did a bare empty for any alias-typed
    constructor field. The cardinality check now reads through type names, including alias chains,
    and is safe on cyclic ones.
  • riddlc dump --json misreported alias-typed fields. cardinality and acceptsEmpty came
    back as exactly-one and false for a field whose alias names an optional or a collection.
  • Prettify dropped the keyword from empty record R, so the output re-parsed as a different
    AST.
  • Messages.justWarnings returned advisories. It filtered by severity band, and Advisory
    sits inside that band while reporting isWarning = false. RiddlLib.ValidateResult (as a
    trailing defaulted field) and the JS facade both gain an advisories bucket. Before this, an
    advisory reached consumers only inside all. Blocking behaviour (--fail-on) was never
    affected.
  • PromptValue had no JS export. Its @JSExportTopLevel annotation was attached to
    EmptyValue.

Deprecations

  • EmptyValue.typeEx and PromptValue.typeEx are deprecated in favour of typeRef and
    ascribedType. Both still parse and are still populated, so existing readers see no change.

Internal

  • BAST and JSON wire formats are unchanged; typeRef is derived on read, so files written by
    2.3.x load to the same AST the parser builds.
  • EbnfReservedWordsTest keeps the grammar's hand-kept word lists in step with the parser.
  • A corpus walk in the test suite prunes target/ instead of filtering it afterwards.
  • Corpus check: all 191 riddl-models entry points validate with 0 errors, as they did on 2.3.1.