8.12

2.4 Sets🔗ℹ

When {} is used with elements that do not have : to separate a key and value, then {} creates a set. (If a set-element expression uses :, then it will need to be in parentheses to avoid being parsed as a key–value pair.) A set is indexable with [], where the set’s elements act as indices to values of #true, while using any other value as an index produces #false. There’s a Set constructor that’s analogous to Map, but Set accepts just values to include in the set. The ++ operator effectively unions sets.

def friends = {"alice", "bob", "carol"}

> if friends["alice"] && friends["carol"]

  | "I know both"

  | "Who are they?"

"I know both"

def new_friends = friends ++ {"david"}

> new_friends["david"]

#true

> friends["david"]

#false

Using Set explicitly before {} disables the special treatment of : to indicate a map, and each element within {} is simply an expression. The Set constructor can also be used like a function with () instead of {}.

Set.of and MutableSet work as you’d expect. When [] with := is used to modify a mutable set, the index is removed from the set if the assigned value is #false, otherwise the index is added to the set.

Within a set construction using {}, a & form splice a set into the constructed set, analogous to the way & works for list constructions.

> {"dennis", & friends}

{"alice", "bob", "carol", "dennis"}

Also similar to maps, a repetition can be used to construct a set.

def [elem, ...] = ["a", "b", "a", "c", "c"]

> {elem, ...}

{"a", "b", "c"}

Set forms work as bindings, too, analogous to map binding forms.

def {"carol", other_friend, ...} = friends

> [other_friend, ...]

["bob", "alice"]