fusionlanguage/fut

Copy-constructed object storage

pfusik opened this issue · 5 comments

Discussed in #175

Originally posted by MieszkoP September 8, 2024
Does the swebsite use the current translator from Fusion for other languages? I'm asking this question because I think I've found a bug that's probably pretty important. The following code:

public class JakasKlasa
{
    int x = 7;
    public void setInt!(int _int)
    {
        x = _int;
    }
    
    public int getInt()
    {
        return x;
    }
}

public class Program
{
     public static void Main()
    {
        
        JakasKlasa() a;
        JakasKlasa! b = a;
        JakasKlasa() c = a;
        
        b.setInt(2);
        c.setInt(3);
        
        Console.WriteLine("a: ");
        Console.WriteLine(a.getInt());
        Console.WriteLine("b: ");
        Console.WriteLine(b.getInt());
        Console.WriteLine("c: ");
        Console.WriteLine(c.getInt());
    }   
}

in c++ it is translated in such a way that we have:

  1. an object
  2. a pointer to it
  3. a copy of it.

C++

JakasKlasa a;
JakasKlasa * b = &a;
JakasKlasa c = a;

b->setInt(2);
c.setInt(3);

in C# it is translated in such a way that we have:

  1. an object
  2. a reference of it (class is reference type in C#)
  3. and another reference.

C#

JakasKlasa a = new JakasKlasa();
JakasKlasa b = a;
JakasKlasa c = a;

b.setInt(2);
c.setInt(3);

in Python it is translated in such a way that we have:

  1. an object
  2. a reference of it (copying in Python means copying reference)
  3. and another a reference of it .

Python

a: JakasKlasa = JakasKlasa()
b: JakasKlasa = a
c: JakasKlasa = a

b.set_int(2)
c.set_int(3)

Results:

C++:

a:
**2**
b:
**2**
c:
3

C# and Python:

a:
3
b:
3
c:
3

Thank you for reporting this!

This is invalid Fusion code. Object storage cannot be copy-constructed. I will add an error message.

@pfusik You're welcome! :D
The copy assignment operator doesn't seem to work as it should either. Is there any way to copy an object, not its reference?

JakasKlasa() c;
c = a;

Translates to copying object storage in C++:

JakasKlasa c;
c = a;

but not in C#

JakasKlasa c = new JakasKlasa();
c = a;

neither in Python:

c: JakasKlasa = JakasKlasa()
c = a

For copying to object-storage to work, there would probably have to be something like this in Python:

import copy
....
...
c: JakasKlasa = JakasKlasa()
c = copy.copy(a)

In C# a separate function would have to be added to the class:

public class JakasKlasa
{
...
  public JakasKlasa ShallowCopy()
  {
      return (JakasKlasa)MemberwiseClone();
  }
...
}
JakasKlasa c = new JakasKlasa();
c = a.ShallowCopy();

No, there is no object copy assignment. Could you give a real-world scenario where it would be useful?

C++ made it (too) easy to copy objects, then started introducing mechanisms that prevent these copies, which take both the memory (and cache) and CPU time: move semantics and Foo(const Foo &) = delete.

Thank you for answer! I think sometimes a prototype is useful. For example, I wanted to write a linked list, so it would be nice if I could copy it. Nevertheless, I understand your point. Will it be still possible to apply copying using, for example, an additional method? .Clone()?

Will it be still possible to apply copying using, for example, an additional method? .Clone()?

Sure, you can define your method to return new object storage or dynamically allocated object, initialized as appropriate.