Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Understanding actor concurrency, Part 1: Actors in Erlang

A new way to think about structuring concurrent applications

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 4 of 6

Listing 3. Lists

1> List=[1,2,3].
[1,2,3]
2> [First | Rest]=List.
[1,2,3]
3> First.
1
4> Rest.
[2,3]

Functions are first-class values, as you would expect in a functional language. They are defined by a function name and the number of parameters, using a simple syntax. Here we match the anonymous function to the Square variable. You can then execute it or even create functions that return functions, like the TimesN function in Listing 4.

Listing 4. Functions

1> Square = fun(X) -> X*X end.
#Fun<erl_eval.6.13229925>
2> Square(5).
25.
3> TimesN = fun(N) -> (fun(X) -> N*X end)
3> end.
#Fun<erl_eval.6.13229925>
4> lists:map(TimesN(10), [1,2,3]).
[10,20,30]

At the end of Listing 4 you can see a call to the function map in one of the most important Erlang modules: lists.

Normally you define Erlang code in source files with the .erl extension. Each source file can declare a module and which functions are exported or imported to that module. For example, Listing 5 is a definition of the mymath module, which has two functions -- square and fib.

Listing 5. The mymath.erl module

-module(mymath).
-export([square/1,fib/1]).

square(Value) -> Value*Value.

fib(0) -> 0;
fib(1) -> 1;
fib(N) when N>1 -> fib(N-1) + fib(N-2).

In Listing 5, fib is defined by three different patterns, and the runtime will decide which pattern to call as appropriate. The when ... is a guard clause that can constrain when a pattern is applicable.

Listing 6 shows how to compile and load this module in the shell.

Listing 6 Compiling a module and executing its functions

1> c(mymath.erl).
2> mymath:square(5).
25
3> mymath:fib(7).
13

Actors in Erlang

Now that you're at least a little bit comfortable with Erlang, we can begin looking at actors. Three basic elements in Erlang form the foundation for concurrency. First, the built-in spawn function creates a new process executing a function and returns the new process's process identifier. Second is a syntax for sending a message to a process with the ! operator. And finally, actors can use a receive...end function to pattern-match messages from the actor's mailbox.

To see how these pieces fit together, we'll create a process that does conversions between Celsius and Fahrenheit temperatures. First we must define the function that the process will run, as shown in Listing 7.

Listing 7. temperature.erl

temperatureConverter() ->
 receive
 {toF, C} ->
 io:format("p C is p Fn", [C, 32+C*9/5]),
 temperatureConverter();
 {toC, F} ->
 io:format("p F is p Cn", [F, (F-32)*5/9]),
 temperatureConverter();
 {stop} ->
 io:format("Stoppingn");
 Other ->
 io:format("Unknown: pn", [Other]),
 temperatureConverter()
 end.

This function receives messages in the form of three possible tuple formats. The first format is {toF, C}. In this tuple, the first element is the toF atom, and the second is the temperature in Celsius. In the code the variable C is matched to the value. On match, it prints the answer and calls back to this function again. This is a tail-recursive call. Erlang actor functions often follow this idiom of matching an incoming message, then making a tail-recursive call back to the same function. State can be maintained in the actor by passing it in a function parameter and modifying it on the recursive call.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (2)
Login
Forgot your account info?

{stop} is bad formBy Anonymous on September 20, 2009, 12:39 pmJust a quick comment, you don't need to wrap {stop} in a tuple just becuase it is a message. A message like that should just be the raw atom.

Reply | Read entire comment

Amdahl's LawBy Anonymous on March 28, 2009, 11:36 amThere seems to be an implication here that Amdahl's Law is specific to shared-state concurrency, and doesn't apply to Actor concurrency. This is clearly absurd,...

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources

More from JavaWorld