Polymorphic or: with block argument

Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Polymorphic or: with block argument

Lorenz Köhl-2
I don't understand why Smalltalk doesn't allow me to have an or:
method that takes a block argument (except on Boolean). For example:

Set or: 1. ==> MNU as expected.

Set or: [1]. ==> NonBooleanReceiver exception.

Set or: [:x | x] ==> Argument has too many arguments

Is it because the compiler specializes this to boolean when it sees
the or: [ ... ] syntax? Is this a tradeoff made for performance?

greetings,
  Lorenz

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

David T. Lewis
On Sun, Sep 10, 2017 at 01:33:15PM +0200, Lorenz K??hl wrote:

> I don't understand why Smalltalk doesn't allow me to have an or:
> method that takes a block argument (except on Boolean). For example:
>
> Set or: 1. ==> MNU as expected.
>
> Set or: [1]. ==> NonBooleanReceiver exception.
>
> Set or: [:x | x] ==> Argument has too many arguments
>
> Is it because the compiler specializes this to boolean when it sees
> the or: [ ... ] syntax? Is this a tradeoff made for performance?


Hi Lorenz,

If you are looking for set operations, check these methods:

  Collection>>union:
  Collection>>intersection:
  Collection>>difference:

I am not sure what you are trying to do with your examples. Can you
explain the intent?

Dave

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

marcel.taeumel
Hi, there.

I think the issue is that you cannot implement the message #or: for any domain object because the compiler treats it in a special way.

Consider a class Foo with the method #or:

Foo >> #or: block
   ^ block value

You cannot use it as expected:

x := Foo new.
y := x or: [42].

There is an optimisation that interferes with the general concepts of objects and messaging.

Best,
Marcel

Am 10.09.2017 14:45:31 schrieb David T. Lewis <[hidden email]>:

On Sun, Sep 10, 2017 at 01:33:15PM +0200, Lorenz K??hl wrote:

> I don't understand why Smalltalk doesn't allow me to have an or:
> method that takes a block argument (except on Boolean). For example:
>
> Set or: 1. ==> MNU as expected.
>
> Set or: [1]. ==> NonBooleanReceiver exception.
>
> Set or: [:x | x] ==> Argument has too many arguments
>
> Is it because the compiler specializes this to boolean when it sees
> the or: [ ... ] syntax? Is this a tradeoff made for performance?


Hi Lorenz,

If you are looking for set operations, check these methods:

Collection>>union:
Collection>>intersection:
Collection>>difference:

I am not sure what you are trying to do with your examples. Can you
explain the intent?

Dave

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

Lorenz Köhl-2
In reply to this post by David T. Lewis
I am not sure what you are trying to do with your examples. Can you
explain the intent?

Set was just an example object that's quick to test the behaviour. My intent
is to understand this behaviour, bc. Smalltalk usually goes to great length
to keep the messaging system consistent. But in VisualWorks the behaviour
is the same, so I presume (and Marcel confirms) that without this the performance
of the whole system suffers.

greetings, Lorenz

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

Ralph Johnson
In reply to this post by Lorenz Köhl-2
Yes, when the compiler sees   exp or: [ ... ] then it assumes that "exp" is a boolean-valued expression and generates code that fails if it isn't.    Not all Smalltalk compilers perform this optimization, but it is very common.  There are a bunch of methods treated like this, ifTrue:ifFalse: is another.

whileTrue: is an interesting slightly different case.   The compiler usually optimizes whileTrue: only when both receiver and the argument are blocks.    So, you can define whileTrue: in other classes without any problem.

-Ralph Johnson

On Sun, Sep 10, 2017 at 6:33 AM, Lorenz Köhl <[hidden email]> wrote:
Boxbe This message is eligible for Automatic Cleanup! ([hidden email]) Add cleanup rule | More info

I don't understand why Smalltalk doesn't allow me to have an or:
method that takes a block argument (except on Boolean). For example:

Set or: 1. ==> MNU as expected.

Set or: [1]. ==> NonBooleanReceiver exception.

Set or: [:x | x] ==> Argument has too many arguments

Is it because the compiler specializes this to boolean when it sees
the or: [ ... ] syntax? Is this a tradeoff made for performance?

greetings,
  Lorenz

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

Bert Freudenberg
In reply to this post by Lorenz Köhl-2
On Sun, Sep 10, 2017 at 3:06 PM, Lorenz Köhl <[hidden email]> wrote:
I am not sure what you are trying to do with your examples. Can you
explain the intent?

Set was just an example object that's quick to test the behaviour. My intent
is to understand this behaviour, bc. Smalltalk usually goes to great length
to keep the messaging system consistent. But in VisualWorks the behaviour
is the same, so I presume (and Marcel confirms) that without this the performance
of the whole system suffers.

​It avoids a message send and the allocation of a block. These used to be very costly with the interpreter, but even now with a JIT compiler having these get transformed to simple jumps behind the scenes is advantageous.

You can see how it works in class MessageNode, which is used by the Compiler.

In MessageNode class>>initialize all the macro transformations are registered. E.g. for "or:" we have "transformOr:" as a transformer and "emitCodeForIf:encoder:value:" as an emitter. The first transforms the "or:" message into an "ifTrue:ifFalse:" message, and the second emits the proper branch byte code to conditionally skip the blocks:

    a or: [b]

gets transformed to 

    a ifTrue: [true] ifFalse: [b]

and then byte code is emitted like

    a
    jump if false to 1
    push true
    jump to 2
1: b
2: ...

As you can see, the closure is gone completely.

- Bert -​


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

Sean P. DeNigris
Administrator
In reply to this post by Ralph Johnson
Ralph Johnson wrote
> Yes, when the compiler sees   exp or: [ ... ] then it assumes that "exp"
> is
> a boolean-valued expression and generates code that fails if it isn't.

I remember the pain of tripping over these little "everything is a message
send to an object*" sins as a new Smalltalker. I wonder now, with the
incredible speed of Cog, Spur, Sista, etc., if these devil's bargains from
prior decades are still necessary. It would be psychologically satisfying
(and nice for newbies) to remove the asterisk from the principle above.



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Squeak-Beginners-f107673.html
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Polymorphic or: with block argument

Jecel Assumpcao Jr
Sean P. DeNigris wrote on Sun, 17 Sep 2017 06:44:35 -0700 (MST)

> Ralph Johnson wrote
> > Yes, when the compiler sees   exp or: [ ... ] then it assumes that "exp"
> > is
> > a boolean-valued expression and generates code that fails if it isn't.
>
> I remember the pain of tripping over these little "everything is a message
> send to an object*" sins as a new Smalltalker. I wonder now, with the
> incredible speed of Cog, Spur, Sista, etc., if these devil's bargains from
> prior decades are still necessary. It would be psychologically satisfying
> (and nice for newbies) to remove the asterisk from the principle above.

That was one of the changes between Self 1.0 and 2.0. The first version
had a list of selectors it did special tricks for and it was annoying
for programmers to have two code fragments that looked very similar to
each other perform very differently. When Craig Chambers did the second
generation compiler he noticed that he could handle all cases uniformly.
The same should apply to Cog and Sista. Eliminating such tricks would
hurt the interpreter, however.

-- Jecel
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners