Skip to content

Instantly share code, notes, and snippets.

@bjhaid
Last active August 29, 2015 14:06
Show Gist options
  • Save bjhaid/8b1860be1330d940ba1c to your computer and use it in GitHub Desktop.
Save bjhaid/8b1860be1330d940ba1c to your computer and use it in GitHub Desktop.
OO in Erlang

Behaviour

Behaviours in Erlang are similar to Java interface, but unlike Java interfaces they can have implementation

Example:

-module(mammal).
-export([describe/1]).

%% modules implementing this behaviour are expected to define the below functions(this is not enforced but the compiler would issue warnings when they are not defined)
-callback name() -> string(). 
-callback age() -> integer(). 
-callback legs() -> integer().
-callback sound() -> atom().

-spec describe(atom()) -> any().                                                             
describe(Module) ->                                                                          
  io:format("~p is ~p old, makes a ~p sound and has ~p legs~n", [Module:name(), Module:age(), Module:sound(), Module:legs()]).
%%implementing module

-module(dog).        
-compile(export_all).
-behavior(mammal).   

name() -> "Dog".     
age() -> 10.         
legs() -> 4.         
sound() -> woof.

mammal:describe(dog).
"Dog" is 10 old, makes a woof sound and has 4 legs

Tuple Modules in Erlang

Polymorphism in erlang is available via #Tuple Modules#, it was formerly the implementation details for Parameterize Module which has been removed from Erlang in R16, but then OTP core team decided to keep it has top libraries continued using it

-module(animal).
-compile(export_all).

%% This could be anything other than new
new(Name, Specie, Age, Sound) -> 
  {?MODULE, [Name, Specie, Age, Sound]}.
  
  
%%% Sample accesors
getName({?MODULE, [Name, _Specie, _Age, _Sound]}) -> Name.

getSpecie({?MODULE, [_Name, Specie, _Age, _Sound]}) -> Specie.

getAge({?MODULE, [_Name, _Specie, Age, _Sound]}) -> Age.

getSound({?MODULE, [_Name, _Specie, _Age, Sound]}) -> Sound.
Dog = animal:new("Doggie", "Dog", 10, "Woof").
{animal, ["Doggie", "Dog", 10, "Woof"]} %% This is the tuple module, if we have an idea of the expected internal representation of an Erlang Tuple Module we can bypass the constructor and just call it so:
Dog =:= {animal,["Doggie","Dog",10,"Woof"]}. 
true

%% Calling the getters is as below, notice we are not passing argument(s) to the function(s)
Dog:getName().
"Doggie"
Dog:getAge().
10

Cat = animal:new("Vader", "Cat", 3, "Meew").
Cat:getSound().
"Meew"
Cat:getName(). 
"Vader"

Real world use case of an erlang #Tuple Module# can be found in a couple of places in Mochiweb e.g https://github.com/mochi/mochiweb/blob/master/src/mochiweb_request.erl#L51-L52

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment