The Portland Pattern Repository's Wiki is a wonderful place to go, to
learn about programming languages and how they relate to each other --
it's got some excellent stuff there, and the back-and-forth discussion
and shared experience between great programmers is fascinating.
Portland Pattern Repository Wiki:
http://www.c2.com/cgi/wiki
Here's the functional programming page:
http://www.c2.com/cgi/wiki?FunctionalProgramming
And these is also interesting and related to Lua:
http://www.c2.com/cgi/wiki?LuaLanguage
http://www.c2.com/cgi/wiki?LuaLanguageDiscussion
http://www.c2.com/cgi/wiki?SimplifiedWrapperAndInterfaceGenerator
And of course don't miss Paul Graham's brilliant free book "On Lisp" if
you want to really understand Lisp macros and metaprogramming and CLOS:
http://www.paulgraham.com/onlisp.html
Here's a classic article by Jonathan Rees on Paul Graham's web site
about object oriented programming, which deconstructs it into an a la
carte menu of specific features and properties. It's so interesting
I'll include it here. It's really helped me think about what I'm trying
to accomplish binding C++ to Lua.
http://www.paulgraham.com/reesoo.html
Rees Re: OO
(Jonathan Rees had a
really interesting response to Why
Arc isn't Especially Object-Oriented, which he has allowed me to
reproduce
here.)
Here is an a la carte menu of features or properties that are related
to these terms; I have heard OO defined to be many different subsets of
this list.
- Encapsulation - the ability to syntactically hide the
implementation of a type. E.g. in C or Pascal you always know whether
something is a struct or an array, but in CLU and Java you can hide the
difference.
- Protection - the inability of the client of a type to detect its
implementation. This guarantees that a behavior-preserving change to an
implementation will not break its clients, and also makes sure that
things like passwords don't leak out.
- Ad hoc polymorphism - functions and data structures with
parameters that can take on values of many different types.
- Parametric polymorphism - functions and data structures that
parameterize over arbitrary values (e.g. list of anything). ML and Lisp
both have this. Java doesn't quite because of its non-Object types.
- Everything is an object - all values are objects. True in
Smalltalk (?) but not in Java (because of int and friends).
- All you can do is send a message (AYCDISAM) = Actors model -
there is no direct manipulation of objects, only communication with (or
invocation of) them. The presence of fields in Java violates this.
- Specification inheritance = subtyping - there are distinct types
known to the language with the property that a value of one type is as
good as a value of another for the purposes of type correctness. (E.g.
Java interface inheritance.)
- Implementation inheritance/reuse - having written one pile of
code, a similar pile (e.g. a superset) can be generated in a controlled
manner, i.e. the code doesn't have to be copied and edited. A limited
and peculiar kind of abstraction. (E.g. Java class inheritance.)
- Sum-of-product-of-function pattern - objects are (in effect)
restricted to be functions that take as first argument a distinguished
method key argument that is drawn from a finite set of simple names.
So OO is not a well defined concept.
Some people (eg. Abelson and Sussman?) say Lisp is OO, by which they
mean {3,4,5,7} (with the proviso that all types are in the programmers'
heads). Java is supposed to be OO because of {1,2,3,7,8,9}. E is
supposed to be more OO than Java because it has {1,2,3,4,5,7,9} and
almost has 6; 8 (subclassing) is seen as antagonistic to E's goals and
not necessary for OO.
The conventional Simula 67-like pattern of class and instance will get
you {1,3,7,9}, and I think many people take this as a definition of OO.
Because OO is a moving target, OO zealots will choose some subset of
this menu by whim and then use it to try to convince you that you are a
loser.
Perhaps part of the confusion - and you say this in a different way in
your little memo -
is that the C/C++ folks see OO as a liberation from a world that has
nothing resembling a first-class functions, while Lisp folks see OO as
a prison since it limits their use of functions/objects to the style of
(9.). In that case, the only way OO can be defended is in the same
manner as any other game or discipline -- by arguing that by giving
something up (e.g. the freedom to throw eggs at your neighbor's house)
you gain something that you want (assurance that your neighbor won't
put you in jail).
This is related to Lisp being oriented to the solitary hacker and
discipline-imposing languages being oriented to social packs, another
point you mention. In a pack you want to restrict everyone else's
freedom as much as possible to reduce their ability to interfere with
and take advantage of you, and the only way to do that is by either
becoming chief (dangerous and unlikely) or by submitting to the same
rules that they do. If you submit to rules, you then want the rules to
be liberal so that you have a chance of doing most of what you want to
do, but not so liberal that others nail you.
In such a pack-programming world, the language is a constitution or set
of by-laws, and the interpreter/compiler/QA dept. acts in part as a
rule checker/enforcer/police force. Co-programmers want to know: If I
work with your code, will this help me or hurt me? Correctness is
undecidable (and generally unenforceable), so managers go with whatever
rule set (static type system, language restrictions, "lint" program,
etc.) shows up at the door when the project starts.
I recently contributed to a discussion of anti-OO on the e-lang list.
My main anti-OO message (actually it only attacks points 5/6) was
http://www.eros-os.org/pipermail/e-lang/2001-October/005852.html.
The followups are interesting but I don't think they're all threaded
properly.
(Here are the pet definitions of terms used above:
- Value = something that can be passed to some function
(abstraction). (I exclude exotic compile-time things like parameters to
macros and to parameterized types and modules.)
- Object = a value that has function-like behavior, i.e. you can
invoke a method on it or call it or send it a message or something like
that. Some people define object more strictly along the lines of 9.
above, while others (e.g. CLTL) are more liberal. This is what makes
"everything is an object" a vacuous statement in the absence of clear
definitions.
In some languages the "call" is curried and the key-to-method mapping
can sometimes be done at compile time. This technicality can cloud
discussions of OO in C++ and related languages.
- Function = something that can be combined with particular
parameter(s) to produce some result. Might or might not be the same as
object depending on the language.
- Type = a description of the space of values over which a
function is meaningfully parameterized. I include both types known to
the language and types that exist in the programmer's mind or in
documentation.
)
|