FullBlockClosure - How to create one...

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

FullBlockClosure - How to create one...

Sean P. DeNigris
Administrator
What am I not understanding about FullBlockClosure?

I have a clean block that I'd like to turn into a FullBlockClosure so that I
can serialize it without dragging (unneeded methods) into my object graph.
However, documentation and in-image example usages seem severely limited.
Here was one experiment that ended with a primitive failure. It seems like a
receiver is needed and it can't be a dummy value (see commented "receiver:
1"). But what would the receiver be in the absence of an outer context?!

aBlockClosure := [ :a :b  | 1 + a + b ].
fbc := (FullBlockClosure
                outerContext: nil
                startpc: aBlockClosure startpc
                numArgs: aBlockClosure argumentCount
                copiedValues: Array new) "receiver: 1; yourself".

fbc value: 2 value: 3. "PrimitiveFailed: primitive #value:value: in
FullBlockClosure failed"



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Max Leske

Hi Sean,

You need an outer context. See Context>>cleanCopy, which Fuel uses to serialize blocks.

Cheers,
Max

On 1 May 2020, at 3:23, Sean P. DeNigris wrote:

What am I not understanding about FullBlockClosure?

I have a clean block that I'd like to turn into a FullBlockClosure so that I
can serialize it without dragging (unneeded methods) into my object graph.
However, documentation and in-image example usages seem severely limited.
Here was one experiment that ended with a primitive failure. It seems like a
receiver is needed and it can't be a dummy value (see commented "receiver:
1"). But what would the receiver be in the absence of an outer context?!

aBlockClosure := [ :a :b | 1 + a + b ].
fbc := (FullBlockClosure
outerContext: nil
startpc: aBlockClosure startpc
numArgs: aBlockClosure argumentCount
copiedValues: Array new) "receiver: 1; yourself".

fbc value: 2 value: 3. "PrimitiveFailed: primitive #value:value: in
FullBlockClosure failed"



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html


signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Eliot Miranda-2
In reply to this post by Sean P. DeNigris
Hi Sean,

> On Apr 30, 2020, at 7:36 PM, Sean P. DeNigris <[hidden email]> wrote:
>
> What am I not understanding about FullBlockClosure?
>
> I have a clean block that I'd like to turn into a FullBlockClosure so that I
> can serialize it without dragging (unneeded methods) into my object graph.
> However, documentation and in-image example usages seem severely limited.
> Here was one experiment that ended with a primitive failure. It seems like a
> receiver is needed and it can't be a dummy value (see commented "receiver:
> 1"). But what would the receiver be in the absence of an outer context?!
>
> aBlockClosure := [ :a :b  | 1 + a + b ].
> fbc := (FullBlockClosure
>        outerContext: nil
>        startpc: aBlockClosure startpc
>        numArgs: aBlockClosure argumentCount
>        copiedValues: Array new) "receiver: 1; yourself".

FullBlockClosure doesn’t have a startpc.  Because it has its own method its startpc is implicit, just like a normal method.

I’m on my phone now, so I don’t know what the creation method is off hand.  But if you look at how Context implements the FullBlockClosure value primitives in doPrimitive:... you should find it.

>
> fbc value: 2 value: 3. "PrimitiveFailed: primitive #value:value: in
> FullBlockClosure failed"
>
>
>
> -----
> Cheers,
> Sean
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>

Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Eliot Miranda-2
In reply to this post by Max Leske
Hi Max,

On Thu, Apr 30, 2020 at 11:51 PM Max Leske <[hidden email]> wrote:

Hi Sean,

You need an outer context. See Context>>cleanCopy, which Fuel uses to serialize blocks.


One does *not* need an outer context.  An outer context of nil should be fine, provided that the block never attempts an up-arrow return.


| blockMethod |
blockMethod := [:a :b| a < b] method.
(FullBlockClosure receiver: nil outerContext: nil method: blockMethod copiedValues: nil) value: 1 value: 2

So one needs to use FullBlockClosure class>>receiver:outerContext:method:copiedValues: and one can supply nil for the outerContext provided that the block does not do an up-arrow return.
 

Cheers,
Max

On 1 May 2020, at 3:23, Sean P. DeNigris wrote:

What am I not understanding about FullBlockClosure?

I have a clean block that I'd like to turn into a FullBlockClosure so that I
can serialize it without dragging (unneeded methods) into my object graph.
However, documentation and in-image example usages seem severely limited.
Here was one experiment that ended with a primitive failure. It seems like a
receiver is needed and it can't be a dummy value (see commented "receiver:
1"). But what would the receiver be in the absence of an outer context?!

aBlockClosure := [ :a :b | 1 + a + b ].
fbc := (FullBlockClosure
outerContext: nil
startpc: aBlockClosure startpc
numArgs: aBlockClosure argumentCount
copiedValues: Array new) "receiver: 1; yourself".

fbc value: 2 value: 3. "PrimitiveFailed: primitive #value:value: in
FullBlockClosure failed"



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html



--
_,,,^..^,,,_
best, Eliot
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Eliot Miranda-2
you might want to adapt this change set into a package, to rename BlockClosure's startups inst var to startpcOrMethod to clear up confusion.



On Fri, May 1, 2020 at 9:49 AM Eliot Miranda <[hidden email]> wrote:
Hi Max,

On Thu, Apr 30, 2020 at 11:51 PM Max Leske <[hidden email]> wrote:

Hi Sean,

You need an outer context. See Context>>cleanCopy, which Fuel uses to serialize blocks.


One does *not* need an outer context.  An outer context of nil should be fine, provided that the block never attempts an up-arrow return.


| blockMethod |
blockMethod := [:a :b| a < b] method.
(FullBlockClosure receiver: nil outerContext: nil method: blockMethod copiedValues: nil) value: 1 value: 2

So one needs to use FullBlockClosure class>>receiver:outerContext:method:copiedValues: and one can supply nil for the outerContext provided that the block does not do an up-arrow return.
 

Cheers,
Max

On 1 May 2020, at 3:23, Sean P. DeNigris wrote:

What am I not understanding about FullBlockClosure?

I have a clean block that I'd like to turn into a FullBlockClosure so that I
can serialize it without dragging (unneeded methods) into my object graph.
However, documentation and in-image example usages seem severely limited.
Here was one experiment that ended with a primitive failure. It seems like a
receiver is needed and it can't be a dummy value (see commented "receiver:
1"). But what would the receiver be in the absence of an outer context?!

aBlockClosure := [ :a :b | 1 + a + b ].
fbc := (FullBlockClosure
outerContext: nil
startpc: aBlockClosure startpc
numArgs: aBlockClosure argumentCount
copiedValues: Array new) "receiver: 1; yourself".

fbc value: 2 value: 3. "PrimitiveFailed: primitive #value:value: in
FullBlockClosure failed"



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html



--
_,,,^..^,,,_
best, Eliot


--
_,,,^..^,,,_
best, Eliot

