Paradigms / OO vs CO

Jay Nelson <>
Sat Mar 8 17:41:02 CET 2003


 > I think this is the germ of a good model, and that, appropriately
 > developed, it could fit between OO and CO. Decompose the problem into
 > objects which may or may not have agency (processes.) But the hard
 > part is making sure that objects can be treated the same by other
 > objects, regardless of whether they are dynamic or not. I'd like to
 > see something more transparent than "concurrent objects" or "Erlang
 > with object extensions" - either of which seems to be a short-sighted
 > approach where features with essentially incompatible
 > assumptions would
 > get slapped onto a pre-existing framework - rather than generating a
 > smooth & novel synthesis of the two.

I haven't used ocaml or any other "object-oriented" functional language
so I may be way off here, but thinking about it raised some issues for
me.

Chris Okasaki talks about persistence in "Purely Functional Data
Structures".  Functional data structures are persistent, meaning that
multiple versions can exist simultaneously, whereas imperative data
structures are ephemeral meaning that only one version exists at a
time.

All the OO paradigms I've seen are designed around ephemeral objects,
with the exception of versioning OO databases which are generally
approximations since only the DB saved versions exist, not the temporary
versions that were used to get to a save state.  In OO you don't have to deal
with outdated copies of objects, every instance is ephemeral.  In erlang
if you were to make some sort of static object, you would have to make
sure that it is not modified in more than one process, or stashed inside
some list, or else you have to serialize it in a server or store it in an ets
table and always get a fresh copy (well, I guess the ets approach isn't
even guaranteed to work).

The safest thing is to have an object pool, with unique ids, that is managed
as a separate process.  When you need to deal with an object you ask for
it from the pool by sending a message.  You could try to lock it and use
synchronization to allow modification and check-in of the new version, but
you would run into deadlock issues.  So instead you make each object a
process -- even if it is a static object (if it truly never changes, you might
not have to but...).  And all is good.  Use messaging to get objects to 
respond,
rely on the message queue for serialization and the object pool for
synchronization.

Step back and look at it.  You have implemented pure Smalltalk, everything
is an object (process) and all work is accomplished via message sending,
but it looks just like the erlang process register namespace.

How do you do inheritance in this scheme?  Inheritance in my mind grows
up rather than down.  Create a new process that delegates to other processes
as Vlad said.  It has a new interface, looks and acts like a new object, but
relies on existing behaviour for implementation.  It is not at all static, 
though.
You could remove or inhibit delegation, kill the process and replace it with
a different collection of behaviours; it appears more like a prototype instance
that can be modified after it is created and can violate the strict 
inheritance.
If you kill and create a new instance in an OO environment your choices are
limited to the strictly defined parent class hierarchy; in erlang you can 
combine
any modules or subsets of modules you want.

What would you be trying to accomplish by using an OO approach?  I think
that at the fundamental roots of the language, erlang contains versioned data
and OO is antithetical to that.  Suppose you have an erlang textbox UI 
record structure
in your internal model.  Every time a character is added you create a new
copy of the structure and throw away the old one.  Undo would be very easy
if you keep all the old versions of the data.  The mixin approach of adding
behaviour to display the data would work well (just call functions in a display
textbox module or delegate to a single process), but the inheritance 
approach of
statically structured OO wouldn't work as well because you would end up with
multiple processes delegating to each other depending on the depth of the
inheritance hierarchy just to draw the characters in the
right place, and then you would have to communicate each version of the data
when implementing undo, or else repeating the data versioning edit in all
processes in the delegation chain whenever a character came in.

I guess my thinking is to do two things: 1) push erlang in the erlang-y 
direction
as far as I can to see what problems it is suitable for, and 2) state a problem
and see how many approaches I can think of for implementing it in erlang.
Use OO is not a problem, it is a solution.  What problem are you trying to 
solve?
Right now for UI I have taken the #2 step and am thinking hard about the #1
step.

jay




More information about the erlang-questions mailing list