A lot of work has gone into making Cone's grammar simple and clear. The lesser benefit is that code creation is faster and easier to remember. The greater benefit is that the resulting concise, readable code is easier to understand and improve, especially when one's eyes are not distracted by unnecessary, space-consuming boilerplate.

On another page, we will review Cone's rich code reuse mechanisms which can also play a huge role in keeping code small, by making it easier to create a single piece of code that well serves a number of diverse needs. For now, let's concentrate on Cone's grammatical shortcuts that help keep Cone programs small and easy-to-understand:

Significant indentation

By default, Cone supports significant indentation. Rather than requiring curly braces { } to mark the begin and end of blocks, as other systems programming languages do, Cone infers blocks according to variations in line indentation. A new block starts when line indentation increases. When indentation is restored, the block ends. Similarly, statement ending semi-colons are implicitly assumed to exist at the end of lines:

fn fact(nbr u32)
  if nbr<=1
    1
  else
    n*fact(n-1)

This approach eliminates both the visual distraction and the need to type these punctuation characters. Another benefit is that code takes up less space vertically, allowing more of the meat of the program to be visible in a code editor. The resulting code often looks like a neat, clean, declarative outline.

Significant indentation is controversial. Personal preferences and IDE tools vary. Some programmers prefer to write code that uses curly braces and semi-colons. Cone easily supports this style as well. When it notices the presence of curly braces, it automatically switches to free form mode and thereafter expects explicit semicolons and closing braces.

This blocks

'this' blocks are unique to Cone. They enable code to focus on a specific value, usually a collection, for the duration of a block. A 'this' block starts with an expression which establishes the value to focus on. Throughout the course of the block, the pseudo-variable this refers to that value. More importantly, the dot ('.') and colon (':') operators can implicitly refer to this:

// A 'this' block, where 'this' refers to the Frosty npc
$.npcs["Frosty"]
  .size *= .reducer   // equivalent to: this.size = this.size * this.reducer
  behavior: "jumping" // equivalent to: this.behavior = "jumping"
  .jump(2.0)          // equivalent to: this.jump(2.0) 

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.

When used in conjunction with significant indentation, 'this' blocks make it possible for Cone, as a procedural language, to express static content as concisely and declaratively as any markup language. Furthermore, the indented, compositional structure of Cone's code greatly facilitates the modular "snap-together" assembly of strings, collections, and 3D world parts.

Type Inference

A key reason most statically-typed languages are somewhat more verbose than dynamic languages is the requirement for type annotations scattered throughout the code. Type inference and defaults go a long way towards reducing this overhead.

Cone supports unidirectional type inference, which means that type annotations are generally required on function signatures and object creation, but can mostly be avoided otherwise (particularly variable declarations). Furthermore, Cone supports type defaults for the most common usage. For example, '&' defaults to a const, borrowed reference. Similarly, methods allow a parameter's type to be omitted, should it be the same as the type that the method is declared within.

High-level Control Abstractions

Although if and while control structures offer general-purpose flexibility, there are certain control flow patterns that are common enough that more-concise formulations are worth baking into Cone:

Return inference

As the earlier indentation example showed, the return keyword can often be omitted. Functions that don't return a value don't need it. Functions that do return one or more values, can specify the values to return on the last line. This inference bubbles into if and match control structures, as illustrated above.

Implicit return is consistent with Cone treating blocks and if/match structures as expressions. Just like return inference, the last value in each block is treated as the computed value for that block. Such consistency simplifies code refactoring and makes macro expansions more versatile.

Control clauses

Control clauses (inspired by Ruby) make it possible to append to a statement expression one or more if, while or each control clauses. The earlier factorial example can be made even simpler this way:

fn fact(nbr u32)
  return 1 if nbr<=1
  n*fact(n-1)

Prudence is advised here, as sometimes use of control clauses can make code a bit harder to read, especially if the code editor does not color highlight the control clause's keyword. However, control clauses are often ideal for short statements, like return, break, continue or brief expressions.

Tuples

Tuples (ad hoc structs) greatly improve the convenience of working with multiple values simultaneously. Implicit use of tuples avoids the code overhead involved with declaring the data structure and then individually moving around (destructuring) each element of the tuple. Important use cases for tuples are parallel assignment, multiple return values and marshalling queued-messaging data for use by a thread or actor.

a,b = b,a                      // parallel assignment used to swap values
success, result = action(val)  // multiple return values

Operator Overloading

Infix punctuation operators are both concise and readily digestible, far more so than named functions and methods. Cone allows any type to define appropriate methods for a large number of these operators, include equality comparisons, pattern matching, arithmetic and logic operators, and even various operator assignments (e.g., '+=').