Extending built-in types

Tuesday, 2 June 2009 5:21pm

I ran into an issue where I really needed to tag the built-in Javascript types with additional information to make Fan work better. The big one is annotating a Number to be either a Int or Float, which you need to do to make all the equality checks work consistently (since 5 != 5f).

This is was my first attempt, which I assumed would work:

>>> var x = 15;
>>> x.$fanType = sys_Type.find("sys::Int");
>>> x.$fanType
undefined

But no dice. After a bit of googling, I found this page, which says in order to add properties to the built-in types, you must create objects using the constructor syntax:

>>> var x = new Number(15);
>>> x.$fanType = sys_Type.find("sys::Int");
>>> x.$fanType
"sys::Int"

I assume this a performance optimization, where you can use a primitive int value in the first case, and have to allocate an object in the latter. Though since Javascript is a pure-OO language, I would be interested in seeing how VMs actually implement this behavior.

Edit 8 Jun 09: Just realized using the object syntax breaks equality checks for numbers:

>>> var x = new Number(4);
>>> var y = new Number(4);
>>> x == y
false

Which sort of sucks, but you can work around it using valueOf, but still annoying.

>>> x.valueOf() == y.valueOf()
true