One object in Cicada that is not supported by C is the set. A set is basically a magical bag of assorted items---variables, functions, classes, even other sets---that also exist somewhere else. To define a set we write curly braces around a list of objects separated by commas (or end-of-lines). Here is an example where each object is in several places.
Alice :: Bob :: Christine :: Daniel :: Elan :: friend_of_mine
men :: { Daniel, Elan, Bob }
neighbors :: { Christine, Bob }
cleaning_schedule :: { Bob, Alice, Bob, Alice, Elan, Elan, Daniel }
We typically access members of a set using square brackets (as if they were arrays). So after running the code, Bob, men[3], neighbors[2], cleaning_schedule[1] and cleaning_schedule[3] are all the same thing. If we set men[3].needsSleep = true then Bob.needsSleep and neighbors[2].needsSleep will also be true. Notice how the same object can even appear in several places in a set. Sets come handy when the objects have convoluted path names.
to_buy :: {
food.produce.fruits.apples
clothes.shoes.black
clothes.socks.black
}
to_buy[1] is much quicker than food.produce.fruits.apples.
Cicada sets are pretty flexible in what they can store. Along with variables, we can throw constants, other sets (including ones that we define on the fly), and even the void into the bag.
collections :: { men, neighbors, { Patty, Don }, "Herbert", 3.3, this[3], this, nothing }
Here collections[3] is an inlined subset containing two objects. The fourth and fifth items are inlined constants. The collections[6] is also the third item, the subset containing Patty and Don, and notice that it had to be listed after the third item because otherwise this[3] would not have existed yet. collections[7] is collections itself -- so collections[7][7][7][2] is just neighbors. Trying to print collections from the command line won’t work because of the self reference.
The reason we access set elements by their index (as opposed to name) is that those set elements have no name, at least the way we defined them in our examples. In other words, collections[1] is effectively an alias for men but that doesn’t mean that that set element has the name men -- collection.men will cause Cicada to draw a blank. But there is actually a way to name certain elements of a set, and that is to manually define aliases for their respective objects. To illustrate, here we give a different way of defining collections which assigns names to members 2, 3, 4, 7 and 8.
collections :: {
men
neighbors := @parent.neighbors | use same name for convenience
peeps :: { Patty, Don }
Herby := "Herbert"
3.3, this[3] | set elements 5 and 6
myself := @this
zilch := @nothing
}
With the verbose definition we can write collections.Herby in place of collections[4], although collections[4] is still perfectly legal.
Just as with composite variables, items can be added to and removed from sets after they have been defined. So if we want to shuffle “Herbert’’ to the end of the set we might write:
collections[top+1] := @collections.Herby
remove collections.Herby
(and those 2 lines could go in any order).
As with variables, we can use one set to define another. The following is legal:
newCollections :: collections
Importantly, newCollections is defined using the old set collections’s original definition. So even if we had rearranged the elements of collections, in the new set Herbert will be both at newCollections[4] and newCollections.Herby. We might as well have defined both sets on the same line:
newCollections :: collections :: { ... }
Last update: May 8, 2024