Discussion:
OOP in Erlang
unknown
2010-08-08 19:27:32 UTC
Permalink
Hello everyone,
I came across the mentioning of two undocumented features in Erlang -
Parameterized modules and module inheritance.
1. From which version and on are there features included in the Erlang
distro?
2. Are these features considered stable? Experimental? Risky?

Thanks,
Guy
unknown
2010-08-08 20:32:06 UTC
Permalink
To my knowledge both features are considered experimental.

Neither of these are really "OOP" features. Parameterized modules merely
make the module name and a prespecified set of variables implicit/hidden.
However, a call to a parameterized module is still just a function call.
Objects interpret and dispatch incoming messages.

Module inheritance doesn't provide inheritance in the traditional style of
OOP. It's more like "mix-ins", if you're familiar with those.

If you're really looking for OOP in Erlang, I suggest you take a look at my
language Reia, which provides a true "everything is an object"-style object
orientation, true single inheritance, real hidden state with better handling
of code change, and more.

More on Reia:
http://wiki.reia-lang.org/wiki/Reia_Programming_Language

More on Reia's object orientation:
http://www.unlimitednovelty.com/2010/06/reia-everything-is-object.html
Post by unknown
Hello everyone,
I came across the mentioning of two undocumented features in Erlang -
Parameterized modules and module inheritance.
1. From which version and on are there features included in the Erlang
distro?
2. Are these features considered stable? Experimental? Risky?
Thanks,
Guy
--
Tony Arcieri
Medioh! A Kudelski Brand
unknown
2010-08-11 02:17:43 UTC
Permalink
The mostly used feature of OOP is probably encapsulating code and
data. Have a look at gen_server:
http://www.erlang.org/doc/man/gen_server.html
unknown
2010-08-11 07:44:22 UTC
Permalink
I have to stand up for OOP at this point: OOP does not start and end with
"encapsulating code and data". The OOP feature that has the strongest impact
on code brevity is *inheritance*. Thus, the interest in extending modules.

Also, IMHO, parameterized modules are a more compact way to encapsulate code
and data, since that you don't have to pass the data structure around as an
explicit state (assuming, of course, that the data is immutable).

Guy
Post by unknown
The mostly used feature of OOP is probably encapsulating code and
http://www.erlang.org/doc/man/gen_server.html
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
unknown
2010-08-11 08:37:33 UTC
Permalink
Post by unknown
I have to stand up for OOP at this point: OOP does not start and end with
"encapsulating code and data". The OOP feature that has the strongest impact
on code brevity is *inheritance*. Thus, the interest in extending modules.
I can't agree with you. Inheritance is only way how some OOP language
copes with complexity of OO systems. Inheritance is neither core nor
mandatory feature of OOP. What worse, many of OO affected people what
I met stated that inheritance is most controversial and mostly misused
feature of OOP. I also observe that there is positive correlation with
person experience and probability that will tell or agree with above
statement.
Post by unknown
Also, IMHO, parameterized modules are a more compact way to encapsulate code
and data, since that you don't have to pass the data structure around as an
explicit state (assuming, of course, that the data is immutable).
Guy
Post by unknown
The mostly used feature of OOP is probably encapsulating code and
http://www.erlang.org/doc/man/gen_server.html
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
--
--Hynek (Pichi) Vychodil

Analyze your data in minutes. Share your insights instantly. Thrill
your boss.? Be a data hero!
Try GoodData now for free: www.gooddata.com
unknown
2010-08-11 09:03:13 UTC
Permalink
Post by unknown
Post by unknown
I have to stand up for OOP at this point: OOP does not start and end with
"encapsulating code and data". The OOP feature that has the strongest impact
on code brevity is *inheritance*. Thus, the interest in extending modules.
I can't agree with you.
Me neither. To provoke: Inheritance (In Java/C++ style OO) has a
strong impact, but it is negative rather than positive. In my
experience, all languages with no inheritance features whatsoever beat
those with in brevity. In Erlang, whenever somebody thinks
inheritance, you should take a step back and think "closure" or
"higher order function". The whole concept of "Red car inherits from
car" does not work, save for introductory Java courses. So in
practice, inheritance is used to facilitate code reuse and composition
- and in my experience, functional programming tend to have much
better tools for composing code[1].

Another point is google Go, which has no inheritance per se, but uses
an interface concept: an object can belong to zero, one or many
interfaces by implementing the methods in that interface. The
declaration is implicit and inferred so the programmer is saved from
doing boilerplate notation. That is, interface implementation is
purely structural. "If you implement these methods with these types,
you are an implementor of the interface and can be used whenever the
interface is used." There is a way to embed all methods from one
object into another which gives somewhat the inheritance concept, but
it is subtly different. Structurally constructing the type hierarchy
is not new. Ocaml has had it for years.

Parameterized modules make me warm and fuzzy because they seem to give
a way to implement ML-style functors (maps from modules to modules).
It may look like an object, but I don't think it is. Module parameters
are static unless you jump hoops for instance.


[1] Erlang, even with a lack of currying, fares better here.
--
J.
unknown
2010-08-11 10:24:31 UTC
Permalink
Post by unknown
Post by unknown
Post by unknown
I have to stand up for OOP at this point: OOP does not start and end with
"encapsulating code and data". The OOP feature that has the strongest impact
on code brevity is *inheritance*. Thus, the interest in extending modules.
I can't agree with you.
Me neither. To provoke: Inheritance (In Java/C++ style OO) has a
strong impact, but it is negative rather than positive. In my
experience, all languages with no inheritance features whatsoever beat
those with in brevity. In Erlang, whenever somebody thinks
inheritance, you should take a step back and think "closure" or
"higher order function". The whole concept of "Red car inherits from
car" does not work, save for introductory Java courses. So in
practice, inheritance is used to facilitate code reuse and composition
- and in my experience, functional programming tend to have much
better tools for composing code[1].
It's certainly useful to have the slightly abstracted discussion:
What types of programs are a breeze to write in language X, but
cumbersome in Erlang? What parts of Erlang make it cumbersome?
Could they be fixed? Do we care enough to fix it?

There are certainly problems that are not solved as easily in Erlang
as in other languages. Backtracking a bit, we can observe that one
of the first areas where Erlang departed from its main inspiration,
Prolog, was ...uhm, backtracking. This was not done because
backtracking is bad per se, but because it doesn't play that well
with soft real-time characteristics and hardware control.

Similarly there have been discussions on other features that are
much liked by proponents of Language X, but not found in Erlang:

- Strong static (a la Haskell & ML) typing is praised by many
as a great boon to software quality and productivity.
Explaining why Erlang doesn't have it sometimes borders on
revisionism, but when defending his PhD thesis, Joe was asked
about it and basically said that at the time, they didn't know
that much about static typing, and were mainly inspired by
dynamically typed languages like LISP and Prolog. In other words,
it wasn't so much a question of deciding *against* static typing
as getting inspiration elsewhere. Still, managing large projects
with loosely coupled components that need to be upgradable in
service is not an easy problem to solve, and largely still a
research area.

- Lazy evaluation is superb for some problems, and e.g. QuickCheck
relies heavily on it. While it can be done in Erlang, you have
to make do with "poor-man's lazy evaluation", rolling your own.
Again, going all the way seems to be somewhat at odds with soft
real-time characteristics and predictable memory utilization.

- Shared-memory concurrency is the cat's miau for some problems,
but Erlang carefully stays away from it, since it was designed
for problems where shared memory is more trouble than it's
worth - not least because all bets are off in terms of fault
tolerance if a process with write access to your memory dies
in the process of modifying it.

Finally, OO was on the plate even during the language experiments
that led to Erlang. It received favourable mention, but the old
papers (the ones I've read) don't clearly describe why OO features
were left out. I believe the main reason was that the team decided
to use Prolog as a base - as it was closest to what they imagined.
It was only later that they decided to make a language in its own
right.

My own experience from telecoms tells me that OO gives the wrong
signals to people in complex projects. They tend to want to
maximize design-time dependencies rather than going with a style
more similar to electrical component design - black boxes, with
well-defined interfaces. While expert OO programmers tend to
violently disagree with me, my opinion is based more on what
mere mortals tend to do with OO than on what the experts do.
I've seen too many occasions where C++ hackers have come up
with a great-looking prototype, offering superb performance
and seemingly ultra-compact code, although carefully ignoring
many of the harder problems and exception flows. The problem is
that the prototype is then handed off to "normal" programmers,
who have to address all the trickiness that the prototype
didn't cover, and that's when it tends to go south...

In short, I have not missed OO when using Erlang in its original
domain. I have, on occasion, missed being able to conveniently
extend modules and override individual functions when working
on other things (e.g. like extending mnesia). OTOH, I've also
dug into some Ruby-on-Rails code to see if I could extend some
Redmine plugins, and that experience only strengthened my
opinion that you can go horribly wrong with OO and method
overriding - especially when there can be many modules overriding
the same function, and it's not especially clear in which order
they are processed[1].

The hardest part of designing a language is probably not what to
include, but what to leave out. Erlang is not a multi-paradigm
language[2], and shouldn't strive to become one IMHO.

BR,
Ulf W

[1] Actually it is clearly defined, but it took some time for me
to find it. RoR defines one order, and Redmine modifies it.
Maybe it's an acquired taste, but I must say I didn't immediately
take to it.

[2] There are such languages; e.g. Oz, Scala and perhaps LISP
(although LISP probably deserves a classification of its own).
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-11 10:38:15 UTC
Permalink
...Still, managing large projects [WELL]
with loosely coupled components [WRITTEN IN A STATICALLY
TYPED LANGUAGE] that need to be upgradable in
service is not an easy problem to solve, and largely still a
research area.
I accidentally left out the parts in brackets above.
I think Erlang solves it pretty well, albeit often through
convention and intuitive patterns rather than with guarantees.

It could well be that we will eventually see solutions based on
statically typed languages that turn out to be superior, if
they can come up with ways to write concise and readable code
that is statically checkable to an extent that Erlang code
possibly never will be. It'd be sad if that didn't happen,
actually.

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-11 11:20:56 UTC
Permalink
when defending his PhD thesis, Joe was asked about it and basically said that at the time
From http://www.infoq.com/news/2010/07/objects-smalltalk-erlang
--------------------------
Joe Armstrong's thesis advisor is quoted making a very similar argument:

I started wondering about what object oriented programming was and I
thought Erlang wasn't object oriented, it was a functional programming
language. Then, my thesis supervisor said "But you're wrong, Erlang is
extremely object oriented". He said object oriented languages aren't
object oriented. I might think, though I'm not quite sure if I believe
this or not, but Erlang might be the only object oriented language
because the 3 tenets of object oriented programming are that it's
based on message passing, that you have isolation between objects and
have polymorphism.

Dr. Armstrong indicates he is not entirely convinced by his advisor's
arguments, but does seem to think that Erlang "might be the only
object oriented language."
--------------------------
unknown
2010-08-11 12:08:40 UTC
Permalink
2010/8/11, Ulf Wiger <ulf.wiger>:
[...]
Post by unknown
In short, I have not missed OO when using Erlang in its original
domain. I have, on occasion, missed being able to conveniently
extend modules and override individual functions when working
on other things (e.g. like extending mnesia).
This is something I also miss. I've seen way too many instances of
code simply copied and only 2 functions were substantially changed out
of 16. Of course, this can be refactored, but it just doesn't feel
elegant.

But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
unknown
2010-08-11 14:02:22 UTC
Permalink
Post by unknown
[...]
Post by unknown
In short, I have not missed OO when using Erlang in its original
domain. I have, on occasion, missed being able to conveniently
extend modules and override individual functions when working
on other things (e.g. like extending mnesia).
This is something I also miss. I've seen way too many instances of
code simply copied and only 2 functions were substantially changed out
of 16. Of course, this can be refactored, but it just doesn't feel
elegant.
That's just poor programming.
Post by unknown
But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
Well, we have expressions. Look on the bright side you don't have to
wrap with unnecessary begin ... end blocks and have needless
connecting words like 'else' spread everywhere like you do in less
well-designed languages. If you really need a more classic style
syntax look at Lisp Flavoured Erlang or Effene (albeit different
classic).

Robert
unknown
2010-08-11 17:56:22 UTC
Permalink
On Wed, Aug 11, 2010 at 5:08 AM, Attila Rajmund Nohl
Post by unknown
But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
lfe?
reia?
unknown
2010-08-12 03:29:38 UTC
Permalink
Post by unknown
But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
I'm a little puzzled by this.
Allowing expressions to be called statements,
Erlang doesn't have *ANY* way to "end" them.
(Of course every kind of opening bracket has a corresponding
closing bracket, but I'm not counting ")" as a way to end a
"statement".)

Erlang uses the full stop to terminate top level forms.
That is the ONLY way they can end.
They are the ONLY things so terminated.

Commas and semicolons are not terminators,
they are separators.

Semicolon is the "else" that someone recently said Erlang
didn't have. Much confusion can be saved by putting
semicolons at the beginning of lines, making it clear
that ";" is no more of a statement terminator in Erlang
than "else" can be called a statement terminator in Pascal.
unknown
2010-08-12 03:51:33 UTC
Permalink
I've never really had the problems that others seem to with Erlang's
punctuation. I've always thought of an Erlang function as like a
sentence. Just like in sentences, you use different punctuation to
separate the different parts. When you see the full stop, the sentence
ends. A single line is not necessarily a single, self-contained "statement".

Geoff
Post by unknown
But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
unknown
2010-08-12 04:17:36 UTC
Permalink
I also really like the Erlang syntax with commas and semicolons because
it is more of a logical language with the comma as an "and" and the
semicolon as an "or" (like in Prolog). Enforcing a type of indentation
like Python, might help create more order within the source code.
However, the Erlang language itself already contains much logical order
as a functional language.
Post by unknown
I've never really had the problems that others seem to with Erlang's
punctuation. I've always thought of an Erlang function as like a
sentence. Just like in sentences, you use different punctuation to
separate the different parts. When you see the full stop, the sentence
ends. A single line is not necessarily a single, self-contained "statement".
Geoff
Post by unknown
But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
unknown
2010-08-12 07:25:13 UTC
Permalink
Post by unknown
I've never really had the problems that others seem to with Erlang's
punctuation. I've always thought of an Erlang function as like a
sentence. Just like in sentences, you use different punctuation to
separate the different parts. When you see the full stop, the sentence
ends. A single line is not necessarily a single, self-contained "statement".
Hear, hear!

I've always found (well-laid out) erlang code to be particularly elegant.

deryk
unknown
2010-08-12 19:31:05 UTC
Permalink
On Wed, Aug 11, 2010 at 8:08 AM, Attila Rajmund Nohl <
Post by unknown
But it's nothing compared to the headache caused by the four different
ways to end a "statement": comma, full stop, semicolon or nothing.
Maybe this can help? http://ferd.ca/on-erlang-s-syntax.html
I wrote this a while ago especially for such complaints, let me know what
you think.
It addresses the actual problem: "unable to swap lines of code without
changing the token at the end of the line". I only write new code in
about 1% of my work time, the rest is about fixing bugs in existing
code and refactoring.

For example I have a macro in vim that generates an io:format printing
the value of the variable under the cursor. It works fine when the
line ends with comma, but doesn't work that fine if the variable is on
the last line of a case clause or a function clause. It's not a huge
deal, but a constant annoyance.
unknown
2010-08-11 12:25:21 UTC
Permalink
On Wed, Aug 11, 2010 at 6:24 AM, Ulf Wiger
Post by unknown
In short, I have not missed OO when using Erlang in its original
domain. I have, on occasion, missed being able to conveniently
extend modules and override individual functions when working
on other things (e.g. like extending mnesia).
BR,
Ulf W
I believe you use mnesia:activity/4 to do this (change the callback module),
but wouldn't the -extend(Mod) module attribute solve your problem (even in
the case of mnesia?). As far as I know, it does exactly that: override
functions and leave the others to be called from 'Mod' when they are
undefined. Any reason why this wouldn't do or why you [maybe] dislike the
feature?
unknown
2010-08-12 08:03:04 UTC
Permalink
I agree that -extend(Mod) seems like it would solve this.
I have not used it myself yet and am not yet ready to have
a firm opinion about whether that is the way to go.

To be clear, it does address something that has occasionally
bugged me, but I've not considered it a big enough problem
that I've made it a priority to evaluate it.

BR,
Ulf W
Post by unknown
On Wed, Aug 11, 2010 at 6:24 AM, Ulf Wiger
<ulf.wiger <mailto:ulf.wiger>>
In short, I have not missed OO when using Erlang in its original
domain. I have, on occasion, missed being able to conveniently
extend modules and override individual functions when working
on other things (e.g. like extending mnesia).
BR,
Ulf W
I believe you use mnesia:activity/4 to do this (change the callback
module), but wouldn't the -extend(Mod) module attribute solve your
problem (even in the case of mnesia?). As far as I know, it does exactly
that: override functions and leave the others to be called from 'Mod'
when they are undefined. Any reason why this wouldn't do or why you
[maybe] dislike the feature?
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-11 12:44:47 UTC
Permalink
On Wed, Aug 11, 2010 at 12:24 PM, Ulf Wiger
<ulf.wiger> wrote:

I simply cannot resist replying to this one :)
Post by unknown
What types of programs are a breeze to write in language X, but
cumbersome in Erlang? What parts of Erlang make it cumbersome?
Could they be fixed? Do we care enough to fix it?
I think your last paragraph is the most important. A language is
defined by what you leave out rather than what you let slip in. So it
is entirely possible to punt on certain problems and eschew their
addition to the programming language in question. There are two kinds
of programs I still prefer to write in Ocaml rather than Erlang:

1) Programs which are relying heavily on algebraic datatypes (ADTs).
That is, symbolic manipulation. A struct where the first field is
tagged with an atom() type simply just doesn't feel the same as having
a rigorously defined variant type with fast member access.

2) Programs with a computationally intensive kernel. An optimization
in Ocaml makes arrays of floats be unboxed by default. This means that
numeric code actually runs fast in ocaml. Add all the virtues of
functional programming on top of this and you have an
imperative/functional hybrid which rips apart most other programming
languages. One way around this trouble can be achieved by using NIFs
and write the kernels in C.

Ocaml doesn't fare well on concurrency however. It can do parallellism
with some trouble (There is a rather nice MPI-interface), but for
concurrency, I'd much rather have Erlang.

The only way to add this to Erlang is to open up Pandoras box. This
box contain the destructive updates and I would rather that it is not
opened.

[...]
Post by unknown
- Strong static (a la Haskell & ML) typing is praised by many
?as a great boon to software quality and productivity.
With a channel-primitive, it is possible to add strong static typing
to a concurrent language. The upgradeable processes part is far more
interesting however. One simple way to achieve it is to postpone
type-checking till on-load-time but you will still need to resolve
types around channels if they change. In principle you need
functionality akin to code_change/3 on the type level - and perhaps
some fairly deep dependency tracking features if more than one module
is loaded. Indeed, the ramifications are deep.
Post by unknown
- Lazy evaluation is superb for some problems, and e.g. QuickCheck
?relies heavily on it. While it can be done in Erlang, you have
?to make do with "poor-man's lazy evaluation", rolling your own.
?Again, going all the way seems to be somewhat at odds with soft
?real-time characteristics and predictable memory utilization.
Lazy evaluation is also a curse for other problems. Lazily evaluating
is slower so you need strictness analysis to get it to run fast. If
the strictness analyzers can't "see" what is going on in the program
you end up with a program that in the worst case fills up all of your
memory. In the common case, the program will fill up memory and then
consume it, fill up, consume, ..., and so on. This way of computing is
hard on the memory bandwidth - the scarcest resource we have in modern
computers. Also, writing daemons which do not leak takes time as you
have to go over all the details of strictness in the program. I much
prefer strict evaluation and then the ability to "go lazy" on a
by-need basis.

Note that rpc:async_call/4 and its cousin rpc:yield/1 defines a lazy
promise if the call is *not* executed by a separate thread in the
background. Alice ML uses lazy promises like this for lazy evaluation
and in addition for concurrent background work as in Erlang.
Post by unknown
- Shared-memory concurrency is the cat's miau for some problems,
?but Erlang carefully stays away from it, since it was designed
?for problems where shared memory is more trouble than it's
?worth - not least because all bets are off in terms of fault
?tolerance if a process with write access to your memory dies
?in the process of modifying it.
There is one idea here I have been toying with. One problem of Erlangs
memory model is that sending a large datastructure as a capability to
another process, several megabytes in size, will mean a copy. In the
default VM setup that is. But if you had a region into which it got
allocated, then that region could safely be sent under a proof that
the original process will not touch it anymore. It is possible to
infer regions like these (See Tofte/Talpin and later
Niss/Makholm/Henglein) but I would opt for a simpler variant with
explicit mention of regions for starters. If the (albeit cumbersome)
model of explicit region management can't work out, why have any hope
for an automatic variant? There is also a tangent here with
substructural type systems, linear types or uniqueness types in
particular. A destructive update can be allowed if we can prove we are
the only one holding a reference to the data.

But unless such a system works out rahter clearly, it is not worth the
hassle of adding. Practical usefulness is more important for Erlang -
so it should be kept in a theoretic toy language first for play, fun,
and profit.
Post by unknown
My own experience from telecoms tells me that OO gives the wrong
signals to people in complex projects. They tend to want to
maximize design-time dependencies rather than going with a style
more similar to electrical component design - black boxes, with
well-defined interfaces.
This is my experience as well. The trap of OO is to be an architecture
astronaut and define a wild system - only to find that your wrapping
of objects 4-5 times is what kills your Java heap. And Garbage
collectors with one big heap greatly dislikes having to walk large
amounts of live data...
Post by unknown
The hardest part of designing a language is probably not what to
include, but what to leave out. Erlang is not a multi-paradigm
language[2], and shouldn't strive to become one IMHO.
Precisely. It is about choosing a few concepts which can support each
other well with little overlap. And aggressively shaving off
everything that Occam's Razor suggest. For that reason, Joe Armstrongs
idea of removing something whenever you add something is a good one.
Improvement should come from "silent" optimizations, like the
gen_server:call/2,3 mailbox optimization recently added. I for one
have enjoyed that every time a new version of Erlang came out, my
program got faster.
--
J.
unknown
2010-08-11 13:59:01 UTC
Permalink
On Wed, Aug 11, 2010 at 8:44 AM, Jesper Louis Andersen <
Post by unknown
There is one idea here I have been toying with. One problem of Erlangs
memory model is that sending a large datastructure as a capability to
another process, several megabytes in size, will mean a copy. In the
default VM setup that is. But if you had a region into which it got
allocated, then that region could safely be sent under a proof that
the original process will not touch it anymore. It is possible to
infer regions like these (See Tofte/Talpin and later
Niss/Makholm/Henglein) but I would opt for a simpler variant with
explicit mention of regions for starters. If the (albeit cumbersome)
model of explicit region management can't work out, why have any hope
for an automatic variant? There is also a tangent here with
substructural type systems, linear types or uniqueness types in
particular. A destructive update can be allowed if we can prove we are
the only one holding a reference to the data.
But unless such a system works out rahter clearly, it is not worth the
hassle of adding. Practical usefulness is more important for Erlang -
so it should be kept in a theoretic toy language first for play, fun,
and profit.
One interesting point of *always* copying data structures is that you need
to plan for small messages (as far as possible) whether you are on a single
node or in a distributed setting. Moving up from a [partially] shared memory
model to a fully isolated one when going distributed is likely going to have
its share of performance problems and might create a dissonance between
"what is acceptable locally" and "what is acceptable when distributed".

I believe forcing messages to always be copied (except for large binaries)
reinforce the transparency and predictability of distribution in Erlang, on
top of keeping it all conceptually simpler on all levels. I'm not sure I
would necessarily like to give up these
hard-to-notice-but-still-pretty-useful advantages for the sake of speed on
local nodes.
unknown
2010-08-12 08:01:28 UTC
Permalink
Post by unknown
On Wed, Aug 11, 2010 at 8:44 AM, Jesper Louis Andersen
<jesper.louis.andersen
There is one idea here I have been toying with. One problem of Erlangs
memory model is that sending a large datastructure as a capability to
another process, several megabytes in size, will mean a copy. In the
default VM setup that is. But if you had a region into which it got
allocated, then that region could safely be sent under a proof that
the original process will not touch it anymore. [...]
One interesting point of *always* copying data structures is that you
need to plan for small messages (as far as possible) whether you are on
a single node or in a distributed setting. Moving up from a [partially]
shared memory model to a fully isolated one when going distributed is
likely going to have its share of performance problems and might create
a dissonance between "what is acceptable locally" and "what is
acceptable when distributed".
So a number of different variations on this theme have been tried
in the past and discussed as future extensions:

- Robert Virding used to have his own implementation called VEE.
It had a global shared heap and incremental GC.

- A 'shared heap' option in BEAM once had experimental status.
It passed messages by reference. Note that in neither of these
cases is there any change in semantics - conceptually, msg
passing was still copying. The main problem with this version
was that it still used the old copying garbage collector. The
idea was to implement a reference-counting GC, but for various
reasons, it didn't happen. When multicore started becoming
interesting, the shared-heap version was left behind.

- Hybrid heap was an evolution of 'shared heap', where only
data sent in messages were put on a global heap. In the first
implementation, data was copied to the global heap on send
(unless already there) instead of being copied to the receiver's
heap. This implementation was also broken by SMP.

- Lately, some exploration has gone into allowing a set of
processes to share the same heap. This could be done in (at
least) two ways:
a) either co-locate all processes in the group on the same
scheduler. This would ensure mutual exclusion and mainly
serve to reduce message-passing cost in a process group.
b) allow processes in a group to run on different schedulers,
using mutexes to protect accesses to the heap data. This
could allow for parallel processing, but the locking
granularity would either be heap-level or ...very subtle,
I guess. I favour option (a).

I think it is appropriate to use under-the-cover tricks to
speed up message passing as much as possible, as long as the
semantics stay the same. In other words, in all the above cases,
isolation has been a given, and conceptually, messages are
still copied.

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-14 00:23:36 UTC
Permalink
Co-locating processes on a shared heap on 1 scheduler might be dangerous.
What if a process migrates to another core/scheduler? Should that be
allowed? Blocked? Should you pay the cost of a largely uncontested lock
(azul claims it is almost free)? What if one of those processes forks
another one? Should it belong to the flock and be bound to that scheduler?
Should it be allowed to migrate to another scheduler? Should the message it
is receiving dictate the scheduler it is going to process it on? (ie: on
receive, check where the message originates from (heap wise) and force the
process to reschedule on the proper scheduler so it can have access to the
memory) etc.
I think it will be quite hard to do transparently (sharing msg data between
processes without copying) mainly because it might be hard to tell data that
is a msg from data that isn't. If a process sends a message then dies,
you'll have to either: allocate the msg from the shared heap, somehow
knowing or copying, or copy it in case the process heap gets garbage
collected/freed (or prevent that from happening, which could have a
detrimental effect on the system if the receiving process has a very large
queue and takes a very long time before consuming said message)

This could be mitigated by adding a special syntax for message creation
where they would be created on a shared heap (or a special syntax for shared
heap allocation). Perhaps something like {Foo} = Whatever (or Foo }=
Whatever.). Where 'Foo' would be copied on the shared heap. Binaries are
already reference counted so it might not be too bad to implement.

IMO though, the whole sending a large datastructure as a message is largely
a non-issue. You can easily wrap it in a process and allocate it from that
processe's heap and just pass the PID around. Sure you have to pay an
overhead for accessing said data through messages but if you are clever,
that isn't too bad. If you are going to communicate accross nodes, you don't
have much of a choice anyway: either you copy to the other node or you pass
the PID and pay the price of cross node communication. That will be largely
determined by your overall design. How much data can you afford to transfer?
How likely are you to query from it? What if the data node goes down? etc.

The only case requiring shared memory i've run into (ever, programming, with
or without erlang) is large number crunching. You either need to access
large amounts of data concurrently or you need to access non trivial amounts
of data from many processes/threads. If that is what you need to do, I would
advice against using erlang (as much as I like it). You'll be better off
making a C++/C#/Java node for those, or a driver. Chances are if you need to
do number crunching or process large amounts of data you'll care about cache
alignment and such and erlang isn't the tool for that particular job.

I guess the only other viable alternative would be to have all processes
allocated from a shared heap and implement a concurrent GC. That would make
sharing messages quite easy as you would be guaranteed that a message has a
live reference somewhere (the sender, the receiver or both). This would
however impact just about every system out there and could be quite risky...
Then again, concurrent GCs are the new hot stuff nowadays and erlang is in
dire need of modernizing.

Anyhow, 2cents. I like the current erlang design and probably wouldn't
change it much if i could.
Nicholas

On Thu, Aug 12, 2010 at 4:01 AM, Ulf Wiger
Post by unknown
Post by unknown
On Wed, Aug 11, 2010 at 8:44 AM, Jesper Louis Andersen <
jesper.louis.andersen <mailto:jesper.louis.andersen>>
There is one idea here I have been toying with. One problem of Erlangs
memory model is that sending a large datastructure as a capability to
another process, several megabytes in size, will mean a copy. In the
default VM setup that is. But if you had a region into which it got
allocated, then that region could safely be sent under a proof that
the original process will not touch it anymore. [...]
One interesting point of *always* copying data structures is that you need
to plan for small messages (as far as possible) whether you are on a single
node or in a distributed setting. Moving up from a [partially] shared memory
model to a fully isolated one when going distributed is likely going to have
its share of performance problems and might create a dissonance between
"what is acceptable locally" and "what is acceptable when distributed".
So a number of different variations on this theme have been tried
- Robert Virding used to have his own implementation called VEE.
It had a global shared heap and incremental GC.
- A 'shared heap' option in BEAM once had experimental status.
It passed messages by reference. Note that in neither of these
cases is there any change in semantics - conceptually, msg
passing was still copying. The main problem with this version
was that it still used the old copying garbage collector. The
idea was to implement a reference-counting GC, but for various
reasons, it didn't happen. When multicore started becoming
interesting, the shared-heap version was left behind.
- Hybrid heap was an evolution of 'shared heap', where only
data sent in messages were put on a global heap. In the first
implementation, data was copied to the global heap on send
(unless already there) instead of being copied to the receiver's
heap. This implementation was also broken by SMP.
- Lately, some exploration has gone into allowing a set of
processes to share the same heap. This could be done in (at
a) either co-locate all processes in the group on the same
scheduler. This would ensure mutual exclusion and mainly
serve to reduce message-passing cost in a process group.
b) allow processes in a group to run on different schedulers,
using mutexes to protect accesses to the heap data. This
could allow for parallel processing, but the locking
granularity would either be heap-level or ...very subtle,
I guess. I favour option (a).
I think it is appropriate to use under-the-cover tricks to
speed up message passing as much as possible, as long as the
semantics stay the same. In other words, in all the above cases,
isolation has been a given, and conceptually, messages are
still copied.
BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
unknown
2010-08-14 14:45:57 UTC
Permalink
Note: these are all hand-waving comments from me.
Post by unknown
Co-locating processes on a shared heap on 1 scheduler might be
dangerous. What if a process migrates to another core/scheduler? Should
that be allowed? Blocked?
An implementation issue, but yes, I imagine it could be forbidden,
or rather, the group would be considered as a whole for migration.
Post by unknown
What if one of those
processes forks another one? Should it belong to the flock and be bound
to that scheduler?
This could be at the parent's discretion, using a new spawn_opt
option, e.g. 'same_heap', dictating that the child should use the
parent's heap.
Post by unknown
Should the message it is receiving dictate the scheduler it is going to
process it on?
No, I think this would be complicated, and can't see the need
for it.
Post by unknown
I think it will be quite hard to do transparently (sharing msg data
between processes without copying) mainly because it might be hard to
tell data that is a msg from data that isn't.
But a lot of thinking already went into this.
Binaries are often off-heap, although in that case, you only need
to look at the type tag to know.

In the case I suggested, the only check needed is for whether the
receiver is sharing the sender's heap.
Post by unknown
If a process sends a
message then dies, you'll have to either: allocate the msg from the
shared heap, somehow knowing or copying, or copy it in case the process
heap gets garbage collected/freed (or prevent that from happening, which
could have a detrimental effect on the system if the receiving process
has a very large queue and takes a very long time before consuming said
message)
To my uneducated eye, this seems fairly similar to normal process
death + normal GC. If a process (not the last on that heap) dies,
the extra problem is that some data can be "freed" that is still
referenced by other processes. Something similar should have been
necessary for the 'shared heap' emulator to work in the first place.
Post by unknown
This could be mitigated by adding a special syntax for message creation
where they would be created on a shared heap (or a special syntax for
shared heap allocation). Perhaps something like {Foo} = Whatever (or Foo
}= Whatever.). Where 'Foo' would be copied on the shared heap. Binaries
are already reference counted so it might not be too bad to implement.
IMHO - no language changes! An option to spawn_opt is the right place
and scope. That's where you can peek under the covers and affect things
like GC parameters, which are otherwise fully transparent.
Post by unknown
IMO though, the whole sending a large datastructure as a message is
largely a non-issue. You can easily wrap it in a process and allocate it
from that processe's heap and just pass the PID around.
But in my experience, from complex telephony and multimedia apps,
it is in fact pretty common to have thousands of small 'clusters'
of state machines, each cluster sharing a whopping big state
record and taking turns processing different parts of the control flow.

The suggestion is that this would work as an optimization for the
tuning stage of such an application, much like it is now possible
to tune heap size, GC thresholds, etc.

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-17 13:27:20 UTC
Permalink
"... in my experience, from complex telephony and multimedia apps, it is in
fact pretty common to have thousands of small 'clusters' of state machines,
each cluster sharing a whopping big state record and taking turns processing
different parts of the control flow."

But what's behind the decision to structure things that way?

I'm not sure what you mean by "processing different parts of the control
flow"? Do you mean you had a kind of pipeline process structure?

Taking Nicholas' view, but with due concern for performance: what about
finding some way to privilege processes that manage big data structures? At
the cost of a certain amount of global flow analysis, you might be able to
automatically identify processes that were basically the system's Whopping
Big State Record Managers (i.e., infinitely tail-recursive, passing Big
State to itself each time, usually taking messages only in order to
immediately send back fragments of Big State Record). Maybe you could then
generate code that would do something more like a synchronous context switch
(and back again) than a full message-send (with corresponding reply), when
communicating with these processes. These record-access pseudo-messages
might be made particularly fast for operations that do little more than read
Big State data that never gets modified -- these probably being the
overwhelming majority of accesses anyway.

This could break hot-loading of modules, of course, depending on how you
structure things. The interprocess coupling would go from being almost as
loose as possible to almost as tight as a subroutine call. I doubt this
idea would be practical if it required Whopping Big State Record Managers to
be entirely local to a module. I don't see how you'd solve that problem in
general.

It would definitely be problematic across node boundaries, but perhaps this
is less of an issue than how to permit hot loading. If your goal was to get
higher speed for accesses of the Whopping Big State Record for a bunch of
FSMs, you wouldn't be making those FSMs reach across node boundaries anyway.

(These thoughts are somewhat inspired by an admittedly dilettantish interest
in microkernel performance. For similar reasons, a number of similar issues
about sharing, copying and performance arose in microkernel research. These
issues seem to have been resolved pretty successfully in the L3/L4
microkernel family.)

-michael turner


On Sat, Aug 14, 2010 at 11:45 PM, Ulf Wiger
Post by unknown
Note: these are all hand-waving comments from me.
Post by unknown
Co-locating processes on a shared heap on 1 scheduler might be dangerous.
What if a process migrates to another core/scheduler? Should that be
allowed? Blocked?
An implementation issue, but yes, I imagine it could be forbidden,
or rather, the group would be considered as a whole for migration.
What if one of those processes forks another one? Should it belong to the
Post by unknown
flock and be bound to that scheduler?
This could be at the parent's discretion, using a new spawn_opt
option, e.g. 'same_heap', dictating that the child should use the
parent's heap.
Should the message it is receiving dictate the scheduler it is going to
Post by unknown
process it on?
No, I think this would be complicated, and can't see the need
for it.
I think it will be quite hard to do transparently (sharing msg data
Post by unknown
between processes without copying) mainly because it might be hard to tell
data that is a msg from data that isn't.
But a lot of thinking already went into this.
Binaries are often off-heap, although in that case, you only need
to look at the type tag to know.
In the case I suggested, the only check needed is for whether the
receiver is sharing the sender's heap.
If a process sends a message then dies, you'll have to either: allocate
Post by unknown
the msg from the shared heap, somehow knowing or copying, or copy it in case
the process heap gets garbage collected/freed (or prevent that from
happening, which could have a detrimental effect on the system if the
receiving process has a very large queue and takes a very long time before
consuming said message)
To my uneducated eye, this seems fairly similar to normal process
death + normal GC. If a process (not the last on that heap) dies,
the extra problem is that some data can be "freed" that is still
referenced by other processes. Something similar should have been
necessary for the 'shared heap' emulator to work in the first place.
This could be mitigated by adding a special syntax for message creation
Post by unknown
where they would be created on a shared heap (or a special syntax for shared
heap allocation). Perhaps something like {Foo} = Whatever (or Foo }=
Whatever.). Where 'Foo' would be copied on the shared heap. Binaries are
already reference counted so it might not be too bad to implement.
IMHO - no language changes! An option to spawn_opt is the right place
and scope. That's where you can peek under the covers and affect things
like GC parameters, which are otherwise fully transparent.
IMO though, the whole sending a large datastructure as a message is
Post by unknown
largely a non-issue. You can easily wrap it in a process and allocate it
from that processe's heap and just pass the PID around.
But in my experience, from complex telephony and multimedia apps,
it is in fact pretty common to have thousands of small 'clusters'
of state machines, each cluster sharing a whopping big state
record and taking turns processing different parts of the control flow.
The suggestion is that this would work as an optimization for the
tuning stage of such an application, much like it is now possible
to tune heap size, GC thresholds, etc.
BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
unknown
2010-08-17 13:35:02 UTC
Permalink
Post by unknown
"... in my experience, from complex telephony and multimedia apps, it is
in fact pretty common to have thousands of small 'clusters' of state
machines, each cluster sharing a whopping big state record and taking
turns processing different parts of the control flow."
But what's behind the decision to structure things that way?
The fact that the signaling carries all information as a single
session, but when you break it apart, there are lots of different
state machines in there. You split them into different processes
in order to avoid interference between state machines. Still,
the signaling protocol forces them all to pack the data into
a single state.

Your proposed alternative seems quite complicated compared to
the (optimization) option of letting the FSMs share a common heap,
but that is from a *very* cursory perusal. I will try to read it
more closely later.

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-17 14:28:24 UTC
Permalink
Perhaps erlang would benefit from a system similar to C# appdomains:
Functions calls intra appdomain are simple calls, function calls extra
appdomain are rpc calls where everything is copied. Obviously, this would
translate to message passing for erlang and not necessarily function calls.
Perhaps this could be implicit (ie: 1 domain per erlang application) or
perhaps explicit (ie: as groups using spawn_opt as you suggested). Maybe it
would make sense to create an EPP for a feature like the one you are
requesting Ulf, since as you've shown, there are cases where the simplest
design for a class of applications would benefit greatly from it (and thus
prevent complicating the design to work around performance bottlenecks).

Nicholas

On Tue, Aug 17, 2010 at 9:35 AM, Ulf Wiger
Post by unknown
Post by unknown
"... in my experience, from complex telephony and multimedia apps, it is
in fact pretty common to have thousands of small 'clusters' of state
machines, each cluster sharing a whopping big state record and taking turns
processing different parts of the control flow."
But what's behind the decision to structure things that way?
The fact that the signaling carries all information as a single
session, but when you break it apart, there are lots of different
state machines in there. You split them into different processes
in order to avoid interference between state machines. Still,
the signaling protocol forces them all to pack the data into
a single state.
Your proposed alternative seems quite complicated compared to
the (optimization) option of letting the FSMs share a common heap,
but that is from a *very* cursory perusal. I will try to read it
more closely later.
BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-18 03:26:36 UTC
Permalink
"Your proposed alternative seems quite complicated compared to the
(optimization) option of letting the FSMs share a common heap, ..."

It does complicate compilation, but at least it requires no changes to
source code, and encourages loosely coupled encapsulation of large state
records.

Garbage collection issues seem to haunt this whole arena. I wonder if more
compiler smarts would help here as well.

I've read that almost all reference counting overhead (95%?) can be
eliminated by optimizing compilers. Since using the memory hierarchy
inefficiently is an increasing source of performance problems, even the
remaining overhead of reference counting (i.e., in cases where the compiler
can't resolve the liveness status of data at compile time) might be
worthwhile. After all, heap use tends to be roughly stack-like. You'd
probably get much better locality of reference in most cases if you
collected stuff as soon as possible, or at least very soon after it had been
orphaned.

I don't see how SMP *necessarily* breaks reference-counting, though of
course it complicates things.

Processes that build but then "forget" complex data structures only to die
not long after might run more slowly than before, since they'd be doing a
lot of GC that wouldn't be necessary under an
always-copy/infrequently-collect regime. But I wouldn't be surprised if
everything else sped up, by reaping the advantages of (1) using short-term
memory more efficiently, (2) using less memory overall for longer-term data
by sharing large data structures, and (3) avoiding copy operations
regardless of the size of the data.

-michael turner

On Tue, Aug 17, 2010 at 10:35 PM, Ulf Wiger
Post by unknown
Post by unknown
"... in my experience, from complex telephony and multimedia apps, it is
in fact pretty common to have thousands of small 'clusters' of state
machines, each cluster sharing a whopping big state record and taking turns
processing different parts of the control flow."
But what's behind the decision to structure things that way?
The fact that the signaling carries all information as a single
session, but when you break it apart, there are lots of different
state machines in there. You split them into different processes
in order to avoid interference between state machines. Still,
the signaling protocol forces them all to pack the data into
a single state.
Your proposed alternative seems quite complicated compared to
the (optimization) option of letting the FSMs share a common heap,
but that is from a *very* cursory perusal. I will try to read it
more closely later.
BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-12 07:38:13 UTC
Permalink
On Aug 11, 11:03?am, Jesper Louis Andersen
Post by unknown
Parameterized modules make me warm and fuzzy because they seem to give
a way to implement ML-style functors (maps from modules to modules).
Yes, they do. This is the real functional fun :)
unknown
2010-08-11 17:59:53 UTC
Permalink
Post by unknown
I can't agree with you. Inheritance is only way how some OOP language
copes with complexity of OO systems. Inheritance is neither core nor
mandatory feature of OOP.
I would say some type of polymorphism is a mandatory requirement of OOP.
Inheritance is one way to provide polymorphism, but certainly not the only
one.
--
Tony Arcieri
Medioh! A Kudelski Brand
unknown
2010-08-11 18:07:09 UTC
Permalink
Post by unknown
I would say some type of polymorphism is a mandatory requirement of OOP.
Inheritance is one way to provide polymorphism, but certainly not the only
one.
there are quite a lot of different kinds of polymorphism.

not true that e.g. a language with only parametric polymorphism is
guaranteed OO (cf. haskell), so i suspect you have to narrow it down a
little. maybe something more like "OO requires messaging, and
different objects can react differently to the same message" (cf.
typeclasses)? which isn't anything about inheritance.

sincerely.
unknown
2010-08-12 02:49:56 UTC
Permalink
Post by unknown
I have to stand up for OOP at this point: OOP does not start and end with
"encapsulating code and data". The OOP feature that has the strongest impact
on code brevity is *inheritance*. Thus, the interest in extending modules.
I was recently reading a collection of essays by Kent Beck, one of the
big names in the Smalltalk and Patterns worlds. Oddly enough, he said
that he didn't think inheritance was all that big a deal.

Having worked on a Smalltalk system for several years, I've found that
every time a new subclass is created you have to revise up and down the
inheritance hierarchy to make sure that everything still makes sense.
The more goodies you put in the parent class, the harder it is to make
a child class that gets them all exactly right.

