-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for dataful enums? #40
Comments
Generally, having such a feature would be nice and I think some experimentation might be warranted. That experimentation should probably address:
I probably won't do this myself as I don't really have a need for tagged enums in my current APIs, but any decently clean PR that has answers to the points above has a good chance getting merged. I can also help answer questions. |
I really appreciate the thorough response!
Further discussion of ergonomics:So, I recognise that this is both necessary for usability and potentially very subjective, so I'm keen to discuss the ergonomics. I think the ideal situation would be:
Unfortunately, though I don't know how many languages other than C# allow for partial classes (i.e. having multiple additive definitions / implementations of a class). Given that caveat, I think providing Here's an example of a public abstract partial class ValueClass
{
public abstract R Match<R>(Func<byte, R> byte_f, Func<Single, R> float_f);
public partial class ByteValue : ValueClass
{
public Byte b;
public ByteValue(byte b)
{
this.b = b;
}
public override R Match<R>(Func<byte, R> byte_f, Func<float, R> float_f)
{
return byte_f(b);
}
}
public partial class FloatValue : ValueClass
{
public Single f;
public FloatValue(float f)
{
this.f = f;
}
public override R Match<R>(Func<byte, R> byte_f, Func<float, R> float_f)
{
return float_f(f);
}
}
} As an example, once the match operation is possible (on a class or struct or otherwise), it should be trivial to implement other methods (like public void Match(Action<byte> byte_f, Action<Single> float_f)
{
Match<object>(
b =>
{
byte_f(b);
return null;
},
f =>
{
float_f(f);
return null;
}
);
}
public R IfByte<R>(Func<byte, R> byte_f, R def)
{
return Match(byte_f, f => def);
}
public R IfFloat<R>(Func<float, R> float_f, R def)
{
return Match(b => def, float_f);
}
public void IfByte(Action<byte> byte_f)
{
Match(byte_f, f => { });
}
public void IfFloat(Action<float> float_f)
{
Match(b => { }, float_f);
}
public R Switch<R>(R byte_v, R float_v)
{
Match(b => byte_v, f => float_v);
}
public bool IsByte()
{
Switch(true, false);
}
public bool IsFloat()
{
Switch(false, true);
} |
Some random thoughts:
You can do something similar already if you implement
I agree this needs some investigation, probable candidate is
I would look at each language in total isolation. The most important point is Rust -> C is sane (sound and reasonable). Then it's just up to each other language to have 'nice enough' FFI utils. About your C# proposal, I'd have to play, but I think your |
If i'm not mistaken, all interoptopus types are required to be |
Noting for anyone who implements this for the C# backend (possibly me), the F# language spec has a section on the compiled form of F#'s own discriminated unions in other .NET languages, including C#. This seems like a good form to mimic in interoptopus' C# backend. In the current latest (F# 4.1) this is section 8.5.4 "Compiled Form of Union Types for Use from Other CLI Languages". |
Dataful enums are a powerful feature of rust's type system, and unfortunately this means they are difficult to represent elegantly in many other languages. However, at minimum dataful enums in rust can be represented as a tagged union in C, and in languages with structural inheritance, this could be translated to a class or record type hierarchy.
Adding support for dataful enums, even rudimentary support only mapping them to tagged unions in the target languages, would be a very valuable feature for rust interoperability.
As an example of a simple dataful enum on rust side:
And its equivalent on the C# side, including the facility to perform basic matching on the variant:
Optionally, this tagged union could be converted to a class hierarchy, if this is deemed valuable:
The text was updated successfully, but these errors were encountered: