- Referential transparency
- Side effects
- Pure functions/languages

Algebraic reasoning about program expressions and equality. These two ‘should’ be equivalent: \(3*e^2+4\) and \(3*e*e+4\). Consider if \(e\) is a C++ function like:

This function `f1`

is pure (no side effects), so the equivalence works:

```
3 * e^2 + 4 where e = f1(5)
== 3 * f1(5)^2 + 4
== 3 * 6^2 + 4
== 3 * 36 + 4
== 108 + 4
== 112
3 * e * e + 4 where e = f1(5)
== 3 * f1(5) * f1(5) + 4
== 3 * 6 * f1(5) + 4
== 3 * 6 * 6 + 4
== 108 + 4
== 112
```

But consider instead this function:

```
3 * e^2 + 4 where e = f2(5)
== 3 * f2(5)^2 + 4
== 3 * 6^2 + 4 // Outputs "Hello!"
== 3 * 36 + 4
== 108 + 4
== 112
3 * e * e + 4 where e = f2(5)
== 3 * f2(5) * f2(5) + 4
== 3 * 6 * f2(5) + 4 // Outputs "Hello!"
== 3 * 6 * 6 + 4 // Outputs "Hello!" again
== 108 + 4
== 112
```

The function `f2`

does have a side effect: its output. Although both expressions produce the same final value, they can be distinguished by how many times “Hello!” appears.

We can do even worse than this. Here’s another type of side effect:

```
3 * e^2 + 4 where e = f3(5)
== 3 * f3(5)^2 + 4 // g becomes 9
== 3 * 14^2 + 4
== 3 * 196 + 4
== 588 + 4
== 592
// Let's assume g is reset to 8 before proceeding
3 * e * e + 4 where e = f3(5)
== 3 * f3(5) * f3(5) + 4 // g becomes 9 in first application of f3
== 3 * 14 * f3(5) + 4 // g becomes 10 in next application
== 3 * 14 * 15 + 4
== 630 + 4
== 634
```

Now we get completely different results.

Another typical violation of referential transparency is any function that returns random numbers. This also amounts to modification of global state.

- GHC = Glasgow Haskell Compiler
- REPL = Read, Eval, Print, Loop

Save this as `hello.hs`

:

Then you can compile and run:

```
% ghc hello.hs
% ./hello
Hello, world... this is a test!
```

Here’s what starting the REPL looks like:

```
% ghci
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
Prelude>
```

At that prompt, you can type expressions and have them evaluated:

```
Prelude> 1+2*3
7
Prelude> 19 `div` 2
9
Prelude> 19 / 2
9.5
Prelude> 2**pi
8.824977827076287
```

The double-star is floating-point exponentiation. You can instead use the hat (`^`

) for integer exponentiation.

Caveat about negation operator: in Haskell, the negative sign (subtraction operator) sometimes causes syntactic confusion:

```
Prelude> 3 * -2
<interactive>:7:1: error:
Precedence parsing error
cannot mix ‘*’ [infixl 7] and prefix `-' [infixl 6]
in the same infix expression
```

The solution to this is just to use parentheses around negation.

```
Prelude> 3 * (-2)
-6
```

Function application does not require parentheses. Here are some simple examples of defining small functions right in the REPL.

```
Prelude> areaCircle r = pi * r**2
Prelude> volumeSphere r = 4/3 * pi * r**3
Prelude> areaCircle 5
78.53981633974483
Prelude> volumeSphere 5
523.5987755982989
```

Notice that we don’t need parentheses to invoke those functions. You don’t need to say `areaCircle(5)`

, just `areaCircle 5`

is sufficient. If parentheses do appear, they are used to group arguments together. For example,

`areaCircle 5 + 2`

would be interpreted as

```
(areaCircle 5) + 2
== 78.53981633974483 + 2
== 80.53981633974483
```

but if you want to add first, then use explicit parens:

```
areaCircle (5 + 2)
== areaCircle 7
== 153.93804002589985
```

Functions in Haskell can be named either with alphanumeric identifiers (examples: `sqrt`

, `div`

, `areaCircle`

) or symbolic identifiers (examples: `/`

, `**`

, `<*>`

, `>@>>`

).

By default, alphanumeric identifiers are defined and invoked using *prefix* notation – the function name appears before any of its arguments. In contrast, symbolic identifiers are defined and invoked using *infix* notation – it is assumed that the operation takes two parameters, and the symbol appears *between* them.

For example, the integer division function (`div`

) is alphanumeric and the floating-point division function (`/`

) is symbolic. They each take two parameters. So the default way to call them is:

However, you can override this. We can use alphanumeric function names with infix notation (as long as the function takes exactly two parameters) by surrounding them with “back ticks” – on most keyboards this is on the same key as the tilde (`~`

) character:

We can also use symbolic function names with prefix notation by surrounding the symbol with parentheses:

These notation rules also apply to the function definition. Let’s make up an operation of two parameters that adds their squares:

This defines it:

and here’s a sample usage: