Copy vs Clone

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

Re: [SOLVED] Re: Copy vs Clone

Phil B
On Fri, 2015-05-15 at 10:19 -0300, Juan Vuletich wrote:

> Well, I took a look at the image you sent me (btw, neat stuff!). My
> point is that usually we don't really need closures:
>
> a) For control flow, all we need is code blocks. The compiler knows
> that, and optimizes most cases, avoiding the creation of a real closure.
> These are never serialized by themselves (maybe the complete method is
> serialized).
>
> b) Real closures. Used for new control structures, that the compiler
> doesn't know about. Also used for functional programming and
> continuations. Not really needed most of the time: Squeak existed
> without closures for over 10 years. These are hard and expensive to
> serialize.
>
> c) "context free lambdas" a.k.a. "clean closures". State is stored in
> objects. All state is passed to the block as arguments. These are easy
> and cheap to serialize. A typical example for these is a sort block in a
> SortedCollection.
>
> The code you sent me uses b). It stores state in variables in the
> context of the closure. But this is not really needed. I could convert
> your code to c). See the attach. What I did is to take that state and
> store it in an instance variable. There was yet another variable that
> could simply be a temporal inside the block. Then, the default
> implementation of Morph>>copy worked without problems.
>
> I think it would be good to have different syntax for "clean" or
> "context free" blocks. And encourage their use above real closures,
> whenever possible.
>

If it's handled at compile-time, what's the downside to letting the
compiler sort it out... is there not enough context for it to do so
reliably?  If there isn't, would a pragma do the job? (i.e. default to
shallow unless the compiler determines that deep is needed, and a pragma
could be one way of telling the compiler deep is needed)

> Cheers,
> Juan Vuletich

Thanks,
Phil


_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: Copy vs Clone

Juan Vuletich-4
In reply to this post by KenDickey
On 5/15/2015 12:03 PM, Ken.Dickey wrote:
> On Fri, 15 May 2015 10:33:46 -0300
> Juan Vuletich<[hidden email]>  wrote:
> ...
>> So, I recommend (as general advice) to use clean closures if at all
>> possible ...
>> I hope all this makes sense for you.
> Very good sense, but for #clean I would substitute the term #trivial, which makes more sense in this context.
>
> After all, closures are called closures because they "close over their environment".

Right. Just did a commit, and amongst several things, I changed #isClean
to #isTrivialClosure .

> Trivial closures are more akin to Traits.  We could split closures, including nested closures, into trivial code blocks and their associated environment vectors.
>
> The basics are covered in:
>    http://www.iro.umontreal.ca/~feeley/papers/FeeleyLapalmeCL92.pdf
>

Thanks for the read. Enhancing support for Closures, and why not?
integrating them with Traits are interesting trails to walk.

Cheers,
Juan Vuletich

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: [SOLVED] Re: Copy vs Clone

Juan Vuletich-4
In reply to this post by KenDickey
Hi Ken,

On 5/15/2015 8:14 PM, Ken.Dickey wrote:

> Hi Juan,
>
> Thanks for your time and the example code.
>
> As a long time user of Scheme, Lisp, Dylan, and other languages we have some differences of opinion.
>
> Personal reflections follow.
>
>
>> Squeak existed without closures for over 10 years.
> Yes. Squeak ignored the Smalltalk standard.
>
> This is a polarizing issue for some people.  I refused to use Squeak until closures were supported.

I didn't know they were that important for you. Fortunately, and thanks
to Eliot, we have closures in Cuis. Not having you around would be a big
loss.

>>>> Sometimes I think it would be nicer if all closures were clean. I'm not
>>>> really sure what would we lose with such restriction...
> Looking out from the other side of the mirror, Schemers had the saying "Objects are a poor man's Closures".  I have implemented quite a number of object systems in Scheme in a variety of styles.
>
> Closures and Objects are in a sense duals.  One can implement Scheme in Smalltalk or Smalltalk in Scheme. I did an implementation of R5RS Scheme in Squeak which passed the test suite.  So call me linguistically promiscuous.

Thanks. This made me read a bit about this duality. It was enlightening.

