Is Buffer.clone a deep clone?

If I have a Buffer of Buffers and I clone the parent Buffer, does it clone the buffers all the way down the buffer chain, or will my clone have pointers to the original child buffers?

Never mind…found it…looks like it is shallow:

 /// Returns a copy of this buffer.
    public func clone() : Buffer<X> {
      let c = Buffer<X>(elems.size());
      var i = 0;
      label l loop {
        if (i >= count) break l;
        c.add(elems[i]);
        i += 1;
      };
      c
    };

There is no generic way to clone values(*), so the buffer’s clone method necessarily has to be shallow. If you need a deep clone, you have to program it manually by iterating over the buffer and do whatever needs to be done for the elements explicitly.

(*) Nor must there be – the ability to externally clone e.g. an object would break encapsulation.

I wanted to validate some of my assumptions here so I put this quick bit of code together to verify that both standard types and variants are generally handled by value rather than by ref. I think it is the “class” distinction that moves something to a by val treatment to a by ref treatment. This may all make sense to most but I still have Visual Basic trauma that I’m dealing with.

https://m7sm4-2iaaa-aaaab-qabra-cai.raw.ic0.app/?tag=3465183483

Motoko is a sufficiently high-level language that there isn’t an observable difference between by-value vs by-reference. That’s an implementation detail entirely. The only thing that’s semantically visible is that a value containing a mutable member (e.g. a var field or var array element) is never implicitly copied.

FWIW, class is completely immaterial in that regard as well. It is merely syntactic sugar for a regular function that returns an object, plus a type definition.

1 Like