Getting started with erlang

This post is more of notes as compared to a step-by-step tutorial.

Install Erlang
Download and install Erlang http://erlangcentral.org/downloads/

Shell

$ erl
Erlang/OTP 17 [erts-6.0] [source-07b8f44] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Eshell V6.0  (abort with ^G)

erl is the command to start the Erlang shell.

You can also use this online interpreter: http://www.erlangcentral.com/interpreter/index.yaws

Numbers
Expressions in Erlang are terminated by .(dot) followed by whitespace (line break, space etc.)

Usage of arithmetic operators (+, *, /, div, rem and -):

1> 5+5.
10
2> 5*10.
50
3> 25/2.
12.5
4> 25 div 2.
12
5> 25 rem 2.
1
6> 10-5.
5
  • ‘/’ operator by default performs a floating point operation.
  • For integer division, use ‘div’ operator.
  • For modulo operation, use ‘rem’ operator.

Numbers in other bases

Numbers can be expressed with base other than 10.

7> 2#101.
5
8> 8#723.
467
9> 16#abe.
2750

Variables

  • Being a functional programming language, variables are immutable.
  • Variable names must start with a capital letter or ‘_’.
10> FirstVariable.
* 1: variable 'FirstVariable' is unbound
11> Three.
* 1: variable 'Three' is unbound
12> Three=3.
3
13> Five=Three+2.
5
14> Two=2.
2
15> Five=Three+Two.
5
16> Five=Five+1.
** exception error: no match of right hand side value 6
17> Three=4.
** exception error: no match of right hand side value 4
  • A variable once assigned a value cannot be changed. (Refer command 16 and 17).
  • A variable can be assigned the same value any number of times. (Refer command 13 and 15).
  • ‘=’ operator tries to compare the values on left and right side. If there is a variable on left hand side and it is not bound, it is assigned the value.
  • If left and right side both have value and do not match, it throws an error.
18> 85=45+40.
85
19> 85=40+40.
** exception error: no match of right hand side value 80

More examples on variables:

20> three=3.
** exception error: no match of right hand side value 3
21> _=3.
3
22> _.
* 1: variable '_' is unbound
  • ‘three’ is invalid variable name as it does not start with capital letter.
  • _ is a special variable to which no value can be bound.

Erase a variable’s value

23> Three.
3
24> f(Three).
ok
25> Three.
* 1: variable 'Three' is unbound
26> Five.
5
27> Two.
2
28> f().
ok
29> Two.
* 1: variable 'Two' is unbound
30> Five.
* 1: variable 'Five' is unbound

Atoms

Atoms are the reason why variable names cannot start with lower-case letters. Atoms are literals,constants with the value same as their name. As the name suggests, it cannot be smashed into species nor can it be changed.

Well, ironman is ‘ironman’ and it can’t be ‘Tony Stark’ 🙂

An atom that does not start with lower-case letter or contains anything other than alphanumeric characters, “_” or “@” must be enclosed in single quotes (‘).

31> iamatom.
iamatom
32> iamatom=5.
** exception error: no match of right hand side value 5
33> iamatom='iamatom'.
iamatom
34> iamatom=iamatom.
iamatom
35> 'I am also an atom'.
'I am also an atom'
  • Atoms generally represent constants and should be used with care as they are not garbage-collected.
  • They are referred in ‘atom table’ with memory usage of 4 bytes/atom in 32-bit and 8 bytes/atom in 64-bit system.
  • Reserved atoms: after and andalso band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse query receive rem try when xor.

Boolean Algebra and comparison operators

Well, what is the use of a language if it can’t distinguish apple to oranges 🙂

1> true and false.
false
2> true or false.
true
3> true and true.
true
4> false or false.
false
5> not (true and true).
false
6> true xor false.
true
7> true xor true.
false
8> false xor true.
true
9> false xor false.
false
10> true andalso true.
true
11> false andalso true.
false
12> true orelse false.
true
  • and, or, not, xor are quite straight forward.
  • andalso is similar to and. The difference is that it does not evaluate another expression if it does not need to.
  • orelse is counterpart of or as andalso is for and.

Euality and Inequality:

13> One=1.
1
14> Two=2.
2
15> 2=:= 2.
true
16> 2=/=2.
false
17> 5=/=2.
true
18> One=:=One.
true
19> One=/=Two.
true
  • =:= is comparable to ‘==’ in other languages and =/= is comparable to ‘!=’
  • ‘==’ and ‘/=’ in Erlang are used to compare values of different types.