Wow! is that Scheme available somewhere? Please port it to Cuis!


>> Well, I took a look at the image you sent me (btw, neat stuff!). My
>> point is that usually we don't really need closures:
> Right.  I can flatten environments by hand instead of letting the compiler do it.  Call me lazy.
>
> However, one can serialize closures and might be called lazy if that bit is left undone.  ;^)

Hehehehe. You might be right. But it is also true that if you just
serialize any closure, without checking the consequences, en many cases
you could end serializing the whole Smalltalk image. I guess it was one
of the Fuel papers that talked a bit about this.

> Given the seemingly continuous changes in compilation strategies with Squeak/Pharo, I would not choose to do this in neglect of more fun things to do.
>
> The problem in this case is not that copy serializes Morphs, but that in the absence of network export it should NOT be serializing closures.
>
> That would be killing flies with a sledge hammer.

I am _really_ not sure about this. Maybe one morph holds a closure that
has state stating if this morph is stepping or not. Then you duplicate
your morph, and in #postCopy you are careful enough to avoid sharing
state, so that the original and the copy are separate, independent
objects. But the original and the copy will always share the closure,
and the associated state. With our current inspectors, browsers and
debuggers, "good luck debugging that sh*t". (Apologies for the language.
It is a joke to my good friend Andrés, and I can't help it).


>> The code you sent me uses b). It stores state in variables in the
>> context of the closure. But this is not really needed. I could convert
>> your code to c). See the attach.
> Again.  Thank you very much for taking the time and trouble to do this.  It was very thoughtful of you.

My pleasure. Many times "a picture is worth a thousand words".

>> What I did is to take that state and
>> store it in an instance variable. There was yet another variable that
>> could simply be a temporal inside the block.
> Again, I am lazy.  I am used to letting the compiler do the work of optimizing environments and using closures to prototype until I figure out the typical usage pattern(s).
>
>
>> I think it would be good to have different syntax for "clean" or
>> "context free" blocks. And encourage their use above real closures,
>> whenever possible.
> I am just not used to flattening and managing environments by hand, used real closures for too many years.  As you saw from
> http://www.iro.umontreal.ca/~feeley/papers/FeeleyLapalmeCL92.pdf
> I know how to play compiler, and I have done enough runtime work (wrote a GC in 88k assembler among other things) to know the basics.
>
> I guess I may have to be less lazy.
>
> What a shame!   ;^)
>
> Thanks again,
> -KenD

:) I will not judge your style or taste! I'm just a bit sorry that Cuis'
support for Closures might not be good enough.

Cheers,
Juan Vuletich

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: [SOLVED] Re: Copy vs Clone

Juan Vuletich-4
In reply to this post by Phil B
On 5/15/2015 9:12 PM, Phil (list) wrote:

> On Fri, 2015-05-15 at 10:19 -0300, Juan Vuletich wrote:
>> Well, I took a look at the image you sent me (btw, neat stuff!). My
>> point is that usually we don't really need closures:
>>
>> a) For control flow, all we need is code blocks. The compiler knows
>> that, and optimizes most cases, avoiding the creation of a real closure.
>> These are never serialized by themselves (maybe the complete method is
>> serialized).
>>
>> b) Real closures. Used for new control structures, that the compiler
>> doesn't know about. Also used for functional programming and
>> continuations. Not really needed most of the time: Squeak existed
>> without closures for over 10 years. These are hard and expensive to
>> serialize.
>>
>> c) "context free lambdas" a.k.a. "clean closures". State is stored in
>> objects. All state is passed to the block as arguments. These are easy
>> and cheap to serialize. A typical example for these is a sort block in a
>> SortedCollection.
>>
>> The code you sent me uses b). It stores state in variables in the
>> context of the closure. But this is not really needed. I could convert
>> your code to c). See the attach. What I did is to take that state and
>> store it in an instance variable. There was yet another variable that
>> could simply be a temporal inside the block. Then, the default
>> implementation of Morph>>copy worked without problems.
>>
>> I think it would be good to have different syntax for "clean" or
>> "context free" blocks. And encourage their use above real closures,
>> whenever possible.
>>
> If it's handled at compile-time, what's the downside to letting the
> compiler sort it out... is there not enough context for it to do so
> reliably?  If there isn't, would a pragma do the job? (i.e. default to
> shallow unless the compiler determines that deep is needed, and a pragma
> could be one way of telling the compiler deep is needed)

What Ken said is that the compiler can build closures for us, closing
over the appropriate scope.

You suggest having hints for the serializer to be able to say what to
duplicate and what not. This is an interesting idea. Right now, the
things that are not duplicated are those we are sure we'll be able to
find when deserializing. What you suggest means that serializing for
local copying might mean sharing additional state. So serializing for
copying for local use would be different from serializing for
persistence, or for pasting into another Cuis image (local, networked,
whatever).

Cheers,
Juan Vuletich

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: [SOLVED] Re: Copy vs Clone

Phil B
On Sat, 2015-05-16 at 18:05 -0300, Juan Vuletich wrote:

> On 5/15/2015 9:12 PM, Phil (list) wrote:
> > On Fri, 2015-05-15 at 10:19 -0300, Juan Vuletich wrote:
> >> Well, I took a look at the image you sent me (btw, neat stuff!). My
> >> point is that usually we don't really need closures:
> >>
> >> a) For control flow, all we need is code blocks. The compiler knows
> >> that, and optimizes most cases, avoiding the creation of a real closure.
> >> These are never serialized by themselves (maybe the complete method is
> >> serialized).
> >>
> >> b) Real closures. Used for new control structures, that the compiler
> >> doesn't know about. Also used for functional programming and
> >> continuations. Not really needed most of the time: Squeak existed
> >> without closures for over 10 years. These are hard and expensive to
> >> serialize.
> >>
> >> c) "context free lambdas" a.k.a. "clean closures". State is stored in
> >> objects. All state is passed to the block as arguments. These are easy
> >> and cheap to serialize. A typical example for these is a sort block in a
> >> SortedCollection.
> >>
> >> The code you sent me uses b). It stores state in variables in the
> >> context of the closure. But this is not really needed. I could convert
> >> your code to c). See the attach. What I did is to take that state and
> >> store it in an instance variable. There was yet another variable that
> >> could simply be a temporal inside the block. Then, the default
> >> implementation of Morph>>copy worked without problems.
> >>
> >> I think it would be good to have different syntax for "clean" or
> >> "context free" blocks. And encourage their use above real closures,
> >> whenever possible.
> >>
> > If it's handled at compile-time, what's the downside to letting the
> > compiler sort it out... is there not enough context for it to do so
> > reliably?  If there isn't, would a pragma do the job? (i.e. default to
> > shallow unless the compiler determines that deep is needed, and a pragma
> > could be one way of telling the compiler deep is needed)
>
> What Ken said is that the compiler can build closures for us, closing
> over the appropriate scope.
>
> You suggest having hints for the serializer to be able to say what to
> duplicate and what not. This is an interesting idea. Right now, the
> things that are not duplicated are those we are sure we'll be able to
> find when deserializing. What you suggest means that serializing for
> local copying might mean sharing additional state. So serializing for
> copying for local use would be different from serializing for
> persistence, or for pasting into another Cuis image (local, networked,
> whatever).
>

You answered my question:  the compiler is already doing it
automatically.  I think I was getting caught up in a tangent of the
overall conversation when you were talking about the cost (overhead) of
closures.  It wasn't clear to me if the compiler was handling the scope
of the closure automatically or not so I was suggesting a pragma... but
it sounds like it is handling this, so my point is moot.

> Cheers,
> Juan Vuletich



_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: [SOLVED] Re: Copy vs Clone

Juan Vuletich-4
On Sat, May 16, 2015 6:17 pm, Phil (list) wrote:

> On Sat, 2015-05-16 at 18:05 -0300, Juan Vuletich wrote:
>
>> On 5/15/2015 9:12 PM, Phil (list) wrote:
>>
>>> On Fri, 2015-05-15 at 10:19 -0300, Juan Vuletich wrote:
>>>
>>>> Well, I took a look at the image you sent me (btw, neat stuff!). My
>>>>  point is that usually we don't really need closures:
>>>>
>>>> a) For control flow, all we need is code blocks. The compiler knows
>>>>  that, and optimizes most cases, avoiding the creation of a real
>>>> closure. These are never serialized by themselves (maybe the
>>>> complete method is serialized).
>>>>
>>>> b) Real closures. Used for new control structures, that the
>>>> compiler doesn't know about. Also used for functional programming
>>>> and continuations. Not really needed most of the time: Squeak
>>>> existed without closures for over 10 years. These are hard and
>>>> expensive to serialize.
>>>>
>>>> c) "context free lambdas" a.k.a. "clean closures". State is stored
>>>> in objects. All state is passed to the block as arguments. These are
>>>> easy and cheap to serialize. A typical example for these is a sort
>>>> block in a SortedCollection.
>>>>
>>>>
>>>> The code you sent me uses b). It stores state in variables in the
>>>> context of the closure. But this is not really needed. I could
>>>> convert your code to c). See the attach. What I did is to take that
>>>> state and store it in an instance variable. There was yet another
>>>> variable that could simply be a temporal inside the block. Then, the
>>>> default implementation of Morph>>copy worked without problems.
>>>>
>>>> I think it would be good to have different syntax for "clean" or
>>>> "context free" blocks. And encourage their use above real closures,
>>>> whenever possible.
>>>>
>>> If it's handled at compile-time, what's the downside to letting the
>>> compiler sort it out... is there not enough context for it to do so
>>> reliably?  If there isn't, would a pragma do the job? (i.e. default
>>> to shallow unless the compiler determines that deep is needed, and a
>>> pragma could be one way of telling the compiler deep is needed)
>>
>> What Ken said is that the compiler can build closures for us, closing
>> over the appropriate scope.
>>
>> You suggest having hints for the serializer to be able to say what to
>> duplicate and what not. This is an interesting idea. Right now, the
>> things that are not duplicated are those we are sure we'll be able to
>> find when deserializing. What you suggest means that serializing for
>> local copying might mean sharing additional state. So serializing for
>> copying for local use would be different from serializing for
>> persistence, or for pasting into another Cuis image (local, networked,
>> whatever).
>>
>
> You answered my question:  the compiler is already doing it
> automatically.  I think I was getting caught up in a tangent of the overall
> conversation when you were talking about the cost (overhead) of closures.
> It wasn't clear to me if the compiler was handling the scope
> of the closure automatically or not so I was suggesting a pragma... but it
> sounds like it is handling this, so my point is moot.
>

Ok. This is all thanks to Eliot, who gave Closures to the Squeak world. He
did both the VM and Compiler work, I only brought it to Cuis.

Cheers,
Juan Vuletich


_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
Reply | Threaded
Open this post in threaded view
|

Re: Copy vs Clone

KenDickey
In reply to this post by Juan Vuletich-4
On Sat, 16 May 2015 17:44:04 -0300
Juan Vuletich <[hidden email]> wrote:

...
> Right. Just did a commit, and amongst several things, I changed #isClean
> to #isTrivialClosure .

Juan, thanks for that.  I find it incredibly thoughtful of you.

--
-KenD

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
-KenD
Reply | Threaded
Open this post in threaded view
|

Re: [SOLVED] Re: Copy vs Clone

KenDickey
In reply to this post by Juan Vuletich-4
On Sat, 16 May 2015 18:01:23 -0300
Juan Vuletich <[hidden email]> wrote:

> > Closures and Objects are in a sense duals.  One can implement Scheme in Smalltalk or Smalltalk in Scheme. I did an implementation of R5RS Scheme in Squeak which passed the test suite.  So call me linguistically promiscuous.

> Thanks. This made me read a bit about this duality. It was enlightening.
>
> Wow! is that Scheme available somewhere? Please port it to Cuis!

Juan, you may be the only person in the world interested in this -- especially after I explain the details.

I had intended to compile to bytecodes, but the Squeak compiler was in its perennial state of flux, so I did a translator.

I wrote a very small kernel for Scheme runtime support in Smalltalk, wrote a file based translator from Scheme->SqueakSmalltalk in Scheme.  This included a full R5RS Scheme reader in Scheme.

Using a Scheme system, I ran the Scheme translator code to translated the translator into Smalltalk.  The resulting translator, running in Smalltalk, then could translate itself.

I used the translated translator to translate the R5RS test suite into Smalltalk.  The entire test suite passed except for two small edge cases.  Note that the passing tests included Call/CC.

If you are seriously interested in the above, it is a good time ad I am moving to a smaller house and giving or throwing away most of my old computing texts, papers, proceedings, computers, and back-up disks.  I will need to grovel through a pile of backups to find the code.

The Scheme->Smalltalk translator generated Squeak .st code files, which probably need some tweaks for Cuis, but I could probably get things working again with a small bit of work.

Not being integrated into the tool chain makes the translator a bit of an academic exercise.  If someone were to look at Pharo's RIng model and newer compiler -- the compiler is always in a state of flux -- it might be a starting point for bytecode generaton and toolset integration.  But I fear that Scheme is another dying language these days.  Not sure there would be enough interest to be worthwhile.

Anyway, let me know if I should hunt for the code.

--
-KenD

_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
-KenD
Reply | Threaded
Open this post in threaded view
|

Re: [SOLVED] Re: Copy vs Clone

Juan Vuletich-4
Hi Ken,

On 5/17/2015 11:22 AM, Ken.Dickey wrote:

> On Sat, 16 May 2015 18:01:23 -0300
> Juan Vuletich<[hidden email]>  wrote:
>
>>> Closures and Objects are in a sense duals.  One can implement Scheme in Smalltalk or Smalltalk in Scheme. I did an implementation of R5RS Scheme in Squeak which passed the test suite.  So call me linguistically promiscuous.
>> Thanks. This made me read a bit about this duality. It was enlightening.
>>
>> Wow! is that Scheme available somewhere? Please port it to Cuis!
> Juan, you may be the only person in the world interested in this -- especially after I explain the details.
>
> I had intended to compile to bytecodes, but the Squeak compiler was in its perennial state of flux, so I did a translator.
>
> I wrote a very small kernel for Scheme runtime support in Smalltalk, wrote a file based translator from Scheme->SqueakSmalltalk in Scheme.  This included a full R5RS Scheme reader in Scheme.
>
> Using a Scheme system, I ran the Scheme translator code to translated the translator into Smalltalk.  The resulting translator, running in Smalltalk, then could translate itself.
>
> I used the translated translator to translate the R5RS test suite into Smalltalk.  The entire test suite passed except for two small edge cases.  Note that the passing tests included Call/CC.

I'm surprised you haven't published this before. It is seriously cool.

> If you are seriously interested in the above, it is a good time ad I am moving to a smaller house and giving or throwing away most of my old computing texts, papers, proceedings, computers, and back-up disks.  I will need to grovel through a pile of backups to find the code.

If I lived closer to your place, I'd offer to help sorting your old
stuff in exchange for a couple of interesting things I'm sure I'd find :)

In any case, as usual, I think it would be good to rescue and publish
valuable stuff you created. I wasn't interested in learning Scheme, but
this is tempting. If you'd like to see your creation have a chance of
going on, I'd help with the port.

> The Scheme->Smalltalk translator generated Squeak .st code files, which probably need some tweaks for Cuis, but I could probably get things working again with a small bit of work.
>
> Not being integrated into the tool chain makes the translator a bit of an academic exercise.  If someone were to look at Pharo's RIng model and newer compiler -- the compiler is always in a state of flux -- it might be a starting point for bytecode generaton and toolset integration.  But I fear that Scheme is another dying language these days.  Not sure there would be enough interest to be worthwhile.
>
> Anyway, let me know if I should hunt for the code.

If I were teaching a course on Programming Paradigms, I'd love to use
this to show and compare OO and Functional in the same environment. But
I'm not. So many interesting things, and so little time! It's up to you.
If you do, I'll help with the port, and if ok with you, will host it at
the Cuis repo.

Thanks,
Juan Vuletich


_______________________________________________
Cuis mailing list
[hidden email]
http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
12