[squeak-dev] Re: [BUG] [ :a | ] value: 1

Eliot Miranda eliot.miranda at gmail.com
Wed Dec 16 17:24:35 UTC 2009


Hi Lukas,

    can you forward my response to Pharo?  TIA.

On Wed, Dec 16, 2009 at 2:54 AM, Lukas Renggli <renggli at gmail.com> wrote:

> Hi Eliot
>
> While working on a way to use the RB-AST with the standard compiler I
> think I found a problem in your code. To reproduce evaluate the
> following expression:
>
>    [ :a | ] value: 1
>
> According to my understanding that should return nil, not the first
> argument 1.
>
> The generated bytecode is:
>
>    pushTemp: 0
>    blockReturn
>
> I think it should be:
>
>    pushConstant nil
>    blockReturn
>
> Cheers,
> Lukas
>

:) :)  This is funny.  VisualWorks has exactly the same bug^H^H^Hfeature.
 And if you look at the ANSI standard (ok, this is from the draft, but it is
essentially the actual document) there is an exception for precisely this
case,  See the last sentence in section 3.4.4 Blocks:

If a block has no <block body> or no <statements> in its <block body> then
the value of the block is undefined.
Which allows [] to be implemented as e.g. [Random new next].  In fact both
VisualWorks and Squeak answer the last argument:
[:a ] value: 1 1
[:a :b|] value: 1 value: 2 2
[:a :b :c :d :e :f :g :h| ] valueWithArguments: (1 to: 8) 8
[:a | nil] value: 1 nil
[:a :b| nil] value: 1 value: 2 nil

At least it is consistent whether the block is inlined or not ;)

1+2 ifNotNil: [:arg|] 3

It as ever been so.  This from Smalltalk-80 V2:
*BlockNode methods for initialize-release*
arguments: argNodes statements: statementsCollection returns: returnBool
from: encoder
sourceEnd: sourceEnd
"compile"
sourceRange  _ sourceEnd to: sourceEnd.
arguments _ argNodes.
statements _ statementsCollection size > 0
ifTrue: [statementsCollection]
ifFalse: [argNodes size > 0
ifTrue: [statementsCollection copyWith: arguments last]
ifFalse: [Array with: NodeNil]].
returns _ returnBool

This from VW:
BlockNode methods for code generation
emitBody: codeStream
"The codeStream invokes this to compile
the body of the block, including the final return."

(body isEmpty and: [arguments isEmpty not])
ifTrue:
[codeStream noteSourceStart: body.
arguments last variable emitLocalReturn: codeStream from: body]
ifFalse: [body emitLocalReturn: codeStream from: body]

This from Squeak (my timestamp, but I just changed the _'s to :='s :) )

BlockNode methods for initialize-release
arguments: argNodes statements: statementsCollection returns: returnBool
from: encoder
"Compile."

arguments := argNodes.
statements := statementsCollection size > 0
ifTrue: [statementsCollection]
ifFalse: [argNodes size > 0
ifTrue: [statementsCollection copyWith: arguments last]
ifFalse: [Array with: NodeNil]].
optimized := false.
returns := returnBool

So at least it is easy to fix ;)  The question you have to ask yourself is
how much code is affected by this wafer thin change. I'm with you, I think
this is a bug.  But perhaps it was well thought through.  What say you, Dan
& Peter?  Did y'all agonise over this?  What say you Squeak & Pharo
communities?  Should we fix this or make it a preference ;)

best
Eliot


P.S.  I'm caught between wanting to fix it and wanting to let sleeping dogs
lie.  I'd like to know what all the other dialects do.  If a substantial
majority have the same curio I think we have to live with this, uh,
ornament.  Just to be clear, making it a preference is a sick joke on my
part.


> --
> Lukas Renggli
> http://www.lukas-renggli.ch
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20091216/6213566e/attachment.htm


More information about the Squeak-dev mailing list