Open Simn opened 1 year ago
Ahh, true! I can see how this would become a headache 🤔
Unfortunately, I don't remember what exactly the problem was with an approach that would emit
Nullable
only if the parameter is not a reference type.
Reference types can already be assigned null
in C# right? Perhaps the problem that was being solved is @:struct class types can be assigned null
in Haxe(?), but not in C#. So instances are wrapped with Nullable
?
But it would probably suck to just wrap all the custom value types in a reference type, removes the whole point of their optimization. Hmmmm... guess @:struct types can just throw an error if found being assigned a null
during generation (without wrapping in Null<T>
), but would be nice if null
usage could be tracked better.
@Simn Sorry if this has been asked before, but I've been meaning to inquire: is having null-safety always "on" on the table for Haxe 5? Outside of the safety stuff, feels like it would help with optimizing generation for static targets for situations like this. But would probably break everything... so idkkk...
As far as I can tell, I would see the generated code like this:
Nullable<T>
value types (int
, double
, struct
types...) when using Null<Int>
, Null<Float>
, ... on Haxe sideType
or Null<Type>
on Haxe sideBut yes, that won't solve all cases, like if in the original Haxe code there is some generic class or function literally taking Null<T>
as argument, which mean it could theoretically accept both value types and reference types as T
, then, yes, in that case we might need wrap the value into some custom Nullable type...
If there is no going away from this, I guess we should try our best to use a custom Nullable type only in places where we can't do otherwise (like haxe generic Null<T>
), and stick to C# Nullable value types or plain references in all other situations when possible. Can imagine that will require the exporter to be smart about that and can definitely see this as a challenge 😅. But not sure there is a better option...
Regarding default null-safety, I don't know yet. It might become a thing like DCE that is enabled by default for user-code. But at the end of the day, the problem here isn't going to go away.
The C# target has its own Null implementation that doesn't have the struct restriction. However, this has always caused some friction and doesn't seem ideal either.
@Simn Do you have more details about the problems/friction you had when using that custom Null<T>
implementation for C# target?
I never used it much, but from my understanding it makes native interop a mess. Maybe @klabz has some insight, he's the expert on Haxe/C# annoyances.
One of the biggest challenges when it comes to Haxe code generation is the handling of
Null<T>
. My experience is that it's good to get this out of the way early because otherwise it's going to come back with a vengeance.The problem with C# Nullable is that it is constrained to
struct
. This means that it cannot be used with reference types, which in turn means that it cannot be "blindly" used in place of Haxe'sNull<T>
. Unfortunately, I don't remember what exactly the problem was with an approach that would emitNullable
only if the parameter is not a reference type.The C# target has its own Null implementation that doesn't have the struct restriction. However, this has always caused some friction and doesn't seem ideal either.
I'm interested in knowing what the best approach is in the C# world!