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
|

Copy vs Clone

KenDickey
I am seeing a strange behavior.

The simple way to see it is to make a child class of PartsBinMorph.  Call it, say, PartsBinTestMorph.

Add a method #PartsBinTestMorph>>
  aboutToGrab: aMorph

        ^aMorph clone "parent has aMorph copy"

WHen I obtain a PartsBinMorph from the new morph menu, then add, say, a ellipse morph, I get the expected behavior.  WHen I "drag the ellipse out", the hand gets a copy of the ellipse and the original ellipse remains where I can see it.

But doing the same thing in a PartsBinTestMorph, I appear to grab the ellipse.

Now it turns out that the original ellipse is still a submorph of the PartsBinTestMorph, but it's morphPosition seems to be set to some random value.

I tried saving the original morphPosition, doing the clone, then resetting the saved morphPosition, but this does not change anything.

Unfortunately, my copy of the blue book is saved in a box somewhere (I am moving), so I don't have a spec for #clone.

Interestingly, this happens both on the ARM and Intel Cog Stack VMs.

Can someone help me out to understand this?

Thanks much,
-KenD

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

Re: Copy vs Clone

Dan Norton
On 13 May 2015 at 15:41, Ken.Dickey wrote:

> I am seeing a strange behavior.
>
> The simple way to see it is to make a child class of PartsBinMorph.
> Call it, say, PartsBinTestMorph.
>
> Add a method #PartsBinTestMorph>>
>   aboutToGrab: aMorph
>
> ^aMorph clone "parent has aMorph copy"
>
> WHen I obtain a PartsBinMorph from the new morph menu, then add,
> say, a ellipse morph, I get the expected behavior.  WHen I "drag the
> ellipse out", the hand gets a copy of the ellipse and the original
> ellipse remains where I can see it.
>
> But doing the same thing in a PartsBinTestMorph, I appear to grab
> the ellipse.
>
> Now it turns out that the original ellipse is still a submorph of
> the PartsBinTestMorph, but it's morphPosition seems to be set to
> some random value.
>
> I tried saving the original morphPosition, doing the clone, then
> resetting the saved morphPosition, but this does not change
> anything.
>
> Unfortunately, my copy of the blue book is saved in a box somewhere
> (I am moving), so I don't have a spec for #clone.
>

Searching my copy of BlueBook.pdf for clone comes up empty.

 - Dan

_______________________________________________
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

David T. Lewis
On Wed, May 13, 2015 at 09:19:56PM -0400, Dan Norton wrote:

> On 13 May 2015 at 15:41, Ken.Dickey wrote:
>
> > I am seeing a strange behavior.
> >
> > The simple way to see it is to make a child class of PartsBinMorph.
> > Call it, say, PartsBinTestMorph.
> >
> > Add a method #PartsBinTestMorph>>
> >   aboutToGrab: aMorph
> >
> > ^aMorph clone "parent has aMorph copy"
> >
> > WHen I obtain a PartsBinMorph from the new morph menu, then add,
> > say, a ellipse morph, I get the expected behavior.  WHen I "drag the
> > ellipse out", the hand gets a copy of the ellipse and the original
> > ellipse remains where I can see it.
> >
> > But doing the same thing in a PartsBinTestMorph, I appear to grab
> > the ellipse.
> >
> > Now it turns out that the original ellipse is still a submorph of
> > the PartsBinTestMorph, but it's morphPosition seems to be set to
> > some random value.
> >
> > I tried saving the original morphPosition, doing the clone, then
> > resetting the saved morphPosition, but this does not change
> > anything.
> >
> > Unfortunately, my copy of the blue book is saved in a box somewhere
> > (I am moving), so I don't have a spec for #clone.
> >
>
> Searching my copy of BlueBook.pdf for clone comes up empty.

Checking the wayback machine at try.squeak.org, I tried loading the
Squeak1.13u.image under SqueakJS. I do not see an Object>>clone, so
#clone probably did not exist when the blue book was written.

http://try.squeak.org/#url=http://freudenbergs.de/bert/squeakjs&files=[Squeak1.13u.image,Squeak1.13u.changes,SqueakV1.sources]&swapButtons=true

