What does this F# code look like in Erlang – Part 1 of N

You can become a serverless blackbelt. Enrol to my 4-week online workshop Production-Ready Serverless and gain hands-on experience building something from scratch using serverless technologies. At the end of the workshop, you should have a broader view of the challenges you will face as your serverless architecture matures and expands. You should also have a firm grasp on when serverless is a good fit for your system as well as common pitfalls you need to avoid. Sign up now and get 15% discount with the code yanprs15!

Brushing up on Erlang again having spent so much time with F# since I last looked at Erlang, it’s startling how much parallels I see between the two languages in terms of features and syntax, and I’m sure it’s no coincidence Winking smile

To help myself and other F# programmers who’re curious about Erlang get started more easily, I’m going to run a series of blog posts on how F# code would look in Erlang.

 

Related Posts

 

Assignment

Assignment in F# is done via the let keyword:

let x = 42

let y = 10.0

let z = x * int y

In Erlang, you just write:

1> X = 42.

42

2> Y = 10.0.

10.0

3> Z = X * Y.

420.0

It’s worth noting that in Erlang, variable names have to start with a capital letter or an underscore (‘_’). Also, Erlang variables can be ‘unbound’, and assigned once:

1> A. 

* 1: variable ‘A’ is unbound

2> A = 123.

123

3> A = 321.

** exception error: no match of right hand side value 321

However, you can assign the same value to a bound variable more than once:

1> A = 123.

123

2> A = 123.

123

This works because the equals (‘=’) operator in Erlang is a pattern match operator as opposed to assignment!

The = operator compares values and complains if they’re different, if they are the same it will return the value instead. In the case of an unbound variable, the operator will automatically bind the right-hand side value to the variable on the left-hand side.

 

Wildcard

In F#, you can use the underscore ‘_’ as a wildcard to ignore the value on the right-hand side of an expression:

let _ = 42

In Erlang, it’s the same thing!

1> _ = 42.

42

 

Boolean Algebra

F#:

let a = true && true   // true

let b = true || false    // true

let c = not b            // false

Erlang:

1> A = true and true.

true

2> B = true or false.

true

3> C = not B.

false

In F#, the logical and (‘&&’) and logical or (‘||’) operators will only evaluate arguments on both sides of the operator if necessary, so in the following code snippet only f () is evaluated:

let f () = printfn "hello"; true

let g () = printfn "world"; false

let x = f () || g ()      // prints ‘hello’

let y = g () && f ()   // prints ‘world’

In Erlang, the boolean and and or operators will always evaluate arguments on both sides of the operator. If you want short-circuit behaviour, use the andalso and orelse operators instead.

 

Comparison

F#:

let x = 5 = 5     // true

let y = 5 <> 6   // true

let a = 5 < 6     // true

let b = 5 <= 5   // true

let c = 6 > 5     // true

let d = 5 >= 5   // true

Erlang:

1> 5 =:= 5.

true

2> 5 =/= 6.

true

3> 5 < 6.

true

4> 5 =< 5.

true

5> 6 > 5.

true

6> 5 >= 5.

true

 

Tuples

In F#, a tuple is written in the form ( Element1, Element2, … ElementN ):

let point = (4, 5)

let x, y = point

In Erlang, a tuple is written in the form { Element1, Element2, …, ElementN }, such as:

1> Point = { 4, 5 }.

{ 4, 5 }

2> { X, Y } = Point.

{ 4, 5 }

 

Lists

Lists in F# and Erlang are both implemented as linked-lists, whilst F#’s lists can hold elements of the same type, Erlang’s lists can hold a mixture of anything.

F#:

let lst = [ 1; 2; 3; 4 ]      // [ 1; 2; 3; 4 ]

let hd = lst.Head          // hd = 1

let _::tl = lst                 // tl = [ 2; 3; 4 ]

let lst2 = 1::2::3::4::[ ]    // [ 1; 2; 3; 4 ]

Erlang:

1> Lst = [ 1, "one", { 2, 3 } ].

[1,"one",{2,3}]

2> hd(Lst).

1

3> [ _ | Tl ] = Lst.

["one",{2,3}]

4> Tl.

[“one”,{2, 3}]

6> [ 1 | [ 2 | [ 3 | [ 4 | [ ] ] ] ] ].

[1,2,3,4]

 

List Comprehensions

You can write a simple list comprehension in F# like this:

let lst = [ for x in [ 1..4 ] -> x * 2 ]

This code will look like this in Erlang:

1> Lst = [ X * 2 || X <- [ 1, 2, 3, 4 ] ].

[ 2, 4, 6, 8 ]

Erlang’s list comprehensions also lets you specify conditions on the input for instance:

1> Lst = [ X * 2 || X <- [ 1, 2, 3, 4, 5, 6, 7, 8 ], X =< 4 ].

[ 2, 4, 6, 8 ]

Support for when guards in F#’s list comprehension was removed quite a while back, but you can still achieve the same effect easily enough with a simple if conditions:

let lst = [ for x in [ 1..8 ] do if x <= 4 then yield x * 2 ]

In F#, you can also nest multiple list comprehensions:

let lst = [ for x in [1..8] do

                  for y in [1..4] do

                      if x <= 4 then yield x, y]

To do the same in Erlang, you can specify a second ‘generator expression’:

Lst = [ { X, Y } || X <- [ 1, 2, 3, 4, 5, 6, 7, 8 ], Y <- [ 1, 2, 3, 4 ], X =< 4].

In general, Erlang’s list comprehension is of the form: [ Expression || GeneratorExp1, GeneratorExp2, …, GeneratorExpN, Condition1, Condition2, …, ConditionM ].

 

Functions

In F#, you can define a function using the let keyword followed by the name of the function and its parameters:

let ident x = x

In Erlang, functions can be defined only in modules, and is defined like the following:

-module(my_module).

-export([ident/1]).

ident ( X ) –> X

 

Lambda (anonymous function)

In F#, you can declare a lambda using the fun keyword:

let add = (fun (x, y) –> x + y);

let ans = add(3, 2);     // ans = 5

Guess what, it’s fun to declare lambdas in Erlang too Winking smile

1> Add = fun (X, Y) –> X + Y end.

#Fun<erl_eval.12.82930912>

2> Add(3, 2).

5

Liked this article? Support me on Patreon and get direct help from me via a private Slack channel or 1-2-1 mentoring.
Subscribe to my newsletter


Hi, I’m Yan. I’m an AWS Serverless Hero and I help companies go faster for less by adopting serverless technologies successfully.

Are you struggling with serverless or need guidance on best practices? Do you want someone to review your architecture and help you avoid costly mistakes down the line? Whatever the case, I’m here to help.

Hire me.


Skill up your serverless game with this hands-on workshop.

My 4-week Production-Ready Serverless online workshop is back!

This course takes you through building a production-ready serverless web application from testing, deployment, security, all the way through to observability. The motivation for this course is to give you hands-on experience building something with serverless technologies while giving you a broader view of the challenges you will face as the architecture matures and expands.

We will start at the basics and give you a firm introduction to Lambda and all the relevant concepts and service features (including the latest announcements in 2020). And then gradually ramping up and cover a wide array of topics such as API security, testing strategies, CI/CD, secret management, and operational best practices for monitoring and troubleshooting.

If you enrol now you can also get 15% OFF with the promo code “yanprs15”.

Enrol now and SAVE 15%.


Check out my new podcast Real-World Serverless where I talk with engineers who are building amazing things with serverless technologies and discuss the real-world use cases and challenges they face. If you’re interested in what people are actually doing with serverless and what it’s really like to be working with serverless day-to-day, then this is the podcast for you.


Check out my new course, Learn you some Lambda best practice for great good! In this course, you will learn best practices for working with AWS Lambda in terms of performance, cost, security, scalability, resilience and observability. We will also cover latest features from re:Invent 2019 such as Provisioned Concurrency and Lambda Destinations. Enrol now and start learning!


Check out my video course, Complete Guide to AWS Step Functions. In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. There is something for everyone from beginners to more advanced users looking for design patterns and best practices. Enrol now and start learning!