20> 5=:=5.0.
false
21> 5==5.0.
true
22> 5=/=5.0.
true
23> 5/=5.0.
false

Other comparison operators:

24> 1<2.
true
25> 1>2.
false
26> 1>=2.
false
27> 1<=2.
* 1: syntax error before: '<='
  • Oh!! Does this mean there is no ‘less than or equal to’ operator? Here it is with a different symbol:
27> 1=<2.
true
28> 2=<2.
true

Well, do you think you have got it all correct? Let’s try this:

29> 7-foo.
** exception error: an error occurred when evaluating an arithmetic expression
in operator -/2
called as 7 - foo
30> 5=:=false.
false
  • Erlang slapped you hard with the error details when you subtracted foo from 7.
  • But, it is all okay comparing 5 to false!!!! – Well, 5 is not false, right?

If this is not enough, take this:

31> 1<false.
true
32> 2<false.
true
33> 54<false.
true
34> 546734<false.
true

A total ordering on all data types is defined based on which numbers < atoms. Hence, 1<false. ‘false’ is not a special value. It is just an atom, remember?

Well, we have had enough now. Let’s take a break and we will continue from here.

Scala: Part 2: Arrays, List & Tuples

I will continue exploring more features in Scala here.

1. Parameterize Array with types:

val big = new java.math.BigInteger("12345")
$ cat 6_arrays.scala
val greetScala = new Array[String](3)

greetScala(0) = "Hi "
greetScala(1) = args(0) + ", "
greetScala(2) = "Welcome to Scala!\n"

for(str <- greetScala)
print(str)

$ scala 6_arrays.scala Rasesh
Hi Rasesh, Welcome to Scala!

Use of parenthesis makes a call to method apply of the first object passing values in the parenthesis as arguments to method called apply.

In the previous example, greetScala(0) is translated to greetScala.apply(0). It is true for any object that has method called apply.

Also, Scala has no operators in traditional sense. Its just functions names +,-,/,*. It seems weird if you are not familiar with functional programming but this is how its done in most languages like Lisp and Scheme.

This means 1+2 is a call to method called ‘+’ and its passed 2 as argument. Its same as (1).+(2)

scala> 1+2
res0: Int = 3

scala> (1).+(2)
res1: Int = 3

Similarly, when used on left side of ‘=’, parenthesis are replaced by a call to update method as in greetScala(0) = "Hi " is equivalent to greetScala.update(0, "Hi ")

Note: Everything in Scala, from arrays to expressions are objects with methods.

Initialize an array without specifying datatype:

val numNames = Array("zero", "one", "two")

This is similar to calling Array.apply(“zero”,”one”,”two”). We can assume apply to be a static function in Array class.

2. Using Lists:

List are immutable elements as in functional programming languages Lisp, Scheme etc. It means once created list elements do not change. It is similar to String class in Java.

scala> val oneTwo=List(1,2)
oneTwo: List[Int] = List(1, 2)

scala> val numStr=List(1,"str")
numStr: List[Any] = List(1, str)

List has a method ‘:::‘ for list concatenation. As it is a method, it can also be used with dot operator as mentioned previously (a catch here, explained after :: operator) and explained in example below:

scala> val concatenated = oneTwo ::: numStr
concatenated: List[Any] = List(1, 2, 1, str)

scala> println(concatenated)
List(1, 2, 1, str)

scala> val con2=(oneTwo).:::(numStr)
con2: List[Any] = List(1, str, 1, 2)

Original List oneTwo is not mutated.

scala> println(oneTwo)
List(1, 2)

Another operator on list is ‘::‘ which has exactly the same purpose as ‘cons’ in Scheme, if you are familiar with it. It considers the left element as the first element of the new list appended by the list on the right side of the operator.

scala> val newList = 0 :: oneTwo
newList: List[Int] = List(0, 1, 2)

scala> val nestedList = oneTwo :: numStr
nestedList: List[Any] = List(List(1, 2), 1, str)

scala> oneTwo.::(numStr)
res2: List[Any] = List(List(1, str), 1, 2)

