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 4: Classes & Objects

This post will focus on basics of OOP in Scala.

Basics

As we all know, Class is a blueprint of object. A simple class with no variables & methods:

scala> class SimpleClass{}
defined class SimpleClass

scala> var obj=new SimpleClass
obj: SimpleClass = SimpleClass@1364ee5

Member variables: Can be defined using var or val.

Methods: Can be defined using the keyword def as used to define functions.

You must provide initial values of variables in the class

scala> class Person {var name}
<console>:1: error: '=' expected but '}' found.
class Person {var name}
                      ^
scala> class Person {var name=""; var age=0}
defined class Person

scala> p.name="Rasesh"

scala> p.age=24

scala> println(p.age)
24

Now, check the difference between var and val in terms of reference to object:

scala> val p1=new Person
p1: Person = Person@18a80d4

scala> p1=new Person
<console>:6: error: reassignment to val
p1=new Person
  ^

You can change the variables in the object pointed by p1 but not the object being pointed by p1.

Default access in Scala is public for the variables defined. To make it private:

scala> class Person {private var name=""; private var age=0}
defined class Person

scala> var p=new Person
p: Person = Person@9578c1

scala> p.name="Rasesh"
<console>:6: error: variable name cannot be accessed in Person
p.name="Rasesh"

You cannot access or change the fields in the object as they are defined private. So, we will need to add getters and setters in the class:

scala> class Person {private var name=""; def getName() : String = {return name}; def setName(nm: String): Unit = {name=nm} }
defined class Person

scala> val p=new Person
p: Person = Person@1450337

scala> p.setName("Rasesh")

scala> println(p.getName())
Rasesh

Unit is similar to void in Scala. If you don’t specify any return value, it is assumed to be a procedure returning no value i.e. Unit.

The values passed as argument in methods are val, and hence cannot be changed. See an example:

scala> class Person {private var name=""; def getName() : String = {return name}; def setName(nm: String): Unit = {nm="new name"} }
<console>:4: error: reassignment to val
class Person {private var name=""; def getName() : String = {return name}; def setName(nm: String): Unit = {nm="new name"} }

The “return” keyword is not mandatory in Scala and in absence of it returns the last value computed by the method.

scala> def f(): Unit = "this string is lost"
f: ()Unit

scala> f

scala> def g() = "this string is not lost"
g: ()java.lang.String

scala> g
res16: java.lang.String = this string is not lost

scala> def h() { "this string is also lost" }
h: ()Unit

scala> h

scala> def g(): String = { "this string is also lost" }
g: ()String

scala> g
res18: String = this string is also lost

Singleton Objects

Scala does not have static members but it has singleton objects. A singleton object definition looks similar to class but with the keyword “object”

object Person{
var staticInt=0
val person=new Person
person.name="Rasesh Mori"
person.age=24

def greetPerson(): String = "Hello "+person.name+" static int: "+staticInt
}

The singleton object’s name is the same as the class defined above.

When a singleton object shares the same name with a class, it is called that class’s companion object. You must define both the class and its companion object in the same source file. The class is called the companion class of the singleton object. A class
and its companion object can access each other’s private members.

Singleton object is similar to home of static fields in Java. I can also hold methods as described in previous object (greetPerson) and it can be accessed as follows:

$ cat person.scala
class Person{
   private var name=""
   private var age=0

   def getName() : String = name
   def setName(nm: String) { name = nm }

   def getAge() : Int = age
   def setAge(ag: Int) {age=ag}
}

object Person{
   var staticInt=0
   val person=new Person
   person.name="Rasesh Mori"
   person.age=24

   def greetPerson(): String = "Hello "+person.name+" static int: "+staticInt
}

Person.staticInt=1
println(Person.greetPerson())

$ scala person.scala
Hello Rasesh Mori static int: 1

Singleton object acts similar to static block in Java and is executed once it is accessed.

A singleton object that does not share the same name with a companion
class is called a standalone object. You can use standalone objects for many
purposes, including collecting related utility methods together.

Scala Application:

To run a Scala program, you must supply the name of a standalone singleton
object with a main method that takes one parameter, an Array[String],
and has a result type of Unit.

Now, we make some changes in previous “person.scala” file and add a new file “runPerson.scala” as follows:

$ cat person.scala 
class Person{
	private var name=""
	private var age=0

	def getName() : String = name
	def setName(nm: String) { name = nm; Person.staticInt=1 }

	def getAge() : Int = age
	def setAge(ag: Int) {age=ag}
}

object Person{
	var staticInt=0
	val person=new Person
	person.name="Rasesh Mori"
	person.age=24

	def greetPerson(): String = "Hello "+person.name+" static int: "+staticInt
}

$ cat runPerson.scala 
object PersonMain {
	def main(args: Array[String]) {
		val p=new Person
		p.setName(args(0))
		p.setAge(args(1).toInt)
		println(p.getName()+" "+p.getAge())
	}
}

Let’s compile them using scalac, Scala compiler:

$ scalac person.scala runPerson.scala

This creates class files for corresponding classes as shown below:

$ ls *.class
Person.class Person$.class PersonMain.class PersonMain$.class

Now, let’s run the application. Don’t be confused looking at class files that it will be interpreted by ‘java’ but there is a special interpreter that we already used, scala

$ scala PersonMain Rasesh 24
Rasesh 24

Ok. Enough for today. Let’s see what we learn new next time.

<= Previous Post

Scala: Part 3 : Sets & Maps

I will continue with some more data structures offered by Scala.

As Scala focuses on both imperative and functional programming, it offers both immutable and mutable implementations of below mentioned data structures:

1. Using Sets

scala> var jetSet = Set("Boeing","Airbus")
jetSet: scala.collection.immutable.Set[java.lang.String] = Set(Boeing, Airbus)

scala> println(jetSet)
Set(Boeing, Airbus)

Using Set’s apply method (i.e. using parenthesis remember??), by default, it uses immutable implementation of Set as mentioned in the output.

scala.collection.mutable.* contains mutable implementations whereas
scala.collection.immutable.* contains immutable implementations.

“+=” method can be used to append to it. Mutable objects include them whereas immutable objects create new objects to incorporate new element.

scala> jetSet+="Lear"

scala> println(jetSet)
Set(Boeing, Airbus, Lear)

scala> jetSet.+=("Lear2")

scala> println(jetSet)
Set(Boeing, Airbus, Lear, Lear2)

To use mutable set:

scala> import scala.collection.mutable.Set
import scala.collection.mutable.Set

scala> var mutableJetSet=Set("Boeing","Airbus")
mutableJetSet: scala.collection.mutable.Set[java.lang.String] = Set(Airbus, Boeing)

scala> mutableJetSet += "Lear"

scala> println(mutableJetSet)
Set(Airbus, Lear, Boeing)

HashSet is also available in both the implementations:

scala> var hashSet = HashSet("Tomatoes", "Potatoes")
<console>:4: error: not found: value HashSet
var hashSet = HashSet("Tomatoes", "Potatoes")
^

scala> import scala.collection.immutable.HashSet
import scala.collection.immutable.HashSet

scala> var hashSet = HashSet("Tomatoes", "Potatoes")
hashSet: scala.collection.immutable.Set[java.lang.String] = Set(Tomatoes, Potatoes)

scala> import scala.collection.mutable.HashSet
import scala.collection.mutable.HashSet

scala> var mutableHashSet = HashSet("Tomatoes", "Potatoes")
mutableHashSet: scala.collection.mutable.Set[java.lang.String] = Set(Tomatoes, Potatoes)

2. Using Maps:

Again, they are both mutable and immutable available in the same packages.

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala> val battingOrder = Map[Int, String]()
battingOrder: scala.collection.mutable.Map[Int,String] = Map()

scala> battingOrder += (1 -> "Shikhar Dhawan")

scala> battingOrder += (2 -> "Rohit Sharma")

scala> battingOrder += (3 -> "Virat Kohli")

scala> println(battingOrder(2))
Rohit Sharma

Again, HashMap implementations are provided in both the packages.

Now, battingOrder += (2 -> "Rohit Sharma") is internally converted by Scala Compiler as battingOrder.+=((2).->("Rohit Sharma"))

So, here first “->” method is called returning a tuple that is passed to “+=” method.

<= Previous Post                                                                                               Next Post =>

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 =>