# Lojic Technologies

## Chapter 4 – Functions

Lambda expressions are written as:

`fn var : typ => exp`

For example:

```fn x : real => Math.sqrt (Math.sqrt x)
(fn x : real => Math.sqrt (Math.sqrt x)) (16.0)
val fourthroot : real -> real =
fn x : real => Math.sqrt (Math.sqrt x)
fourthroot 16.0```

ML provides a special syntax for function bindings that’s more concise:

`fun fourthroot (x:real):real = Math.sqrt (Math.sqrt x)`

By experimenting (I expect this is covered later), I found the following is sufficient due to type inference:

```fun fourthroot x = Math.sqrt (Math.sqrt x)
```

Local val bindings may shadow parameters and other val bindings. For example, in the following, the last occurrence of x refers to the parameter of h, but the preceding two occurrences of x refer to the local binding with a value of 2.0:

```fun h(x:real):real =
let val x:real = 2.0 in x+x end * x```

## Chapter 5 – Products and Records

The n-tuple is the simplest form of aggregate data structure. They are of the form:
(val1, … ,valn)
An n-tuple is a value of a product type of the form:
typ1* … *typn
For example:

```val pair : int * int = (2, 3)
val triple : int * real * string = (2, 2.0, "2")
val pair_of_pairs : (int * int) * (real * real) = ((2,3),(2.0,3.0))```

A 0-tuple, also known as a null tuple, is the empty sequence of values, ( ). It is a value of type unit. 1-tuples are absent from the language.

### Tuple Patterns

We can use pattern matching to extract portions of an n-tuple. For example, in the code snippet below, r will be equal to 3.14. Underscores indicate “don’t care” positions:

```val foo : (int * string) * (real * char) = ((7,"hello"),(3.14,#"z"))
val ((_, _), (r:real, _)) = foo```

We can give names to the first and second components of the pair – using the REPL:

```- val (is:int*string,rc:real*char) = foo;
val is = (7,"hello") : int * string
val rc = (3.14,#"z") : real * char```

A pattern is one of three forms:

1. A variable pattern of the form var : typ
2. A tuple pattern of the form (pat1, …, patn), where each pati is a pattern. This includes as a special case the null-tuple pattern, ()
3. A wildcard pattern of the form _

### Record Types

Tuples can become more difficult to use as the number of elements increases. Record types allow labeling each component. A record type has the form:
{ lab1:typ1, …, labn:typn}
A record value has the form:
{ lab1=val1, …, labn=valn}
A record pattern has the form:
{ lab1=pat1, …, labn=patn}

For example, the record type hyperlink is defined as follows:

```type hyperlink =
{ protocol : string,
display  : string }
```

The following record binding defines a variable of type hyperlink:

```val mailto : hyperlink =
{ protocol = "mailto",
```

The following record binding:

```val { protocol=prot, display=disp, address=addr } = mailto
```

decomposes into the three variable bindings:

```val prot = "mailto"
```

We can use wildcard to extract selected fields:

```val {protocol=prot, address=_, display=_ } = mailto
```

However, this isn’t very helpful with many fields, so we can use ellipsis patterns:

```val {protocol=prot, ... } = mailto
```

ML provides an abbreviated form of record pattern {lab1,…labn} which stands for { lab1=var1, …, labn=varn} where the variables have the same name as the corresponding labels. For example, the following:

```val { protocol, address, display } = mailto
```

decomposes into these bindings:

```val protocol = "mailto"
```

### Multiple Arguments and Multiple Results

```fun dist (x:real, y:real):real = sqrt (x*x + y*y)
```

Keyword parameters are supported through record patterns:

```fun dist’ {x=x:real, y=y:real} = sqrt (x*x + y*y)
```

Invoked as follows:

```dist' {x=2.0,y=3.0}
```

Functions with multiple results may be thought of as functions yield tuples (or records).

```fun dist2 (x:real, y:real):real*real
= (sqrt (x*x+y*y), abs(x-y))
```

Sharp notation allows us to conveniently access the Nth item in a tuple.

```- val foo = (3,7,5,2);
val foo = (3,7,5,2) : int * int * int * int
- #3 foo;
val it = 5 : int
```

A similar notation is used for record field selection:

``` - val foo = { name = "Brian", phone = "555-1212" };
val foo = {name="Brian",phone="555-1212"} : {name:string, phone:string}
- #name foo;
val it = "Brian" : string
```

However, Harper states, “Use of the sharp notation is strongly discouraged!