Dave
 

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

[SOLVED] Re: Copy vs Clone

KenDickey
In reply to this post by KenDickey
On Wed, 13 May 2015 15:41:00 -0700
"Ken.Dickey" <[hidden email]> wrote:

> ^aMorph clone "parent has aMorph copy"

Ah.  Figured it out.

When a Morph duplicated by clone or shallowCopy, the location (a MorphicTranslation) is shared, so when the hand moves, the location in the original Morph is set to the offset of the hand within the World PasteUpMorph.

The solution is to set the location in the clone/shallowCopy to a new MorphicTranslation.

--
-KenD

PS: I did get and search the online copy of the blue book (with negative result).  Thanks to all!

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

Re: Copy vs Clone

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

On 5/13/2015 7:41 PM, Ken.Dickey wrote:

> I am seeing a strange behavior.
>
> The simple way to see it is to make a child class of PartsBinMorph.  Call it, say, PartsBinTestMorph.
>
> Add a method #PartsBinTestMorph>>
>    aboutToGrab: aMorph
>
> ^aMorph clone "parent has aMorph copy"
>
> WHen I obtain a PartsBinMorph from the new morph menu, then add, say, a ellipse morph, I get the expected behavior.  WHen I "drag the ellipse out", the hand gets a copy of the ellipse and the original ellipse remains where I can see it.
>
> But doing the same thing in a PartsBinTestMorph, I appear to grab the ellipse.
>
> Now it turns out that the original ellipse is still a submorph of the PartsBinTestMorph, but it's morphPosition seems to be set to some random value.
>
> I tried saving the original morphPosition, doing the clone, then resetting the saved morphPosition, but this does not change anything.
>
> Unfortunately, my copy of the blue book is saved in a box somewhere (I am moving), so I don't have a spec for #clone.
>
> Interestingly, this happens both on the ARM and Intel Cog Stack VMs.
>
> Can someone help me out to understand this?
>
> Thanks much,
> -KenD

Morphs should be copied using #copy.

#clone is almost the same as #shallowCopy (except if the primitive
fails, in the implementation in Object). All the implementors and
senders come from Squeak. I never questioned them (yet). In my copy of
the purple book, on p.97 "Copying Objects" it only mentions #copy,
#shallowCopy and #deepCopy. I removed #deepCopy from Cuis, but we also
have #veryDeepCopy.

I found this:
http://wiki.squeak.org/squeak/2088
http://squeak-dev.squeakfoundation.narkive.com/nNy0QaLf/semantics-of-clone

None of this sounds really relevant to Cuis to me... I think it could be
good to replace the calls to #clone with calls to #copy (by default) or
#shallowCopy (if needed), and just remove #clone...

Does anybody know why #clone was added to Squeak?

Thanks,
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
On 5/13/2015 11:05 PM, Ken.Dickey wrote:

> On Wed, 13 May 2015 15:41:00 -0700
> "Ken.Dickey"<[hidden email]>  wrote:
>
>> ^aMorph clone "parent has aMorph copy"
> Ah.  Figured it out.
>
> When a Morph duplicated by clone or shallowCopy, the location (a MorphicTranslation) is shared, so when the hand moves, the location in the original Morph is set to the offset of the hand within the World PasteUpMorph.
>
> The solution is to set the location in the clone/shallowCopy to a new MorphicTranslation.
>

Well, but why do #clone or #shallowCopy? Isn't #copy ok?

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

David T. Lewis
In reply to this post by Juan Vuletich-4
On Wed, May 13, 2015 at 11:24:09PM -0300, Juan Vuletich wrote:
>
> Does anybody know why #clone was added to Squeak?
>

I do not know the historical background, but Object>>clone invokes #primitiveClone
in the VM. This is an efficient shallow copy, in which the object header and data
fields are copied to a newly allocated object, and the object hash and GC bits
are updated in the new copy.

I think that this must have been done for efficiency, to provide the fastest
possible means of shallow copying an object. The methods in the VM and in Object
are both old enough that they had no author initials, so this was a very early
optimization in Squeak.

Dave
 

_______________________________________________
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

KenDickey
In reply to this post by Juan Vuletich-4
On Wed, 13 May 2015 23:25:37 -0300
Juan Vuletich <[hidden email]> wrote:

>
> Well, but why do #clone or #shallowCopy? Isn't #copy ok?

Not when using closures with state.
  Error: can only serialize clean closures

Morph>>copy serializes, but does not have to.

We can make all closures serializable (e.g. KaliScheme does this to export closures over the network).  This is clean but it is still a bit of work.

The original Object>>copy would work where I implement postCopy to set location to a new MorphicTranslation.

Object>>copy
    ^self shallowCopy postCopy


--
-KenD

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

Re: Copy vs Clone

Juan Vuletich-4
In reply to this post by David T. Lewis
On 5/14/2015 12:22 AM, David T. Lewis wrote:

> On Wed, May 13, 2015 at 11:24:09PM -0300, Juan Vuletich wrote:
>> Does anybody know why #clone was added to Squeak?
>>
> I do not know the historical background, but Object>>clone invokes #primitiveClone
> in the VM. This is an efficient shallow copy, in which the object header and data
> fields are copied to a newly allocated object, and the object hash and GC bits
> are updated in the new copy.
>
> I think that this must have been done for efficiency, to provide the fastest
> possible means of shallow copying an object. The methods in the VM and in Object
> are both old enough that they had no author initials, so this was a very early
> optimization in Squeak.
>
> Dave

Thanks Dave.

I searched a bit more and found
http://lists.squeakfoundation.org/pipermail/vm-dev/2014-February/014683.html 
and the more detailed
http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html 
(by Levente).

After these references, I decided to remove #clone from Cuis. Most
senders were replaced by sends to #shallowCopy (it uses the same VM
primitive). But for several, calling #copy works the same, and #copy
sounds more natural to me. I also refactored several implementations of
#copy et al, in SequenceableCollection and AbstractSound hierarchies.
Will commit to github soon.

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/14/2015 1:16 AM, Ken.Dickey wrote:
> On Wed, 13 May 2015 23:25:37 -0300
> Juan Vuletich<[hidden email]>  wrote:
>
>> Well, but why do #clone or #shallowCopy? Isn't #copy ok?
> Not when using closures with state.
>    Error: can only serialize clean closures
>
> Morph>>copy serializes, but does not have to.
> We can make all closures serializable (e.g. KaliScheme does this to export closures over the network).  This is clean but it is still a bit of work.

Interesting! I wasn't aware of KaliScheme. I believe Fuel also does it.
The problem with this is that it is easy to clone the whole Smalltalk
image inadvertently.

> The original Object>>copy would work where I implement postCopy to set location to a new MorphicTranslation.
>
> Object>>copy
>      ^self shallowCopy postCopy

But the problem with this is that the original and the copy would share
that state embedded in the closure... They would also share submorphs, etc.

Can you help me reproduce the problem with the closure? I think the best
would be to make that closure a "clean" one, storing any needed state in
the morph (maybe as properties), and accessing it via messages to self...

Steps to reproduce, or a pre-built image (via private email) or any
other means would be ok.

Sometimes I think it would be nicer if all closures were clean. I'm not
really sure what would we lose with such restriction...

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

KenDickey
On Thu, 14 May 2015 11:03:29 -0300
Juan Vuletich <[hidden email]> wrote:


> > The original Object>>copy would work where I implement postCopy to set location to a new MorphicTranslation.
> >
> > Object>>copy
> >      ^self shallowCopy postCopy
>
> But the problem with this is that the original and the copy would share
> that state embedded in the closure... They would also share submorphs, etc.

In this case, that is the desired outcome.

> Can you help me reproduce the problem with the closure? I think the best
> would be to make that closure a "clean" one, storing any needed state in
> the morph (maybe as properties), and accessing it via messages to self...

Hmmm..  I'll have to send you the image.

I have things taken apart and a bunch of parts all over the floor..  I have yet to comstruct a clean change-set.

 
> Sometimes I think it would be nicer if all closures were clean. I'm not
> really sure what would we lose with such restriction...

I think you are tired.  You would lose _closures_!

--
-KenD

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

Re: Copy vs Clone

David T. Lewis
In reply to this post by Juan Vuletich-4
Forwarding to squeak-dev for consideration after the next release.

Object>>clone can be replaced by #shallowCopy. Perhaps it is time to
deprecate #clone.

Juan is removing it from Cuis, with reference to this summary by Levente:
http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html

Dave

On Thu, May 14, 2015 at 10:53:12AM -0300, Juan Vuletich wrote:

> On 5/14/2015 12:22 AM, David T. Lewis wrote:
> >On Wed, May 13, 2015 at 11:24:09PM -0300, Juan Vuletich wrote:
> >>Does anybody know why #clone was added to Squeak?
> >>
> >I do not know the historical background, but Object>>clone invokes #primitiveClone
> >in the VM. This is an efficient shallow copy, in which the object header and data
> >fields are copied to a newly allocated object, and the object hash and GC bits
> >are updated in the new copy.
> >
> >I think that this must have been done for efficiency, to provide the fastest
> >possible means of shallow copying an object. The methods in the VM and in Object
> >are both old enough that they had no author initials, so this was a very early
> >optimization in Squeak.
> >
> >Dave
>
> Thanks Dave.
>
> I searched a bit more and found
> http://lists.squeakfoundation.org/pipermail/vm-dev/2014-February/014683.html 
> and the more detailed
> http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html 
> (by Levente).
>
> After these references, I decided to remove #clone from Cuis. Most
> senders were replaced by sends to #shallowCopy (it uses the same VM
> primitive). But for several, calling #copy works the same, and #copy
> sounds more natural to me. I also refactored several implementations of
> #copy et al, in SequenceableCollection and AbstractSound hierarchies.
> Will commit to github soon.
>
> 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
I seem to recall an early Smalltalk paper (OOPSLA?) on "Creation Relations" which specifically manage share vs duplicate copy semantics.

I am most familiar with this from prototype based multimedia authoring environments.

In brief, there are cases where one wants to distinguish where ivar state is shared vs individual.

So I make a new, say automobile.  It gets its own (unshared) tires, doors, and engine but all cars manufactured by Honda share their manufacturer.

I believe this is the reason for Object's definition of #copy, which allows complete control of share/duplicate:

Object>>copy
        ^self shallowCopy postCopy

I am not proposing a system which manages "creation relations" here, just pointing out the need for awareness of the Share vs Duplicate aspect of Copy/Clone semantics.

Since I am working on adding drag-n-drop behaviors to individual morphs, my usages are more prototype like.  More Self-like.

Morph's #copy has very different semantics which basically disallows sharing:

Morph>>copy
        ^ Object unStream: (ReferenceStream streamedRepresentationOf: self)  

Hence some of my inital confusion with #copy.  Same name, different semantics.
 
--
-KenD

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

Re: Copy vs Clone

Hannes Hirzel
I have summarized this thread so far under issue 55

https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev/issues/55

NotesOnMorphic.md -- add note about #copy

Morphs should be copied using #copy.
 #clone should be deprecated.

Is this still the conclusion?

--Hannes

On 5/15/15, Ken.Dickey <[hidden email]> wrote:

> I seem to recall an early Smalltalk paper (OOPSLA?) on "Creation Relations"
> which specifically manage share vs duplicate copy semantics.
>
> I am most familiar with this from prototype based multimedia authoring
> environments.
>
> In brief, there are cases where one wants to distinguish where ivar state is
> shared vs individual.
>
> So I make a new, say automobile.  It gets its own (unshared) tires, doors,
> and engine but all cars manufactured by Honda share their manufacturer.
>
> I believe this is the reason for Object's definition of #copy, which allows
> complete control of share/duplicate:
>
> Object>>copy
> ^self shallowCopy postCopy
>
> I am not proposing a system which manages "creation relations" here, just
> pointing out the need for awareness of the Share vs Duplicate aspect of
> Copy/Clone semantics.
>
> Since I am working on adding drag-n-drop behaviors to individual morphs, my
> usages are more prototype like.  More Self-like.
>
> Morph's #copy has very different semantics which basically disallows
> sharing:
>
> Morph>>copy
> ^ Object unStream: (ReferenceStream streamedRepresentationOf: self)
>
> Hence some of my inital confusion with #copy.  Same name, different
> semantics.
>
> --
> -KenD
>
> _______________________________________________
> Cuis mailing list
> [hidden email]
> http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
>

_______________________________________________
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/14/2015 11:23 AM, Ken.Dickey wrote:

> On Thu, 14 May 2015 11:03:29 -0300
> Juan Vuletich<[hidden email]>  wrote:
>
>
>>> The original Object>>copy would work where I implement postCopy to set location to a new MorphicTranslation.
>>>
>>> Object>>copy
>>>       ^self shallowCopy postCopy
>> But the problem with this is that the original and the copy would share
>> that state embedded in the closure... They would also share submorphs, etc.
> In this case, that is the desired outcome.
Then, in this class, it is appropriate to have the same implamemtation
as in Object. Like, for example, SortedCollection.

>> Can you help me reproduce the problem with the closure? I think the best
>> would be to make that closure a "clean" one, storing any needed state in
>> the morph (maybe as properties), and accessing it via messages to self...
> Hmmm..  I'll have to send you the image.
>
> I have things taken apart and a bunch of parts all over the floor..  I have yet to comstruct a clean change-set.
>
>
>> Sometimes I think it would be nicer if all closures were clean. I'm not
>> really sure what would we lose with such restriction...
> I think you are tired.  You would lose _closures_!
>
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.

Cheers,
Juan Vuletich

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

forKen.st (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Copy vs Clone

Juan Vuletich-4
In reply to this post by David T. Lewis
Good!

Cheers,
Juan Vuletich

On 5/14/2015 9:23 PM, David T. Lewis wrote:

> Forwarding to squeak-dev for consideration after the next release.
>
> Object>>clone can be replaced by #shallowCopy. Perhaps it is time to
> deprecate #clone.
>
> Juan is removing it from Cuis, with reference to this summary by Levente:
> http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html
>
> Dave
>
> On Thu, May 14, 2015 at 10:53:12AM -0300, Juan Vuletich wrote:
>> On 5/14/2015 12:22 AM, David T. Lewis wrote:
>>> On Wed, May 13, 2015 at 11:24:09PM -0300, Juan Vuletich wrote:
>>>> Does anybody know why #clone was added to Squeak?
>>>>
>>> I do not know the historical background, but Object>>clone invokes #primitiveClone
>>> in the VM. This is an efficient shallow copy, in which the object header and data
>>> fields are copied to a newly allocated object, and the object hash and GC bits
>>> are updated in the new copy.
>>>
>>> I think that this must have been done for efficiency, to provide the fastest
>>> possible means of shallow copying an object. The methods in the VM and in Object
>>> are both old enough that they had no author initials, so this was a very early
>>> optimization in Squeak.
>>>
>>> Dave
>> Thanks Dave.
>>
>> I searched a bit more and found
>> http://lists.squeakfoundation.org/pipermail/vm-dev/2014-February/014683.html
>> and the more detailed
>> http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html
>> (by Levente).
>>
>> After these references, I decided to remove #clone from Cuis. Most
>> senders were replaced by sends to #shallowCopy (it uses the same VM
>> primitive). But for several, calling #copy works the same, and #copy
>> sounds more natural to me. I also refactored several implementations of
>> #copy et al, in SequenceableCollection and AbstractSound hierarchies.
>> Will commit to github soon.
>>
>> 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

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

On 5/15/2015 7:33 AM, Ken.Dickey wrote:

