-
Notifications
You must be signed in to change notification settings - Fork 32
LanguageReference
Variables start with uppercase and can’t be set twice (single assignment)
A = 2
to change it’s value assign to a new variable
B = A + 1
each expressions ends with a new line, you can make multiline extensions escaping the new line with the ‘\’ character
E = 12 + \
5 * 2
arithmetic expressions are like any programming language
A = (2 + 3) * (6 / (B + 1)) - 5 % 2
logic expressions are like python
(true or false) xor false and not true
binary operations are like C/C++/Java and similar languages
Bin = (2 << 5) | (255 & ~0)
different ways to express numbers (decimal, hexadecimal, octal, binary)
D = 12 + 0xf - 0o10 + 0b1101
strings
S = "Hello"
S1 = "World"
S2 = S ++ " " ++ S1
the basic types supported are integers, floats, booleans, strings which you saw above and lists, tuples, binaries and atoms.
List = [1, 2, 3, 4]
commas are not required
List1 = [2 3 4 5]
lists can contain any type inside (even other lists)
List2 = [1 2.0 false ["another list"]]
tuples are like lists but once you define them you can’t modify them
Tuple = (1, 2, 3, 4)
tuples can also be specified without commas
Tuple1 = (1 2 3 4)
and also can contain anything inside them
Tuple2 = (1 2.0 false ["a list" ("another" "tuple")])
binaries are a type that contains binary data inside them, you can store numbers or even a binary string (common strings are represented as lists internally)
Bin1 = <[1, 2, 3, 4]>
you can have a string represented as a binary
Bin2 = <["mariano"]>
an atom is a named constant. It does not have an explicit value.
A = foo
T = (foo bar baz)
they may seem useless at first, but believe me, they will be useful.
functions are declared with the following format:
<name> = fn ([<arguments>]) {
<body>
}
where arguments are optional
an actual example
divide = fn (A B) {
A / B
}
see that we don’t declare types, and the returned value is the last expression evaluated.
commas on the arguments are optional
now we can call the function
divide(10 5)
we know that we can’t divide by 0, so we can use pattern matching for that
divide = fn (A 0) {
error
} (A B) {
A / B
}
here we give two definitions for the function, the first “matches” when the second argument is zero and returns the error atom.
the second definition is more generic and will match everything that didn’t matched the previous definitions.
we can declare functions and assign them to variables and pass them around like any common variable, the syntax is the same and you can do the same things.
SayHi = fn (Name) {
io.format("hi ~s!~n", [Name])
}
SayHi("efene")
we can restrict our functions adding guards, that check conditions on the arguments before calling them, we could restrict our previous function to allow only numbers
divide = fn (A 0) when is_number(A) {
error
} (A B) when is_number(A) and is_number(B){
A / B
}
here we say that the function will be called only when A and B are numbers.
this items are not advanced because of their complexity, only they are advanced because you may need them when you master the items explained above.