notes about erlang

Keeping a spawn process alive

-module(dolphins).
-compile(export_all).

dolphin1() ->

    receive
    
        {From, do_a_flip} ->
            From ! "what about no?~n", dolphin1();
            
        {From, fish} ->
            From ! "thanks~n", dolphin1();
            
        _ ->
            io:format("beh~n") 
            
    %% you can't call dolphin() here,
    %% everything at this point is unreachable!
    end.

This is a shorter version


dolphin2() ->

    receive
    
        {From, do_a_flip} ->
            From ! "what about no?~n";
            
        {From, fish} ->
            From ! "thanks~n";
            
        _ ->
            io:format("beh~n") 
            
    
    end,
    
    %% keep this process alive
    dolphin2().

receive, waiting, and functions
If a given [non spawned] function has a receive block, then such a function will be waiting for an answer.

take(Pid, Food) ->
    Pid ! {self(), {take, Food}},
    receive
        {Pid, Msg} ->    % waiting for a response!
            Msg
    end.

Now, suppose that you call take using an arbitrary pid:

40> kitchen:take(pid(0, 250, 0), milk).
% waiting, press ctrl+g, i, c

To overcome this situation, just add an after clause:

take(Pid, Food) ->
    Pid ! {self(), {take, Food}},
    receive
        {Pid, Msg} ->
            Msg
    after 3000 ->
        timeout.
    end.

This way, if there is no an answer after 3 seconds, the function will return timeout.

Conclusion: don’t add a receive block on a non spawned function unless you know what you are doing.

Flush my mailbox

Add some messages to your mailbox:

44> self() ! self() ! self() ! new_message

Then, flush and print them using your own version of flush:

flush() ->

    receive
        Any -> io:format("~p~n", [Any]), flush()
    after 0 -> ok % if you comment this line, 
                  % it will be waiting for more messages in the mailbox

    end.

This function works as follows.

1. Given that a receive block is involved, flush will read its mailbox looking for a message that match the pattern Any (in this case, all the messages match).
2. Then, the message is printed, removed from the mailbox, and flush is started again.
3. When the mailbox is empty, the function will wait for 0 secs and return ok.

Guards: (orelse,andalso) vs. (;,)

According to lyshfgg, andalso and orelse are preferred to , and ; when exception handling is involved.

if and pattern matching

These two snippets are equivalent. Obviously, the latter is shorter and cleaner.

% if
oh_god(N) ->
    if N =:= 3 -> equals_three;
       N =:= 4 -> equals_four;
       true -> error     % else
    end. 
% guards
oh(X) when X =:= 3 -> equals_three;
oh(X) when X =:= 4 -> equals_four;
oh(_) -> error.
% pattern matching
oh_no(3) -> equals_three;
oh_no(4) -> equals_four;
oh_no(_) -> error.

Also, remember to add a true clause inside an if block. Other atoms and “_” are not allowed.

talking(Animal) ->
    Talk = if   Animal == cat -> "meoow";
                Animal == dog -> "woof";
                Animal == cow -> "mooo";
                true -> "??"                % it must be true, "_" is not allowed within an if block
            end,
        {Animal, "says " ++ Talk ++ "!"}.

about pids and spawned process
The pid of a spawned process does not change after sending several messages. Also, if a function is spawned n times, then there will be n different pids. Consider the following snippet:

-module(process).
-compile(export_all).

start_process() ->
    SpawnedPid = spawn(?MODULE, process, []),       %% spawn process
    io:format("Spawned pid: ~p~n", [SpawnedPid]),   %% print pid
    SpawnedPid.                                     %% return pid as output
    
process() ->

    MyPid = self(),

    receive
        Any ->
            io:format("Message received: ~p, Pid: ~p~n", [Any, MyPid]),
            process()
    end.

In the following, the function process is spawned two times, and two pids are created: Pid1 (0.117.0), and Pid2 (0.119.0).

45> c(process).                    
{ok,process}
46> Pid1 = process:start_process().
Spawned pid: <0.117.0>
<0.117.0>
47> Pid2 = process:start_process().
Spawned pid: <0.119.0>
<0.119.0>
48> Pid1 ! message.                
Message received: message, Pid: <0.117.0>
message
49> Pid1 ! message.
Message received: message, Pid: <0.117.0>
message
50> Pid2 ! message.
Message received: message, Pid: <0.119.0>
message
51> Pid2 ! message.
Message received: message, Pid: <0.119.0>
message

tail recursion and spawned process

The following snippet computes the factorial of a number using tail recursion.

tail_fact(N) -> tail_fact(N, 1).

tail_fact(0, Acc) -> Acc;
tail_fact(N, Acc) when N > 0 -> tail_fact(N-1, N*Acc).

The idea is to keep the result of each operation using a temporary variable called accumulator (Acc). When the recursion process is finished (i.e. the base case is reached), the accumulator is returned. In the following example, the previous function will be implemented using message passing. To this end, we will follow the pattern described in the previous point (about pids and spawned process).

We start with a simple function which takes as parameters the pid of the shell (i.e. the pid that will receive the output of the factorial function) and the number which factorial will be computed.

start_sfactorial(From, N)

This function is almost the same as start_process, previously described. The goal of this function is to spawn the main process, in our case, to compute the factorial of a given number.

start_sfactorial(From, N) ->
    SpawnedPid = spawn(?MODULE, sfactorial, [From]),            %% spawn factorial process
    io:format("Spawned factorial pid: ~p~n", [SpawnedPid]),     %% print pid
    
    SpawnedPid ! {SpawnedPid, N, 1},                            %% start
    
    SpawnedPid.                                                 %% return pid as output    

First, we spawn a function called sfactorial, which takes a single value as parameter: the pid that will receive the answer (From). Then, the spawned pid is printed (SpawnedPid). The next line is the most important one. In this line, the factorial process is started by sending an initial message with this format:

SpawnedPid ! {SpawnedPid, N, Acc}

where SpawnedPid represents the pid of the [spawned] factorial function (sfactorial), N is the number which factorial will be computed, and Acc is our accumulator. At the beginning, the accumulator is 1 (the same as tail_fact). Finally, SpawnedPid is returned, but this step can be omited or replaced by an ok atom.

Our sfactorial function is sketched as follows:

sfactorial(From) ->

    MyPid = self(),
    
    receive
    
        %% base case
        {MyPid, ...} ->
            do_something;
    
        %% otherwise
        {MyPid, ...} ->
            do_something
    end.

As you can see, this function works using messages. Note that only those messages coming from MyPid are received. The base case is implemented as follows:

    {MyPid, 0, Acc} ->
        io:format("Acc: ~p~n", [Acc]),
        From ! Acc;

In this case, the value of N is 0. Therefore, the accumulator is returned. To this end, we send Acc to From‘s pid. That’s it! Additionally, we can output Acc using io:format.

The remaining case is implemented as follows:

    {MyPid, N, Acc} -> 
        MyPid ! {MyPid, N-1, Acc*N}
        sfactorial(From),

First, a message is sent to MyPid:

MyPid ! {MyPid, N-1, Acc*N}

As you can see, the factorial of N is computed using Acc (Acc*N). Then, we ask for the factorial of N-1. Note that we keep this process alive by using sfactorial(From).

Putting all together:

-module(process).
-compile(export_all).

tail_fact(N) -> tail_fact(N, 1).

tail_fact(0, Acc) -> Acc;
tail_fact(N, Acc) when N > 0 -> tail_fact(N-1, N*Acc).


start_sfactorial(From, N) ->
    SpawnedPid = spawn(?MODULE, sfactorial, [From]),            %% spawn factorial process
    io:format("Spawned factorial pid: ~p~n", [SpawnedPid]),     %% print pid
    
    SpawnedPid ! {SpawnedPid, N, 1},                            %% start
    
    SpawnedPid.                                                 %% return pid as output
    



sfactorial(From) ->

    MyPid = self(),          
    receive
    
        {MyPid, 0, Acc} ->
            
            %% end of recursion
            %% send Acc
            io:format("Acc: ~p~n", [Acc]),
            
            %% send Acc to From
            From ! Acc;
            
        {MyPid, N, Acc} -> 
        
            %% send Acc    
            MyPid ! {MyPid, N-1, Acc*N},
            
            %% keep process alive
            sfactorial(From)
    
    end.

Finally, this function can be called as follows:

11> c(process).
{ok,process}
12> process:start_sfactorial(self(), 5).
Spawned factorial pid: <0.70.0>
Acc: 120
<0.70.0>

Maybe you have noticed that this implementation does not use any guards. So,
you can do the following:

103> f(), c(process).
{ok,process}
104> Pid = spawn(process, sfactorial, [self()]).
<0.281.0>
105> Pid ! {Pid, number, 1}.

=ERROR REPORT==== 6-Jan-2016::21:34:42 ===
Error in process <0.281.0> with exit value: {badarith,[{process,sfactorial,1,[{file,"process.erl"},{line,60}]}]}

{<0.281.0>,number,1}

In this case, we are asking for the factorial of an atom: number. That is, we can send anything to Pid, even if it is not a number. In order to avoid this, we can use guards. The next snippet contains a better implementation of our previous function, now using guards. Also, we added a new clause to output a comment when the received message did not matched any pattern.