The output of oneTwo :: numStr should be same as oneTwo.::(numStr) as per our understanding so far. But, we see something else here. In Scala, when a method name ends with a ‘:’, the calling object is on the right side and the passed object in the one on left. This means oneTwo :: numStr is equivalent to numStr.::(oneTwo).

‘Nil’ or List() is used to specify empty list which is equivalent of ‘() or empty in Scheme. To create a list 1,2,3 in Scheme, one can write (cons 1 (cons 2 (cons 3 ‘()))). Similarly, in Scala, you can write

scala> val oneTwoThree = 1 :: 2 :: 3 :: Nil
oneTwoThree: List[Int] = List(1, 2, 3)

This is just an introduction to list. There are many more list operations supported by Scala.

3. Using Tuples:

Tuple is a combination of multiple values of any data type similar to ‘pair’ in C++ STL but not limited to 2 values. In Java, you need to create a class of 2 variables to return multiple values from a method, but it can be done using tuples in Scala.

Tuples are immutable like List.

scala> val pair = (1, "Hi", 4.5)
pair: (Int, java.lang.String) = (1,Hi,4.5)

scala> println(pair._1)
1

scala> println(pair._2)
Hi

scala> println(pair._3)
4.5

First element is referred by _1 element and second one by _2 and so on.

Further exploration of language in next posts.

<= Previous Post                                                                                            Next Post =>

Getting started with Scala

This post is not to teach scala but a small reference for what I am going to learn about Scala. I am referring to the book “Programming in Scala”.

Feel free to look at small code snippets I used to get started with JVM based OOP and functional programming language. I will start with Scala shell prompt.

1. val defines variables similar to final identifier in Java:

scala> val msg="Hello World"
msg: java.lang.String = Hello World
scala> println(msg)
Hello World
scala> msg="Hi"
<console>:5: error: reassignment to val 
msg="Hi" 
   ^ 
scala>

2. Print a value or variable using println():

scala> println("Hello Scala")
Hello Scala

scala> println(msg)
Hello World

3. Using variables:

scala> var msg="Hello Scala"
msg: java.lang.String = Hello Scala

scala> var msg2: java.lang.String = "Hello Scala with explicit data type"
msg2: java.lang.String = Hello Scala with explicit data type

4. Define Function:

scala> def max(x: Int, y: Int): Int = {
| if(x>y) x
| else y
| }
max: (Int,Int)Int
scala> max(5,8)
res13: Int = 8

def – keyword to define function
max – function name
x and y – Parameters to function max of type Int that maps to int(primitive data type) in Java
Int – Return type of the function

scala> def greet() = println("Hello, world!")
greet: ()Unit

scala> greet()
Hello, world!

scala> greet
Hello, world!

5. Scala Scripts

$ cat first_script.scala
println("Hello Scala from script")
$ scala first_script.scala
Hello Scala from script

Arguments to Scala script are made available in an array named args and elements are accessed using () as in older languages.

$ cat second_script.scala
// Comment in scala
println("Hello "+args(0))
$ scala second_script.scala Rasesh
Hello Rasesh
$ scala second_script.scala
java.lang.ArrayIndexOutOfBoundsException: 0
at Main$$anon$1.<init>((virtual file):6)
at Main$.main((virtual file):4)
at Main.main((virtual file))

6. Loops: while

$ cat 3_printargs.scala
var i=0
while(i<args.length){
println(args(i))
i+=1
}

$ scala 3_printargs.scala

$ scala 3_printargs.scala Hi Hello Scala
Hi
Hello
Scala

Note: i++ or ++i does not work in Scala as in Java

7. Loops: foreach and for

$ cat 4_foreach.scala
args.foreach(arg => println(arg))

$ scala 4_foreach.scala 1 2 3
1
2
3
$ cat 4_foreach.scala
args.foreach((arg:String) => println(arg))

$ scala 4_foreach.scala 1 2 3
1
2
3
$ cat 4_foreach.scala
args.foreach(println)

$ scala 4_foreach.scala 1 2 3
1
2
3

foreach accepts a function as an argument (functional programming aspect) and in each of 3 examples above, we passed a function to it and it executed it for each element in args array.

Imperative for:

$ cat 5_for.scala
for (arg <- args)
println(arg)

$ scala 5_for.scala 1 2 3
1
2
3

This was first glimpse of Scala and I will continue in other post as I try different things learning Scala.

This is helpful: http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html

Next Post =>