That is, if you *bother*. I love the Smalltalk language, but one thing
that bugs me about all the actual Smalltalk systems (other than my own,
of course) that I've tried is the high frequency of stuff in superclasses
that does NOT in fact work with subclasses. (What bugs me about _my_
Smalltalk is the effort it takes to make sure that doesn't happen.)

Here's the example that currently annoys me.

(0) Squeak 4.1 has a #closed method in Stream, that you can send to
a stream to find out whether it needs closing or not.
Some of the streams in VisualWorks 7.5 non-commercial also have this.

(1) ('abc' readStream) close; closed
returns false in Squeak. Now the way I read the ANSI Smalltalk
standard, closing a stream is supposed to release all the resources
it is holding onto. A ReadStream is holding onto the collection it
is streaming over, so closing it ought to release that.

In fact #closed is giving the right answer here, because #close does
NOT close a ReadStream. It's worse than that: when I tried to fix
this by defining #close suitably for ReadStream, a core part of the
system broke, because it relied on #close *NOT* closing certain
derived streams!

(2) In VisualWorks it just raises an exception because file streams do
have #closed but data structure streams don't.

(3) I thought that #closed sounded like a neat idea and decided to add
it to my system. This turned out to require the careful reinspection
of some 75 classes, and the addition of some new ones.

On the whole, I'm pleased that I'm doing this (I've done all the
input streams and am working on the output ones). Previously I
had taken far too much advantage of the fact that ANSI says sending
anything to a closed stream has "undefined" effects. Now either
something sensible will happen or you will get a defined exception.
Adding more test cases did no harm either.

The problem is that inheritance per se is easy.
Making sure that all inherited code works in all places is hard.

Conclusion: inheritance is NOT an unmixed blessing. It can, in fact,
create maintenance nightmares.

Then there's the Standard Template Library in C++.
Alexander Stepanov is on record as not having found inheritance
of much use for that. The book about programming he published
recently makes much use of "types belonging to CONCEPTS" but
none of types belonging to inheritance hierarchies.

Then of course there's CORBA, with inheritance of _interfaces_,
but no inheritance of code.

There's the interesting distinction between Haskell type classes
(which do provide 'default implementations' that you can inherit)
and the otherwise identical Clean type classes (which don't).

Oh yes, one other thing. In developing stream classes, inheritance
in Smalltalk is less help than you might expect. For example,
ReadWriteStream must provide all the methods that ReadStream and
WriteStream do, but can inherit from only one of them. And I have
a special case of that, StringReadWriteStream, which ought to
inherit from String as well, but can't. There are several other
examples of this kind. I have four copies of some methods.

Until my compiler supports Traits, I've considered using file
inclusion to handle such duplicate methods. Erlang _has_ file
inclusion, so we can use that.

In a language with hot loading, it's not completely clear what
module extension MEANS.

Suppose we have
module P
module C extends P

load C

Does P also get loaded, or is it just the compiler that's aware of it?

change P
load P

Should C change?
What if some of the functions of P have been inlined in C?
Post by unknown
Also, IMHO, parameterized modules are a more compact way to encapsulate code
and data, since that you don't have to pass the data structure around as an
explicit state (assuming, of course, that the data is immutable).
When I called myself an ML programmer, I *had* modules which took
values, types, and modules as parameters (called 'functors').
When I switched to Haskell, I found that I never missed them.

In fact with Erlang parameterised modules you DO have to pass
around the explicit state. As noted before in this mailing list,
it's just as easy, if not easier, to put functions inside a
data structure. Parameterised modules solve a problem that Erlang
did not actually have.
unknown
2010-08-12 03:35:02 UTC
Permalink
Post by unknown
I was recently reading a collection of essays by Kent Beck, one of the
big names in the Smalltalk and Patterns worlds. Oddly enough, he said
that he didn't think inheritance was all that big a deal.
I must respectfully disagree here, especially in an everything-is-an-onject
language like Smalltalk.

With everything-is-an-object and inheritance, all of your objects speak a
common object protocol, which can provide all sorts of things to the end
user by default for every object, including powerful introspection methods
which let you peruse and probe a particular object's state at runtime.

Is this possible without inheritance? Sure. But I find it to be particularly
powerful and elegant in languages like Ruby.
--
Tony Arcieri
Medioh! A Kudelski Brand
unknown
2010-08-12 06:09:14 UTC
Permalink
Post by unknown
Post by unknown
I was recently reading a collection of essays by Kent Beck, one of the
big names in the Smalltalk and Patterns worlds. Oddly enough, he said
that he didn't think inheritance was all that big a deal.
I must respectfully disagree here, especially in an everything-is-an-onject
language like Smalltalk.
It wasn't me. It was a great big Smalltalk guru saying that.
Post by unknown
With everything-is-an-object and inheritance, all of your objects speak a
common object protocol,
No they don't. Oh sure, there are a bunch of methods in Object.
VisualWorks 7.5 has 253 methods available in Object.
Squeak-3.8Full has 441 methods available in Object.
My own Smalltalk has 98 methods available in Object,
and that's despite trying to keep the number down.
(It's about 80 if you exclude private error reporting methods.)

Of course, *without* inheritance, all my objects would
*still* support all these methods.

There is nothing in the definitions of "OO" that have
been bandied around to this point that implies "everything is
an object" or "has a single root".

I repeat: inheritance can be a great burden.

Imagine me adding a new class to Squeak 3.8.
"What should my object do for each of these 441 methods?"
I don't even know what most of them *are*, and when I look
at them, the documentation usually isn't there so that I
don't really understand what the methods do for *any* object.

Take just one example, which I had never looked at before.

actAsExecutor
"Prepare the receiver to act as executor for
any resources associated with it."
self breakDependents

What should that do for MY object? Hmm, what does everyone
else do? Oh, only StandardFileStream overrides it, and that
just calls super and then sets the name to nil.
Who sends it?

executor
"Return an object which can act as executor for
finalization of the receiver."
^self shallowCopy actAsExecutor

I am beginning to get a glimmer here. If _this_ object is
going to be finalised, then the message about it is going
to be sent to some *other* object which has a copy of this
object's internal state. Let's see what breakDependents
does.

breakDependents
"Remove all of the receiver's dependents."
self myDependents: nil

Got that. Oh dear. I haven't done anything about #myDependents:.
That's OK, turns out I don't need to. Looking further,
#executor is called in WeakRegistry, where

add: anObject
"Add anObject to the receiver.
Store the object as well as the associated executor."
|executor|
executor := anObject executor.
self protected: [
valueDictionary at: anObject put: executor].
^anObject

I see. #actAsExecutor is something I have to worry about if and
only if my object is ever added to a WeakRegistry. Whoops! I
don't and can't know if that will ever happen, so I had better
worry about it for ALL classes. I don't understand how things
are supposed to work if my object has a reference to something,
an executor for it is made (which holds onto that reference),
and then my object replaces that reference by a different one.
Won't the executor use the wrong object?

Now I am thoroughly confused and worried (and happier than ever
to have my own Smalltalk).

Multiply this by about 100 to discover how it feels to
be inherited at by something with so many methods.

Now suppose you want to make something that is a subclass of
OrderedCollection. Oh my: there are 719 methods. I have to
make sure I don't break -any- of them.

I have actually done this, and BOY was it a pain.

Being inherited upon from a great height is no fun at all.
The more there is to inherit, the harder it is.

I'm afraid the Smalltalk tradition seems to be "check that
the methods I currently want to use work and the H**L with
the rest of them". Case in point: RunArray. When I came
to implement RunArray, I found it difficult to implement
certain methods that the ANSI standard requires sequences to
have. So I wondered how other Smalltalks had done them.
Turned out they hadn't bothered.
Post by unknown
which can provide all sorts of things to the end
user by default for every object,
It isn't inheritance that makes all sorts of things available
to the user, it is conformance to common interfaces.
It's wonderful for whoever gets to use the stuff.

It's painful for whoever has to implement it.
Amongst other things, just because you didn't override a method
doesn't mean you have no need to test it. Any time you make a
new class, you need to test *ALL* its methods, and if you
inherited 441 of them, that's 441 methods needing several test
cases each. You *might* be able to inherit some test cases,
but it's practically certain you will have to write a heck of a
lot of tests for things you personally aren't responsible for
and wish weren't there.
Post by unknown
including powerful introspection methods
which let you peruse and probe a particular object's state at runtime.
Is this possible without inheritance? Sure. But I find it to be particularly
powerful and elegant in languages like Ruby.
And Ruby copied practically all of it from Smalltalk.
Yes, introspection is possible without inheritance.
For example, my Smalltalk can find
- the class of an object
- the name of the class
- the comment of the class (if there is one)
- the methods defined in that class
- the methods available in that class
and can - call any of those methods
and as it happens, the way this works makes no use of inheritance.
ALL of the key methods are in Object or Class and are not
overridden.
It so happens that I don't provide
X the names of the instance variables
X access to the instance variables of another object
but an object can
- access its own instance variables in an array-like way
so that - the persistence machinery can do this.

Persistence *does* make use of inheritance, but if inheritance had
not been available it could have been done another way.


I'm not saying that inheritance is always a bad thing.
Just that it has fairly massive costs as well as benefits,
so that it isn't always an overall win.
unknown
2010-08-12 04:12:54 UTC
Permalink
Post by unknown
Post by unknown
I have to stand up for OOP at this point: OOP does not start and end with
"encapsulating code and data". The OOP feature that has the strongest impact
on code brevity is *inheritance*. Thus, the interest in extending modules.
I was recently reading a collection of essays by Kent Beck, one of the
big names in the Smalltalk and Patterns worlds. Oddly enough, he said
that he didn't think inheritance was all that big a deal.
I agree that inheritance can be more trouble than it is worth in large
systems. A good example is the Microsoft Foundation Classes which were
replaced by .NET (i.e., if MFC was great, it would not need to be
rewritten). Has-A relationships are much easier to understand with
proper scoping than Is-A relationships. The most useful book I have
found for designing large systems that are maintainable is "Large Scale
C++" by Lakos
(http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620).
However, these types of design issues are much easier to find in C++
than in Erlang, since you can accomplish more with less source code
(i.e., smaller systems when judging by a non-whitespace line count) in
Erlang (and Erlang does not provide inheritance, but rather has the
simpler concept of behaviours).

A common mistake that is easy to make in C++ is to have a small fine
grained type of object that is abstract (only virtual methods) with a
very large vertical inheritance hierarchy of perhaps 5 or more levels.
I think such object hierarchies make the system less scalable because of
the virtual function calls with extreme runtime polymorphism. Usually
source code that is written like this was over-engineered and only
exists to waste both development-time and run-time.

Erlang would not benefit from the added complexity of OOP inheritance.
unknown
2010-08-11 11:04:39 UTC
Permalink
From: Hynek Vychodil <hynek>
Subject: Re: [erlang-questions] OOP in Erlang
To: "Guy Wiener" <wiener.guy>
Cc: "Erlang Questions" <erlang-questions>
Date: Wednesday, August 11, 2010, 4:37 AM
On Wed, Aug 11, 2010 at 9:44 AM, Guy
Wiener <wiener.guy>
Post by unknown
I have to stand up for OOP at this point: OOP does not
start and end with
Post by unknown
"encapsulating code and data". The OOP feature that
has the strongest impact
Post by unknown
on code brevity is *inheritance*. Thus, the interest
in extending modules.
I can't agree with you. Inheritance is only way how some
OOP language
copes with complexity of OO systems. Inheritance is neither
core nor
mandatory feature of OOP. What worse, many of OO affected
people what
I met stated that inheritance is most controversial and
mostly misused
feature of OOP. I also observe that there is positive
correlation with
person experience and probability that will tell or agree
with above
statement.
Post by unknown
Also, IMHO, parameterized modules are a more compact
way to encapsulate code
Post by unknown
and data, since that you don't have to pass the data
structure around as an
Post by unknown
explicit state (assuming, of course, that the data is
immutable).
Post by unknown
Guy
On Wed, Aug 11, 2010 at 5:17 AM, Ngoc Dao <ngocdaothanh>
Post by unknown
The mostly used feature of OOP is probably
encapsulating code and
Post by unknown
Post by unknown
http://www.erlang.org/doc/man/gen_server.html
When I first studied OOP, in 1990, I was taught that OO was defined by four features: Encapsulation, Abstraction, Inheritance, and Polymorphism. That if any of these were missing it was not OO.

-EdK

Ed Keith
e_d_k

Blog: edkeith.blogspot.com
unknown
2010-08-11 13:20:46 UTC
Permalink
Post by unknown
When I first studied OOP, in 1990, I was taught that OO was defined by four features: Encapsulation, Abstraction, Inheritance, and Polymorphism. That if any of these were missing it was not OO.
? ? ? -EdK
I was taught this also. However, I'm pretty certain that Alan Kay
doesn't subscribe to this definition. Java-style OOP, of course, does.

Let's not ignore what java objects are. Instances of user-defined
types that are bundled with a number of transformations (methods) that
are legal (hopefully) on that type.

Looking at this another way, there's really only two things going on
here:
1) Data structures and
2) Transformations of data structures.

The class type definition defines a data structure, often as a
composite of other, previously defined structures. "Encapsulation"
insulates you from this detail. Thus you can program in a world at a
higher level, and that world of "Abstraction" was defined by one or
more programmers each with a different view of correctness and
applicability. So you'd better hope that all the detail of the
implementation was appropriate and well thought through. Of course it
usually isn't entirely appropriate to *your* problem and *your*
current notion of applicability...

...but never mind along comes a toolset to change all
that."Inheritance" will allow you to add to or modify the underlying
data structure and define or redefine the applicable transformations.
You can re-invent your abstraction as you please. Obviously, you are
taking care to make sure everything is correct and applicable to the
problem domain (at least, the one you are currently aware of). Any mis-
step in this process has ramifications way beyond what you can
currently appreciate, when other programmers program in the world of
your new abstractions, along with any other issues inherited by it.

While you are making this wonderful re-useable software by extension
of other data structures and transformations you can do some radical
things to fix up problems of the past. Overloading, to allow you to
parameterize your transformations with other structures that may
impact the transformation of the subject of the transformation. With
overriding, you can just redefine the entire transformation.

Somehow you want to allow all these (different) types to continue to
be used with this new transformations, so you need type
"Polymorphism". You are careful to be sure that your new
transformation (method) will be applicable and correct for all data
structures that could be represented by the polymorphic type
(interface), so I guess you really need to know quite a bit about the
abstracted and encapsulated data structures so that your system
doesn't end up in an illegal state of some kind. Of course when you
don't know what type to use, just can just shove in a 'null'.

Having built your beautiful cathedral of types and transformations,
you may then need to define and implement a protocol to send it as
binaries over the network. To conform to the contract of the protocol,
you'll need to account for all that hidden state and implicit
transformations of it to keep the system consistent.

So... does OOP (Java-style) sound complicated and hard to manage? It
is. You are usually dealing with in a language of type definitions,
invented by all the programmers who touched the code, each with
different motivations, and which you do not (and probably cannot)
fully understand. You have lost the ability to reason effectively
about your program and your system.

/s
unknown
2010-08-13 03:03:45 UTC
Permalink
On Wed, Aug 11, 2010 at 9:20 PM, Steve Davis <steven.charles.davis
Post by unknown
things going on
1) Data structures and
2) Transformations of data structures.
I agree. Mandatory features of OOP includes encapsulation, abstraction,
inheritance, and polymorphism. After reviewing this thread, opinions are
summarized that including
* if we do OOP in Erlang syntax,
* if features of OOP are able to be implemented in Erlang,
* and if exactly Erlang is an OOP language or OO language.

Now knowledge of OOP is mixture of origin concepts, languages such as
Smalltalk or Java, and UML modelling methods. Recently I read the book
"Design Patterns Explained," which hints that OOP/OOD is to treat
everything,
including primitive datatypes, as object. And he explained how abstraction
is
different from implementation. Then I thought that Erlang treats everything
as
function or process, but really? And, Erlang is not toward OOP, so it may
not
be OOP-like.

Let's consider how to implement OOP in Erlang, either using Erlang syntax
or realizing OOP system in Erlang.

Encapsulation: values and functions should be organized as an object
structure tagged as an object name, belong to some class. It is done by
Erlang record syntax or as a module, and somehow messages are sent
to the object or to some member of the structure. Functions in a structure
may call other fields or functions in other structures. Encapsulation means
how an object is structured. Any object is generated by following a object
specification, the class. Object and class are implemented in the same
way: structure.

Abstraction: it's separated from implementation. Abstraction is done in
Erlang
by hot code replacement.

Inheritance: it should be done by taking objects by following
both superclass
and subclass specifications and then overriding the superclass object with
the subclass object, that is to merge base functions into extended functions
effectively. Inheritance shall not be as copying of superclass object, but
keeping a newest copy of a extended function while keeping the reference to
its base function. Inheritance semantics shall be consistent.

Polymorphism: it means that different objects, even if they are in the same
class, may behave separately. It's not a problem because Erlang has this
feature.

On real OOP, I think that OOP is a feature, and somehow it's the problem
itself.
So, when talking about OOP in Erlang, you can have a try to write Erlang in
OOP style, however, Erlang need not be too OOP-like.
unknown
2010-08-13 08:18:22 UTC
Permalink
Post by unknown
Recently I read the book
"Design Patterns Explained," which hints that OOP/OOD is to treat
everything, including primitive datatypes, as object.
And he explained how abstraction
is different from implementation. Then I thought that Erlang
treats everything as function or process, but really?
Yeah, well, I've had some pretty interesting discussions with
proponents of that view, and I would rather say that it is
possible to deal with abstractions as wholly separate from
implementation, but it is wrong to say that it holds in general
(at least for any useful definition of implementation).

The idea, as I understand it, is that you want to adapt to
the common pattern that you have separate teams that handle
requirements, architecture, and programming (oh, and yet
another team doing testing, usually). I am very well familiar
with that way of working, and will go as far as saying that
it can sometimes be extremely difficult to avoid.