sfactorial(From) ->

    MyPid = self(),          %% same as SpawnedPid
    receive
    
        {MyPid, 0, Acc} ->
            
            %% end of recursion
            %% send Acc
            io:format("Acc: ~p~n", [Acc]),
            
            %% send Acc to From
            From ! Acc;
        
        %% previous line
        %{MyPid, N, Acc} ->
        
        %% adding a guard   
        {MyPid, N, Acc} when is_integer(N), N > 0 -> 
         
        
            %% send Acc    
            MyPid ! {MyPid, N-1, Acc*N},
            
            %% keep process alive
            sfactorial(From);
            
        %% any other message
        _Any ->
            io:format("Wrong format~n"),
            sfactorial(From)
    
    end.

Now, we can omit meaningless messages.

106> f(), c(process).                           
{ok,process}
107> Pid = spawn(process, sfactorial, [self()]).
<0.289.0>
108> Pid ! {Pid, number, 1}.                    
Wrong format
{<0.289.0>,number,1}
109> Pid ! {Pid, -1, 1}.    
Wrong format
{<0.289.0>,-1,1}
110> Pid ! {Pid, 5, 1}. 
Acc: 120
{<0.289.0>,5,1}

Mixing c++ and c code during compilation

TL;DR: use extern "C" for calling C++ functions from C code and compile using gcc -lstdc++

Suppose that you need to use some C++ code in your C environment and translating this legacy code is not an option. That is, C is your principal language and you need some libraries in C++. In this post, I will show you how to compile C++ and C sources togheter You can use both languages and link the object files in a single executable. Consider the following example with three source files:

/*
| legacy_code.h
| 
| Interface between legacy code (c++) and an external (c) program.
| If your program need c++ libraries, such as iostream, include them in legacy_code.cpp
| 
| Things to consider:
| 
| 1) Note that both c and c++ programs could read this file, thus this file need to be 'readable' or compatible with respect to both languages.
| For that reason, dont put things like 
|   
|   #include <iostream>  
|   using namespace std;
|   cout << var;
| 
| 2) Put the following block before each function header
| #ifdef __cplusplus
|   extern "C"
| #endif
*/

#ifndef LEGACY_CODE_H
#define LEGACY_CODE

// printer for int
#ifdef __cplusplus
extern "C"
#endif
void print_int (int a);

// printer for double
#ifdef __cplusplus
extern "C"
#endif
void print_double(double a);

#endif
/*
| legacy_code.cpp
|
| All your legacy code (c++ functions) are here. 
| 
| Two things to notice in this file
| 
| 1) The header of every function must be accessible from c, that is
| 
|   void print_vector ( int *v )        it is OK
|   void print_vector ( vector<int> v ) NOT OK
| 
| 2) If you need some c++ library, such as iostream, put it here, not in legacy_code.h
| 
*/

// -- c++ libraries here --
#include <iostream>
// -- end c++ libreries --

#include "legacy_code.h"


void print_int (int a) {
    std::cout << "integer " << a << std::endl;   
}

void print_double(double a) {
    std::cout << "double " << a << std::endl;    
}


/*
| main.c
| 
| This code will use c++ functions trough the legacy_code.h interface.
| 
| how to compile (note the -lstdc++ flag)
| $ g++ -c legacy_code.cpp
| $ gcc -c main.c 
| $ gcc legacy_code.o main.o -o program -lstdc++
*/

#include <stdio.h>
#include "legacy_code.h"

int main () {
 
    // we are using c++ functions right here
    print_int(10);
    print_double(2.5);
 
    return 0;   
}

# makefile
all: 
	g++ -c legacy_code.cpp
	gcc -c main.c 
	gcc legacy_code.o main.o -o program.out -lstdc++
	
clean:
	rm *.o *.out

Finally, compile these files using make or the following commands:

g++ -c legacy_code.cpp
gcc -c main.c
gcc legacy_code.o main.o -o program -lstdc++

Stackoverflow
Oracle

how to compile the C++ WFG benchmark

TL;DR: you need to add a makefile!

WFG (Walking Fish Group) benchmark is a set of testing problems. Such a benchmark has been developed in C++ and can be downloaded here. However, compiling it can be problematic, at least for me. If you are facing the same issue, unzip WFG_v2006.03.28.zip, copy this snippet and save it as makefile inside WFG_v2006.03.28:

# compiler
CC=g++

# flags
CFLAGS=-c -Wall -g

all: main 

main:         main.o exampleproblems.o exampleshapes.o exampletransitions.o frameworkfunctions.o misc.o shapefunctions.o transfunctions.o
	$(CC) -g  main.o exampleproblems.o exampleshapes.o exampletransitions.o frameworkfunctions.o misc.o shapefunctions.o transfunctions.o -lm -o main.out

# -------------- dependencies ------------

main.o:
	$(CC) $(CFLAGS) main.cpp

exampleproblems.o:
	$(CC) $(CFLAGS) Toolkit/ExampleProblems.cpp -o exampleproblems.o
	
exampleshapes.o:
	$(CC) $(CFLAGS) Toolkit/ExampleShapes.cpp -o exampleshapes.o
	
exampletransitions.o:
	$(CC) $(CFLAGS) Toolkit/ExampleTransitions.cpp -o exampletransitions.o
	
frameworkfunctions.o:
	$(CC) $(CFLAGS) Toolkit/FrameworkFunctions.cpp -o frameworkfunctions.o
	
misc.o:
	$(CC) $(CFLAGS) Toolkit/Misc.cpp -o misc.o
	
shapefunctions.o:
	$(CC) $(CFLAGS) Toolkit/ShapeFunctions.cpp -o shapefunctions.o
	
transfunctions.o:
	$(CC) $(CFLAGS) Toolkit/TransFunctions.cpp -o transfunctions.o

# -------------- clean ------------

clean:
	rm *.o *.out

Your WFG directory should look like this:

auraham@roku:~/Desktop/zips/WFG_v2006.03.28$ ls
CHANGE_LOG.txt main.cpp makefile README.txt Toolkit

Then, execute the following command:

auraham@roku:~/Desktop/zips/WFG_v2006.03.28$ make

Output:
g++ -c -Wall -g main.cpp
g++ -c -Wall -g Toolkit/ExampleProblems.cpp -o exampleproblems.o
g++ -c -Wall -g Toolkit/ExampleShapes.cpp -o exampleshapes.o
g++ -c -Wall -g Toolkit/ExampleTransitions.cpp -o exampletransitions.o
g++ -c -Wall -g Toolkit/FrameworkFunctions.cpp -o frameworkfunctions.o
g++ -c -Wall -g Toolkit/Misc.cpp -o misc.o
g++ -c -Wall -g Toolkit/ShapeFunctions.cpp -o shapefunctions.o
g++ -c -Wall -g Toolkit/TransFunctions.cpp -o transfunctions.o
g++ -g main.o exampleproblems.o exampleshapes.o exampletransitions.o frameworkfunctions.o misc.o shapefunctions.o transfunctions.o -lm -o main.out

Now, you are ready to run the test program:


auraham@roku:~/Desktop/zips/WFG_v2006.03.28$ ./main.out WFG1

And that’s all!

Things to install on your fresh laptop

latex
sudo apt-get install texlive-lang-spanish

development
sudo apt-get install python-setuptools

sudo apt-get install aspell aspell-es

stackoverflow

sources
stackoverflow

inkscape + latex support (tex text plugin)
Download the latest version of textext from here. At the time of this writting, the latest version is textext-0.4.4.tar.gz.

Extract the content:


auraham@roku:~/Downloads$ tar xzvf textext-0.4.4.tar.gz
textext.py
textext.inx
LICENSE.txt

Copy these files to inkscape extensions directory:
auraham@roku:~/Downloads$ cp textext.* ~/.config/inkscape/extensions/

Install pstoedit:

auraham@roku:~/Downloads$ sudo apt-get install pstoedit

Restart inkscape. Textext will appear in the menu Extension/Tex Text. Before using this option, you need to save this ini template (template.ini or whatever you want):

\usepackage{amsfonts}

Now, run tex text plugin. In the Preamble file option, select template.ini. Then, you will be able to write equations using latex syntax.

stackoverflow

my touhpad is too slow (not so sensitive)!

tl;dr: use synclient to setup your touchpad instead of Mouse & Touchpad options on System Settings.

After installing Ubuntu 15.04 on my new HP 240, my first reaction was “well, my touchpad sucks, it is too slow”. But, what I tried to say was “it is not sensitive enough”. I use my touchpad (and probably you too with the tip of my finger. But, in order to use my new laptop, I need to use almost my whole fingertip! So, after googling for a while, I found this post with the solution: synclient. This utility enable us to configure our touchpad in a simple way. There is a lot of options to set up, but in order to solve this problem, you only need to change FingerLow and FingerHigh. To know what is your current configuration, execute:


synclient | grep FingerLow
synclient | grep FingerHigh

In order to change these values, execute:


synclient FingerLow=8 && synclient FingerHigh=10

Higher values implies less sensitivity. Finally, to make this change persisntent after rebooting, do the following:


cd /usr/share/X11/xorg.conf.d/
sudo cp 50-synaptics.conf 50-synaptics.conf.bak
sudo vim 50-synaptics.conf

And add “FingerLow” and “FingerHigh” in the corresponding block as follows:


Section "InputClass"
Identifier "touchpad catchall"
Driver "synaptics"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
# added
# http://ianrenton.com/guides/howto-linux-and-synaptics-touchpads-for-little-fingers/
Option "FingerLow" "8"
Option "FingerHigh" "10"

It is possible that the file


/usr/share/X11/xorg.conf.d/50-synaptics.conf

does not even exist on your computer. In this case, you can create from scratch. More info on Ian’s blog.