Is there any difference between a Self/Smalltalk block and a LISP closure?
Cheers, Steve
It depends on the Smalltalk. A full closure can be returned from a function and still refer to that function's variables. Self disallows this, as do some Smalltalks I beleive. If you support this feature you can no longer put all your local variables on the stack, because references to them may outlive the function activation in which they were created.
On Wednesday, April 9, 2003, at 01:28 PM, Steve Dekorte wrote:
Is there any difference between a Self/Smalltalk block and a LISP closure?
Cheers, Steve
James McCartney asynth@io.com writes:
It depends on the Smalltalk. A full closure can be returned from a function and still refer to that function's variables. Self disallows this, as do some Smalltalks I beleive. If you support this feature you can no longer put all your local variables on the stack, because references to them may outlive the function activation in which they were created.
This is a fiction that the Smalltalk crowd likes to talk about, and it's a shame that the Self crowd also repeats it.
In languages which support closures, it is rare to return them. Most functions never return them. So you can store such local variables on the stack just fine, for all but the minority of functions which return closures.
But what about the ones that do? Well, if you didn't return a closure, you'd have to do something else to hold the same data, some kind of allocation, and that has just whatever cost the alternative non-stack compilation has for the same data.
There is a wrinkle because Smalltalk and Self use internal closures (whether real or pseudo) for control structures to a higher degree than Lisp/Scheme usually do. However, it is still very rare to actually return them.
A Lisp/Scheme system therefore can use non-stack allocation for any function where a closure is created, even if it is not returned (that is, if it can be taken to have dynamic extent). But this is not strictly necessary--Smalltalk and Self do just fine with pseudo-closures, that is, closures with merely dynamic extent.
So, since Smalltalk/Self code is more aggressive in creating closures, which are typically not returned, the trick is for the compiler to detect ones which won't be returned. This is in general a matter of detecting aliasing, and it's not too tough for the common uses of closures in Smalltalk and Self.
So, my suggestion is to bite the bullet and do it right. Demand real closures.
If you think this is "too hard", then what are you doing with Smalltalk and Self anyhow? The whole glory here is that things that are "too hard" can, indeed, be made quite tractible through good compilation. In the case of closures, the techniques are well-known, and it's a shame that the Smalltalk/Self crowd mostly disregard them.
On Wed, 9 Apr 2003 tb@becket.net wrote:
[snipped analysis I agree with.]
So, my suggestion is to bite the bullet and do it right. Demand real closures.
We've been following this course with Slate.
On Wednesday, April 9, 2003, at 10:31 PM, tb@becket.net wrote:
James McCartney asynth@io.com writes:
It depends on the Smalltalk. A full closure can be returned from a function and still refer to that function's variables. Self disallows this, as do some Smalltalks I beleive. If you support this feature you can no longer put all your local variables on the stack, because references to them may outlive the function activation in which they were created.
This is a fiction that the Smalltalk crowd likes to talk about, and it's a shame that the Self crowd also repeats it.
I'm probably not in the Self crowd since I've yet to actually run it. My own language does support full closures. I think you didn't read my words as carefully as I wrote them.
In languages which support closures, it is rare to return them. Most functions never return them. So you can store such local variables on the stack just fine, for all but the minority of functions which return closures.
I said you can't store "all" local variables on the stack. Which is certainly the case.
James McCartney asynth@io.com writes:
I'm probably not in the Self crowd since I've yet to actually run it. My own language does support full closures. I think you didn't read my words as carefully as I wrote them.
I'm sorry that I may have mistaken your words; this was not my intention.
I said you can't store "all" local variables on the stack. Which is certainly the case.
Right, and I should have been more moderate in my words. I really wanted to criticize the common assumption that "closures are really expensive", which is strangely dominant among some Smalltalk folk, and it was wrong to incorrectly ascribe that view to you.
Dear All!
Curiously not wanting to provoke you or offend you, Smalltalk was
the only language among Basic, Fortran ( I studied Fortran when I was nineteen years old and a Biological Sciences student concerned with ecological modeling - my ex-husband was the professor, he was teaching a graduate course for electronic engineers! I was the best student! I got 10 and he has not at all helped me! Indeed he hated to teach me anything!)
, Pascal, C, Modula, Oberon, Simula, C++, Eiffel, Sather, CLOS, Beta (The Mjolner Beta System and the Simula system) that I was unable to study by myself!
This is fun because for me this is the opposite. But I come from a lisp background and I not syntax-aware and not polluted by {}.
OK! Let's check how wonderful and didactic it is to study Smalltalk and associated languages!
First of all, I have read nine pages from the paper The Early History of Smalltalk that may be downloaded from http://www.iam.unibe.ch/~ducasse/
and has recently been published at ACM SIGOLAN Notices, vol. 28 no.3 March 1993 Alan Kay is very honest and makes evident how naïve and simple ideas dawned on the computer scientists to keep the ball rolling are woven into computer systems! Then it is up to the users to reject them or simply pretend they are doing research on computer science that is really having impact on the change of the quality of life on Mother Earth! Sorry if I do not manage to teach seventeen-year old architects how to program complex systems such as to design and plan sustainable cities, I do not see mankind is really building a sustainable basis for our cities. Hence everybody will face collapse soon! Nobody cares about this of course! But I do care! This is my mission!
Alan Kay says: The bridge to an object-based system could be in terms of each object as a syntax-directed interpreter of messages sent to it. = unify OO semantics with the ideal of a completely extensible language
Just perfect:-)! Then to continue reading the rest of paper he takes for granted that I know about car, cdr, cons eval apply functions, lambda expressions, quotes conds etc! Then I start reading On Lisp from Paul Graham you can download on site http://www.paulgraham.com/onlisp.htm or html?
Of course not only does he explain nothing about car, cdr, cons etc and worse introduce lots of expressions and commands I have never heard of!!! For example can someone explain to me how can I understand the following closure to make a new database?
(defun make-dbms (db) (list #'(lambda (key) (cdr (assoc key db)) #'(lambda (key val) (push (cons key val) db) key) #'(lambda (key) (setf db (delete key db :key #' car)) key)))
For me this is a nightmare! And the same obstacles I find when I try to delve deeper into Smalltalk and Self!!! It is worse than biochemistry because in biochemistry every new enzyme or organic product that appears one knows why! I mean it is a coherent whole! Special thanks and apologies for complaining, but I do need to understand the gist of exploratory programming. Is it the same as bottom-up programming what's the difference? Have a fun-filled peaceful creative weekend Albertina
tb@becket.net wrote:
James McCartney asynth@io.com writes:
It depends on the Smalltalk. A full closure can be returned from a function and still refer to that function's variables. Self disallows this, as do some Smalltalks I beleive. If you support this feature you can no longer put all your local variables on the stack, because references to them may outlive the function activation in which they were created.
This is a fiction that the Smalltalk crowd likes to talk about, and it's a shame that the Self crowd also repeats it.
In languages which support closures, it is rare to return them. Most functions never return them. So you can store such local variables on the stack just fine, for all but the minority of functions which return closures.
But what about the ones that do? Well, if you didn't return a closure, you'd have to do something else to hold the same data, some kind of allocation, and that has just whatever cost the alternative non-stack compilation has for the same data.
There is a wrinkle because Smalltalk and Self use internal closures (whether real or pseudo) for control structures to a higher degree than Lisp/Scheme usually do. However, it is still very rare to actually return them.
A Lisp/Scheme system therefore can use non-stack allocation for any function where a closure is created, even if it is not returned (that is, if it can be taken to have dynamic extent). But this is not strictly necessary--Smalltalk and Self do just fine with pseudo-closures, that is, closures with merely dynamic extent.
So, since Smalltalk/Self code is more aggressive in creating closures, which are typically not returned, the trick is for the compiler to detect ones which won't be returned. This is in general a matter of detecting aliasing, and it's not too tough for the common uses of closures in Smalltalk and Self.
So, my suggestion is to bite the bullet and do it right. Demand real closures.
If you think this is "too hard", then what are you doing with Smalltalk and Self anyhow? The whole glory here is that things that are "too hard" can, indeed, be made quite tractible through good compilation. In the case of closures, the techniques are well-known, and it's a shame that the Smalltalk/Self crowd mostly disregard them.
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Albertina Lourenci lourenci@lsi.usp.br writes:
Of course not only does he explain nothing about car, cdr, cons etc and worse introduce lots of expressions and commands I have never heard of!!! For example can someone explain to me how can I understand the following closure to make a new database?
I guess he just expects you have already studied the language somewhat. My suggestion is to get a copy of SICP, which can show you a fair bit about the Scheme dialect of Lisp. Others here would be better placed to recommend resources in Smalltalk.
To me, that make-dbms function is a trivial one, very easy to understand at a mere glance.
tb@becket.net wrote:
Dear!
Albertina Lourenci lourenci@lsi.usp.br writes:
Of course not only does he explain nothing about car, cdr, cons etc and worse introduce lots of expressions and commands I have never heard of!!! For example can someone explain to me how can I understand the following closure to make a new database?
I guess he just expects you have already studied the language somewhat. My suggestion is to get a copy of SICP, which can show you a fair bit about the Scheme dialect of Lisp. Others here would be better placed to recommend resources in Smalltalk.
Chapter 2 Common Lisp from Paul Graham explains everything!!!
To me, that make-dbms function is a trivial one, very easy to understand at a mere glance.
Sure it is a trivial one! But to understand it I had to look for Common Lisp
book and here it is: http://lib1.store.vip.sc5.yahoo.com/lib/paulgraham/acl1.txt http://lib1.store.vip.sc5.yahoo.com/lib/paulgraham/acl2.txt Paul Graham thinks about everything! And I would recommend reading other papers that tune with my needs: http://www.paulgraham.com/paulgraham/langdes.html http://www.paulgraham.com/paulgraham/hundred.html
Special thanks!
Good night! Albertina
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
On Wednesday 09 April 2003 17:28, Steve Dekorte wrote:
Is there any difference between a Self/Smalltalk block and a LISP closure?
That depends on what you mean by "Self block". You might be thinking about any of the following three objects:
1) what is translated from the "[...]" source text and stored in the literal vector of some method. When a "push literal" bytecode is executed which refers to this object, a new object of type 2 is actually created and pushed on the stack. Most Smalltalks don't bother with this and actually compile the "[...]" to a sequence of special bytecodes that will explicitly create the type 2 object.
2) this is an object that holds on to the execution context in which it is created in addition to the information originally in the type 1 object. It also understands messages like 'whileTrue:', 'loop' and 'value'.
3) this is very much like a regular method context created as a result of sending 'value' (or its brothers) to a type 2 object, but it is set to inherit from the execution context saved in the type 2 object and not from its receiver (which would be the type 2 object itself, in this case).
So the answer to your question is 1) no, 2) essentially the same thing, 3) no - this would be like a Lisp application of (to?) a closure.
Are we having fun yet, or should we move on to continuations? ;-) -- Jecel
On Wednesday, April 9, 2003, at 04:41 PM, Jecel Assumpcao Jr wrote:
So the answer to your question is 1) no, 2) essentially the same thing, 3) no - this would be like a Lisp application of (to?) a closure.
Thanks for the response(from you and James).
Are we having fun yet, or should we move on to continuations? ;-)
Actually, I was wondering how Self implements coroutines. Does it do it by manipulating it's internal stack only or does it save and swap C/C++ stacks as well?
Cheers, Steve Io, a small language: http://www.iolanguage.com/
self-interest@lists.selflanguage.org