The real danger with that setup, and the viewing of abstraction
as somehow separate from implementation, is that you tend to
to do "abstraction" for its own sake. The quotation marks are
there because in many cases, people confuse drawing visual
symbols with abstraction; while it may be in some dimension,
it is not abstraction in any useful sense for a programmer.


"The purpose of abstraction is not to be vague, but to create a
new semantic level in which one can be absolutely precise."
Edsger W. Dijkstra, "The Humble Programmer", October 1972


To do abstraction in the way Dijkstra intends, you should have
a very good intuition about implementation issues. You might
say that abstraction grows from implementation.

The key here is that you need to *pick* your abstractions
carefully based on your understanding of the domain *and*
details, opportunities and limitations of the implementation
layer. Erlang provides some abstractions that are a bit
unusual, but have been found in practice to work exceedingly
well in some domains.

Some of those abstractions tend to be sub-optimal if your
aim is to write computational code that goes blazingly
fast. OTOH, some of the abstractions that have traditionally
fared well in that regard are suffering now, as the
hardware becomes increasingly parallel - something that
happens to suit Erlang just fine.

Programming is all about abstraction - layers on top of
layers of abstraction, reaching all the way deep down into
the hardware your program runs on.
Post by unknown
Abstraction: it's separated from implementation. Abstraction
is done in Erlang by hot code replacement.
No. Abstraction is when you make a model of something by
hiding underlying details. Abstraction is all over the place
in programming. Any Erlang data type is an abstraction - as
Erlang doesn't allow you do address memory directly, you
cannot control how many bits are assigned, how the data is
laid out, where it is, whether it is shared, etc. Nor are you
supposed to care.

"Programming is both a top down activity from requirements and
overall structure of the system and a bottom up activity based
on the abstractions provided by the programming language.
Abstractions such as modules, processes, higher order
functions, etc. are to the programmer like transistors,
capacitors, resistors, etc. to the hardware designer.
It is important that the abstractions be few, simple to
understand and yet powerful and provide the needed
functionality. For example, if the application is inherently
concurrent it would be very dfficult to program without
some process concept. In that case the application program
itself would have to include some form of scheduler.
Distribution, error handling, and hot code loading are
extremely complicated requirements and the support for them
provided by Erlang enables the programmer to concentrate on
the application rather than on the basic programming technology."

(Bjarne Dacker, http://www.erlang.se/publications/bjarnelic.pdf,
pg 26)

BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
unknown
2010-08-13 20:36:49 UTC
Permalink
Interesting discussion....

The term OO seems to mean different things to different people.

Since Alan Kay invented the term I think what he said should bear some
weight. On several occasions Alan said that OOP was all about messaging
not "all that other stuff". Let me give you a few quotes:

Quote 1:

OOP to me means only messaging, local retention and protection and
hiding of state-process, and extreme late-binding of all things. It
can be done in Smalltalk and in LISP. There are possibly other
systems in which this is possible, but I'm not aware of them.

Ref: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en

Quote 2:

Folks --

Just a gentle reminder that I took some pains at the last OOPSLA to try to
remind everyone that Smalltalk is not only NOT its syntax or the class
library, it is not even about classes. I'm sorry that I long ago coined the
term "objects" for this topic because it gets many people to focus on the
lesser idea.

The big idea is "messaging" -- that is what the kernal of Smalltalk/Squeak
is all about

Ref: http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html

Quote 3:

...

In other words, always having real objects always retains the
ability to simulate anything you want, and to send it around the
planet. If you send data 1000 miles you have to send a manual
and/or a programmer to make use of it. If you send the needed
programs that can deal with the data, then you are sending an
object (even if the design is poor).

And RCATWD also provides perfect protection in both
directions. We can see this in the hardware model of the Internet
(possibly the only real object-oriented system in working order).

You get language extensibility almost for free by simply agreeing on
conventions for the message forms.

My thought in the 70s was that the Internet we were all working on
alongside personal computing was a really good scalable design,
and that we should make a virtual internet of virtual machines
that could be cached by the hardware machines. It?s really too
bad that this didn?t happen.

Ref: http://www.computerworld.com.au/article/352182/z_programming_languages_smalltalk-80

--- this last quote is from an interview in computer world in Australia.
(read the full article it is full of wisdom

It is pretty clean that when Alan dreamt up the idea of OO it was
"all about messaging" - he says this time and time again. I talked
to Dan Ingalls about this and he was in complete agreement. He (Dan) said
in a lecture (paraphrased) "the great thing about messaging is that
is decouples
the sender from the receiver"

In a sense the receiver of a message does not care who sent the
message, and the
sins of the sender are not visited on the receiver of the message.

This is the key point. If your program can crash my program they we are
totally screwed. This should never ever happen. never ever ever
ever ever ever ...
(repeat zillions of times).

This is the property of isolation. The mechanism of isolation is
message passing.
(note: asynchronous MP - synchronous MP breaks isolation since the
receiver could block the caller by refusing to read a message)

Note also that communication though messaging is the easiest way possible to
glue things together - think Unix pipes.

(aside: read this: http://cm.bell-labs.com/cm/cs/who/dmr/mdmpipe.html
this is Doug McLlroys memo to Dennis Richie and Ken Thompson

quote: Summary--what's most important.

To put my strongest concerns into a nutshell:

1. We should have some ways of connecting programs like garden
hose--screw in another segment when it becomes when it becomes
necessary to massage data in another way. This is the way of IO
also.
...


)

Wonderful stuff - "like a garden hose" ... "screw in another
segment" ...

This is *precisely* what Alan Kay was talking about. There is a
stong conceptual link between Alan's ideas on messaaging and isolation
and McIlroys pipes - they are the same idea in a different guise -
Unix processes connected though pipes and sockets *are* communiction
objects (by Kay's definitions)

So we have the pipes (garden hoses) that pass messages - that is
the big idea.

Polymorphism - (all objects respond to a asString message) is
there so make programming easy - so we can guess the names of things.

All the rest - organisation into classes and objects has zilch do
do with the central concept of OOP. As Alan Kay said, this was " the
less idea " (his words). This is "just" how you organise code (this
is not to belittle the point - but remember the *big* idea is
messaging )

To me the Erlang angle has always been that of making things
fault tolerant. "my stuff should not crash your stuff" - this
necessitates message passing passing systems. (ie you must have two or
more machines).

In conclusion Erlang is very much an OOPL - since deep down, very
deep down, it tries to make makes a passable job of getting message
passing and isolation right. In this sense it is far more OO than
languages like Java (etc.) that have no notion of isolation and thus
cannot be considered OOPLs :-)

/Cheers

Joe
Post by unknown
Post by unknown
Recently I read the book
"Design Patterns Explained," which hints that OOP/OOD is to treat
everything, including primitive datatypes, as object.
And he explained how abstraction
is different from implementation. Then I thought that Erlang
treats everything as function or process, but really?
Yeah, well, I've had some pretty interesting discussions with
proponents of that view, and I would rather say that it is
possible to deal with abstractions as wholly separate from
implementation, but it is wrong to say that it holds in general
(at least for any useful definition of implementation).
The idea, as I understand it, is that you want to adapt to
the common pattern that you have separate teams that handle
requirements, architecture, and programming (oh, and yet
another team doing testing, usually). I am very well familiar
with that way of working, and will go as far as saying that
it can sometimes be extremely difficult to avoid.
The real danger with that setup, and the viewing of abstraction
as somehow separate from implementation, is that you tend to
to do "abstraction" for its own sake. The quotation marks are
there because in many cases, people confuse drawing visual
symbols with abstraction; while it may be in some dimension,
it is not abstraction in any useful sense for a programmer.
"The purpose of abstraction is not to be vague, but to create a
new semantic level in which one can be absolutely precise."
Edsger W. Dijkstra, "The Humble Programmer", October 1972
To do abstraction in the way Dijkstra intends, you should have
a very good intuition about implementation issues. You might
say that abstraction grows from implementation.
The key here is that you need to *pick* your abstractions
carefully based on your understanding of the domain *and*
details, opportunities and limitations of the implementation
layer. Erlang provides some abstractions that are a bit
unusual, but have been found in practice to work exceedingly
well in some domains.
Some of those abstractions tend to be sub-optimal if your
aim is to write computational code that goes blazingly
fast. OTOH, some of the abstractions that have traditionally
fared well in that regard are suffering now, as the
hardware becomes increasingly parallel - something that
happens to suit Erlang just fine.
Programming is all about abstraction - layers on top of
layers of abstraction, reaching all the way deep down into
the hardware your program runs on.
Post by unknown
Abstraction: it's separated from implementation. Abstraction
is done in Erlang by hot code replacement.
No. Abstraction is when you make a model of something by
hiding underlying details. Abstraction is all over the place
in programming. Any Erlang data type is an abstraction - as
Erlang doesn't allow you do address memory directly, you
cannot control how many bits are assigned, how the data is
laid out, where it is, whether it is shared, etc. Nor are you
supposed to care.
"Programming is both a top down activity from requirements and
overall structure of the system and a bottom up activity based
on the abstractions provided by the programming language.
Abstractions such as modules, processes, higher order
functions, etc. are to the programmer like transistors,
capacitors, resistors, etc. to the hardware designer.
It is important that the abstractions be few, simple to
understand and yet powerful and provide the needed
functionality. For example, if the application is inherently
concurrent it would be very dfficult to program without
some process concept. In that case the application program
itself would have to include some form of scheduler.
Distribution, error handling, and hot code loading are
extremely complicated requirements and the support for them
provided by Erlang enables the programmer to concentrate on
the application rather than on the basic programming technology."
(Bjarne Dacker, http://www.erlang.se/publications/bjarnelic.pdf,
pg 26)
BR,
Ulf W
--
Ulf Wiger
CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
http://www.erlang-solutions.com
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
unknown
2010-08-14 03:25:10 UTC
Permalink
Yes I agree, The lack of isolation is where the the big names of OOP went
wrong; the likes of C++, Java, C# and JavaScript provide ways for state to
'leak out' of objects by means of pointers and references. What good is
encapsulation if member variables are bound to shared objects. One can
avoid this problem if he goes our of his way, but in practice, this is
rarely done. Strict encapsulation should be the rule, not an options.
Arguing that encapsulation is a virtue with respect to these languages seems
very shallow indeed.

Respectfully, I would not go as far as Joe to say that OO is a poor
paradigm for modelling real world applications, as I've heard him argue in
the past. I've made a career out of object modelling and writing software
in C++ and Java -- it's very much the way I approach software design.

The inheritance concept, on the other hand is crucial to OO design; not so
much for the inherited functionality as for type polymorphism. Other
languages provide this using algebraic data types and other distinguished
unions, but in OO we work with classes, and we need polymorphic types to
avoid the deluge of conditionals that we would see otherwise.

--DS


2010/8/13 Joe Armstrong <erlang>
Post by unknown
ery much an OOPL - since deep down, very
deep down, it tries to make makes a passable job of getting message
passing and isolation right. In this sense it is far more OO than
languages like Java (etc.) that have no notion of isolation and thus
cannot be considered OO
unknown
2010-08-14 06:58:04 UTC
Permalink
"The inheritance concept, on the other hand is crucial to OO design; not
so much for the inherited functionality as for type polymorphism.
Other languages provide this using algebraic data types and other
distinguished unions, but in OO we work with classes, and we need
polymorphic types to avoid the deluge of conditionals that we would see
otherwise."

With all due respect, when I boiled this paragraph down to its essentials,
it read to me like this: "The definition of 'object-oriented design' entails
inheritance, because that's the way 'object-oriented' was defined."

There's a particularly strenuous force-fitting of this definition in one of
the comments on that Alan Kay interview -- it's first admitted that Alan Kay
coined the term and contributed a lot of ideas, but then flatly asserted
that object-orientation was defined by the architects of Simula -- even
though Simula 67 lacked encapsulation (no class variables, even -- you had
to use globals) and even though Simula 67's treatments of types and
inheritance probably doesn't meet some people's definitions of polymorphism.

There's a Humpty Dumpty feeling about a lot of these debates. ISTR a
similar one, almost two decades ago, about whether C++ was truly
"polymorphic" despite being strongly typed. It turned out that
"polymorphic" had come to mean different things to different people, that
there was no hard-and-fast formal definition. Whether you were going to
"win" such arguments often depended on your staying power in debate.

