2 Diving In

2.1 Numbers and Operators

2.1.1 Integers and Floats

Let's start with something simple :-) To follow along, fire up your LFE REPL. Numbers are simple in LFE, just like Erlang:

> 1
1
> 2
2
> 3
3
>

Of course, it might be more interesting to look at something like different bases:

> #b101010
42
> #o52
42
> #x2a
42
> #36r16
42
>

LFE supports representing binary (#b), octal (#o), decimal (#d), hexidecimal (#x), as well as aribtrary bases from 1 through 36 (#XrY).

With some help from calling an Erlang function, we can work the bases in reverse, too:

> (integer_to_list 123 2)
"1111011"

Note that the first argument is the number you want to convert and the second is the base you want to use (see here for more details).

2.1.2 Arithmatic Operators

But numbers by themselves aren't going to do us much good if we can't operate on them. The usual apply:

> (+ 1 2 3 4 5 6)
21
> (- 6 21)
15
> (/ 36 7)
5.142857142857143
> (+ #b101010 #o52 #x2a #36r16)
168
> (* 42 4)
168
> (integer_to_list (+ #b1001 #b100 #b10) 2)
"1111"
> (div 11 2)
5
> (rem 11 2)
1
> `(,(div 11 2) ,(rem 11 2))
(5 1)
>

2.1.3 Logical Operators

The usual suspects are used as follows:

> (< 1 2)
true
> (> 1 2)
false
> (>= 2 2)
true
> (=< 3 2)
false
> (>= 3 2)
true
> (== 1 1)
true
> (== 1 1.0)
true
> (/= 1 1)
false
> (/= 2 1)
true
>

Note the rather awkward different between "less than" and "greater than": it's easy to forget that the angle brackets go at different ends for each.

Then there are the operators which also check against type for exact (non-)equality:

> (=:= 1 1.0)
false
> (=:= 1.0 1.0)
true
> (=/= 1.0 1.0)
false
> (=/= 1 1.0)
true
>

2.1.4 Boolean Operators

How about some logic?

> (and 'true 'false)
false
> (and 'true 'true)
true
> (or 'true 'true)
true
> (or 'true 'false)
true
> (or 'false 'false)
false
> (not 'false)
true
> (not 'true)
false
> (xor 'true 'true)
false
> (xor 'false 'false)
false
> (xor 'true 'false)
true
>

There are also two boolean operators that you can use if you want to make a decision based on the truth value of the first term without having to compute the second term (useful if you have no need to do the second computation when the first term is false):

> (andalso 'false 1)
false
> (andalso 'true 1)
1
> (orelse 'true 1)
true
> (orelse 'false 1)
1
>

In the case of andalso if the first argument is false the second one will not be evaluated; false will be returned. In the case of orelse if the first argument is true then true will be returned without evaluating the second argument.

Contrast this to regular or and and:

> (and 'false 1)
exception error: badarg
  in (: erlang and false 1)

> (and 'true 1)
exception error: badarg
  in (: erlang and true 1)

> (or 'false 1)
exception error: badarg
  in (: erlang or false 1)

> (or 'true 1)
exception error: badarg
  in (: erlang or true 1)

>

2.1.5 Bitwise Operators

As one would expect, Erlang has the usual bitwise operators as well. Binary representation is used below for clarity of demonstration. Let's define a utility function that will save a little typing:

> (set dec-to-bin (lambda (x) (integer_to_list x 2)))
#Fun<lfe_eval.10.53503600>
>

With that defined so that we can use it, let's take a look at some of these operators:

> (funcall dec-to-bin (band #b10001 #b1001))
"1"
> (funcall dec-to-bin (bor #b10001 #b1001))
"11001"
> (funcall dec-to-bin (bxor #b10001 #b1001))
"11000"
> (funcall dec-to-bin (bnot #b10001))
"-10010"
> (funcall dec-to-bin (bnot (bnot #b10001)))
"10001"
> (funcall dec-to-bin (bsl #b10001 1))
"100010"
> (funcall dec-to-bin (bsr #b10001 1))
"1000"
>