Go figure. OO is a natural form of expression for me. I was doing OO before the languages were OO. Maybe that is Graham's point, but I think formalizing my ad hoc pseudo-OO-wannabe techniques was a Good Thing. And CLOS especially does not really lock you in too badly, especially with the MOP.
I think there's a big backlash happening / going to happen against OO-as-it-has-become, which really means some terribly restrictive cultish thing involving obsessive data hiding, restrictive inheritance protocols making programming unduly difficult (you want to support this protocol? well, sorry you can't mix in this class that does it, you have to reimplement it all with nice different bugs), tying everything into class definitions and so on. Of course this is nothing to do with what object oriented programming actually once was, or with what CLOS is.
So he's worked this out, I guess, and is positioning arc as non-OO. He's missed the point a bit with CLOS, since it turns out that CLOS isn't OO either (That's OO-the-cult as opposed to being object oriented...), but maybe that's just anti-CLism, or just a matter of style (I'm kind of an inverse Paul Graham: I use CLOS all the time, but I don't think I do OOP).
Having taught CL courses over the last 5-6 years where I've tried to demonstrate that CL really is OO, even if it has these inconvenient things like method definitions outside classes and so on, I can see that now I'll have to reposition it as `not *actually* OO even though it looks a bit like it'.
tfb+goo...@tfeb.org (Tim Bradshaw) writes: > things like method definitions outside classes and so on, I can see > that now I'll have to reposition it as `not *actually* OO even though > it looks a bit like it'.
I can see your point - but isn't it a bit sad to surrender to the cultish definition of OO? On the other hand - maybe we should start referring to CLOS programming as "generic function programming" and refer, in footnotes, to "Cult OO" as a "a severely constrained special case of GFP" ;-)? -- (espen)
> > things like method definitions outside classes and so on, I can see > > that now I'll have to reposition it as `not *actually* OO even though > > it looks a bit like it'.
> I can see your point - but isn't it a bit sad to surrender to the cultish > definition of OO? On the other hand - maybe we should start referring > to CLOS programming as "generic function programming" and refer, in > footnotes, to "Cult OO" as a "a severely constrained special case of GFP"
I've tried to make the point to Paul that he is setting up a Java-like strawman of OO, then knocking it down. So what, big deal. So instead of thinking about the useful things OO can provide, he's throwing out the baby with the bathwater.
Here's a suggestion: stop calling what languages such as Common Lisp and Dylan provide "object-oriented programming". God forbid, don't call it "function-oriented programming", because that will get other people's knickers in a twist. Some years ago I suggested "protocol-oriented programming".
Kenny Tilton <ktil...@nyc.rr.com> writes: > Bill Clementson wrote:
> > FYI, Paul Graham has posted a new article on his web site > > discussing why Arc isn't especially OO: > > http://www.paulgraham.com/noop.html
> Go figure. OO is a natural form of expression for me. I was doing OO > before the languages were OO. Maybe that is Graham's point, but I think > formalizing my ad hoc pseudo-OO-wannabe techniques was a Good Thing. And > CLOS especially does not really lock you in too badly, especially with > the MOP.
> programmers sure do differ on basic stuff. :)
Well, he doesn't really say doing OO is bad, does he? Just that he personally never felt the need to use CLOS. Actually, I sympathize with most of the articles he writes about his `Arc' language; I don't like the look of the long `multiple-value-bind' either. But what I absolutely, positively don't get is why he thinks all those (IMO) minor issues justify all the effort of the creation of a new language. He could easily write a few macros that would turn CL into the very language he describes in those articles, or something very similar. I guess he has become rich and doesn't know how to use his time for something useful :-)
Regards, -- Nils Goesche "Don't ask for whom the <CTRL-G> tolls."
* "Scott McKay" <s...@mediaone.net> | Some years ago I suggested "protocol-oriented programming".
That is probably _the_ most constructive suggestion I have seen.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
"Scott McKay" <s...@mediaone.net> writes: > Here's a suggestion: stop calling what languages such as Common Lisp > and Dylan provide "object-oriented programming". God forbid, don't > call it "function-oriented programming", because that will get other > people's knickers in a twist. Some years ago I suggested > "protocol-oriented programming".
There's a solid scientific theory behind what we do, the lambda& calculus[0]. And it does count as both functional and object-oriented. So why hide?
Andreas
[0] For those who don't know, not the regular lambda calculus, but extended by multiple dispatch. See http://www.di.ens.fr/~castagna/pub.frametop.html Buy the book if you're interested in a calculus explaining CLOS and Dylan.
-- "In my eyes it is never a crime to steal knowledge. It is a good theft. The pirate of knowledge is a good pirate." (Michel Serres)
> > > FYI, Paul Graham has posted a new article on his web site > > > discussing why Arc isn't especially OO: > > > http://www.paulgraham.com/noop.html
> > Go figure. OO is a natural form of expression for me. I was doing OO > > before the languages were OO. Maybe that is Graham's point, but I think > > formalizing my ad hoc pseudo-OO-wannabe techniques was a Good Thing. And > > CLOS especially does not really lock you in too badly, especially with > > the MOP.
> > programmers sure do differ on basic stuff. :)
> Well, he doesn't really say doing OO is bad, does he? Just that he > personally never felt the need to use CLOS. Actually, I sympathize > with most of the articles he writes about his `Arc' language; I don't > like the look of the long `multiple-value-bind' either. But what I > absolutely, positively don't get is why he thinks all those (IMO) > minor issues justify all the effort of the creation of a new > language. He could easily write a few macros that would turn CL into > the very language he describes in those articles, or something very > similar.
This is what struck me very hard too. But I didn't read it in great detail...
> > Well, he doesn't really say doing OO is bad, does he? Just that he > > personally never felt the need to use CLOS. Actually, I sympathize > > with most of the articles he writes about his `Arc' language; I don't > > like the look of the long `multiple-value-bind' either. But what I > > absolutely, positively don't get is why he thinks all those (IMO) > > minor issues justify all the effort of the creation of a new > > language. He could easily write a few macros that would turn CL into > > the very language he describes in those articles, or something very > > similar.
> This is what struck me very hard too. But I didn't read it in great > detail...
I haven't read it at all, but I can still speak to the issue of this point. I think it's related to the IF* thing, though I mention that only to show another instance of a small matter turned big, when other small matters don't, so that one has more understanding that this is a general issue, not specific one to Paul.
It comes back to my thesis that languages are political parties and to the thought experiment raised in my paper http://world.std.com/~pitman/PS/Lambda.html where I suggest that EVEN IF you vacated some other language's semantics and made it identical to Lisp, or vice versa, the two languages might be momentarily at the same point in design space, but their velocity vector, or perhaps better, their acceleration (since we're really talking gravitational force here), is different. Over time, as long as there ARE two languages, they would drift, not move forever after in lockstep evolving the same. In time, they would be different again. It's almost like them snapping back to their original destiny (as I vaguely recall might have been the thesis in Asimov's The End of Eternity, where I think they said that you could make local changes in time without affecting the whole future of time because things would eventually converge again). (Ironic, I suppose that the "controlled" aspect of design might lead to divergence but the "uncontrolled" aspect of natural forces might leave to convergence. Hmm. I'll have to think about that.) Anyway, my point is that the analysis here about "small change" presumes you are measuring distance in design space rather than acceleration due to gravity. If you measure the latter, you may find that the diffrence is much greater, even if the two things are coincidentally co-located.
In plain English, it isn't where you are but where you're going that defines whether there might be a need to diverge.
And unlike in physics, politics uses "negotiated gravitational attraction" where the quark named "spin" (as in "spin control") is what makes the difference in who's going to be attracted to whom.
I don't know if that makes it right for people to diverge. But hopefully it makes it easier to understand that they did it for reasons that are perhaps more non-trivial than they seem. Always negotiations on getting someone back into the fold should be on the issue of "direction" not "position", or they will fall on deaf ears.
> > "Nils Goesche" <car...@cartan.de> wrote in message > > news:lkpu5k4fnu.fsf@pc022.bln.elmeg.de... > > > Kenny Tilton <ktil...@nyc.rr.com> writes: > > > <snip ...> > > > language. He could easily write a few macros that would turn CL into > > > the very language he describes in those articles, or something very > > > similar.
> > This is what struck me very hard too. But I didn't read it in great > > detail...
It could be that this is what will be (has been?) done. Paul Graham references comments that were made by Jonathan Rees. On Jonathan's home page, under the link related to jobs he has had, he mentions that he is currently working for a company called Clear Methods Inc. His comments about the company:
"a startup still somewhat in stealth mode. We are using the enhanced productivity made possible by Lisp to make tools for web application construction and deployment. The company's Lisp dialect is disguised as an extension of XML, both to obtain excellent XML integration and because of the immense popular prejudice against Lisp."
The web page for Clear Methods is a bit Spartan, indicating a Q4/2001 launch and a slogan "Ending the Software Crisis": http://www.clearmethods.com/
It is unclear who owns Clear Methods or what their product is. Maybe Arc is either a "feeler" to gauge potential support or a "teaser" for functionality that will be released by a company as a commercial product. This is, of course, just speculation on my part ...
bc19...@attbi.com writes: > It is unclear who owns Clear Methods or what their product is. Maybe > Arc is either a "feeler" to gauge potential support or a "teaser" > for functionality that will be released by a company as a commercial > product. This is, of course, just speculation on my part ...
I'm pretty sure that whatever Clear Methods' product is, it isn't Paul Graham's Arc, if that's what you're hinting at.
Language designers just like to chat among each other, like any other interest group.
> > It is unclear who owns Clear Methods or what their product is. Maybe > > Arc is either a "feeler" to gauge potential support or a "teaser" > > for functionality that will be released by a company as a commercial > > product. This is, of course, just speculation on my part ...
> I'm pretty sure that whatever Clear Methods' product is, it isn't > Paul Graham's Arc, if that's what you're hinting at.
I wasn't "hinting" at anything, I noticed that there were some similarities between the stated goals for Arc and the work that Jonathan Rees was doing and made a speculative comment on that. If they did happen to be collaborating on a product, I would view that as a positive thing as it would make more sense to me. I have trouble understanding why anyone would try to create a new dialect of Lisp and, if Arc happened to be a precursor to a product built on Lisp but customized for web site creation, I would find that more logical than an attempt to create a new lisp dialect just for the hell of it.
> It comes back to my thesis that languages are political parties and to > the thought experiment raised in my paper > http://world.std.com/~pitman/PS/Lambda.html where I suggest that EVEN > IF you vacated some other language's semantics and made it identical > to Lisp, or vice versa, the two languages might be momentarily at the > same point in design space, but their velocity vector, or perhaps > better, their acceleration (since we're really talking gravitational > force here), is different. Over time, as long as there ARE two > languages, they would drift, not move forever after in lockstep > evolving the same. In time, they would be different again. It's > almost like them snapping back to their original destiny
The C/C++ community did perform a form of your thought experiment, with one of the original goals of the C++ standardisation committee being to let ANSI Classic C be as much a subset of ISO C++ as possible, which they succeeded in remarkably well. (Most differences are of the trivia kind.) The updated C standard has taken off in a very different direction and the new C++ standard probably will remove further from the common subset too. And this is with a reasonable amount of overlap in the two standard communities.
-- Lieven Marchand <m...@wyrd.be> She says, "Honey, you're a Bastard of great proportion." He says, "Darling, I plead guilty to that sin." Cowboy Junkies -- A few simple words
Nils Goesche <car...@cartan.de> writes: > But what I absolutely, positively don't get is why he thinks all > those (IMO) minor issues justify all the effort of the creation of > a new language. He could easily write a few macros that would > turn CL into the very language he describes in those articles, or > something very similar. I guess he has become rich and doesn't > know how to use his time for something useful :-)
Now now, don't be too mean (although I'd love to be rich and have time to tinker with new languages too). I'd bet that the first implementation *will* be in a Lisp, but the whole point is to have a small and easily compiled language. Scheme is small but not easily compilable, and CL is large. Recall that his method of web-service using Lisp was to spawn processes for each new connection. Smaller processes (using smaller languages) spawn more quickly, and take up less memory. They also run faster.
I understand his purpose perfectly. CL is really too large for the purpose he applied it to. If you don't need CLOS or hash tables for instance, then you're losing lots of code space in your binary. Trimming down CL is a start, but he's taking the chance to tinker with a new language design, which is fun enough, and might eventually be useful.
And the Lisp Hacker that has not written their own Lisp-like language is not the true Lisp Hacker.
'james
-- James A. Crippen <ja...@unlambda.com> ,-./-. Anchorage, Alaska, Lambda Unlimited: Recursion 'R' Us | |/ | USA, 61.20939N, -149.767W Y = \f.(\x.f(xx)) (\x.f(xx)) | |\ | Earth, Sol System, Y(F) = F(Y(F)) \_,-_/ Milky Way.
> I understand his purpose perfectly. CL is really too large for the > purpose he applied it to. If you don't need CLOS or hash tables for > instance, then you're losing lots of code space in your binary.
The purpose of responding to http requests, or the implementation method of spawning a new process for each request? If you instead implement http responses using threads (as, e.g., cl-http does) you get faster "process" start-up times then spawning a new OS-level process and the size of the executable (environment, interpreter, compiler, delivered app, whatever) and language becomes largely irrelevant.
Of course, this assumes that Lisp has threads, which, unfortunately, is arguable.
* James A. Crippen | I understand his purpose perfectly. CL is really too large for the | purpose he applied it to. If you don't need CLOS or hash tables for | instance, then you're losing lots of code space in your binary.
I do not understand this position at all. Regardless of the "tree shaking" issues, "too large language" is simply false. The concept of a language being "too large" is vacuous. Just because starting up a new process is thought to be slow, does not mean that the language is too large. First, startup time has nothing to do with language size. Second, code size has nothing to do with startup time. Third, neither has binary size or disk footprint or any of the other numerous idiot measures of size. As a matter of counter-evidential fact, most of the Schemes I used before I came to my senses are still way, way slower to start up than the Common Lisps I have used, especially with actual code being used, and Scheme is about the smallest language you can get.
Execing a new image is usually quite expensive, but forking is not, at least under reasonable Unices, so it should be possible to fork a running image of a large binary with almost no overhead. Reasonable Unices even do copy-on-write and will not waste memory needlessly, either. This means that the startup time has become _completely_ irrelevant.
Furhtermore, the one-thread-per-connection model is inefficient compared to a tightly integrated I/O loop because a context switch is so much more expensive than merely running the same code with several file descriptors.
Making languages smaller to get faster startup time in a system that has decided on the fork and exec model appears to me no smarter or effective than shaving to lose weight.
| And the Lisp Hacker that has not written their own Lisp-like language is | not the true Lisp Hacker.
Nor is he who has not seen the folly of the endeavor in time.
/// -- The past is not more important than the future, despite what your culture has taught you. Your future observations, conclusions, and beliefs are more important to you than those in your past ever will be. The world is changing so fast the balance between the past and the future has shifted.
Erik Naggum wrote: > * James A. Crippen > | I understand his purpose perfectly. CL is really too large for the > | purpose he applied it to. If you don't need CLOS or hash tables for > | instance, then you're losing lots of code space in your binary.
> I do not understand this position at all. Regardless of the "tree > shaking" issues, "too large language" is simply false. The concept of a > language being "too large" is vacuous. Just because starting up a new > process is thought to be slow, does not mean that the language is too > large. First, startup time has nothing to do with language size. > Second, code size has nothing to do with startup time. Third, neither > has binary size or disk footprint or any of the other numerous idiot > measures of size. As a matter of counter-evidential fact, most of the > Schemes I used before I came to my senses are still way, way slower to > start up than the Common Lisps I have used, especially with actual code > being used, and Scheme is about the smallest language you can get.
> Execing a new image is usually quite expensive, but forking is not, at > least under reasonable Unices, so it should be possible to fork a > running > image of a large binary with almost no overhead. Reasonable Unices even > do copy-on-write and will not waste memory needlessly, either. This > means that the startup time has become _completely_ irrelevant.
> Furhtermore, the one-thread-per-connection model is inefficient compared > to a tightly integrated I/O loop because a context switch is so much > more expensive than merely running the same code with several file > descriptors.
I have no experience with server programming in lisp, but I would think that a fork-once-in-a-while model would be an efficient method for implementing a server in a garbage-collected language. In the fork-once-in-a-while model, you have a "tree-shaked" mother process and fork off a pool of processes that handle connections. Each process can handle more than one connection, but when the processes have consed too much, you kill them off and fork a new process instead of starting garbage collection.
In this system, you have to explicitly communicate with the mother process whenever you want to change global state (session management etc. for a http server). In such a system you could also take all kinds of shortcuts with the memory allocator since you don't want to garbage collect in the slave process.
Now, what I am saying is that you might be best off by using fork() to overcome perceived limitations of garbage collection for implementation of server processes. A server usually receives a request, processes that request, delivers a result, and starts from scratch. Another way to say this is that most lisps (correct me if I am wrong) don't support the most efficient method for setting up and tearing down memory heaps for server applications. This might be a grave accusation given that I stated that I have no experience in this area, but read on :-)
A generational garbage collector probably works fairly well for a server application. Most objects live fairly short, and if you garbage collect between requests, you'll get decent performance. However, as you suggest above, the most efficient method to implement most server applications is as an event-driven state machine. In such an implementation, you can expect to have, say 200 simultaneous requests. In this situation, there is no point in time where a generational garbage collector will work well. If you garbage collect after a request has finished, you will only reclaim 0.5% of the local heap. In order to get decent performance out of the generational garbage collector you will have to garbage collect every, say 200 requests which would reclaim on average 50% of the local heap. The downside of this is that you would use twice the memory compared to a server written in C.
I think a solution to this problem is to support multiple heaps. Each request should use a separate heap that can be teared down after the request has been serviced. This requires a tiny bit of compiler support, but I think it would make it possible to implement a server application with virtually no memory or garbage collection overhead compared to a server written in C.
The operations I think are needed to support multiple heaps are: an operation to create heaps with various characteristics, and the ability to call a function so that consing happens within the given heap for everything that is done within that function (recursively).
In order to take full advantage of the ability to create heaps with various characteristics, I would need a little help from the memory system and the compiler. For instance, I woule like to create a heap with the invariant that no object outside the heap (except for the evaluation stack) should be able to refer to an object inside the heap. This is a fantastic heap because it allows me to allocate objects fast, and it allows me to throw away the whole heap after I am done with it - exactly the thing I want for server programming.
The compiler support that I need for this heap is that when I do (call-with-heap my-heap #'my-func) above, the compiler should make a copy of all stack variables, and it should make all global variables copy-on-write. That way it impossible for my-func and functions called by it to "communicate" with the outside world. To communicate with the outside world, a message passing interface could be used, just as we would do in a fork()-based server.
I think this is one cool thing that Arc could implement - and something that would make it ideal for server programming.
There are of course lots of additional issues that needs to be considered before this can work, but I think this idea is sound and can make a real difference for a certain class of programs (a class which is getting more and more important it seems).
> Scheme is small but not easily > compilable, and CL is large.
CL is large? What on earth are languages like Java / C++ then? Oh I know, there's some theoretical minimal core of Java which is `small' but I don't think you can count it as a java system unless it has at least a Gb of libraries. Likewise perl, python (if not now, soon) &c &c.
CL is really really small.
And this `it takes a long time to start' stuff. CLISP starts *really* fast on my semi-antique Sun.
> > Here's a suggestion: stop calling what languages such as Common Lisp > > and Dylan provide "object-oriented programming". God forbid, don't > > call it "function-oriented programming", because that will get other > > people's knickers in a twist. Some years ago I suggested > > "protocol-oriented programming".
> There's a solid scientific theory behind what we do, the > lambda& calculus[0]. And it does count as both functional > and object-oriented. So why hide?
Because Java, e.g., has staked out what it calls "object-oriented" and the model is broken. We just disassociate ourselves with the name. And anybody who ever attended an old Lisp & Functional Programming Conference will remember how bitter the fights are over the word "functional".
Sometimes retreating to find a better point of entry is a better way to win a battle.
Alexander Kjeldaas <astor-n...@fast.no> writes: > I think a solution to this problem is to support multiple heaps. Each > request should use a separate heap that can be teared down after the > request has been serviced. This requires a tiny bit of compiler support, > but I think it would make it possible to implement a server application > with virtually no memory or garbage collection overhead compared to a > server written in C.
On the LispM one can create an "area" which is explicitly marked as temporary and later clear it when you are absolutely certain that you are finished with the storage. However, this is a extremely dangerous way to manually manage memory. You will find yourself in serious trouble if anything pointed into that area prior to resetting it.
It is much safer (and simpler) to pool the objects you will be using for each request.
Carl Shapiro <cshap...@panix.com> writes: > Alexander Kjeldaas <astor-n...@fast.no> writes:
> > I think a solution to this problem is to support multiple heaps. Each > > request should use a separate heap that can be teared down after the > > request has been serviced. This requires a tiny bit of compiler support, > > but I think it would make it possible to implement a server application > > with virtually no memory or garbage collection overhead compared to a > > server written in C.
> On the LispM one can create an "area" which is explicitly marked as > temporary and later clear it when you are absolutely certain that you > are finished with the storage. However, this is a extremely dangerous > way to manually manage memory. You will find yourself in serious > trouble if anything pointed into that area prior to resetting it.
> It is much safer (and simpler) to pool the objects you will be using > for each request.
Indeed. The Lisp Machine experimented briefly with the idea of using temporary areas for consing during compilation, figuring all the result of compilation went away after. The number of bugs this turned up in programs was extraordinary and they backed out of it, in favor of the resource kind of model Carl mentions.
Of course, the lispm used a dynamic flag to control consing. This means that code that didn't know it was executing in a temporary area ended up consing into the other heap. One might say a lexical flag was better, but then the code would either be specialized for a given heap (and you'd need duplicate code specialized to other heaps in order to reuse the code) or else you'd need explicit dataflow in from an outer caller saying what heap to use and every call to anything at all that consed would need to take an extra arg saying what area to cons into. Each of these is messy.
A good generational GC gives you all of this with none of these hassles, even without resourcing. Generational GC is ideally designed for things like server situations that drop all their pointers when they are done. The amount of work required to reclaim storage in such situations is very small and the application robustness is MUCH higher.
> > > Here's a suggestion: stop calling what languages such as Common Lisp > > > and Dylan provide "object-oriented programming". God forbid, don't > > > call it "function-oriented programming", because that will get other > > > people's knickers in a twist. Some years ago I suggested > > > "protocol-oriented programming".
> > There's a solid scientific theory behind what we do, the > > lambda& calculus[0]. And it does count as both functional > > and object-oriented. So why hide?
> Because Java, e.g., has staked out what it calls "object-oriented" > and the model is broken. We just disassociate ourselves with > the name. And anybody who ever attended an old Lisp & Functional > Programming Conference will remember how bitter the fights are > over the word "functional".
> Sometimes retreating to find a better point of entry is a better way > to win a battle.
> Summary: it's not hiding, it's just politics.
I wholeheartedly agree. I would go as far as claiming that a good time to retreat is when the "hype level" gets to high :)
Anyway, I really like the term "protocol oriented programming". I would also adopt KMP's "identity oriented programming".
As an aside, there is still the question of "distributed object oriented programming". Maybe, "distributed protocol programming" is what we want?
Cheers
-- Marco Antoniotti ======================================================== NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488 719 Broadway 12th Floor fax +1 - 212 - 995 4122 New York, NY 10003, USA http://bioinformatics.cat.nyu.edu "Hello New York! We'll do what we can!" Bill Murray in `Ghostbusters'.
Marco Antoniotti <marc...@cs.nyu.edu> writes: > Anyway, I really like the term "protocol oriented programming". I > would also adopt KMP's "identity oriented programming".
I think the word "programming" is what is really causing the problem.
Programming is an "internal" thing. That is, it's on what Java calls "the private side". But from the outside, it doesn't really matter if a thing is programmed one way or another, IMO. That is, you can black box things as we've done with BUILT-IN-CLASS, and it's not a lot different than a sealed standard class (a la Dylan).
From the outside, the issue is whether there is discovery and of what nature that discovery is.
One might claim that Lisp and Java both have protocols, but that Lisp is gf-centric and Java is interface-centric. It's a pity these two aren't unified, frankly, since each has its virtues. C++ I don't see as having protocols, really, and not even gf's, just overloading.
When I refer to "identity oriented", I'm less referring to how one programs (which I regard as a personal matter) and more referring to the external way one treats an object they didn't program.
And there's the question of reflectivity. Can a program ask what another program has available or must one consult the doc.
I'd be comfortable saying Lisp is a protocol-oriented, gf-centric, call-by-identity, partially reflective, dynamic language.
I'd say Java is a protocol-oriented, class/interface-centric, call-mostly-by-identity, partially reflective, half-dynamic/half-static language.
I'd say C++ is a protocol-wannabe, class-centric, call-by-this-and-that, overly static language.
> As an aside, there is still the question of "distributed object > oriented programming".
For those who want to be dooped.
Though the acronym doop has already been used for dynamic object oriented programming and is a good one to stay away from.
> Maybe, "distributed protocol programming" is what we want?