I think the Erlang community would do itself a world of good by finding
somebody to go knock on Alan Kay's door in Glendale and spend 15 minutes
with him showing how Erlang does things. As far as I can tell, he's never
said anything about the language. (Perhaps because he's hardly heard of it.
After all, if there's one thing the Erlang community seems dismayingly bad
at, it's self-promotion.) If Alan Kay said, "Erlang looks like almost what
I've been talking about since the mid-60s, I wonder how I missed it for so
many years?" I think some of you might be surprised by how many highly
influential people in the programming world would sit up and take notice.

-michael turner

2010/8/14 Dave Smith <dave.smith.to>
Post by unknown
Yes I agree, The lack of isolation is where the the big names of OOP went
wrong; the likes of C++, Java, C# and JavaScript provide ways for state to
'leak out' of objects by means of pointers and references. What good is
encapsulation if member variables are bound to shared objects. One can
avoid this problem if he goes our of his way, but in practice, this is
rarely done. Strict encapsulation should be the rule, not an options.
Arguing that encapsulation is a virtue with respect to these languages seems
very shallow indeed.
Respectfully, I would not go as far as Joe to say that OO is a poor
paradigm for modelling real world applications, as I've heard him argue in
the past. I've made a career out of object modelling and writing software
in C++ and Java -- it's very much the way I approach software design.
The inheritance concept, on the other hand is crucial to OO design; not so
much for the inherited functionality as for type polymorphism. Other
languages provide this using algebraic data types and other distinguished
unions, but in OO we work with classes, and we need polymorphic types to
avoid the deluge of conditionals that we would see otherwise.
--DS
2010/8/13 Joe Armstrong <erlang>
Post by unknown
ery much an OOPL - since deep down, very
deep down, it tries to make makes a passable job of getting message
passing and isolation right. In this sense it is far more OO than
languages like Java (etc.) that have no notion of isolation and thus
cannot be considered OO
unknown
2010-08-14 15:22:56 UTC
Permalink
On Sat, Aug 14, 2010 at 8:58 AM, Michael Turner
Post by unknown
"The inheritance concept, on the other hand is crucial to OO design; not
so?much for the ?inherited functionality as for type polymorphism.
?Other?languages provide this using algebraic data types and other
distinguished?unions, but in OO we work with classes, and we need
polymorphic types to?avoid the deluge of conditionals that we would see
otherwise."
With all due respect, when I boiled this paragraph down to its essentials,
it read to me like this: "The definition of 'object-oriented design' entails
inheritance, because that's the way 'object-oriented' was defined."
There's a particularly strenuous force-fitting of this definition in one of
the comments on that Alan Kay interview -- it's first admitted that Alan Kay
coined the term and contributed a lot of ideas, but then flatly asserted
that object-orientation was defined by the architects of Simula -- even
though Simula 67 lacked encapsulation (no class variables, even -- you had
to use globals) and even though Simula 67's treatments of types and
inheritance probably doesn't meet some people's definitions of polymorphism.
There's a Humpty Dumpty feeling about a lot of these debates. ?ISTR a
similar one, almost two decades ago, about whether C++ was truly
"polymorphic" despite being strongly typed. ?It turned out that
"polymorphic" had come to mean different things to different people, that
there was no hard-and-fast formal definition. ?Whether you were going to
"win" such arguments often depended on your staying power in debate.
I think the Erlang community would do itself a world of good by finding
somebody to go knock on Alan Kay's door in Glendale and spend 15 minutes
with him showing how Erlang does things. ?As far as I can tell, he's never
said anything about the language. ?(Perhaps because he's hardly heard of it.
?After all, if there's one thing the Erlang community seems dismayingly bad
at, it's self-promotion.)
Erlang was developed in Sweden.

In the Swedish culture self-promotion is considered extremely
bad-manners. It's ok for *other people* to say nice things about your
work, but not for you to do this, which is considered rude.

For a Swede to even mention what they have done something is
considered bad-manners and a violation of "Jantelagen"
http://en.wikipedia.org/wiki/Jante_Law.

Erlang evolved in a Swedish culture and has inherited this behaviour.

In some cultures self-promotion is trained into children from birth,
in Sweden the opposite
is true, children are reprimanded for self-promotion. When adults of
these two cultures
meet cross-cultural confusion can occur.

If somebody from a self-promotion culture meets a Sweden and says
"this stuff I did is amazing"
Swedes tend to literally believe this. Why is this, basically because
Swedes will never say that
what they did is good. If pressed they might admit to having done it
at all (which is their way of
saying it's great) so if they (a Swede) meets somebody who actually
claims to have done something
good they view this as such an exceptional circumstance that it must be true.

They (the Swedes) realize that the person from the other culture is
not bragging and do not apply
Jantelagen to the foreigner but they *overcompensate* - since Swedes
never say that what they did
was great they lack a mechanism for calibrating what this means.

In my experience if somebody from a self-effacing culture says they
did something you should
upgrade the significance of what they did, and if somebody from a
self-promoting culture says
something is great you should down-grade the significance.

Janelagen is essential in understanding how Swedes reason - it is
basically untranslatable.
It really takes about five generations of living here and exchange of
genetic material to understand.

/Joe




If Alan Kay said, "Erlang looks like almost what
Post by unknown
I've been talking about since the mid-60s, I wonder how I missed it for so
many years?" I think some of you might be surprised by how many highly
influential people in the programming world would sit up and take notice.
-michael turner
2010/8/14 Dave Smith <dave.smith.to>
Yes I agree, ?The lack of isolation is where the the big names of OOP went
wrong; the likes of C++, Java, C# and JavaScript provide ways for state to
'leak out' of objects by means of pointers and references. ?What good is
encapsulation if member variables are bound to shared objects. ?One can
avoid this problem ?if he goes our of his way, but in practice, this is
rarely done. ?Strict encapsulation should be the rule, not an options.
Arguing that encapsulation is a virtue with respect to these languages seems
very shallow indeed.
?Respectfully, I would not go as far as Joe to say that OO is a poor
paradigm for modelling real world applications, as I've heard him argue in
the past. ?I've made a career out of object modelling and writing software
in ?C++ and Java -- it's very much the way I approach software design.
The inheritance concept, on the other hand is crucial to OO design; not so
much for the ?inherited functionality as for type polymorphism. ?Other
languages provide this using algebraic data types and other distinguished
unions, but in OO we work with classes, and we need polymorphic types to
avoid the deluge of conditionals that we would see otherwise.
--DS
2010/8/13 Joe Armstrong <erlang>
Post by unknown
ery much an OOPL - since deep down, very
deep down, it tries to make makes a passable job of getting message
passing and isolation right. ?In this sense it is far more OO than
languages like Java (etc.) that have no notion of isolation and thus
cannot be considered OO
unknown
2010-08-14 18:17:15 UTC
Permalink
It wasn't my intention to try to define OO. Those of us who work in
industry feel we know what a peer is talking about when he uses the term
(irrespective of what was in Allan Kay's head when he coined the term 40
years ago).




--DS
Post by unknown
"The inheritance concept, on the other hand is crucial to OO design; not
so much for the inherited functionality as for type polymorphism.
Other languages provide this using algebraic data types and other
distinguished unions, but in OO we work with classes, and we need
polymorphic types to avoid the deluge of conditionals that we would see
otherwise."
With all due respect, when I boiled this paragraph down to its essentials,
it read to me like this: "The definition of 'object-oriented design' entails
inheritance, because that's the way 'object-oriented' was defined."
There's a particularly strenuous force-fitting of this definition in one of
the comments on that Alan Kay interview -- it's first admitted that Alan Kay
coined the term and contributed a lot of ideas, but then flatly asserted
that object-orientation was defined by the architects of Simula -- even
though Simula 67 lacked encapsulation (no class variables, even -- you had
to use globals) and even though Simula 67's treatments of types and
inheritance probably doesn't meet some people's definitions of polymorphism.
There's a Humpty Dumpty feeling about a lot of these debates. ISTR a
similar one, almost two decades ago, about whether C++ was truly
"polymorphic" despite being strongly typed. It turned out that
"polymorphic" had come to mean different things to different people, that
there was no hard-and-fast formal definition. Whether you were going to
"win" such arguments often depended on your staying power in debate.
I think the Erlang community would do itself a world of good by finding
somebody to go knock on Alan Kay's door in Glendale and spend 15 minutes
with him showing how Erlang does things. As far as I can tell, he's never
said anything about the language. (Perhaps because he's hardly heard of it.
After all, if there's one thing the Erlang community seems dismayingly bad
at, it's self-promotion.) If Alan Kay said, "Erlang looks like almost what
I've been talking about since the mid-60s, I wonder how I missed it for so
many years?" I think some of you might be surprised by how many highly
influential people in the programming world would sit up and take notice.
-michael turner
2010/8/14 Dave Smith <dave.smith.to>
Yes I agree, The lack of isolation is where the the big names of OOP went
Post by unknown
wrong; the likes of C++, Java, C# and JavaScript provide ways for state to
'leak out' of objects by means of pointers and references. What good is
encapsulation if member variables are bound to shared objects. One can
avoid this problem if he goes our of his way, but in practice, this is
rarely done. Strict encapsulation should be the rule, not an options.
Arguing that encapsulation is a virtue with respect to these languages seems
very shallow indeed.
Respectfully, I would not go as far as Joe to say that OO is a poor
paradigm for modelling real world applications, as I've heard him argue in
the past. I've made a career out of object modelling and writing software
in C++ and Java -- it's very much the way I approach software design.
The inheritance concept, on the other hand is crucial to OO design; not so
much for the inherited functionality as for type polymorphism. Other
languages provide this using algebraic data types and other distinguished
unions, but in OO we work with classes, and we need polymorphic types to
avoid the deluge of conditionals that we would see otherwise.
--DS
2010/8/13 Joe Armstrong <erlang>
Post by unknown
ery much an OOPL - since deep down, very
deep down, it tries to make makes a passable job of getting message
passing and isolation right. In this sense it is far more OO than
languages like Java (etc.) that have no notion of isolation and thus
cannot be considered OO
unknown
2010-08-14 20:56:13 UTC
Permalink
It wasn't my intention to try to define OO. ?Those of us who work in
industry feel we know what a peer is talking about when he uses the term
(irrespective of what was in Allan Kay's head when he coined the term 40
years ago).
Beware of OO having a too specific meaning. Like most CS nomenclature,
it is not well-defined. In particular, one should always keep in mind
the rant by Jonathan Rees:

http://www.paulgraham.com/reesoo.html

Even if you know of what you speak about among your peers, it is good
to have this as a perspective. It somewhat amazes me nobody has linked
to the rant yet, as it seems very valuable as an input to the
discussion.

Personally, I try to avoid the OO term because of its vague meaning.
Instead, I try to define the parts that make up OO in diferent
languages and use them. Java for instance has a class-type system with
explicit subtyping relations. Erlang is defined by isolated processes
and message passing among them. And so on. If there is a mistake made
in language theory, then it is precisely the lack of mathematical
nomenclature and rigor.

OO is more of a philosophical statement about how to structure
programs and is a mighty fine example of a bug-ridden, informal, and
weak notion. The devil is in the details - how you achieve and support
the philosophy. I claim that we might take different paths in
different languages, but in general end in the vicinity of the OO
philosophy. Herein lies my hypothesis: because there are more than one
path to the goal, the OO term will keep being vague. Hence I try to
abstain from its use.

End of rant.
--
J.
unknown
2010-08-14 08:11:07 UTC
Permalink
2010/8/13 Joe Armstrong <erlang>
Post by unknown
Erlang is very much an OOPL - since deep down, very
deep down, it tries to make makes a passable job of getting message
passing and isolation right. In this sense it is far more OO than
languages like Java (etc.) that have no notion of isolation and thus
cannot be considered OOPLs :-)
I strongly agree with this, except when it comes to managing sequential,
immutable state. The mechanisms Erlang provides, namely records and
paramaterized modules, kind of suck. I think some type of object-like thing
could really benefit Erlang in that regard. I've implemented such a thing
(immutable objects) in Reia.
--
Tony Arcieri
Medioh! A Kudelski Brand
unknown
2010-08-13 20:58:51 UTC
Permalink
I thought I'd note that what you're describing sounds a *lot* like how Reia
implements immutable objects. However, Reia does not support
instance-specific behavior. Polymorphism is only offered in the form of
class-based inheritance.

2010/8/12 ??? (Yau-Hsien Huang) <g9414002.pccu.edu.tw>
Post by unknown
On Wed, Aug 11, 2010 at 9:20 PM, Steve Davis <
steven.charles.davis
Post by unknown
things going on
1) Data structures and
2) Transformations of data structures.
I agree. Mandatory features of OOP includes encapsulation, abstraction,
inheritance, and polymorphism. After reviewing this thread, opinions are
summarized that including
* if we do OOP in Erlang syntax,
* if features of OOP are able to be implemented in Erlang,
* and if exactly Erlang is an OOP language or OO language.
Now knowledge of OOP is mixture of origin concepts, languages such as
Smalltalk or Java, and UML modelling methods. Recently I read the book
"Design Patterns Explained," which hints that OOP/OOD is to treat
everything,
including primitive datatypes, as object. And he explained how abstraction
is
different from implementation. Then I thought that Erlang treats everything
as
function or process, but really? And, Erlang is not toward OOP, so it may
not
be OOP-like.
Let's consider how to implement OOP in Erlang, either using Erlang syntax
or realizing OOP system in Erlang.
Encapsulation: values and functions should be organized as an object
structure tagged as an object name, belong to some class. It is done by
Erlang record syntax or as a module, and somehow messages are sent
to the object or to some member of the structure. Functions in a structure
may call other fields or functions in other structures. Encapsulation means
how an object is structured. Any object is generated by following a object
specification, the class. Object and class are implemented in the same
way: structure.
Abstraction: it's separated from implementation. Abstraction is done in
Erlang
by hot code replacement.
Inheritance: it should be done by taking objects by following
both superclass
and subclass specifications and then overriding the superclass object with
the subclass object, that is to merge base functions into extended functions
effectively. Inheritance shall not be as copying of superclass object, but
keeping a newest copy of a extended function while keeping the reference to
its base function. Inheritance semantics shall be consistent.
Polymorphism: it means that different objects, even if they are in the same
class, may behave separately. It's not a problem because Erlang has this
feature.
On real OOP, I think that OOP is a feature, and somehow it's the problem
itself.
So, when talking about OOP in Erlang, you can have a try to write Erlang in
OOP style, however, Erlang need not be too OOP-like.
--
Tony Arcieri
Medioh! A Kudelski Brand
unknown
2010-08-11 15:57:30 UTC
Permalink
Post by unknown
From: Hynek Vychodil <hynek>
Subject: Re: [erlang-questions] OOP in Erlang
To: "Guy Wiener" <wiener.guy>
Cc: "Erlang Questions" <erlang-questions>
Date: Wednesday, August 11, 2010, 4:37 AM
On Wed, Aug 11, 2010 at 9:44 AM, Guy
Wiener <wiener.guy>
Post by unknown
I have to stand up for OOP at this point: OOP does not
start and end with
Post by unknown
"encapsulating code and data". The OOP feature that
has the strongest impact
Post by unknown
on code brevity is *inheritance*. Thus, the interest
in extending modules.
I can't agree with you. Inheritance is only way how some
OOP language
copes with complexity of OO systems. Inheritance is neither
core nor
mandatory feature of OOP. What worse, many of OO affected
people what
I met stated that inheritance is most controversial and
mostly misused
feature of OOP. I also observe that there is positive
correlation with
person experience and probability that will tell or agree
with above
statement.
Post by unknown
Also, IMHO, parameterized modules are a more compact
way to encapsulate code
Post by unknown
and data, since that you don't have to pass the data
structure around as an
Post by unknown
explicit state (assuming, of course, that the data is
immutable).
Post by unknown
Guy
On Wed, Aug 11, 2010 at 5:17 AM, Ngoc Dao <ngocdaothanh>
Post by unknown
The mostly used feature of OOP is probably
encapsulating code and
Post by unknown
Post by unknown
http://www.erlang.org/doc/man/gen_server.html
When I first studied OOP, in 1990, I was taught that OO was defined by four features: Encapsulation, Abstraction, Inheritance, and Polymorphism. That if any of these were missing it was not OO.
Same to me. It was in all books what I read in 1990s and it is still
in many books. But I learnt that not all what they taught me and not
all what is written in books is true.

http://en.wikipedia.org/wiki/Object-oriented_programming#History

Starts from 1960 through 1970s when "The Smalltalk language, which was
developed at Xerox PARC (by Alan Kay and others) in the 1970s,
introduced the term object-oriented programming to represent the
pervasive use of objects and messages as the basis for computation."

Smalltalk contains inheritance but Alan Kay doesn't state that
inheritance is key feature of OOP. Especially in these days he is
telling something different. (For example:
http://www.google.co.uk/search?q=alan+kay+message+passing)
Post by unknown
? ? ?-EdK
Ed Keith
e_d_k
Blog: edkeith.blogspot.com
--
--Hynek (Pichi) Vychodil

Analyze your data in minutes. Share your insights instantly. Thrill
your boss.? Be a data hero!
Try GoodData now for free: www.gooddata.com
unknown
2010-08-12 07:46:26 UTC
Permalink
Hynek Vychodil wrote: "Smalltalk contains inheritance but Alan Kay doesn't
state that inheritance is key feature of OOP. Especially in these days he
is telling something different."

Not just recently but originally.

http://forum.trapexit.org/viewtopic.php?p=51130&sid=bf412b1a24a7b9e777beeb2035d5f7a0

<http://forum.trapexit.org/viewtopic.php?p=51130&sid=bf412b1a24a7b9e777beeb2035d5f7a0>IIRC,
the affirmative response immediately following was from Joe Armstrong, not
from "Guest". Ah, yes, I *do* RC:


http://groups.google.com/group/erlang-programming/msg/546621f6b27970bb?hl=en

<http://groups.google.com/group/erlang-programming/msg/546621f6b27970bb?hl=en>Possibly
off-topic: can someone please tell me why TrapExit mirrors this list in a
"forum" that's not even really a forum? Multi-threaded, searchable mailing
list archives of the usual kind would not only be easier to use, but
actually an honest representation of the origin of the discussion. I
suppose the counter-argument will be that "a mailing list is a subclass of
forum", but if so why did the typecast of one to another reduce Joe
Armstrong to a mere guest?

-michael turner
Post by unknown
Post by unknown
From: Hynek Vychodil <hynek>
Subject: Re: [erlang-questions] OOP in Erlang
To: "Guy Wiener" <wiener.guy>
Cc: "Erlang Questions" <erlang-questions>
Date: Wednesday, August 11, 2010, 4:37 AM
On Wed, Aug 11, 2010 at 9:44 AM, Guy
Wiener <wiener.guy>
Post by unknown
I have to stand up for OOP at this point: OOP does not
start and end with
Post by unknown
"encapsulating code and data". The OOP feature that
has the strongest impact
Post by unknown
on code brevity is *inheritance*. Thus, the interest
in extending modules.
I can't agree with you. Inheritance is only way how some
OOP language
copes with complexity of OO systems. Inheritance is neither
core nor
mandatory feature of OOP. What worse, many of OO affected
people what
I met stated that inheritance is most controversial and
mostly misused
feature of OOP. I also observe that there is positive
correlation with
person experience and probability that will tell or agree
with above
statement.
Post by unknown
Also, IMHO, parameterized modules are a more compact
way to encapsulate code
Post by unknown
and data, since that you don't have to pass the data
structure around as an
Post by unknown
explicit state (assuming, of course, that the data is
immutable).
Post by unknown
Guy
On Wed, Aug 11, 2010 at 5:17 AM, Ngoc Dao <ngocdaothanh>
Post by unknown
The mostly used feature of OOP is probably
encapsulating code and
Post by unknown
Post by unknown
http://www.erlang.org/doc/man/gen_server.html
When I first studied OOP, in 1990, I was taught that OO was defined by
four features: Encapsulation, Abstraction, Inheritance, and Polymorphism.
That if any of these were missing it was not OO.
Same to me. It was in all books what I read in 1990s and it is still
in many books. But I learnt that not all what they taught me and not
all what is written in books is true.
http://en.wikipedia.org/wiki/Object-oriented_programming#History
Starts from 1960 through 1970s when "The Smalltalk language, which was
developed at Xerox PARC (by Alan Kay and others) in the 1970s,
introduced the term object-oriented programming to represent the
pervasive use of objects and messages as the basis for computation."
Smalltalk contains inheritance but Alan Kay doesn't state that
inheritance is key feature of OOP. Especially in these days he is
http://www.google.co.uk/search?q=alan+kay+message+passing)
Post by unknown
-EdK
Ed Keith
e_d_k
Blog: edkeith.blogspot.com
--
--Hynek (Pichi) Vychodil
Analyze your data in minutes. Share your insights instantly. Thrill
your boss. Be a data hero!
Try GoodData now for free: www.gooddata.com
________________________________________________________________
erlang-questions (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-questions-unsubscribe
unknown
2010-08-12 03:21:36 UTC
Permalink
Post by unknown
When I first studied OOP, in 1990, I was taught that OO was defined by four features: Encapsulation, Abstraction, Inheritance, and Polymorphism. That if any of these were missing it was not OO.
And other teachers taught other students different slogans.
I was taught that the defining characteristics of an object
were "identity, state, and behaviour" and if a language had
objects it was an OO language.

This is arguing over terminology; I hope we can move past that to
argue about semantics. It fundamentally doesn't MATTER whether something
is CALLED Object-Oriented or not.

Take Ada 95, for example. It has encapsulation (associated with
modules, not classes), abstraction (associated with generics, not
classes), inheritance (associated with classes), and two kinds of
polymorphism (parametric polymorphism via generics and inheritance
polymorphism via classes). Does the fact that classes per se
are NOT encapsulated mean that it isn't OO? Ada encapsulation is
actually pretty good, and not only can be used to encapsulate
class information, but normally is. But it's not OBJECT-based
encapsulation. Oh yes, I lied when I said "classes". Ada "methods"
are defined *outside* the hierarchically structured types, not inside.
Doesn't matter.

Who cares what we call it? If you want to program in an OO style,
Ada 95 is perfectly adequate for the job.

If any language is an OO language, surely Smalltalk 80 is. In normal
use, it's well encapsulated, but thanks to its introspection
facilities, that encapsulation amounts to "as long as nobody really
REALLY wants to poke their finger through the tissue paper."
Anyone who said *the* classic OO language wasn't really OO would be
laughed at. For that matter, anyone who pointed out that because
you can cast any pointer to char* and thus scribble on anything,
C++ doesn't really have any *trustworthy* encapsulation to speak of,
C++ cannot be OO either, would get some strange and some hostile
looks. I don't suppose Brad Cox would be too pleased to be told
that Objective C wasn't really OO either.

The question for Erlang is not "OOP in Erlang", but "what ideas
can we steal from _any_ other source that would be useful
_for Erlang_." And for any such idea, "what exactly are we
proposing that Erlang should salvage from the other language,
in what form, and why do we need it?"
unknown
2010-08-11 16:35:10 UTC
Permalink
Jesper Louis Andersen <jesper.louis.andersen> wrote:

jls> [...] One problem of
jls> Erlangs memory model is that sending a large datastructure as a
jls> capability to another process, several megabytes in size, will mean
jls> a copy.

If I can add a pair of small but important points ... First, the
*semantics* require a copy.

jls> In the default VM setup that is.

Second, the implementation is free to do whatever it wishes as long as
it preserves the semantics. Depending on how new you are to the Erlang
world, you may not know about the hybrid heap VM, which can avoid the
copy-between-processes behavior you mention above. It is available, if
you specifically build for it ("./configure --enable-hybrid-heap") and
then start a VM using "erl -hybrid"(*).

To start hunting for research papers, ask a Web-search-gizmo about
"erlang hybrid heap" and/or "erlang shared heap".

Drifting farther afield, the Erjang implementation of Erlang has some
impressive speed gains by avoiding inter-process copying.

-Scott

(*) Odd, the "-hybrid" flag is no longer mentioned in the R13B04 "erl"
reference guide ... except an oblique mention vis a vis the "-smp" flag.
The hybrid heap isn't fully supported by Ericsson right now, IIRC, so
I'm not very surprised.
unknown
2010-08-11 16:44:07 UTC
Permalink
On Wed, Aug 11, 2010 at 6:35 PM, Scott Lystig Fritchie
Post by unknown
Second, the implementation is free to do whatever it wishes as long as
it preserves the semantics. ?Depending on how new you are to the Erlang
world, you may not know about the hybrid heap VM, which can avoid the
copy-between-processes behavior you mention above.
It was exactly for the reason of the Hybrid-heap VM I worded my
sentence as I did. But I think I would prefer the current VM simply on
the basis that modern CPU architectures probably has to let go of
cache-coherency. One large heap without cache coherency sounds like
trouble.
--
J.
unknown
2010-08-14 19:23:32 UTC
Permalink
If you really want inheritance you can always build your own:

http://www.trapexit.org/Cascading_Behaviours

:)
--
-Vance
Loading...