Erlang for Python programmers: Part II

September 16, 2007

In this short tutorial we will take a look at comparison operations, some arithmetic operations and modules. You may also want to skim over Inro and Part I.

Comparison operations

 Python   Erlang   Description             Erlang Example
 --------+--------+-----------------------+----------------
  <        <        strictly less than
 --------+--------+-----------------------+----------------
  <=       =<       less than or equal
 --------+--------+-----------------------+----------------
  >        >        strictly greater than
 --------+--------+-----------------------+----------------
  >=       >=       greater than or equal
 --------+--------+-----------------------+----------------
  !=       /=       not equal
 --------+--------+-----------------------+----------------
  ==       ==       equal                   1> 1 == 1.
                                            true
                                            2> 1 == 1.0.
                                            true
 --------+--------+-----------------------+----------------
           =:=      exactly equal to        1> 1 =:= 1.
                                            true
                                            2> 1 =:= 1.0.
                                            false
 --------+--------+-----------------------+----------------
           =/=      exactly not equal to
 --------+--------+-----------------------+----------------
  is                object identity
 --------+--------+-----------------------+----------------
  is not            negated obj identity

Python notes

Above comparison operations are supported by all objects. In Python you can chain comparisons:

>>> x, y, z = 1, 3, 7
>>> x < y <= z
True
>>> x < y and y <= z
True

Foregoing examples are identical, except that in second case y is evaluated twice.

Erlang notes

Following order is defined:

number < atom < reference < fun < port < pid < tuple < list < binary

1> 5 < erlang.
true
2> erlang < make_ref().
true

Both Erlang comparison operators (<, =<, >, >=, /=, ==) and Python comparison operators(<, <=, >, >=, !=, ==) make type coerce, “narrower” type is widened to that of another, ie when comparing integer and float first integer is converted to float, etc.
Erlang has special operators without type coerce though: =:= and =/=

Arithmetic operations

I’ll provide only several operations, for more take a look at corresponding language references.

 Python   Python Desc.         Erlang    Erlang Desc.   Example
 --------+--------------------+---------+--------------+--------------------
  x % y    remainder            X rem Y   integer        >>> 7 % 3
           of x / y                       remainder      1
                                          of X / Y       >>> 7.0 % 3
                                                         1.0

                                                         1> 7 rem 3.
                                                         1
                                                         1> 7.0 rem 3.
                                                         =ERROR REP..
 --------+--------------------+---------+--------------+--------------------
  x / y    quotient             X / Y     floating       >>> 7 / 3
           of x and y                     point          2
                                          division       >>> 7.0 / 3
                                                         2.3333333333333335

                                                         1> 7 / 3.
                                                         2.33333
 --------+--------------------+---------+--------------+--------------------
  x // y   (floored) quotient   X div Y   integer        >>> 7 // 3
           of x and y,                    division       2
           integer division                              >>> 7.5 // 3
           (result type is                               2.0
           not forced to be
           int)                                          1> 7 div 3.
                                                         2

Modules

Code in Erlang is organized into units called modules, which is familiar word for Python programmer.

Let’s define sample module with function declaration stored in file mymath.erl :

-module(mymath).
-export([fact/1]).

fact(0) -> 1;
fact(N) -> N * fact(N-1).

What we see here:

  1. module’s source code is stored in file with .erl extension
  2. module consists of attributes and function declarations which are terminated by period (.)
  3. we should provide module declaration defining name of the module
  • module name should be atom
  • module name is the same as file name minus .erl extension
  • module declaration is mandatory
  • module declaration attribute should be defined first.

To make functions defined in module accessible outside the module we need to export them, for this -export module attribute exists. We write exported functions inside square brackets in form of func/N where N is the number of arguments of function, called arity. I’ll repeat that functions not pointed in -export will not be accessible outside module.

Before code can be run, module must be compiled. Resulting compiled file will contain extension .beam

If you use Emacs you can compile module with C-c C-k and see results in erlang shell:

1> c("/home/alienoid/dev/erlang/mymath", [{outdir, "/home/alienoid/dev/erlang/"}]).
{ok,mymath}

Or you can compile it directly in shell. Make sure your shell’s current directory is where your mymath.erl lives, if it’s not the case use cd command in erlang shell, cd(“/path/to/dir/with/mymath.erl”) :

