Skip to content

Left‐Hand Sides

Andrew Johnson edited this page Mar 15, 2025 · 20 revisions

Most programming languages focus primarily on right-hand sides. Bias is often given towards towards the program logic that does something. By contrast, left-hand sides are normally very bland. Most languages only permit variable names and maybe a type.

In LSTS, left-hand sides are more diverse.

Left-Hand Sides Are Just as Important as Right-Hand Sides

Right-hand sides do things. Left-hand sides condition things.

In logic, conditions are just as important as expressions. Programming is about determining not just how to do something, but also about determining why to do something. Left-hand sides help us define conditional logic more naturally, so in LSTS the LHS are given just as much feature depth as the RHS.

A Variety of Features

The basic building block of a lhs is the binding. A binding is an optional bind mode and a variable identifier name to bind to. The default bind mode is set. If the binding name is _ underscore, then the name will remain anonymous.

let a = 5;
set a = 3;
a = 2;

Tuples are a simple extension for a common data structure.

(let x, let y) = (1, 2);

Lists, vectors, and other sequential types are also common data structure.

[let x.. let y.. let remainder] = [1, 2, 3, 4, 5];

Objects are important too. Object can have case tags, such as LeftCase. If no case tag is necessary, then an _ underscore can be provided instead.

Tuple { let x, let y } = (1, 2);
# this is equivalent to the earlier tuple example

Objects can be destructured by their field name also.

Tuple{ let x=first } => (1, 2);

Values can also appear on left-hand sides. A value that appears on the left-hand side will make the binding conditional. Conditional left-hand sides can fail.

match 1 {
   1 => print("One");
   2 => print("Two");
}

Value destructuring is potentially complicated. Some types can be partially matched and partially bound. One example of this is matching a prefix or suffix of a string.

match "abc" {
   "a".. remainder => print("'a' + \{remainder}");
}

Variable data can be treated as a value with the ~ tilde operator.

match x {
   ~y => print("X equals Y");
}

Pointers are sometimes automatically dereferenced, but the original value can be saved if a raw specifier is added.

(let raw p, let y) = (&x, 2);
Clone this wiki locally