Archive for May, 2009

Clojure tips: patterns matching

May 28, 2009

This is how it can be done in clojure:

user=> (defmulti fib (fn [x] x) :default :default)
#'user/fib
user=> (defmethod fib 0 [x] 0)
#<MultiFn clojure.lang.MultiFn@de1b8a>
user=> (defmethod fib 1 [x] 1)
#<MultiFn clojure.lang.MultiFn@de1b8a>
user=> (defmethod fib :default [n] (+ (fib (- n 2)) (fib (- n 1))))
#<MultiFn clojure.lang.MultiFn@de1b8a>
user=> (fib 32)
2178309
user=> (time (fib 32))
"Elapsed time: 3406.246008 msecs"
2178309
user=>

Factorial pattern matching:

(defmulti fac (fn [x] x) :default :default)
(defmethod fac 1 [x] 1)
(defmethod fac :default [n] (* n (fac (- n 1))))

Erlang tips: remote module loading

May 26, 2009

Context: when remote module pushing is needed.

Initial setup:
1. 2 nodes (physical nodes, each one having one erlang instance started): node1@10.0.0.1 and node2@10.0.0.2
2. both erlang instances must be started with the same cookie, in order to be able to successfully communicate

Steps:

(On node1, create test module)

-module(test).
-export([test_fun/0]).

test_fun() ->
    io:format("Hello ~s~n",["World"]).

(On node1, start erlang instance)

$ erl -name node1@10.0.0.1 -setcookie testcookie
Erlang R13B (erts-5.7.1) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.7.1  (abort with ^G)
(node1@10.0.0.1)1> 

(On node2, start erlang instance)

$ erl -name node2@10.0.0.2 -setcookie testcookie
Erlang R13B (erts-5.7.1) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.7.1  (abort with ^G)
(node1@10.0.0.2)1> 

(On node1, compile/load/remote load test module)

(node1@10.0.0.1)1> c(test).
{ok,test}
(node1@10.0.0.1)2> {Mod, Bin, _} = code:get_object_code(test).
{test,<<70,79,82,49,0,0,1,252,66,69,65,77,65,116,111,109,
        0,0,0,63,0,0,0,7,4,116,101,...>>,
      "/home/alin/test.beam"}
(node1@10.0.0.1)3> rpc:call('node2@10.0.0.2',erlang,load_module, [Mod, Bin]).
{module,test}
(node1@10.0.0.1)4> spawn('node2@10.0.0.2', test, test_fun, []).
Hello World
<8592.45.0>
(node1@10.0.0.1)5> 

(On node1, edit test.erl)

Instead of

... io:format("Hello ~s~n",["World"]).

set

... io:format("Hello ~s~n",["World2"]).

(On node1, go back to opened erlang shell)

(node1@10.0.0.1)5> f().
ok
(node1@10.0.0.1)6> c(test).
{ok,test}
(node1@10.0.0.1)7> {Mod, Bin, _} = code:get_object_code(test).
{test,<<70,79,82,49,0,0,1,252,66,69,65,77,65,116,111,109,
        0,0,0,63,0,0,0,7,4,116,101,...>>,
      "/home/alin/test.beam"}
(node1@10.0.0.1)8> rpc:call('node2@10.0.0.2',code,purge, [Mod]).
false
(node1@10.0.0.1)9> rpc:call('node2@10.0.0.2',erlang,load_module, [Mod, Bin]).
{module,test}
(node1@10.0.0.1)10> spawn('node2@10.0.0.2', test, test_fun, []).
<8592.48.0>
Hello World2
(node1@10.0.0.1)11> 

Note: node2 was not touched for anything else than starting (erl -name node2@10.0.0.2 -setcookie testcookie)

Done.

Erlang tips: standalone manual

May 24, 2009

Just run:

$ erl -man <module>

for instance:

$ erl -man erl
$ erl -man rpc
$ erl -man erlang

etc.

Erlang tips: starting embeded Yaws server

May 20, 2009

OS: Ubuntu 9.04

sudo apt-get install yaws

Create some document folder:

mkdir /home/alin/public_html

Add data to an test.html file, in order to be rendered:

echo '<html><body><div>Hello from Yaws!</div></body></html>' > /home/alin/public_html/test.html

erlang module for embedded yaws:

-module(test_yaws).
-export([start/1, stop/0]).

-define(YAWS_LIB,"/usr/lib/erlang/lib/yaws-1.80/ebin"). 

start(Port) ->
    code:add_path(?YAWS_LIB),
    SL=[{listen,{0,0,0,0}},
        {port,Port},
        {servername,"localhost"},
        {flags,[{dir_listings,true},{access_log,false}]}],
    GL=[{trace,false},{tmpdir,"/tmp"},{flags,[{auth_log,false},{copy_errlog,false}]}],
    yaws:start_embedded("/home/alin/public_html", SL, GL).

stop() ->
    code:add_path(?YAWS_LIB),
    yaws:stop().

Start embedded yaws:

$ erl
Erlang R13B (erts-5.7.1) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.7.1  (abort with ^G)
1> c(test_yaws).
2> test_yaws:start(5559).
=INFO REPORT==== 24-May-2009::18:28:35 ===
Yaws: Listening to 0.0.0.0:5559 for servers
 - http://localhost:5559 under /home/alin/public_html
ok
3> 

To check if everything is ok, go to: http://localhost:5559/ (listing of public_html folder will be done if no other resource is specified).
If accessing http://localhost:5559/test.html, “Hello from Yaws!” message will be displayed.

Haskell call function from main without using the return value

May 19, 2009

Few days ago I was stuck at some issue:
I wanted to do some profiling of ordinary fibonacci function written in Haskell but I didn’t wanted to display the result (using main function, from Main module). Guys from #haskell irc channel (irc.freenode.net) were very helpful and they guided me to evaluate and rnf

module Main where

import Control.Parallel.Strategies
import Control.Exception

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib(n - 1) + fib(n - 2)

main = do
   evaluate(rnf (fib 32))

or, using function composition:

module Main where

import Control.Parallel.Strategies
import Control.Exception

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib(n - 1) + fib(n - 2)

eval = evaluate . rnf
main = do
   eval(fib 32)

ghc --make Fib.hs
time ./Fib

and for better performance:

ghc --make -O2 Fib.hs
time ./Fib


Follow

Get every new post delivered to your Inbox.