1> c(mymath).
{ok,mymath}

To invoke our function fact we use syntax mod:func :

2> mymath:fact(4).
24

Erlang has also -import attribute which allows to import functions into modules, so that you don’t need to use fully-qualified name mod:func to invoke function, again familiar behaviour and naming to Python programmer.

Erlang allows to insert code from file as-is with -include attribute at point where -import is defined, this is used to include records and macro definitions, for example.

Comments in Erlang module begin with character “%“, continue up to end-of-line and may be placed anywhere except inside string and quoted atoms.
Like in Python Erlang has no multiline comments.
If you use Emacs you can easily comment whole region with M-; command after you marked it.

-module(mymath).
-export([fact/1, print_double/1]).
-import(lists, [foreach/2]).
-include("my_records.hrl").

%% sum(L) ->
%%     sum(L, 0).

%% sum([H|T], Acc) ->
%%     sum(T, H+Acc);
%% sum([], Acc) -> Acc.

fact(0) -> 1;
fact(N) -> N * fact(N-1).
print_double(L) ->
    foreach(fun(X) -> io:format("Double of ~p = ~p~n", [X, X*2]) end, L).

Fin.

Next tutorial will be devoted to thorough exploration of functions in Erlang.


How to say big numbers in English: Common Lisp

September 12, 2007

When i was describing notations and representation of numbers in Erlang(and Python) i forgot to mention very cool feature of format function in Common Lisp, with which i got acquainted exploring highly-recommended Practical Common Lisp book.

This feature is ~R directive which knows how to say really big numbers in English words.

Here is the example (I use SBCL + SLIME):

CL-USER> (format nil "~R" 1604872898756737459538)
"one sextillion six hundred four quintillion eight hundred seventy-two
quadrillion eight hundred ninety-eight trillion seven hundred fifty-six
billion seven hundred thirty-seven million four hundred fifty-nine
thousand five hundred thirty-eight"

Erlang for Python programmers: Intro

August 27, 2007

I assume you have already installed Erlang on your system and are able to run erlang shell either from command line or from within Emacs (C-c C-z).

This is a view of Eshell from my Emacs:

Erlang (BEAM) emulator version 5.5.2  [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.5.2  (abort with ^G)
1> 

Let’s do a simple thing and try to assign a value to a variable in the Eshell. First you should know that variables in Erlang start with uppercase letter or underscore (_), for example:

  • X
  • Name
  • Address
  • _
  • _NoWarn

Ok, let’s finally assign some value to a variable X:

1> X = 4.
4
2>

So far, so good. Make sure to type final “.” at the end of expression when you are done entering code.

Let’s assign new value to X:

2> X = 5.

=ERROR REPORT==== 27-Aug-2007::00:23:02 ===
Error in process <0.29.0> with exit value: {{badmatch,5},[{erl_eval,expr,3}]}

** exited: {{badmatch,5},[{erl_eval,expr,3}]} **
3> 

Here you need to understand and remember couple of things:

  1. Erlang uses single assignment, a variable can only be bound once, bar none.
  2. In expression X = 5 operator = is not an assignment, but match operator and variables are bound to values using pattern matching mechanism.

I think it won’t be an exaggeration if I say that Pattern Matching permeates Erlang. To understand why we got ERROR REPORT in above example with {badmatch, 5} let’s dive into this pattern matching a bit.

When you use pattern matching’s = operator left side called pattern is matched against right side which is a term(piece of data of any Erlang’s data type: integer, float, list, tuple, etc). If your matching fails you get run-time error, if it succeeds then any unbound variable in lefthand pattern becomes bound.

Returning to our example – first we had an unbound variable:

1> X.
** 1: variable 'X' is unbound **
2> 

Then we bound value to variable X with pattern matching:

2> X = 4.
4
3> X.
4
4> 

Now as the variable X is bound we can’t change its value any more (remember single assignment?) otherwise we’ll get badmatch error like in foregoing X = 5 (4 does not match 5), but we may use = to match our variable:

4> X = 4.
4
5> 

Let’s add a bit of tuples to pattern matching. In Erlang tuple is defined inside {…}. ie:

5> {2, 3}.
{2,3}
6> 

and now pattern matching:

6> {X, Y} = {2, 3}.

=ERROR REPORT==== 27-Aug-2007::01:10:45 ===
Error in process <0.29.0> with exit value: {{badmatch,{2,3}},[{erl_eval,expr,3}]}

** exited: {{badmatch,{2,3}},[{erl_eval,expr,3}]} **
7> {X, Y} = {4, 3}.
{4,3}
8> X.
4
9> Y.
3
10> 

In first attempt we tried to match X with 2 and the matching failed as the value of X is 4, in a second attempt the matching succeeded and unbound variable Y also got its value (became bound).

This may look to you like tuple unpacking in Python:

>>> x, y = (4, 3)
>>> x, y
(4, 3)
>>> x, y = (5, 3)
>>> x, y
(5, 3)

but it’s only visual similarity, though i must admit, useful one.

That’s it for today, later you’ll see how pattern matching is uber-useful and how it is used in different parts of Erlang’s constructs.


Erlang man pages in Emacs

August 19, 2007

Well it’s actually as simple as running M-x man RET module_name RET in minibuffer.

I’m using Erlang setup from rpm on FC7 and by default man pages are located under /usr/lib/erlang/man/ so to use above command in minibuffer you must make sure you have your erlang’s man path either in /etc/man.config or you’ve added it into MANPATH with something like export MANPATH=$MANPATH:/usr/lib/erlang/man in your .bash_profile in case your Erlang man pages are not in location accessible by default.

You may also pass man path in minibuffer manually without changing /etc/man.config or MANPATH. In my case to view man page for ‘lists’ module it will look like:

M-x man RET -M /usr/lib/erlang/man lists RET

I’ve customized some stuff for myself in emacs and made binding to F6 key so that whenever i set cursor on module name in my erlang buffer and press F6 i get man page in another window poped up describing module at point. So if you have in your code or in any buffer, for example:

(em@localhost)2> lists:reverse([1, 2, 3]).

you need to move cursor to lists and press F6. Quite handy if you consult man pages often, which is the case for me now as i learn Erlang.

Here is the corresponding elisp helper function and key binding from my dot emacs:

(defun get-erl-man ()
  (interactive)
  (let* ((man-path "/usr/lib/erlang/man")
         (man-args (format "-M %s %s" man-path (current-word))))
    (man man-args)))

(global-set-key [(f6)] (lambda () (interactive) (get-erl-man)))

Htmlize your Erlang code buffer

August 18, 2007

Recently I’ve begun to make blog posts and now want to have highlighting of Erlang’s code(actually any code , be it Python, Lisp, etc) in my posts. I’m using The One True Editor and it goes without saying that i want to convert my erlang code into html from within emacs to have corresponding syntax coloring. Htmlize package to the rescue!

After you downloaded package and put

(add-to-list 'load-path "path_to_your_htmlize.el")
(require 'htmlize)

into your dot emacs – you are ready to use it.

M-x htmlize-buffer or M-x htmlize-region will convert whole buffer or selected region with associated decorations into HTML( See C-h a htmlize RET for more functions). By default htmlize will make HTML output in css mode which is not very suitable for inserting into blog post as output includes also style sheets. Excerpt from htmlize documentation:

;; htmlize supports three types of HTML output, selected by setting
;; `htmlize-output-type': `css', `inline-css', and `font'.  In `css'
;; mode, htmlize uses cascading style sheets to specify colors; it
;; generates classes that correspond to Emacs faces and uses <span
;; class=FACE>...</span> to color parts of text.  In this mode, the
;; produced HTML is valid under the 4.01 strict DTD, as confirmed by
;; the W3C validator.  `inline-css' is like `css', except the CSS is
;; put directly in the STYLE attribute of the SPAN element, making it
;; possible to paste the generated HTML to other documents.  In `font'
;; mode, htmlize uses <font color="...">...</font> to colorize HTML,
;; which is not standard-compliant, but works better in older
;; browsers.  `css' mode is the default.

inline-css is the type of output i want. This can be achieved by customizing htmlize-output-type variable with M-x customize htmlize RET or directly modifying dot emacs. Converting:

(add-to-list 'load-path "path_to_your_htmlize.el")
(require 'htmlize)

with htmlize-region and then applying nxml-mode to produced result gives:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<!-- Created by htmlize-1.34 in inline-css mode. -->
<html>
  <head>
    <title>.emacs</title>
  </head>
  <body style="color: #ffffff; background-color: #000000;">
    <pre>
(add-to-list 'load-path <span style="color: #ffa07a;">"path_to_your_htmlize.el"</span>)
(<span style="color: #00ffff;">require</span> '<span style="color: #7fffd4;">htmlize</span>)
</pre>
  </body>
</html>

As you see I need to cut contents between <pre> </pre> including
<pre> tags itself to insert that then directly into blog post. After that i need manually copy/paste styles from <body> tag into <pre> tag and also add font-size: 8pt to meet my taste. Being lazy i’ve implemented function my-htmlize-region in elisp to make that job for me every time i press F5 key:

(defun my-htmlize-region (beg end)
  "Htmlize region and put into <pre> tag style that is left in <body> tag
plus add font-size: 8pt"
  (interactive "r")
  (let* ((buffer-faces (htmlize-faces-in-buffer))
         (face-map (htmlize-make-face-map (adjoin 'default buffer-faces)))
         (pre-tag (format
                   "<pre style=\"%s font-size: 8pt\">"
                   (mapconcat #'identity (htmlize-css-specs
                                          (gethash 'default face-map)) " ")))
         (htmlized-reg (htmlize-region-for-paste beg end)))
    (switch-to-buffer-other-window "*htmlized output*")
    ; clear buffer
    (kill-region (point-min) (point-max))
    ; set mode to have syntax highlighting
    (nxml-mode)
    (save-excursion
      (insert htmlized-reg))
    (while (re-search-forward "<pre>" nil t)
      (replace-match pre-tag nil nil))
    (goto-char (point-min))))

(global-set-key [(f5)] (lambda (beg end)
                         (interactive "r") (my-htmlize-region beg end)))

So now selecting:

(add-to-list 'load-path "path_to_your_htmlize.el")
(require 'htmlize)

and pressing F5 i get this in another buffer:

<pre style="color: #ffffff; background-color: #000000; font-size: 8pt">
(add-to-list 'load-path <span style="color: #ffa07a;">"path_to_your_htmlize.el"</span>)
(<span style="color: #00ffff;">require</span> '<span style="color: #7fffd4;">htmlize</span>)
</pre>

As you see it’s just what i want:
<pre> tags with content and <pre> tag contains style from above mentioned <body> tag plus font-size is added too.

Factorial in Erlang with syntax coloring as i have it in my Emacs:

-module(factorial).
-export([factorial/1, factorial_rec/1]).

%% tail recursion
factorial(Num) ->
    factorial(Num, 1).

factorial(1, Acc) -> Acc;
factorial(Num, Acc) ->
    factorial(Num-1, Num * Acc).

%% recursion
factorial_rec(1) -> 1;
factorial_rec(Num) ->
    Num * factorial_rec(Num-1).

This is a joy of using Emacs.


More about binary search in Erlang

August 17, 2007

In my previous post My Erlang binary search I’ve implemented binary search in Python and Erlang as small exercise for myself after reading Half-baked Ideas blog post. Good article pointing to specifics of implementation of that algorithm in Erlang was posted on Erlane’s blog which is in a nutshell: binary search in Erlang implemented on list data structure is less efficient than linear search.

So to grasp why linear search which is O(N) is faster in Erlang then binary search which is in theory O(logN) go and read that article.
In Python list data structure (I’m talking here about CPython) is implemented as mutable and extensible vector of references to objects(we might say array of pointers), here is the excerpt from listobject.h:

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     * list.sort() temporarily sets allocated to -1 to detect mutations.
     *
     * Items must normally not be NULL, except during construction when
     * the list is not yet visible outside the function that builds it.
     */
    Py_ssize_t allocated;
} PyListObject;

So Python version works as expected regarding efficiency. While my goal of implementing binary search algorithm in Erlang was learning Erlang and not particulary developing optimized version of that algorithm or using another one it’s always good to pick new tricks of the trade along the way and for me the issue with my implementation of binary search in Erlang just boils down to: your experience and know your tools (language, os, editor(emacs :), etc )

As Aldous Huxly said: “Experience is not what happens to you; it’s what you do with what happens to you.”. So make errors (not many :) in your programs, fix them and gain new experience with your new language.

Another post by Erlane team is good reading describing paradigm shifts when you are newbie and are on your own way to Erlang/OTP wizardry.