Tutorial ======== This tutorial consists of a language tour and a set of exercises, in the order of mentioning. Tour ---- **Arithmetic operations** Addition, multiplication, subtraction and division are supported with +, *, - and / respectively. ```console > (+ 1 1) 2 : int > (* 2 3) 6 : int > (- 5 4) 1 : int > (/ 4 2) 2 : int ``` As addition and multiplication are associative, multiple arguments can be used (even just one, even though that doesn't really make sense): ```console > (+ 1 2 3) 6 : int > (* 2 3 4 5) 120 : int ``` Decimals are truncated in division: ```console > (/ 5 2) 2 : int ``` **Booleans** Myslip supports booleans and `and`, `or`, `xor` and `not` for their comparisons. ```console > true true : bool > false false : bool > (and true true) true : bool > (or true false) true : bool > (xor true true) false : bool > (not true) false : bool ``` **Integer comparisons** To generate booleans from integers, some basic and quite self-explanatory operators are supplied. ```console > (> 2 1) true : bool > (< 1 2) true : bool > (>= 1 1) true : bool > (<= 1 1) true : bool > (= 1 1) true : bool > (!= 1 1) false : bool ``` **Variables** Values can be bound to variables using the let expression. ```console > (let x 1) Bind saved > x 1 : int ``` The REPL interprets this as `((let x 1) x)`, which you could also type but would make a more cumbersome REPLing experience. Shadowing works as expected: ```console > ((let x 1) (+ x ((let x 2) x) x)) 4 : int ``` Here, before the definition inside the addition, `x = 1`, and after it it is too, while in the middle term where `x = 2` is defined, `x = 2`. **Functions** Functions are written in the form of `(fn [argument list] [argument type list] [return type] [function body])`. They don't have names of themselves, but they can be bound using `let`. The following example features a simple increment function and a function for checking if a integer is between two others. ```console > (let ++ (fn a int int (+ a 1))) Bind saved > (++ 1) 2 : int > (let between (fn (a b c) (int int int) bool (and (< b c) (> b a)))) Bind saved > (between 1 2 3) true : bool > (between 1 0 3) false : bool ``` **Lists** Lists in myslip correspond to what is known as tuples in many other programming languages. This difference exists because myslip is a list processor, and not using this underlying construct of the language would be odd. In principle, ```myslip (1 2 3 4 5) ``` is a valid list, but it is evaluated by the interpreter, which assumes that the first term, `1`, is an operator. That's why constructing a list requires the operator `quote`: ```console > quote quote : (T -> (Quote T)) > (quote 1 2 3 4 5) (quote 1 2 3 4 5) : (Quote (int int int int int)) ``` In contrast from many other lisp-variants, in myslip sub-expressions are simplified. ```console > (quote (+ 1 1) (+ 2 2)) (quote 2 4) : (Quote (int int)) ``` The elements of a list can of course be of different types: ```console > (quote - 0 (quote 1 2)) (quote - 0 (quote 1 2)) : (Quote ((int int) -> int) int (Quote (int int))) ``` TODO: List destructuring **Vectors** Vectors behave roughly the same as lists, except their length is not specified on type-level, and their elements can be only of one type. ```console > vector vector : ((T ... T) -> (Vector (T ... T))) > (vector 1 2 3 4) (vector 1 2 3 4) : (Vector (int ... int)) ``` TODO: vector destructuring **Understanding error messages** TODO: div zero TODO: unclosed parenthesis TODO: type errors Exercises --------- TODO