[squeak-dev] valueWithReceiver for BlockClosures?

Yoshiki Ohshima Yoshiki.Ohshima at acm.org
Tue Jan 22 00:38:48 UTC 2013


On Mon, Jan 21, 2013 at 4:27 PM, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
>
>
> On Mon, Jan 21, 2013 at 10:29 AM, Yoshiki Ohshima <Yoshiki.Ohshima at acm.org>
> wrote:
>>
>> I have a potential application of valueWithReceiver for BlockClosures
>> (not CompiledMethod) in my little project.  It'd start with something
>> like:
>>
>> k1 := Dictionary new.
>> k1 at: #foo put: 3.
>> k1 at: #bar put: 4.
>>
>> k2 := Dictionary new.
>> k2 at: #foo put: 6.
>> k2 at: #bar put: 8.
>>
>> and then a closure is created in the context of k1 (thus "self" in the
>> following is k1):
>>
>> self at: #block put: [(self at: #foo) + (self at: #bar)]
>>
>> Then later, I'd like to "steal" the block from k1 and evaluate it in
>> the context of k2:
>>
>> (k1 at: #block) valueWithReceiver: k2.
>>
>> to get 14 instead of 7.  (Otherwise, in my application, the "equal"
>> closure that only differ in their "self" would be created many, many
>> times.  So, I want to share them.)
>>
>> ....
>>
>> And Bert told me that I can just store "k2" into the outerContext's
>> receiver and it works.
>
>
> Phhh... yes, sort-of.  But the outerContext could be shared by other blocks.
> So safest is to copy the outerContext and change the receiver in the copy.
> But since you're doing this to save space and you really, really know what
> you're doing, do it Bert's way.
>
> But IMO it's far from safe for a base image facility, because
>
> a) one should really change the receiver along the static chain as the block
> may be nested within other blocks.
>
> b) one can't tell, without resort to slow allOwners-style code, if the
> outerContext is shared by other blocks.
>
> So this is a really hairy hack that isn't safe in general, but is really
> neat in the right context.
>
>
>>
>>  As long as there is no concurrent invocation,
>> it'd just work.  Do people see other potential problems?
>
>
> Apart form the above no.  But why not simply rewrite as
>
>     self at: #block put: [:scope| (scope at: #foo) + (scope at: #bar)]
>
> and later do
>
>     (k1 at: #block) value: k1
>
> ?

I thought of it and I thought I could not do it (this is a language
that is compiled to Squeak, and I could not think a good compilation
scheme).  But now, with your insistence, I think it is really easy,
actually^^;

Thanks!

--
-- Yoshiki


More information about the Squeak-dev mailing list