Erlang Code Snippet that shows off its benefits? - erlang

I'm giving a small presentation to a group of C/C++ programmers who have very little experience with functional languages. Part of the presentation mentions Erlang, and I would like to give a specific small code example.
There is a ton of awesome information on StackOverflow about how/where Erlang is used and its advantages. One of the most common advantages I see is how it can do a lot with just a little terse code, especially compared to C/C++.
I am looking for a good code snippet of Erlang that simply illustrates these types of benefits. Especially something thats easily done in Erlang with few lines, that would be much more complicated in C/C++.
Anyone have any interesting suggestions?

Check out example 4 for an excellent example of Erlang's bit syntax. I'm sure there are a number of c/c++ developers that will appreciate the brevity of the syntax!

I would use an example which shows how easy it is to do concurrency.
So basically write map-reduce (but never ever use that word to describe it to a C programmer).
You could start with showing a program that plays Fizz Buzz, and then proceed to make it concurrent. Should easily fit a whiteboard, or two pages of powerpoint.

A Co-worker suggested using Merge-Sort as an example:
http://rosettacode.org/wiki/Sorting_algorithms/Merge_sort#Erlang
mergeSort(L) when length(L) == 1 -> L;
mergeSort(L) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
lists:merge(mergeSort(L1), mergeSort(L2)).
Multi-process version:
pMergeSort(L) when length(L) == 1 -> L;
pMergeSort(L) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
spawn(mergesort, pMergeSort2, [L1, self()]),
spawn(mergesort, pMergeSort2, [L2, self()]),
mergeResults([]).
pMergeSort2(L, Parent) when length(L) == 1 -> Parent ! L;
pMergeSort2(L, Parent) when length(L) > 1 ->
{L1, L2} = lists:split(length(L) div 2, L),
spawn(mergesort, pMergeSort2, [L1, self()]),
spawn(mergesort, pMergeSort2, [L2, self()]),
Parent ! mergeResults([]).

Pythagorean Triples. Get all number combinations below 30 whereby the 3 numbers make a right angled triangle as it is according to Pythagoras.
[{X,Y,Z} || X <- lists:seq(1,30),
Y <- lists:seq(1,30),
Z <- lists:seq(1,30), ((X * X) + (Y * Y)) == (Z * Z)].
Try doing that in C/C++ , or Java and see if you will avoid a for loop if not more than one depending on your skill level :)

the factorial code snippet is the best i have always used to show how short erlang programs can be
-module(factorial).
-export([calculate/1]).
calculate(0) -> 1;
calculate(N) -> N * calculate(N -1).
As simple as that. That short program illustrates not only how short Erlang programs can be, But also: Pattern Matching, Function Clauses and Last Call Optimization. I always had a C++ version of the same, below:
#include<iostream.h>
#include<conio.h>
long factorial(unsigned int a);
void main() {
unsigned int a;
long fac;
.....
.....
return factorial(a);
}
long factorial(unsigned int x) {
long fac=1;
if(x == 0) {return 1;}
else {
while(x > 0) {
fac *= x;
x -= 1 ;
}
return fac; }
}
Well, this may not be the shortest C++ version, but i know you get the idea.

Related

this clause cannot match because of different types/sizes

