<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<div class="moz-cite-prefix">On 15/12/2016 12:04, IRLeif wrote:<br>
</div>
<blockquote
cite="mid:CAJYp+xt3su6Q4ob_GVTsngDUKqSWZV+3SM6B-MjEzmV0bhfqvQ@mail.gmail.com"
type="cite">
<div dir="ltr">
<div>Dear Erlang community,</div>
<div><br>
</div>
<div>This is my first email to the mailing list. I apologize in
advance if this is odd or off-topic.</div>
<div><br>
</div>
<div>Coming from an object-oriented and data-centric background,
I have cognitive difficulties when it comes to
conceptualizing, thinking about and designing systems
consisting of modules, processes and key-value data stores.</div>
<div><br>
</div>
<div>My brain reverts to thinking about classes, objects,
inheritance trees, encapsulation and SQL-style relational data
models. I'm afraid this could lead to unidiomatic Erlang
system architectures and implementations, which would be
undesirable.</div>
<div><br>
</div>
<div>Here are some of the essential complexities I have
difficulties grasping:<br>
<br>
</div>
<div>A) Identifying discrete modules and processes and finding
good names for them.</div>
<div>B) Appointing supervisor and worker modules; defining
process hierarchies.</div>
<div>C) Deciding which processes should communicate with each
other and how.</div>
<div>D) Designing a sensible persistent data model with Mnesia
or other NoSQL data models (e.g. using CouchDB).</div>
<div>E) Deciding which processes should read and write
persistent data records.</div>
<div>F) Incorporating global modules/"shared facilities" like
event handlers, loggers, etc.</div>
<div>G) Visualizing the system architecture, processes and
communication lines; what kind of graphics to use.</div>
<div>H) Organizing source code files into separate projects and
directory structures.</div>
<div><br>
</div>
<div>Questions:</div>
<div><br>
1) How do you unlearn "bad habits" from object-oriented way of
thinking?</div>
<div>2) How do you think and reason about process-centric
systems designs?<br>
3) When designing a new system, how do you approach the above
activities?</div>
<br>
</div>
</blockquote>
<br>
Well, for me Erlang is like a better version of OOP, it's how
actually classes should have been implemented from the beginning.
You simply have to mentally match <a
href="https://en.wikipedia.org/wiki/Actor_model">actors</a> with
classes and method invocation with message passing.<br>
<br>
An actor is like a class that creates "living" entities instead of
pieces of data. Having the definition of an actor (in an Erlang
module), you can create multiple actors sharing the same code. Each
actor maintains its own state exposing outside an API through which
other actors can read or update the actor's state.<br>
<br>
In OOP an instance of a class is simply some piece of memory to keep
the state - instance variables. If the responsibility for the state
wasn't delegated to class or instance methods, every method could
change the state in a haphazard way. You need to synchronize which
methods update which variables, add setters and getters, restrict
the variables with private/protected access modifiers, only to
protect the state from becoming undefined or corrupted.<br>
<br>
Actor does the same but better. Whereas you can find a way to update
an instance without invoking any methods (e.g. using pointers) it's
not possible to update a state of an actor if it doesn't expose an
API - Erlang doesn't provide any semantic to do that (you can only
kill an actor).<br>
<br>
But the main difference is that whereas instance methods run
sequentially in the order in which they are called, actors actually
run in parallel. If you have ever tried to implement any concurrent
computation in OOP you will know that those two don't get together
very well. If you have 10 processors and 100 instances of classes
you can't distribute the instances across the processors/servers to
share the load. That even doesn't make sense. You would need to use
some message passing library, e.g. MPI, to distribute such code
across processors.<br>
<br>
However, in Erlang the distribution is done by the VM (BEAM) where
schedulers can transparently exchange messages send between actors
no matter on which processor those actors are running. They can even
transparently distribute the actors across multiple nodes connected
with network interfaces.<br>
<br>
In Erlang an actor is implemented using behaviours, e.g. <a
href="http://erlang.org/doc/man/gen_server.html">gen_server</a>, <a
href="http://erlang.org/doc/man/gen_fsm.html">gen_fsm</a>. During
execution an Erlang application can have as many running
processes/actors as an OOP application can have created instances of
classes.<br>
<br>
You could start by trying to:<br>
- map global state (global variables, data held in static
classes/istances used by the whole application) to <a
href="http://erlang.org/doc/man/ets.html">ets</a> or <a
href="http://erlang.org/doc/man/mnesia.html">mnesia</a>.<br>
- map singletons and classes that maintain state or provide access
to resources to actors/processes.<br>
- map classes that only provide a collection of functions to Erlang
modules.<br>
<br>
Many books discussing OOP try to map the world to classes and
instances (e.g. a class 'washing machine' that has methods 'wash',
'dry', etc). For me it's easier to map the surrounding world to
actors rather than classes because objects in reality don't wait for
each other. They exist, respond to actions and can change in real
time independently of each other - exactly like actors.<br>
<br>
I hope this helps<br>
Greg<br>
<br>
<br>
<br>
</body>
</html>