When working with simple values, like numbers, Cone code looks very much like other languages.
It is when you work with more complex values, like the various forms of collections, you start noticing some subtle but useful tools that help get things done with such values.
Append operator
The <- operator appends the value(s) on the right to the collection on the left.
log <- count, " elements serialized in ", elapsed, " seconds.\n"
This operator is quite versatile, as it can be implemented as one or more overloaded methods on any type. As this example illustrates, it can be used to output data to some device (console or file), pipe, socket, thread channel, collection, or more. This versatile mechanism is typically more efficient, as compared to other strategies like concatenation (which does memory allocation) and functions that bear variable arguments (e.g., printf) that have to interpret values dynamically.
Since the operator supports overloaded methods, it is possible to also "append" formatting instructions that change how values are "appended". Formatting instructions could change text color, line width, etc. In effect, the append operator can be employed as a drawing or rendering tool.
With blocks
'with' blocks make it possible to create declarative-looking code blocks that concisely build or manipulate complex data collections (such as 3D content).
A 'with' block starts with an expression which establishes the value/collection to focus on. Throughout the course of the block, the pseudo-variable this refers to that value. More importantly, the dot ('.') and '<-' operators can implicitly refer to this:
// A with block, where 'this' refers to the Frosty npc
with $.npcs["Frosty"]:
with .inventory: // work with Frosty's inventory ..
<- magnifying_glass // add to the inventory
<- cowboy_hat
.size *= .reducer // equivalent to: this.size = this.size * this.reducer
with .dictionary: // work with Frosty's dictionary
.["carrot"]: "wortel" // add a word and its translation
.["coal"]: "steenkool"
.jump(2.0) // equivalent to: this.jump(2.0)
Although 'with' blocks can sometimes resemble and act like method cascades, Cone's 'with' block mechanism is considerably more versatile and flexible. In human conversations, we regularly use pronouns like "it" or "we" as placeholders to refer to something specific within the context of each conversation. Such pronouns make conversations pithier and less stilted. 'this' plays a similar role in Cone programs.
Each comprehensions
'each' is the special-purpose looping control structure you reach for to iterate over a sequential sequence of collected or generated values, on which various filter, map, summarize and sort operations can then be performed, sometimes with the help of programmer specified closures. Under the covers this mechanism uses a standard set of method calls to create the iterator, bind the values, increment the iterator and ultimately destroy the iterator. Despite the complexity of the underlying mechanisms, the generated code is optimized run quickly with little extra overhead.
Pattern matching
'match' is the special-purpose conditional control structure you reach for to match on some underlying pattern in a potentially-complex value, and then then destructure and bind some of its information for subsequent specialized processing.
It performs different logic based on where some pattern matches. Possible patterns:
- Different value of an enum.
- Different subtypes of a variant type.
- Different numbers or ranges of numbers.
- Tokenized parsing (or regex) of some sentence.
- Use your imagination.