, we argued for a while and eventually decided (I think) that Lisp people see a program as a bunch of sentences in a language, but I see a program as a world of interacting objects, and my complaint about LispMacro
s is that they don't make the objects real enough. And the Lisp people said, "Huh?" So I want to try to explain, and I have no idea how I'm going to do it. :)
I'm talking about touchy-feely stuff here. Psychology, not hardware or mathematics. PaulGraham
talks about the two schools of language design - the mathematical school, which started out with Lisp and is gradually evolving to be fast, and the hardware-oriented school, which started out with Fortran and is gradually evolving to be more like Lisp. I think there's a third school, the human-oriented school, which includes languages like Smalltalk and Self and is also
evolving to be faster, but isn't really headed towards Lisp.
One of the things they talk about in the DesignPrinciplesBehindSmalltalk
is that "A computer language should support the concept of 'object.'" They're not talking about objects as a technical concept. They're saying it because they believe that the idea of "objects" is close to the way that the human brain sees the world. I look at a chair and I see the chair as an object - it's a real thing
, and at that moment my brain has focused on it as a self-contained entity. A moment later I might be looking at a single leg of the chair and thinking of that
as a separate object. "Object" just means, "thing that my brain has distinguished from the rest of the universe." Under the hood it's all just atoms, but our brains have evolved to see the world this way.
(I'm not explaining this well. I don't know a damn thing about psychology. I'm just parroting what I've heard, because it makes sense to me. Read the DesignPrinciplesBehindSmalltalk
To these guys, an object isn't just a thing that does inheritance, polymorphism, and encapsulation (or whatever the textbook definition is these days). And it certainly
isn't just a poor man's closure, as I read on PaulGraham
's website. I don't see the chair as a function with captured local variables; I see it as an object
So an object is just a thing that we've distinguished from the rest of the universe. That's a very broad definition, and not a very useful one. You could say that just about anything is an object, and you'd be right. The important thing is to keep in mind the psychological principles behind it.
If our brains work by distinguishing things from other things and thinking of them as separate objects, then the goal of a language should be to let us "objectify" anything we can think of, and the goal of a programming environment should be to help the programmer manipulate these objects as easily as his brain can manipulate the concepts in his mind.
Self tries to do this by trying to make the objects feel real
. The Self environment isn't a tool to help me twiddle bits, or a language to help me communicate with a machine; it's an artificial reality, where I reify the concepts in my mind and then manipulate them directly. I cannot believe
I just said that, because it sounds like a bunch of touchy-feely hogwash, but it really does feel qualitatively different. And the reason
it feels different is because the Self environment goes to a lot of trouble to maintain the illusion that the objects I'm manipulating are real.
For example, objects in Self behave like they have an identity. In Smalltalk, I can take any object and ask for an inspector, which is a window on the screen that shows me things about that object (what instance variables it has, and so on). I can have two or three or ten inspectors open on the same object at the same time, if I want to. The inspector is a tool that gives me a view of the object. In Self, on the other hand, the equivalent thing (which is called an outliner) behaves like it is
the object. If I ask for a particular object and there's already an outliner for it on the screen somewhere, that outliner slides over to my hand. The outliner is
the object. It's just a gimmick, but it helps create the illusion that I'm directly manipulating the objects in my universe.
Objects in Self can be moved around spatially. My brain is good at dealing with stuff like that, because the real world is like that too. I can pick up a bottle of juice, and put it down on the table, and it stays where I put it. When I want the juice later, I don't have to "navigate" over to the juice, or specify the character-string name of the juice - I just pick up the juice. Similarly, I can move Self objects around on the screen, and pick them up and put them down, and they stay where I put them. When I want to pick up a particular object, I just... pick up the object.
This is the kind of thing that I find completely missing in Lisp. Lisp functions don't feel real to me - and macros certainly
don't. If I look at a program the way Lisp people do, as a bunch of sentences, then it makes sense, but I'm not sure that that's the most productive way to look at a program. Self makes really good use of my brain, by creating a world that's reminiscent of the world that my brain is used to. (But then, everybody's different, and my brain is weirder than most. :)
Sure, it is a good thing for languages to support the concept of objects, but languages like Smalltalk, Ruby, and Self... and even Java and C++... take things too far. Supporting the concept of objects doesn't mean you should drop the concept of RealData
. Objects are meant to reflect an artificial reality; a "chair" object is something you can sit in or stand on or shatter into scrapwood for your fire.
Most "pure" Object Oriented languages have very poor data representation; you are pretty much limited to integers, floating point numbers, and constant strings. If you want more complex data than this, you write objects and methods to manipulate DataObjects?
, like StringBuffers?
and Vectors. I.e. you need to have state in order to have data (at least of any useful sort).
Attempting to reify numbers, characters, strings, lists, etc. is simply foolish. You don't have a 1, you can't kick the string "Hello, World!" across a room, and the list (1 2 3 4) isn't something you can sit down in... or even destroy. (On this latter, you can certainly note that (1 2 3 4) is a list, and you can decompose it, but no matter what you do, the list (1 2 3 4) still doesn't exist, so you can't destroy it.)
An object is something that carries state, even if that state is constant. The state itself is data. E.g. a string buffer with the contents "Hello, World!" still has state, even if it is in the read-only memory. However, "Hello, World!" is data. The chair you are sitting on has a state: a position, a color, a certain mass, etc. If I enumerated all the important or useful facts about it, that would be data.
If it doesn't exist, it can't be an object, and if it exists it must be an object. A virtual existence is still an existence as far as being an object is concerned. E.g., if I wrote a game in which a Dragon is always stealing the virgins, that Dragon exists in the game. Similarly, not every object need be a physical thing; a problem, for example, is something that has a state and is thus a RealObject
Lisp and Scheme focus on data description rather than on object representation. However, through the destructive set! and setq, it is possible to create objects with state in Lisp or Scheme. Getting a simple system with Objects and Message Dispatches, like Smalltalk, would be a snap. If you don't feel you can represent RealObject
s with those languages it is because you generally don't need to do so in order to get a useful program from Lisp or Scheme, and haven't messed around with it much. If your feelings are more along the line that it is simply a hassle to represent RealObject
s in Lisp or Scheme, then you are right... Lisp and Scheme are languages designed so you don't need to include much structure to get stuff done, and to represent objects you need to start by adding a good deal of structure (e.g., to handle inheritance, polymorphism, etc.) That is a hassle.
I am completely baffled. :) I don't understand the distinction you're trying to make between objects and data. Why does it make sense for a dragon to be an object, but not a string or a number? In Self, I can
pick up "Hello, World!" and kick it across the room. Why shouldn't I be able to? -- AdamSpitz
I must say that I find your statements ironic, as objects in Lisp seem to be about as real as in any language I've seen. One could say that Lisp has been object oriented (with object
meaning the touchy feely stuff you're referring to) from the start. To see this, note that Lisp has always had the notion of EQ
, which implements object identity
. And don't be fooled; this is not merely the address at which a pointer lives (though, of course, it's often implemented that way) it's really a promise saying YES, these two objects are in fact the same object
. (Heck, (eq 2 2) is not guaranteed to return T!)
I guess I see things like the return of (list 'a 'b 'c) as a real object
, so is the symbol FOO, so is the function #'BAR, so is what I get when I do (make-instance 'my-fabulous-class).
But Lisp is not, and never has been, wedded to a single paradigm (except perhaps
that code==data) so we don't feel that allowing for expressive sentences as well
as having first class objects for just about everything takes anything away.
As always, YMMV. -- AlainPicard
Is that the sound of two purposes crossing? A lisp object is just as real as a Self object, and both are ultimately bit patterns in memory. But a Self object lives inside a runtime that exposes the object to me in one way, and the lisp runtie a very different way. Intellectually, I can appreciate that the two are much the same, but I've not yet seen a Lisp environment that will let me pick up a lisp object and shake it it. Lisp objects live in a textual world, where they can be interrogated by evaluating textual forms and display text about themselves, or have side effects on some gui, if you're lucky. Self objects live in a visual world and can be poked and prodded to make them exhibit behaviours. Oh, they do have dribs and drabs of textual code in the method objects, but the mode of interaction is primarly visual. -- AnonymousDonor
has a feature called the Inspector where you can look at the contents of any object and manipulate them directly. I've never gotten it to work (the LessTif?
GUI crashes on me far too often to actually get any work done with LispWorks
), but as I understand this type of DirectManipulation
interface is fairly common in the Lisp world, dating back to InterLisp
in the 1970s. You certainly
could do it on a LispMachine
: there's a video at http://lemonodor.com/archives/000103.html
. The LispMachine
s had pretty crummy displays (they were invented when we were toddlers, after all), but you can still use the mouse to view the slots of any object, change them, and have the running program exhibit the changes. -- JonathanTang
I'm curious that you don't see functions as "real". I tend to anthropomorphize my functions in any language that supports passing them around as first-class data. I think of a function as "something that I can hand things too, and it'll give me back the answer", and I can tell them to work together in assembly lines (compose), hold onto some data for a while (PartialApplication?
), perform a subtask for some other function (HigherOrderFunction
), group together in assemblies (objects), and so on. I almost see them as "people" rather than "things".
- The key Nygaardian issue is that objects have existence in space and time just like real world objects, whereas values do not, so objects behave in ways that are more intuitive to us space-time creatures than do values.
[Discussion on first-class macros moved to RuntimeMacro
...and it may take a bit of time to appear that, I'm going to try a little refactoring as I go along....]
Some people seem to be missing the point that when adam say's object, he's not using programming lingo... he using it in the sense of everyday language, an object is a thing, something you can pick up, move around, shake, turn upside down, that's what self gives you. Lisp objects/function/macro's are only real in the metaphorical sense, they are abstractly the same as self objects, but not real in the same way. Like Adam said... you can't pick up a Lisp object/function/macro and shake it, or poke it, it's not real in that sense. In self, you don't have to think of objects as real, because they are real, in other languages, you have to use your imagination, you conceptualize them as real, but you can't shake and poke em..
I believe that to be the original Nygaard intent of objects. -- dm
There's only one part there: that objects are "real": in some sense their behavior parallel how concrete nouns in real life behave. Unlike values. Lisp functions and macros are unreal in that sense. (The references to Lisp objects are/is a red herring; Lisp objects are pretty much like objects in any OO language; the comments above claiming otherwise are talking about DirectManipulation user interfaces
, not about objects per se.)