Object >> #cull:

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

Object >> #cull:

Christoph Thiede

Hi all!


Just another, possibly crazy idea: What about implementing #cull:, #cull:cull: etc. on Object?


Object >> #cull: firstArg

    ^ self value


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:


[2 / 0] on: ZeroDivide do: Float infinity


Some current implementations that call both #isBlock and #cull: also reveal that there might be a small break in the interface. From #haltIf:



Just wanted to share that thought :) In general, do you think blurring the differences between block and object in that way might be a good idea or rather a bad one? At least we already have implemented #value on Object.


Disclaimer: I know that in many cases, you should prefer a block for performance reasons/compiler optimization, but there is still a gap between the interfaces ...


Best,

Christoph



Reply | Threaded
Open this post in threaded view
|

Re: Object >> #cull:

Nicolas Cellier
Hi Christoph,
I would be reluctant to add it to Object, because it's super hard to remove from Object afterward...
IMO whatever condition used in place of Block should quake like a block. So we should add cull: to those evaluable classes... Every other object should not care.

Le lun. 9 déc. 2019 à 18:51, Thiede, Christoph <[hidden email]> a écrit :

Hi all!


Just another, possibly crazy idea: What about implementing #cull:, #cull:cull: etc. on Object?


Object >> #cull: firstArg

    ^ self value


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:


[2 / 0] on: ZeroDivide do: Float infinity


Some current implementations that call both #isBlock and #cull: also reveal that there might be a small break in the interface. From #haltIf:



Just wanted to share that thought :) In general, do you think blurring the differences between block and object in that way might be a good idea or rather a bad one? At least we already have implemented #value on Object.


Disclaimer: I know that in many cases, you should prefer a block for performance reasons/compiler optimization, but there is still a gap between the interfaces ...


Best,

Christoph





pastedImage.png (9K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Object >> #cull:

marcel.taeumel
In reply to this post by Christoph Thiede
Hi Christoph,

let's discuss that after the 5.3 release.

such as blocks or MessageSends 

Well, then BlockClosure and MessageSend would be the place to add #cull:. There is no need to put it in Object because any class can choose to freely and dynamically participate in such a protocol. :-)

Best,
Marcel

Am 09.12.2019 18:51:35 schrieb Thiede, Christoph <[hidden email]>:

Hi all!


Just another, possibly crazy idea: What about implementing #cull:, #cull:cull: etc. on Object?


Object >> #cull: firstArg

    ^ self value


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:


[2 / 0] on: ZeroDivide do: Float infinity


Some current implementations that call both #isBlock and #cull: also reveal that there might be a small break in the interface. From #haltIf:



Just wanted to share that thought :) In general, do you think blurring the differences between block and object in that way might be a good idea or rather a bad one? At least we already have implemented #value on Object.


Disclaimer: I know that in many cases, you should prefer a block for performance reasons/compiler optimization, but there is still a gap between the interfaces ...


Best,

Christoph



Reply | Threaded
Open this post in threaded view
|

Re: Object >> #cull:

Christoph Thiede

Hi Marcel,


I see this sentence of myself was ambiguous:


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:

I meant: improve the polymorphy between, on the one hand, blocks, MessageSends & Co., and on the other hand, objects in general.

When I design an interface, I often wonder whether I should store into an accessor either a block or rather a normal object. A block has a more sophisticated syntax, while normal objects can't vary dependent on an argument.

An example: Let's assume Collections-mt.852 would be merged into Trunk (which uses #cull:).
Then I could say
Array new: 20 filledWith: [100 atRandom].
or even
Array new: 20 filledWith: [:i | i ** 2].
but not
Array new: 20 filledWith: 42.
Instead, I would need to specify extra brackets that appear kind of redundant to me:
Array new: 20 filledWith: [42].

Object >> #cull: would solve this problem.

It would be also analog to the implementation of Object >> #value, which allows you to do
self assert: [Boolean random].
as well as
self assert: Boolean random.
From this point of view, every object is already evaluable today.


Looking forward to your thoughts - before or after 5.3 :-)


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Dienstag, 10. Dezember 2019 09:38:56
An: John Pfersich via Squeak-dev
Betreff: Re: [squeak-dev] Object >> #cull:
 
Hi Christoph,

let's discuss that after the 5.3 release.

such as blocks or MessageSends 

Well, then BlockClosure and MessageSend would be the place to add #cull:. There is no need to put it in Object because any class can choose to freely and dynamically participate in such a protocol. :-)

Best,
Marcel

Am 09.12.2019 18:51:35 schrieb Thiede, Christoph <[hidden email]>:

Hi all!


Just another, possibly crazy idea: What about implementing #cull:, #cull:cull: etc. on Object?


Object >> #cull: firstArg

    ^ self value


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:


[2 / 0] on: ZeroDivide do: Float infinity


Some current implementations that call both #isBlock and #cull: also reveal that there might be a small break in the interface. From #haltIf:



Just wanted to share that thought :) In general, do you think blurring the differences between block and object in that way might be a good idea or rather a bad one? At least we already have implemented #value on Object.


Disclaimer: I know that in many cases, you should prefer a block for performance reasons/compiler optimization, but there is still a gap between the interfaces ...


Best,

Christoph



Reply | Threaded
Open this post in threaded view
|

Re: Object >> #cull:

marcel.taeumel
Hi Christoph.

> ... but not Array new: 20 filledWith: 42.

That's what #new:withAll: is for.

> ... Instead, I would need to specify extra brackets that appear kind of redundant to me: ...

Because it is not required. Use #new:withAll:. :-) I would rather not over-engineer a specific interface if there are others for the job. On the idiomatic side, #new:withAll: would be preferred over #new:filledWith: for constant arguments.

And even #new:filledWith: has not been accepted for Trunk. So this discussion about Object >> #cull: needs a better example. ;-)

Best,
Marcel

Am 10.12.2019 13:06:19 schrieb Thiede, Christoph <[hidden email]>:

Hi Marcel,


I see this sentence of myself was ambiguous:


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:

I meant: improve the polymorphy between, on the one hand, blocks, MessageSends & Co., and on the other hand, objects in general.

When I design an interface, I often wonder whether I should store into an accessor either a block or rather a normal object. A block has a more sophisticated syntax, while normal objects can't vary dependent on an argument.

An example: Let's assume Collections-mt.852 would be merged into Trunk (which uses #cull:).
Then I could say
Array new: 20 filledWith: [100 atRandom].
or even
Array new: 20 filledWith: [:i | i ** 2].
but not
Array new: 20 filledWith: 42.
Instead, I would need to specify extra brackets that appear kind of redundant to me:
Array new: 20 filledWith: [42].

Object >> #cull: would solve this problem.

It would be also analog to the implementation of Object >> #value, which allows you to do
self assert: [Boolean random].
as well as
self assert: Boolean random.
From this point of view, every object is already evaluable today.


Looking forward to your thoughts - before or after 5.3 :-)


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Dienstag, 10. Dezember 2019 09:38:56
An: John Pfersich via Squeak-dev
Betreff: Re: [squeak-dev] Object >> #cull:
 
Hi Christoph,

let's discuss that after the 5.3 release.

such as blocks or MessageSends 

Well, then BlockClosure and MessageSend would be the place to add #cull:. There is no need to put it in Object because any class can choose to freely and dynamically participate in such a protocol. :-)

Best,
Marcel

Am 09.12.2019 18:51:35 schrieb Thiede, Christoph <[hidden email]>:

Hi all!


Just another, possibly crazy idea: What about implementing #cull:, #cull:cull: etc. on Object?


Object >> #cull: firstArg

    ^ self value


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:


[2 / 0] on: ZeroDivide do: Float infinity


Some current implementations that call both #isBlock and #cull: also reveal that there might be a small break in the interface. From #haltIf:



Just wanted to share that thought :) In general, do you think blurring the differences between block and object in that way might be a good idea or rather a bad one? At least we already have implemented #value on Object.


Disclaimer: I know that in many cases, you should prefer a block for performance reasons/compiler optimization, but there is still a gap between the interfaces ...


Best,

Christoph



Reply | Threaded
Open this post in threaded view
|

Re: Object >> #cull:

Chris Muller-3
In reply to this post by Christoph Thiede
This curiosity is fun, Christoph.  Some comments.

When I design an interface, I often wonder whether I should store into an accessor either a block or rather a normal object. A block has a more sophisticated syntax, while normal objects can't vary dependent on an argument.

An interface should be designed to be as rigid as it _can_ be, while still meeting the requirements of those running the code.  As Nicolas alluded in another email, it's much easier to relax constraints than impose them.    TSTTCPW really is a good axiom to try to strictly adhere to.
 
An example: Let's assume Collections-mt.852 would be merged into Trunk (which uses #cull:).
Then I could say
Array new: 20 filledWith: [100 atRandom]. 
or even
Array new: 20 filledWith: [:i | i ** 2].
but not
Array new: 20 filledWith: 42.
Instead, I would need to specify extra brackets that appear kind of redundant to me:
Array new: 20 filledWith: [42]. 


Object >> #cull: would solve this problem.

I think saying its a "problem" might be overstating it.   Attempting to sweeten the syntax as you suggest would introduce a new trade-off -- ambiguity with how one might otherwise make an Array filled with Blocks.
 

It would be also analog to the implementation of Object >> #value, which allows you to do
self assert: [Boolean random].
as well as
self assert: Boolean random.
From this point of view, every object is already evaluable today.

I understand you on this point, however, #cull: arg when the arg will _never_ be consumed, IMO, is a red flag warning that this "blurring" may be trying to go one step too far.  #value is an "accessor", calculated or not.  #cull: is a more-specific responsibility of a "behavioral" object -- a Block or MessageSend -- that implies "selection" or calculation.

Best,
  Chris
 


Looking forward to your thoughts - before or after 5.3 :-)


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Dienstag, 10. Dezember 2019 09:38:56
An: John Pfersich via Squeak-dev
Betreff: Re: [squeak-dev] Object >> #cull:
 
Hi Christoph,

let's discuss that after the 5.3 release.

such as blocks or MessageSends 

Well, then BlockClosure and MessageSend would be the place to add #cull:. There is no need to put it in Object because any class can choose to freely and dynamically participate in such a protocol. :-)

Best,
Marcel

Am 09.12.2019 18:51:35 schrieb Thiede, Christoph <[hidden email]>:

Hi all!


Just another, possibly crazy idea: What about implementing #cull:, #cull:cull: etc. on Object?


Object >> #cull: firstArg

    ^ self value


This could improve the polymorphy between "evaluables" such as blocks or MessageSends and other objects. Example:


[2 / 0] on: ZeroDivide do: Float infinity


Some current implementations that call both #isBlock and #cull: also reveal that there might be a small break in the interface. From #haltIf:



Just wanted to share that thought :) In general, do you think blurring the differences between block and object in that way might be a good idea or rather a bad one? At least we already have implemented #value on Object.


Disclaimer: I know that in many cases, you should prefer a block for performance reasons/compiler optimization, but there is still a gap between the interfaces ...


Best,

Christoph