type Font = [
weight: int,
size: float,
style: .BOLD | .ITALIC | .OBLIQUE,
];
let font: mutable Font = [
weight= 400,
size= 12.0,
style= .ITALIC,
];
font.[.weight] = 700;
let sz: .size = .size;
font.[sz] = 18.5;
font.[if font.size < 24 then .style else .sTyLe] = .OBLIQUE;
Invariance
Tuple and record types that are mutable are invariant as supertypes, meaning for any types ‹S› and ‹T›, if ‹S› is a subtype of ‹T›, then it is never the case that ‹G›<‹S›> is a subtype of ‹G›<mutable ‹T›>. This invariance ensures type safety for mutating operations.
let sub: mutable [int, int] = [4, 2];
let `super`: mutable [int?, int?] = sub; %> TypeError
TypeError: Expression of type mutable [int, int] is not assignable to type mutable [int?, int?].
We get a type error, even though int is assignable to int?. Without this type safety, we’d be able to mutate `super` in a way that would otherwise be invalid for sub:
`super`.0 = null;
The type checker wouldn’t see a problem with this, but by setting `super`.0 = null we would be actually setting sub.0 = null at runtime (since `super` points to sub), and that’s invalid because sub cannot contain null.
However, immutable tuple and record types remain covariant as discussed in #53.
let sub: mutable [int, int] = [4, 2];
let `super`: [int?, int?] = sub; % no error
Type mutable [int, int] is a subtype of type [int?, int?], even if the former is mutable.
Assignment of mutable data structures’ entries. Depends on #25.
DRAFT: Using atoms (#59) as record keys:
Invariance
Tuple and record types that are mutable are invariant as supertypes, meaning for any types ‹S› and ‹T›, if ‹S› is a subtype of ‹T›, then it is never the case that ‹G›<‹S›> is a subtype of ‹G›<mutable ‹T›>. This invariance ensures type safety for mutating operations.
We get a type error, even though
int
is assignable toint?
. Without this type safety, we’d be able to mutate`super`
in a way that would otherwise be invalid forsub
:The type checker wouldn’t see a problem with this, but by setting
`super`.0 = null
we would be actually settingsub.0 = null
at runtime (since`super`
points tosub
), and that’s invalid becausesub
cannot containnull
.However, immutable tuple and record types remain covariant as discussed in #53.
Type
mutable [int, int]
is a subtype of type[int?, int?]
, even if the former is mutable.Specification
Syntactic Grammar
Semantic Schema
Decorate
Checklist
MutabilityError
mutable
type operator