> I seem to recall an early Smalltalk paper (OOPSLA?) on "Creation Relations" which specifically manage share vs duplicate copy semantics.
>
> I am most familiar with this from prototype based multimedia authoring environments.
>
> In brief, there are cases where one wants to distinguish where ivar state is shared vs individual.
>
> So I make a new, say automobile.  It gets its own (unshared) tires, doors, and engine but all cars manufactured by Honda share their manufacturer.
>
> I believe this is the reason for Object's definition of #copy, which allows complete control of share/duplicate:
>
> Object>>copy
> ^self shallowCopy postCopy
>
> I am not proposing a system which manages "creation relations" here, just pointing out the need for awareness of the Share vs Duplicate aspect of Copy/Clone semantics.
>
> Since I am working on adding drag-n-drop behaviors to individual morphs, my usages are more prototype like.  More Self-like.
>
> Morph's #copy has very different semantics which basically disallows sharing:
>
> Morph>>copy
> ^ Object unStream: (ReferenceStream streamedRepresentationOf: self)
>
> Hence some of my inital confusion with #copy.  Same name, different semantics.
>

  Well, but Morph is the same as your automobile. Copying a morph
(usually) means copying submorphs. But not owner (otherwise, the whole
World gets copied). This is taken care at Morph >> storeDataOn: I know
this is rather hidden, code is not really clear, and maybe some
framework to handle "creation relations" would be in order.

The shallowCopy postCopy approach works only for objects that don't form
graphs. For these, the issues of duplications appears. The old
#veryDeepCopy from ST-80 was complicated, and it had problems. I claim:

1) appropriate semantics for copying is usually a matter for each object
to define. That's why it is ok to copy the #copy method from Object to
your morph if appropriate.

2) The problems of duplication, identity, etc, are the same for copy as
for serialization. That's why it is ok to use a serializer to copy graph
objects.

So, I recommend (as general advice) to use clean closures if at all
possible (as I said in the other thread), and to use the serializer to
copy objects that form graph structures (like morphs). But, as #copy
semantics is a responsibility for each object to provide, if this
general advice is not applicable, instead of calling #shallowCopy, or
creating new copy messages, I recommend implementing #copy appropriately
for each class.

I hope all this makes sense for you.

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

Juan Vuletich-4
In reply to this post by Hannes Hirzel
Hi Hannes,

I just did a few clarifications, that you might want to include in the
summary.

Thanks,
Juan Vuletich

On 5/15/2015 8:08 AM, H. Hirzel wrote:

> I have summarized this thread so far under issue 55
>
> https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev/issues/55
>
> NotesOnMorphic.md -- add note about #copy
>
> Morphs should be copied using #copy.
>   #clone should be deprecated.
>
> Is this still the conclusion?
>
> --Hannes
>
> On 5/15/15, Ken.Dickey<[hidden email]>  wrote:
>> I seem to recall an early Smalltalk paper (OOPSLA?) on "Creation Relations"
>> which specifically manage share vs duplicate copy semantics.
>>
>> I am most familiar with this from prototype based multimedia authoring
>> environments.
>>
>> In brief, there are cases where one wants to distinguish where ivar state is
>> shared vs individual.
>>
>> So I make a new, say automobile.  It gets its own (unshared) tires, doors,
>> and engine but all cars manufactured by Honda share their manufacturer.
>>
>> I believe this is the reason for Object's definition of #copy, which allows
>> complete control of share/duplicate:
>>
>> Object>>copy
>> ^self shallowCopy postCopy
>>
>> I am not proposing a system which manages "creation relations" here, just
>> pointing out the need for awareness of the Share vs Duplicate aspect of
>> Copy/Clone semantics.
>>
>> Since I am working on adding drag-n-drop behaviors to individual morphs, my
>> usages are more prototype like.  More Self-like.
>>
>> Morph's #copy has very different semantics which basically disallows
>> sharing:
>>
>> Morph>>copy
>> ^ Object unStream: (ReferenceStream streamedRepresentationOf: self)
>>
>> Hence some of my inital confusion with #copy.  Same name, different
>> semantics.
>>
>> --
>> -KenD
>>
>> _______________________________________________
>> Cuis mailing list
>> [hidden email]
>> http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
>>
> _______________________________________________
> Cuis mailing list
> [hidden email]
> http://jvuletich.org/mailman/listinfo/cuis_jvuletich.org
>


_______________________________________________
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 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".

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

--
-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
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.


> >> 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.


> 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.  ;^)

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.


> 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.

> 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

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