--- title: An introduction to the Cab expression language unlisted: true --- Here is a small Cab snippet, taken from the standard library: ```swift @Any = (@_), {[(1)]} @symbol = {[(2)]} @name & String => {[(3)]} { {[(4)]} @`\(magic.name)` = name, }, @nominate = @name & String => { @`\(magic.name)` = name, @`\(magic.value)` = value, }, {[(5)]} @None = symbol "None", @Some = nominate "Some", @Option = { {[(6)]} @`\(magic.call)` = @value & Any => None | Some value, @unwrapOr = @default & Any => @option & Option (TypeOf default) => if Some @value = option then value else default, @or = @alternative & Option Any => @option & TypeOf alternative => if Some Any = option then option else alternative, }, ``` It may look confusing at first, but the way Cab works is refreshingly simple & at the end of this blog post, you'll understand how "typing", "pattern matching", and other things that don't actually exist in Cab work. Let's start from the top:

```swift @Any = (@_), {[(1)]} ```

Cab doesn't have "declarations", or "pattern matching". This is a _literal_ comparison operation. Exactly the same as the `==` operator in most languages. But then, how do we even declare anything in the local scope? How do we address values by name, instead of inlining them all? The way Cab answers this question is interesting (and original, I have not seen anything like it before): Bindings as values! In Cab, you can create a binding value with the `@` syntax. So here, `@Any` is a binding value. And the way you use bindings (aka, binds) in Cab is simple: You compare them using the comparison operator, `=` or `!=`. A bind is equal to _any_ value, literally anything! So, `@foo = 123` is always true. > So, a bind is like a wildcard value? Then how does it actually "bind" anything > to the local scope? Simple: Binds, when compared with a value, bind that value to the local scope. That means, when we evaluate this expression, the scope will have `foo` set to `123`: ```swift @foo = 123 ``` --- You might have spotted something that hasn't been covered if you were reading carefully: > Why the parenthesis around the `(@_)` bind, then? In order to prevent things from going out of control, Cab limits when binds can bind the value they are compared to to their local scope. The rule that governs this is: A bind, when compared to a value, will bind that value to the scope the bind was declared in _if the comparison operation is within that scope_. So, we don't actually get `_` bound to `@Any` because the `=` is outside the scope (aka parenthesis) of `@_`, and thus we don't litter in our standard library. --- If you are even more keen, you must have noticed `,`, which is the "same" operator. It evaluates both operands at the same time, letting us do neat stuff like: ```swift @countinc = count + 1, @count = 123, ``` Or even: ```swift @a = b, @b = a, ``` This is similar to "toplevel" declarations in programming languages where you can reference a declaration before it is declared in the source text. Basically makes it evaluate in the order that it needs to, instead of top to down. Trailing `,` is a noop operator, `,` and `` are exactly the same. Trailing commas are nice!

```swift @symbol = {[(2)]} @name & String => {[(3)]} { {[(4)]} @`\(magic.name)` = name, }, ```

I've already explained how comparisons & binds work in Cab, so I'll skip the `@symbol =` part. The way lambdas work in Cab is as follows: ` => `. The `=>` is an infix operator, yet again. And the `` can be _any expression_. When a lambda is called, the `` is compared with the argument in a new scope. If they are not "equal", aka when the comparison evaluates to `false`, an exception is thrown. But when it is `true`, the `` is evaluated and returned. Okay, as the way lambdas work in Cab is out of the way, let's see what this expression is actually doing: In this lambda, `@name & String` is the ``, and { @\`\\(magic.name)\` = name, } is the ``. ## The value Let's start with the ``, we know what `@name` is, it's a bind and when compared with the argument, it will set `name` in the local scope to it. What is the `& String` part? Answer: `&` is an infix operator, that takes two values and produces a value that is **all of the given of the values, at the same time**. It's called the `all` operator. What is `String`? It's a value that is equal to all strings. No, not exactly a "type"! This is why Cab doesn't exactly have "typing", as everything is a value. This makes `@name & String` a value that is equal to any string, and when compared to a string value, will bind it to the scope & have the comparison expression evaluate to `true`. ## The body Okay, so assuming the lambda was called properly, we should have a value named `name` in our local scope. We will now evaluate this expression: ```swift { @`\(magic.name)` = name, } ``` Let's break it down: `{}` is a special type of "parenthesis", it is identical to `()`, but unlike `()`, when it evaluates the inner expression, it doesn't return the expression itself. It returns its scope. So, `{ @foo = 123 }` will evaluate to an object of type `Attributes`, with `foo` set to `123`. Let's focus on the inner expression: { @\`\\(magic.name)\` = name, }, specifically the @\`\\(magic.name)\` part, as that is new. It is a bind, but the identifier it has next to it isn't a "literal" identifier. It's interpolated. `\(...)` is how you do string/identifier/path/etc interpolation in Cab, and it takes a single expression within that has to evaluate to a string. And the way you do "quoted" identifiers in Cab is by using \`. And the value within the bind is `magic.name`. `magic` is a builtin value, which contains strings that are used by the runtime for magical stuff. The `.` operator is the "with scope" operator. The way `magic . name` is evaluated is by setting the scope of `name` to `magic`, and evaluating `name`, which is a reference. It's not an "attribute access" operator, because we can do stuff like: `magic.[name, value]`. Here, we effectively get the `name` value within `magic` and use it for the string interpolation.