Skip to content

Records, enums, lists, maps and sets

Every value in HollowScript is immutable. A record, list, map or set is never edited in place, every operation that “changes” one returns a new value, so origin below and Shape.Circle(2.0) never move once they exist.

  • A record is a fixed set of named fields, structural rather than nominal: two record types with the same field names and types are the same type, whatever they are called. See section 2.5 and section 6.1.
  • An enum is one of a fixed set of named variants, each optionally carrying payload values. Unlike records, enums are nominal, and the only way to look inside one is match, covered on the next page. See section 6.3.
  • Lists, maps and sets are the built-in collections: [T], Map<K, V> and Set<T>. Map and set keys must be Int, String or Bool. See section 6.2.
uses print
record Point = { x: Int, y: Int }
enum Shape { Circle(Float), Rectangle(Float, Float) }
fn area(shape: Shape): Float {
match shape {
Circle(radius) { return 3.0 * radius * radius }
Rectangle(width, height) { return width * height }
}
}
constant origin: Point = { x: 0, y: 0 }
constant shapes: [Shape] = [Shape.Circle(2.0), Shape.Rectangle(3.0, 5.0)]
constant scores = ["ada": 3, "grace": 5]
constant tags = set(["urgent", "review", "urgent"])
effect print("origin at ${origin.x}, ${origin.y}")
for shape in shapes {
effect print("area ${area(shape)}")
}
for entry in scores.with("linus", 4) {
effect print("${entry.key}=${entry.value}")
}
effect print("tags: ${tags.toList().join(",")}")

Output:

origin at 0, 0
area 12.0
area 15.0
ada=3
grace=5
linus=4
tags: review,urgent

A few things worth noticing:

  • Shape.Circle(2.0) builds an enum value through its variant. Inside match, the same variant is written without the enum name (Circle(radius)), because the type of the value being matched already tells the checker which enum is meant.
  • scores.with("linus", 4) returns a new map with the entry added, it does not touch scores. Iterating a map always visits entries in ascending key order, never insertion order, which is why ada comes before grace and linus even though linus was added last.
  • set([...]) builds a set from a list, dropping duplicates. There is no set literal.

The methods available on lists, maps and sets, map, filter, reduce, merge, union and the rest, are in Chapter 14 of the specification.