[HTML5] Nullable Int

I have found a situation that can create big problems and misunderstandings, I don’t know if it is a problem/bug or simply an expected and well known behavior of… I suppose… JS.

var a : UInt = null;
trace("a = " + a);
trace("a == 0 -> " + (a == 0));

the trace will return

a = 0
a == 0 -> false

because “a” only looks like 0, but it is not.

There are some cases where the compiler will secretly convert a type (in this case, UInt) to Null<T>, which can cause some confusion… but I thought that it was only in cases like ?param:UInt, not a direct assignment.

I’m actually a little surprised that your code compiled like that.

If you don’t assign a value, JavaScript can leave the value as undefined and it can mess with certain kinds of math. I recommend (as a rule of thumb) that you should give a value (even if it is zero) to a variable before you do math on it.

In other words:

private var a:UInt;

...

private function new () {
    
    trace (a); // do not assume it will be zero
    
}

The default initialization for integers and floats on JavaScript, Neko, C++ and Flash are all a bit different (for some important performance reasons) so I would recommend not making assumptions :slight_smile:

Let’s take a look. I pasted your code into try.haxe.org, hit “Build + Run,” and looked at the JS source:

var a = null;
console.log("a = " + Std.string(_$UInt_UInt_$Impl_$.toFloat(a)));
console.log("a == 0 -> " + Std.string(a == 0));

As you can see, a is untyped when first created. Then in line 2, it calls Std.string(UInt.toFloat(a)). It does this because that’s how UInt.toString() is implemented:

However, UInt.toInt() is a bit different:

It just returns the value unchanged, because it thinks it’s already an integer. So if it’s null, that’s what gets returned.


Seeing that, I decided to add one final line of Haxe:

trace("a == 0.0 -> " + (a == 0.0));

That gets converted to the following in JS:

console.log("a == 0.0 -> " + Std.string(_$UInt_UInt_$Impl_$.toFloat(a) == 0.0));

With the following output:

a == 0.0 -> true

That isn’t exactly what happened here. What happened here is that Javascript is untyped. It just doesn’t care about type.

I went back to try.haxe.org and set the target to “SWF.” It gave this error when I tried to compile:

Test.hx:3: characters 23-27 : On static platforms, null can't be used as basic type UInt

So yeah, it’s all because this is Javascript.

1 Like

@singmajesty: yes, I am aware that in Haxe I have to initialize everything while in AS3 it was not necessary, we talked exactly about this in a very old discussion here, but I am doing a complex porting from AS3 to Openfl and sometimes I obtain undesired and unpredicted situations: in this special case the problems where 2, and the second one was the one I reported here. It took a couple hours to understand what the problem was, and that 0 was not 0.

@player_03: great explanation, thank you! The convertion from Haxe to JS is sometimes… weird.