startpcOrMethod.cs (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Sean P. DeNigris
Administrator
In reply to this post by Max Leske
Max Leske wrote
> You *need* an outer context.

This is the very point of my experimentation! Why? It wreaks havoc on naive
Fuel users when serialized blocks can't be materialized. In the case of
clean blocks, the outer context is irrelevant from the user perspective.
What I'm trying to figure out is where this requirement comes from and
whether it can be removed, at least for clean blocks.

This seems to be the raison d'être of FullBlockClosure. It's class comment:

    A FullBlockClosure is a closure that can be independent of any
outerContext if desired.  It
    has its own method (currently reusing the startpc inst var) and its own
receiver.
    outerContext can be either a MethodContext/Context or nil.

Unfortunately, I'm having trouble creating one to play with. It seems that
maybe the FullBlockClosure concept is a bit unfinished? I ask this both
because BlockClosure still exists in addition to FullBlockClosure (IIUC I
thought the Full one was a replacement) and because I found the following
posts which talk about future work e.g. for clean blocks:
- https://clementbera.wordpress.com/2016/06/27/fullblockclosure-design/
-
https://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/2016-September/124161.html
- (More about Sista) http://wiki.squeak.org/squeak/6589
- (general FullBlock... description) http://wiki.squeak.org/squeak/6610



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Sean P. DeNigris
Administrator
In reply to this post by Eliot Miranda-2
Eliot Miranda-2 wrote
> (FullBlockClosure receiver: nil outerContext: nil method: blockMethod
> copiedValues: nil) value: 1 value: 2

Cool! We're getting closer, but in Pharo8 FullBlockClosure DNU
#receiver:outerContext:method:copiedValues:

I tried to adapt it to Pharo's API, but the following crashes the VM:
blockMethod := [:a :b| a < b] method.
(FullBlockClosure outerContext: nil startpc: nil numArgs: 2 copiedValues:
nil)
        compiledBlock: blockMethod; value: 1 value: 2



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Eliot Miranda-2


> On May 1, 2020, at 11:21 AM, Sean P. DeNigris <[hidden email]> wrote:
>
> Eliot Miranda-2 wrote
>> (FullBlockClosure receiver: nil outerContext: nil method: blockMethod
>> copiedValues: nil) value: 1 value: 2
>
> Cool! We're getting closer, but in Pharo8 FullBlockClosure DNU
> #receiver:outerContext:method:copiedValues:
>
> I tried to adapt it to Pharo's API, but the following crashes the VM:
> blockMethod := [:a :b| a < b] method.
> (FullBlockClosure outerContext: nil startpc: nil numArgs: 2 copiedValues:
> nil)
>    compiledBlock: blockMethod; value: 1 value: 2


Works fine in Squeak trunk.  

>
>
> -----
> Cheers,
> Sean
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>

Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Eliot Miranda-2
In reply to this post by Sean P. DeNigris
Hi Sean,


> On May 1, 2020, at 11:21 AM, Sean P. DeNigris <[hidden email]> wrote:
>
> Eliot Miranda-2 wrote
>> (FullBlockClosure receiver: nil outerContext: nil method: blockMethod
>> copiedValues: nil) value: 1 value: 2
>
> Cool! We're getting closer, but in Pharo8 FullBlockClosure DNU
> #receiver:outerContext:method:copiedValues:
>
> I tried to adapt it to Pharo's API, but the following crashes the VM:
> blockMethod := [:a :b| a < b] method.
> (FullBlockClosure outerContext: nil startpc: nil numArgs: 2 copiedValues:
> nil)
>    compiledBlock: blockMethod; value: 1 value: 2

Does Pharo support the Sista bytecodeset yet?  If not, then no full blocks.

>
>
>
> -----
> Cheers,
> Sean
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>

Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Sean P. DeNigris
Administrator
Eliot Miranda-2 wrote
> Does Pharo support the Sista bytecodeset yet?  If not, then no full
> blocks.

I guess I will have to be patient then because I see:
- TODO: "[Pharo9] Propose a PR for Fuel to support Sista"[1]
- WIP (reported 2019-12-16): "Detecting all the requirements to use the
Sista bytecode in the
default image. This modification requires some changes in Fuel. There
is a need for more changes in the debugger if we want to integrate
full block closures." [2]


1. http://forum.world.st/Mm10s-2020-03-16-tp5113400p5113415.html
2. http://forum.world.st/Mm10s-2019-12-16-tp5108221p5108298.html




-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: FullBlockClosure - How to create one...

Max Leske
In reply to this post by Eliot Miranda-2

Oh, interesting! I did not know that, thanks Eliot.




On 1 May 2020, at 18:49, Eliot Miranda wrote:

Hi Max,

On Thu, Apr 30, 2020 at 11:51 PM Max Leske <[hidden email]> wrote:

Hi Sean,

You need an outer context. See Context>>cleanCopy, which Fuel uses to serialize blocks.


One does *not* need an outer context.  An outer context of nil should be fine, provided that the block never attempts an up-arrow return.


| blockMethod |
blockMethod := [:a :b| a < b] method.
(FullBlockClosure receiver: nil outerContext: nil method: blockMethod copiedValues: nil) value: 1 value: 2

So one needs to use FullBlockClosure class>>receiver:outerContext:method:copiedValues: and one can supply nil for the outerContext provided that the block does not do an up-arrow return.
 

Cheers,
Max

On 1 May 2020, at 3:23, Sean P. DeNigris wrote:

What am I not understanding about FullBlockClosure?

I have a clean block that I'd like to turn into a FullBlockClosure so that I
can serialize it without dragging (unneeded methods) into my object graph.
However, documentation and in-image example usages seem severely limited.
Here was one experiment that ended with a primitive failure. It seems like a
receiver is needed and it can't be a dummy value (see commented "receiver:
1"). But what would the receiver be in the absence of an outer context?!

aBlockClosure := [ :a :b | 1 + a + b ].
fbc := (FullBlockClosure
outerContext: nil
startpc: aBlockClosure startpc
numArgs: aBlockClosure argumentCount
copiedValues: Array new) "receiver: 1; yourself".

fbc value: 2 value: 3. "PrimitiveFailed: primitive #value:value: in
FullBlockClosure failed"



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html



--
_,,,^..^,,,_
best, Eliot

signature.asc (849 bytes) Download Attachment