i tried to implement binary_search in erlang :
binary_search(X , List) ->
case {is_number(x) , is_list(List)} of
{false , false} -> {error};
{false , true} -> {error} ;
{true , false} -> {error} ;
{true , true} ->
Length = length(List) ,
case Length of
0 -> {false};
1 -> case lists:member(X , List) of
true -> {true};
false -> {false}
end ;
_ ->
Middle = (Length + 1) div 2 ,
case X >= Middle of
true -> binary_search(X , lists:sublist(List , Middle , Length));
false -> binary_search(X , lists:sublist(List , 1 , Middle))
end
end
end .
However when i try to compile it , i get the following error : "this clause cannot match because of different types/sizes" in the two lines :
{true , false} -> {error} ;
{true , true} ->
is_number(x) will always return false since you made a typo: x instead of X, an atom instead of a variable.
BTW, I don't know what you are experiencing, but the whole code can be written as:
binary_search(X , [_|_] = List) when is_number(X) ->
{lists:member(X,List)};
binary_search(_,_) -> {error}.
Context: The OP's post appears to be a learning example -- an attempt to understand binary search in Erlang -- and is treated as one below (hence the calls to io:format/2 each iteration of the inner function). In production lists:member/2 should be used as noted by Steve Vinoski in a comment below, or lists:member/2 guarded by a function head as in Pascal's answer. What follows is a manual implementation of binary search.
Pascal is correct about the typo, but this code has more fundamental problems. Instead of just finding the typo let's see if we can obviate the need for this nested case checking entirely.
(The code as written above won't work anyway because X should not represent the value of an index, but rather the value that is held at that index, so Middle will likely never match X. Also, there is another issue: you don't cover all the base cases (cases in which you should stop recursing). So the inner function below covers them all up front as matches within the function head, so it is more obvious how the search works. Note the Middle + 1 when X > Value, by the way; contemplate why this is necessary.)
Two main notes on Erlang style
First: If you receive the wrong sort of data, just crash, don't return an error. With that in mind, consider using a guard.
Second: If you find yourself doing lots of cases, you can usually simplify your life by making them named functions. This gives you two advantages:
A much better crash report than you will get within nested case expressions.
A named, pure function can be tested and even formally verified rather easily if it is small enough -- which is also pretty cool. (As a side note, the religion of testing tests my patience and sanity at times, but when you have pure functions you actually can test at least those parts of your program -- so distilling out as much of this sort of thing as possible is a big win.)
Below I do both, and this should obviate the issue you ran into as well as make things a bit easier to read/sort through mentally:
%% Don't return errors, just crash.
%% Only check the data on entry.
%% Guarantee the data is sorted, as this is fundamental to binary search.
binary_search(X, List)
when is_number(X),
is_list(List) ->
bs(X, lists:sort(List)).
%% Get all of our obvious base cases out of the way as matches.
%% Note the lack of type checking; its already been done.
bs(_, []) -> false;
bs(X, [X]) -> true;
bs(X, [_]) -> false;
bs(X, List) ->
ok = io:format("bs(~p, ~p)~n", [X, List]),
Length = length(List),
Middle = (Length + 1) div 2,
Value = lists:nth(Middle, List),
% This is one of those rare times I find an 'if' to be more
% clear in meaning than a 'case'.
if
X == Value -> true;
X > Value -> bs(X, lists:sublist(List, Middle + 1, Length));
X < Value -> bs(X, lists:sublist(List, 1, Middle))
end.

How to write a while() loop in Gforth

I'd like to write a while() loop in Gforth. Unfortunately, the only tutorial online isn't useful due to a lack of examples, and examples on counted loops (what I'm not looking for) appear fundamentally different.
What are some concrete examples of how to represent something like this?
while (x > 3) { print(x); x--; }
Or really, just some concrete way to represent anything of the form:
while (predicate) { expression(s) }
Your first piece of code translates to:
\ Assuming x is on the top of the stack.
begin dup 3 > while dup . 1- repeat
\ Or if x is in memory.
begin x # 3 > while x ? -1 x +! repeat
And the second:
begin predicate while expressions repeat

Sieve of Erastosthenes highest prime factor in erlang

I have edited the program so that it works(with small numbers) however I do not understand how to implement an accumulator as suggested. The reason why is because P changes throughout the process, therefore I do not know in with which granularity I should break up the mother list. The Sieve of Erastosthenes is only efficient for generating smaller primes, so maybe I should have picked a different algorithm to use. Can anybody recommend a decent algorithm for calculating the highest prime factor of 600851475143? Please do not give me code I would prefer a Wikipedia article of something of that nature.
-module(sieve).
-export([find/2,mark/2,primes/1]).
primes(N) -> [2|lists:reverse(primes(lists:seq(2,N),2,[]))].
primes(_,bound_reached,[_|T]) -> T;
primes(L,P,Primes) -> NewList = mark(L,P),
NewP = find(NewList,P),
primes(NewList,NewP,[NewP|Primes]).
find([],_) -> bound_reached;
find([H|_],P) when H > P -> H;
find([_|T],P) -> find(T,P).
mark(L,P) -> lists:reverse(mark(L,P,2,[])).
mark([],_,_,NewList) -> NewList;
mark([_|T],P,Counter,NewList) when Counter rem P =:= 0 -> mark(T,P,Counter+1,[P|NewList]);
mark([H|T],P,Counter,NewList) -> mark(T,P,Counter+1,[H|NewList]).
I found writing this very difficult and I know there are a few things about it that are not very elegant, such as the way I have 2 hardcoded as a prime number. So I would appreciate any C&C and also advice about how to attack these kinds of problems. I look at other implementations and I have absoulutely no idea how the authors think in this way but its something I would like to master.
I have worked out that I can forget the list up until the most recent prime number found, however I have no idea how I am supposed to produce an end bound (subtle humour). I think there is probably something I can use like lists:seq(P,something) and the Counter would be able to handle that as I use modulo rather than resetting it to 0 each time. Ive only done AS level maths so I have no idea what this is.
I cant even do that can I? because I will have to remove multiples of 2 from the entirety of the list. Im thinking that this algorithm will not work unless I cache data to the harddrive, so I'm back to looking for a better algorithm.
I'm now considering writing an algorithm that just uses a counter and keeps a list of primes which are numbers that do not divide evenly with the previously generated prime numbers is this a good way to do it?
This is my new algorithm that I wrote I think it should work but I get the following error "sieve2.erl:7: call to local/imported function is_prime/2 is illegal in guard" I think this is just an aspect of erlang that I do not understand. However I've no idea how I could find the material to read about it. [Im purposely not using higher order functions etc as I have only read upto the bit on recursion in learnyousomeerlang.org]
-module(sieve2).
-export([primes/1]).
primes(N) -> primes(2,N,[2]).
primes(Counter,Max,Primes) when Counter =:= Max -> Primes;
primes(Counter,Max,Primes) when is_prime(Counter,Primes) -> primes(Counter+1,Max,[Counter|Primes]);
primes(Counter,Max,Primes) -> primes(Counter+1,Max,Primes).
is_prime(X, []) -> true;
is_prime(X,[H|T]) when X rem H =:= 0 -> false;
is_prime(X,[H|T]) -> prime(X,T).
The 2nd algorithm does not crash but runs too slowly, I'm thinking that I should reimplement the 1st but this time forget the numbers up until the most recently discovered prime, does anybody know what I could use as an end bound? After looking at other solutions it seems people sometimes just set an arbitrary limit i.e 2 million (this is something I do not really want to do. Others used "lazy" implementations which is what I think I am doing.
This:
lists:seq(2,N div 2)
allocates a list, and as the efficiency guide says, a list requires at least two words of memory per element. (A word is 4 or 8 bytes, depending on whether you have a 32-bit or 64-bit Erlang virtual machine.) So if N is 600851475143, this would require 48 terabytes of memory if I count correctly. (Unlike Haskell, Erlang doesn't do lazy evaluation.)
So you'd need to implement this using an accumulator, similar to what you did with Counter in the mark function. For the stop condition of the recursive function, you wouldn't check for the list being empty, but for the accumulator reaching the max value.
By the way you don't need to test all numbers up to N/2. It is enough to test up to sqrt(N).
Here I wrote a version that takes 20 seconds to find the answer on my machine. It uses kind of lazy list of primes and folding through them. It was fun because I solved some project-euler problems using Haskell quite a long ago and to use the same approach on Erlang was a bit of strange.
On your update3:
primes(Counter,Max,Primes) when Counter =:= Max -> Primes;
primes(Counter,Max,Primes) when is_prime(Counter,Primes) -> primes(Counter+1,Max,[Counter|Primes]);
primes(Counter,Max,Primes) -> primes(Counter+1,Max,Primes).
You cannot use your own defined functions as guard clauses as in Haskell. You have to rewrite it to use it in a case statement:
primes(Counter,Max,Primes) when Counter =:= Max ->
Primes;
primes(Counter,Max,Primes) ->
case is_prime(Counter,Primes) of
true ->
primes(Counter+1,Max,[Counter|Primes]);
_ ->
primes(Counter+1,Max,Primes)
end.

How to generate integer ranges in Erlang?

From the other languages I program in, I'm used to having ranges. In Python, if I want all numbers one up to 100, I write range(1, 101). Similarly, in Haskell I'd write [1..100] and in Scala I'd write 1 to 100.
I can't find something similar in Erlang, either in the syntax or the library. I know that this would be fairly simple to implement myself, but I wanted to make sure it doesn't exist elsewhere first (particularly since a standard library or language implementation would be loads more efficient).
Is there a way to do ranges either in the Erlang language or standard library? Or is there some idiom that I'm missing? I just want to know if I should implement it myself.
I'm also open to the possibility that I shouldn't want to use a range in Erlang (I wouldn't want to be coding Python or Haskell in Erlang). Also, if I do need to implement this myself, if you have any good suggestions for improving performance, I'd love to hear them :)
From http://www.erlang.org/doc/man/lists.html it looks like lists:seq(1, 100) does what you want. You can also do things like lists:seq(1, 100, 2) to get all of the odd numbers in that range instead.
You can use list:seq(From, TO) that's say #bitilly, and also you can use list comprehensions to add more functionality, for example:
1> [X || X <- lists:seq(1,100), X rem 2 == 0].
[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,
44,46,48,50,52,54,56,58|...]
There is a difference between range in Ruby and list:seq in Erlang. Ruby's range doesn't create list and rely on next method, so (1..HugeInteger).each { ... } will not eat up memory. Erlang lists:seq will create list (or I believe it will). So when range is used for side effects, it does make a difference.
P.S. Not just for side effects:
(1..HugeInteger).inject(0) { |s, v| s + v % 1000000 == 0 ? 1 : 0 }
will work the same way as each, not creating a list. Erlang way for this is to create a recursive function. In fact, it is a concealed loop anyway.
Example of lazy stream in Erlang. Although it is not Erlang specific, I guess it can be done in any language with lambdas. New lambda gets created every time stream is advanced so it might put some strain on garbage collector.
range(From, To, _) when From > To ->
done;
range(From, To, Step) ->
{From, fun() -> range(From + Step, To, Step) end}.
list(done) ->
[];
list({Value, Iterator}) ->
[Value | list(Iterator())].
% ----- usage example ------
list_odd_numbers(From, To) ->
list(range(From bor 1, To, 2)).

Why "do...while" does not exist in F#

I cannot find "do...while..."
I have to code like this:
let bubbleSort a=
let n = Array.length a
let mutable swapped = true
let mutable i = 0
while swapped do
swapped <- false
for j = 0 to n-i-2 do
if a.[j] > a.[j+1] then
let t = a.[j]
a.[j] <- a.[j+1]
a.[j+1] <- t
swapped <- true
i <- i+1
The code is bad without "do...while".
Sadly, "break/continue" are also not available.
F# is very much suitable for non-functional programming. In fact, being able to fine-tune parts of an algorithm in an imperative style is one of the major strong points of the language for me.
For example, in tackling a project euler problem, I started out with a clean functional solution using immutable sets and folds. It took 150 seconds to complete. Now having the framework of my algorithm in place allowed me to pick apart the data structures and folds operations one at a time until I managed to get the run time down to 5 seconds. My final solution was very much an imperative one (and even slightly faster than an equivalent C# version).
As you can see I solved it by coding a solution in functional style first and then rewrite small parts to an imperative style. Not having to deal with indices and other loop conditions explicitly kept the code more understandable for me.
Once you learn how to think like a functional programmer you'll find that you'll rarely want breaks and continues. That's what I experienced. But if you do need them, knowing how to think in a functional way helps in coming up with work-arounds, usually involving a tail-recursive version of what used to be a loop.
By the time you start thinking more in an idiomatic F# way, you'll probably see more and more (tail-)recursive code replacing what you used to do with looping constructs. Heck, writing F# for 2 years now has warped my mind so far that I'm more likely to pick recursion and folds over loops.
Whenever I think I need break/continue, I usually don't because there's a cleaner version of the algorithm hidden and waiting to get out. The biggest challenge is learning how to find that cleaner version. I'm afraid that lots of practice and good examples are the only way to get better at thinking functionally, but I believe that it's an effort well spent.
Edit: ironically, bubble sort is an algorithm which is actually designed for arrays with mutable contents. Any recursive bubble sort is likely to be harder to understand than an imperative version. I think I just killed my own post here.
It turns out to be quite easy to write a good enough do-while in F# as a higher-order function:
let doWhile f c =
f ()
while c () do
f ()
break and continue would be a really useful feature additions; they're reserved words, and maybe we'll see them in a future version of the language. The lack of them is an occasional minor annoyance, but hardly makes the language 'unsuitable'. In the mean time, a mutable sentinel works, as you have in your example.
See also
http://tomasp.net/blog/imperative-ii-break.aspx/
do/while is not available because F# is a functional language and this kind of construct is specific to imperative languages.
break/continue is also not available for the same reasons.
However, you can still write do/while in F#. The following code blocks are equivalent :
in C#
do
{
System.Console.WriteLine("processing something...");
System.Console.WriteLine("doing something complicated");
System.Console.Write("continue?");
} while (Console.ReadLine() == "y");
in F#
let doSomethingAndContinue() =
printfn "processing something..."
printfn "doing something complicated"
printf "continue?"
System.Console.ReadLine()="y"
while doSomethingAndContinue() do ignore None
Although a bit more verbose, you can use recursive functions to avoid the "do while" as in :
let swap (a:int[]) i j =
let t = a.[i]
a.[i] <- a.[j]
a.[j] <- t
let rec bubbleSortAux a nMax j swapped =
if j >= 0 && j <= nMax then
if a.[j] > a.[j+1] then
swap a j (j+1)
bubbleSortAux a nMax (j+1) true
else
bubbleSortAux a nMax (j+1) false
else
swapped
let rec bubbleSortLoop a nMax =
if bubbleSortAux a nMax 0 false then
bubbleSortLoop a (nMax - 1)
let bubbleSort a =
bubbleSortLoop a (a.Length - 2)
let bubbleSort (a: _ []) =
let mutable fin = false
while not fin do
fin <- true
for i=0 to a.Length-2 do
if a.[i] > a.[i+1] then
let t = a.[i]
a.[i] <- a.[i+1]
a.[i+1] <- t
fin <- false
I do not know about F# very well, but F# is a functional language. Usually, there is no such thing as "for" or "while" loops in functional programming languages.
Functional languages define functions in a mathematical sense (like f(x) => ...). Writing a program comes down to defining and combining a set of mathematical functions. This means that the only way of coding loops is using recursion.
In Mathematics, there is no way of saying:
f(x) => "do 5 times this"
What you'd do is define f like:
count > 0 : f(x, count-1)
f(x, count) => {
count <= 0 : ...
And then use this function as in:
y = f(x, 5)
This would be exactly how you implement functions in functional languages.
At least, this is true for purely functional languages like Haskell...
You can do something like
let mutable ind = 0
while (
//Do your stuff here
//Now condition part return some boolean value
ind < 10
) do ind <- ind +1
I just recently found this way. It feels a bit hacky but what I like is that you can build something more complex what usually caused issues in C#, C++.
let mutable ind = 0
while (
(some condition) && (
//do something
let someValue = Eval ....
//Now more complex condition
ind + someValue < 10
)
) do ind <- ind +1

Resources