2 minutes
New Complex Type Syntax
As part of the on-going build-out of recursive types in newt, complex types have been re-worked such
that every complex type is a dictionary of type declarations (previously, record types were a dictionary of
values, with special logic to generate modified copies of this dictionary). In this new model,
type declarations that reference existing types are implemented as type aliases. Thus, in the
following type declaration, person.age
is an alias for int
,
person.name
is an un-aliased record type, and person.name.first
and
person.name.last
both alias the built-in type string
.
person {
age:int,
name {
first:string,
last:string
}
}
For purposes of assignment and conversion, a type alias is directly equivalent to the type it aliases.
The struct
keyword is noteworthily absent from the previous record type definition, and
there are now commas separating type members. These are not accidents, as the re-worked type declarations
allow for arbitrarily nested type definitions, and repeated use of the struct
and
sum
keywords felt heavy and inelegant. For this (primarily aesthetic) reason, the keywords are
omitted from the nested types, and to maintain a uniform, non-astonishing grammar, the keyword is omitted
from the top-level complex type declarations as well.
Omission of the keywords requires another mechanism for differentiating sum and product types, however, so members of record types must now be comma-delimited, while sum type variants are delimited by a vertical bar (that is, a pipe). In this new syntax, a linked list of integers might be expressed as follows:
list {
end
| item {
data:int,
next:list
}
}
The new syntax very closely matches the proposed syntax for map literals, which is a nice isomorphism, but does raise concerns about legibility issues. Time will tell.