Values

This chapter will go through some of the types available in Lamb.

Nil


nil is the simplest value in Lamb as it is both a type, as well as a value. nil is the default value of a block that did not end with an expression, or a function that doesn't explicitly return a value. It's similar to void from C except that it is also a value.

assert_eq(nil, {});
assert_eq(nil, if true {});
assert_eq(nil, case 1 {});
assert_eq(nil, println(""));

Boolean


Booleans like in other languages are either of the value true or false.

assert_eq(true, !false);
assert_eq(false, !true);

Numbers


Unlike most other languages of this size, Lamb makes a hard distinction between floating point numbers and integers. They cannot be used interchangeably, and attempting to do so will result in a type error. Numbers look just as in other languages:

-- Integer Literals
0b123 -- Binary
0x123 -- Hex
0123  -- Octal
123   -- Decimal

-- Float Literals
1.2
1.2e3

Char


A char is a unicode scalar value and therefor 4 bytes in length. Because they are unicode scalar values, they may not be the item that most people expect. For example, is actually two characters, and as such would be two char in Lamb., namely '\u{0065}' and '\u{0301}'

'h'
'e'
'l'
'l'
'o'

Escaping

Escaping in Lamb is currently done with the : character, so to represent a newline char in Lamb, one must write: ':n'.

'::' -- Results in :
':n' -- Results in \n
':r' -- Results in \r
':t' -- Results in \t
':'' -- Results in '

Strings


A string is simply a list of char and can be constructed using the double-quote character:

"This is a string"
"This is also a string"

Functions


Functions are just like other values, and can be passed around as variables to be used. They follow the syntax specified in the previous chapter: [rec] fn(<args>) -> <expr>. The reckeyword is optional and denotes that a function is recursive,and that the name should be visible within the body of the function.

-- This will fail because the function is not marked as recursive and so `fib` is
-- not defined
let fib := fn(i) -> case i {
  0 | 1 -> 1,
  _ -> fib(i - 1) + fib(i - 2),
};

-- Now it will work!
let fib := rec fn(i) -> case i {
  0 | 1 -> 1,
  _ -> fib(i - 1) + fib(i - 2),
};

Functions in Lamb are able to capture items from outside their scope, and because of this are actually closures. If an item cannot be located in the current scope, Lamb will walk backwards until it can find an item with the same name. If it cannot, it will assume the value is a global variable.

Array


An array is a collection of any other kind of values. Like in other languages, those values are required to share a type. Thus, the following are all valid arrays:

[1, 2, 3]
[fn(i) -> i + 1, fn(i) -> i - 1]

To access an element in an array, you can use the postfix index operator [], like in C:

my_array[0]
my_array[{ x := 1; x - 1}]
my_array[if cond { 0 } else { 1 }]