[squeak-dev] Re: [Newbies] Two questions about Smalltalk language design

H. Hirzel hannes.hirzel at gmail.com
Mon Dec 31 13:54:50 UTC 2012


Thank you, Nicolas, for these instructive code snippets and Happy New Year 2013

--Hannes

On 12/31/12, Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com> wrote:
> 2012/12/31 Frank Shearar <frank.shearar at gmail.com>:
>> On 31 December 2012 10:04, Nicolas Cellier
>> <nicolas.cellier.aka.nice at gmail.com> wrote:
>>> 2012/12/31 Nicolas Cellier <nicolas.cellier.aka.nice at gmail.com>:
>>>> 2012/12/31 Frank Shearar <frank.shearar at gmail.com>:
>>>>> On 31 December 2012 05:13, Casey Ransberger <casey.obrien.r at gmail.com>
>>>>> wrote:
>>>>>> Worth pointing out (at least I *think*) there's little real value in
>>>>>> returning nil by default, even though it makes a certain amount of
>>>>>> visceral sense.
>>>>>>
>>>>>> Why would I return nil? Maybe as a sentinel value for something (often
>>>>>> I prefer nil to zero for that when there's a nil concept and I want a
>>>>>> sentinel.)
>>>>>
>>>>> The problem with nil as a sentinel is that it's not sufficiently
>>>>> different from the other things in one's collection. I recall the
>>>>> troubles people had trying to store nils in a Set (which used nil for
>>>>> some special purpose). But there's a trivial way to get a really true
>>>>> blue unique sentinel: sentinel := Object new.
>>>>>
>>>>>> Likewise, there's an argument for returning the last value of a method
>>>>>> (like we do with blocks presently, and Self does everywhere) across
>>>>>> the board, like e.g. Ruby does, but I'd note: Smalltalk's semantics
>>>>>> had a lot of time to evolve. The advantages to answering self by
>>>>>> default have stood the test of time in this context, I think:) though
>>>>>> that certainly doesn't mean we shouldn't continue to ask questions and
>>>>>> look for a better idea.
>>>>>
>>>>> Certainly, if you didn't return self by default you'd lose the trivial
>>>>> cascading. (Look at the hoops others have to jump through to get their
>>>>> "fluent" APIs.)
>>>>>
>>>>> Given my particular interest in the intersection between the
>>>>> techniques of functional and OO programming I rarely use "return self
>>>>> by default". I instead get tripped up by forgetting to use a ^ on the
>>>>> last statement. But I'm not going to suggest we change the return-self
>>>>> behaviour :)
>>>>>
>>>>> frank
>>>>>
>>>>
>>>> An argument for NOT returning the result of last statement is that it
>>>> would more than often expose internal state of the object to the
>>>> outside (in the case you sent last message to an instance variable).
>>>>
>>>> Nicolas
>>>>
>>>
>>> Or, from an other point of view, that means that Smalltalk is more
>>> imperative tan functional...
>>
>> Well, I don't know about that. Certainly many of the standard APIs are
>> imperative (like remove: returning the deleted element rather than a
>> new collection with the element removed). But for instance, how about
>> "there's no distinction between a statement and an expression", which
>> is a pretty Functional (tm) feature.
>>
>> frank
>>
>
> Certainly, one of imperative language with most functional features...
> I played with these snippets:
>
> (SystemNavigation default allMethodsSelect: [:e |
> 	| scanner |
> 	scanner := InstructionStream on: e.
> 	scanner scanFor: [:byte | byte = 120]]) size.
> -> 21944
>
> (SystemNavigation default allMethodsSelect: [:e |
> 	| scanner |
> 	scanner := InstructionStream on: e.
> 	scanner scanFor: [:byte | (byte between: 121 and: 124)]]) size.
> -> 23668
>
> Byte code 120 does return the receiver, 121 true, 12 false, 123 nil,
> 124 stack top, 125 is for block local return.
> So above snippets means that roughly 50% of methods return the receiver
> (self).
>
> The snippet is not perfect, because some methods return both self and
> another object
> (SystemNavigation default allMethodsSelect: [:e |
> 	| scanner |
> 	scanner := InstructionStream on: e.
> 	(scanner scanFor: [:byte | (byte between: 121 and: 124)])
> 		and: [scanner scanFor: [:byte | byte = 120]]]) size.
> -> 1478
>
> Also, it does not cover all methods
> (SystemNavigation default allMethodsSelect: [:e |  true]) size.
> -> 47547
>
> The 3627 simple method that just return an Object (a literal or an
> instance variable) were not caught by the InstructionStream
> SystemNavigation default browseAllSelect: [:e |
> 	| scanner |
> 	scanner := InstructionStream on: e.
> 	(scanner scanFor: [:byte | (byte between: 120 and: 124)]) not].
>
> Nicolas
>
>>> Nicolas
>>>
>>>>>> On Dec 30, 2012, at 11:39 AM, Yoshiki Ohshima
>>>>>> <Yoshiki.Ohshima at acm.org> wrote:
>>>>>>
>>>>>>> On Sun, Dec 30, 2012 at 7:40 AM, Bert Freudenberg
>>>>>>> <bert at freudenbergs.de> wrote:
>>>>>>>> On 2012-12-27, at 01:32, Sebastian Nozzi <sebnozzi at gmail.com>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Why do ST methods return "self" if nothing is explicitly returned?
>>>>>>>>
>>>>>>>>
>>>>>>>> One very simple reason has not been stated yet: In the Virtual
>>>>>>>> Machine, returning self is simpler and more efficient than returning
>>>>>>>> any other object.
>>>>>>>>
>>>>>>>> Smalltalk byte codes implement a stack machine. That means arguments
>>>>>>>> are passed by pushing them onto a stack, rather than putting them
>>>>>>>> into registers. In addition to the arguments as listed in the method
>>>>>>>> signature, a hidden argument is always passed, which is the receiver
>>>>>>>> of the message. So even for unary methods (those without arguments)
>>>>>>>> the receiver is pushed onto the stack, then the method is executed,
>>>>>>>> and the receiver value on the stack is how the method knows "self".
>>>>>>>> By returning "self" if no explicit return statement is given, the VM
>>>>>>>> can just leave the "self" oop on the stack, which saves at least one
>>>>>>>> memory store operation. So from an efficiency and simplicity
>>>>>>>> standpoint, returning "self" is the most elegant thing to do.
>>>>>>>
>>>>>>> I thought of it (when I wrote the reply) but isn't this really the
>>>>>>> argument for returning self instead of nil for example?  Any message
>>>>>>> send pops all arguments including the receiver and pushes the return
>>>>>>> value so "self" is not on the stack.  Typical byte code sequence for
>>>>>>> a
>>>>>>> method that returns self is popping the last result and ends the
>>>>>>> sequence with "returnSelf"; so it should be equally efficient if
>>>>>>> such
>>>>>>> a method endsWIth "returnNil", if such bytecode exists?
>>>>>>>
>>>>>>> --
>>>>>>> -- Yoshiki
>>>>>>>
>>>>>>
>>>>>
>>>
>>
>
>


More information about the Squeak-dev mailing list