<p>A reference or level-0 copy is the same object as the original, only accessed differently.</p>
<p>A level-1 shallow copy is a new object, with every member a reference to the member under the same name in the original object.</p>
<p>A level-∞ deep copy is a new object, with every member a level-∞ deep copy of the member under the same name in the original object.</p>
<p>But the more common implementation is to decide whether to copy or reference according to the type. For example, to copy primitives but not objects, or to copy non-reference members but not referenced objects.</p>
<p>In my experience of programming, it is very rare to need to copy a specific object in multiple different ways (not counting level-0). But the needed way is also quite unpredictable. The built-in copy functionality is usually based on arbitrary decisions and couldn't satisfy all the need.</p>
<p>Copying non-references, or just marking some member to be copied using a special directive, makes the best sense, but may not satisfy all the need if it was in a library having multiple different uses. So it may make sense, to have directives for behaviors in multiple different ways of copy. But I feel this feature (supporting more options than copy and non-copy) might well be completely useless, as one single way of copy is usually needed in a program. So I want to know if something is already explored in this direction in some languages.</p>

<object-oriented><data-structures>
Are there languages having multiple level fine control over deep and shallow copy?
CC BY-SA 4.0
2024-07-24T04:32:28.313Z
Not an answer, but be careful with thoughts along the line of "as [only] one single way of copy is usually needed in a program". Programs rarely are logically atomic, but rather consist of multiple libraries or at least areas of concern. You can still trivially use just one copy style even though you support multiple, but the opposite requires a lot of work or may even be infeasible.
MisterMiyagi
CC BY-SA 4.0
2024-07-24T05:19:52.043Z
This whole area is a mess. The documentation for Microsoft's early attempt to solve this problem indicates how we failed: "The ICloneable interface simply requires that your implementation of the Clone() method return a copy of the current object instance. It does not specify whether the cloning operation performs a deep copy, a shallow copy, or something in between. ... Because callers of Clone() cannot depend on the method performing a predictable cloning operation, **we recommend that ICloneable not be implemented in public APIs**."
Eric Lippert
CC BY-SA 4.0
2024-07-24T05:22:44.567Z
The problems arise from the fundamental question: *why* does the user wish to clone an object in the first place? Typically because they wish to both mutate and *not* mutate an object, and solve this contradiction by mutating a clone. But if you're in that position, maybe the problem would be better solved by an immutable persistent object, and then there is no need to clone.
Eric Lippert
CC BY-SA 4.0
2024-07-25T04:26:52.010Z
Are you looking for "real" instances in languages, or research? Possibly relevant is the ["sheep cloning" described here by Li](https://palez.github.io/papers/Final_verison.pdf) with Mojo-jojo, which uses ownership types to determine the representation to clone. Multiple approaches were explored in his PhD thesis and I'm not sure that there was ever a winner — it turns out to be a pretty tricky question.
Michael Homer
CC BY-SA 4.0
2024-07-25T05:51:02.670Z
@MichaelHomer Researches are also helpful. But I don't know how to edit the question. It appears I need to know more to even understand what the real problem is.
user23013
CC BY-SA 4.0
2024-07-25T15:17:23.517Z
@MichaelHomer It's a bit too technical for me, and too long. As I understand, sheep cloning seems referring to something similar to what I thought making the best sense in my question, but with ownership and more precise about the details. But it doesn't seem to provide directives to control multiple ways of copy. The chapter about Mojo-jojo doesn't seem to mention sheep cloning or any cloning at all. Or did I miss something?
user23013
CC BY-SA 4.0
2024-07-25T15:33:32.383Z
@EricLippert After some thinking, I believe persistent data structures are effectively just deep copied objects in a duck test, only improved by a better algorithm. It actually passes the problem to persistent data structures and makes the later a bigger mess: Every operation is a clone function. They all should consider whether to keep references in the data structure as is, or to automatically make referenced objects also persistent, or the most likely, to make arbitrary decisions and make the user learn.
user23013
CC BY-SA 4.0
2024-07-25T22:48:01.473Z
The [idea behind sheep cloning](https://courses.cs.washington.edu/courses/cse590p/00wi/dynamic-alias-protection.pdf) is essentially that the language has you mark some fields as pointing at objects "owned" by the object, and so part of its representation (a typical ownership system); there is a clone operation that makes copies of all owned references and aliases others, a mixed *sh*allow/d*eep* clone. Each kind of object could have different cloning, but only one sort of clone; is this what you're looking for, or is the question about exposing different kinds of cloning at the use site?
Michael Homer
CC BY-SA 4.0
2024-07-25T22:56:37.300Z
What I'm interested in is, if it has sheepclone1() and sheepclone2(), and something like owned1 and owned2 to make them work differently, decide whether it would be ever useful (and what languages have done it). Probably not the best question, but this was what it has asked as it currently stands.
user23013
CC BY-SA 4.0
2024-07-25T23:06:11.503Z
(Now I have some conflicting ideas. I think the ideal solution might be without multiple cloning methods, as it looks stupid and requires more arbitrary decisions. But if Eric Lippert's comment means something, it probably would depend on some intermediate solutions requiring multiple methods.)
user23013
CC BY-SA 4.0
2024-07-26T10:48:10.827Z
A difficult use case: the resulting union type of [How to make logical operators that return operands consistent in a statically typed language?](https://langdev.stackexchange.com/q/2769/1149) Also relevant: [What language was the first to treat null checks as smart casts to non-nullable types?](https://langdev.stackexchange.com/q/3149/1149)
user23013
# Are there languages having multiple level fine control over deep and shallow copy?
Posted by: username_0 on 2024-07-23
A reference or level-0 copy is the same object as the original, only accessed differently.

A level-1 shallow copy is a new object, with every member a reference to the member under the same name in the original object.

A level-∞ deep copy is a new object, with every member a level-∞ deep copy of the member under the same name in the original object.

But the more common implementation is to decide whether to copy or reference according to the type. For example, to copy primitives but not objects, or to copy non-reference members but not referenced objects.

In my experience of programming, it is very rare to need to copy a specific object in multiple different ways (not counting level-0). But the needed way is also quite unpredictable. The built-in copy functionality is usually based on arbitrary decisions and couldn't satisfy all the need.

Copying non-references, or just marking some member to be copied using a special directive, makes the best sense, but may not satisfy all the need if it was in a library having multiple different uses. So it may make sense, to have directives for behaviors in multiple different ways of copy. But I feel this feature (supporting more options than copy and non-copy) might well be completely useless, as one single way of copy is usually needed in a program. So I want to know if something is already explored in this direction in some languages.
**Tags:** object-oriented data-structures
> **Comments:**
> **username_1**: Not an answer, but be careful with thoughts along the line of "as [only] one single way of copy is usually needed in a program". Programs rarely are logically atomic, but rather consist of multiple libraries or at least areas of concern. You can still trivially use just one copy style even though you support multiple, but the opposite requires a lot of work or may even be infeasible.  
> **username_2**: This whole area is a mess. The documentation for Microsoft's early attempt to solve this problem indicates how we failed: "The ICloneable interface simply requires that your implementation of the Clone() method return a copy of the current object instance. It does not specify whether the cloning operation performs a deep copy, a shallow copy, or something in between. ... Because callers of Clone() cannot depend on the method performing a predictable cloning operation, **we recommend that ICloneable not be implemented in public APIs**."  
> **username_2**: The problems arise from the fundamental question: *why* does the user wish to clone an object in the first place? Typically because they wish to both mutate and *not* mutate an object, and solve this contradiction by mutating a clone. But if you're in that position, maybe the problem would be better solved by an immutable persistent object, and then there is no need to clone.  
> **username_3**: Are you looking for "real" instances in languages, or research? Possibly relevant is the ["sheep cloning" described here by Li](https://palez.github.io/papers/Final_verison.pdf) with Mojo-jojo, which uses ownership types to determine the representation to clone. Multiple approaches were explored in his PhD thesis and I'm not sure that there was ever a winner — it turns out to be a pretty tricky question.  
> **username_0**: @MichaelHomer Researches are also helpful. But I don't know how to edit the question. It appears I need to know more to even understand what the real problem is.  
> **username_0**: @MichaelHomer It's a bit too technical for me, and too long. As I understand, sheep cloning seems referring to something similar to what I thought making the best sense in my question, but with ownership and more precise about the details. But it doesn't seem to provide directives to control multiple ways of copy. The chapter about Mojo-jojo doesn't seem to mention sheep cloning or any cloning at all. Or did I miss something?  
> **username_0**: @EricLippert After some thinking, I believe persistent data structures are effectively just deep copied objects in a duck test, only improved by a better algorithm. It actually passes the problem to persistent data structures and makes the later a bigger mess: Every operation is a clone function. They all should consider whether to keep references in the data structure as is, or to automatically make referenced objects also persistent, or the most likely, to make arbitrary decisions and make the user learn.  
> **username_3**: The [idea behind sheep cloning](https://courses.cs.washington.edu/courses/cse590p/00wi/dynamic-alias-protection.pdf) is essentially that the language has you mark some fields as pointing at objects "owned" by the object, and so part of its representation (a typical ownership system); there is a clone operation that makes copies of all owned references and aliases others, a mixed *sh*allow/d*eep* clone. Each kind of object could have different cloning, but only one sort of clone; is this what you're looking for, or is the question about exposing different kinds of cloning at the use site?  
> **username_0**: What I'm interested in is, if it has sheepclone1() and sheepclone2(), and something like owned1 and owned2 to make them work differently, decide whether it would be ever useful (and what languages have done it). Probably not the best question, but this was what it has asked as it currently stands.  
> **username_0**: (Now I have some conflicting ideas. I think the ideal solution might be without multiple cloning methods, as it looks stupid and requires more arbitrary decisions. But if Eric Lippert's comment means something, it probably would depend on some intermediate solutions requiring multiple methods.)  
> **username_0**: A difficult use case: the resulting union type of [How to make logical operators that return operands consistent in a statically typed language?](https://langdev.stackexchange.com/q/2769/1149) Also relevant: [What language was the first to treat null checks as smart casts to non-nullable types?](https://langdev.stackexchange.com/q/3149/1149)  
---
## 0 answers
