-
-
Save jdonaldson/1278814 to your computer and use it in GitHub Desktop.
// Copyright (c) 2011, the HaXe project authors. | |
// All rights reserved. | |
// Simple test program to compare haXe style js output with dart version: | |
// https://gist.github.com/1277224 | |
// compile: haxe -main HelloHaxeTest -js test.js | |
class HelloHaxeTest { | |
static function main() { | |
trace("Hello, HaXer!"); | |
} | |
} |
$estr = function() { return js.Boot.__string_rec(this,''); } | |
Std = function() { } | |
Std.__name__ = ["Std"]; | |
Std["is"] = function(v,t) { | |
return js.Boot.__instanceof(v,t); | |
} | |
Std.string = function(s) { | |
return js.Boot.__string_rec(s,""); | |
} | |
Std["int"] = function(x) { | |
if(x < 0) return Math.ceil(x); | |
return Math.floor(x); | |
} | |
Std.parseInt = function(x) { | |
var v = parseInt(x,10); | |
if(v == 0 && x.charCodeAt(1) == 120) v = parseInt(x); | |
if(isNaN(v)) return null; | |
return v; | |
} | |
Std.parseFloat = function(x) { | |
return parseFloat(x); | |
} | |
Std.random = function(x) { | |
return Math.floor(Math.random() * x); | |
} | |
Std.prototype.__class__ = Std; | |
IntIter = function(min,max) { | |
if( min === $_ ) return; | |
this.min = min; | |
this.max = max; | |
} | |
IntIter.__name__ = ["IntIter"]; | |
IntIter.prototype.min = null; | |
IntIter.prototype.max = null; | |
IntIter.prototype.hasNext = function() { | |
return this.min < this.max; | |
} | |
IntIter.prototype.next = function() { | |
return this.min++; | |
} | |
IntIter.prototype.__class__ = IntIter; | |
HelloHaxeTest = function() { } | |
HelloHaxeTest.__name__ = ["HelloHaxeTest"]; | |
HelloHaxeTest.main = function() { | |
haxe.Log.trace("Hello, HaXer!",{ fileName : "HelloHaxeTest.hx", lineNumber : 9, className : "HelloHaxeTest", methodName : "main"}); | |
} | |
HelloHaxeTest.prototype.__class__ = HelloHaxeTest; | |
if(typeof haxe=='undefined') haxe = {} | |
haxe.Log = function() { } | |
haxe.Log.__name__ = ["haxe","Log"]; | |
haxe.Log.trace = function(v,infos) { | |
js.Boot.__trace(v,infos); | |
} | |
haxe.Log.clear = function() { | |
js.Boot.__clear_trace(); | |
} | |
haxe.Log.prototype.__class__ = haxe.Log; | |
if(typeof js=='undefined') js = {} | |
js.Lib = function() { } | |
js.Lib.__name__ = ["js","Lib"]; | |
js.Lib.isIE = null; | |
js.Lib.isOpera = null; | |
js.Lib.document = null; | |
js.Lib.window = null; | |
js.Lib.alert = function(v) { | |
alert(js.Boot.__string_rec(v,"")); | |
} | |
js.Lib.eval = function(code) { | |
return eval(code); | |
} | |
js.Lib.setErrorHandler = function(f) { | |
js.Lib.onerror = f; | |
} | |
js.Lib.prototype.__class__ = js.Lib; | |
js.Boot = function() { } | |
js.Boot.__name__ = ["js","Boot"]; | |
js.Boot.__unhtml = function(s) { | |
return s.split("&").join("&").split("<").join("<").split(">").join(">"); | |
} | |
js.Boot.__trace = function(v,i) { | |
var msg = i != null?i.fileName + ":" + i.lineNumber + ": ":""; | |
msg += js.Boot.__unhtml(js.Boot.__string_rec(v,"")) + "<br/>"; | |
var d = document.getElementById("haxe:trace"); | |
if(d == null) alert("No haxe:trace element defined\n" + msg); else d.innerHTML += msg; | |
} | |
js.Boot.__clear_trace = function() { | |
var d = document.getElementById("haxe:trace"); | |
if(d != null) d.innerHTML = ""; | |
} | |
js.Boot.__closure = function(o,f) { | |
var m = o[f]; | |
if(m == null) return null; | |
var f1 = function() { | |
return m.apply(o,arguments); | |
}; | |
f1.scope = o; | |
f1.method = m; | |
return f1; | |
} | |
js.Boot.__string_rec = function(o,s) { | |
if(o == null) return "null"; | |
if(s.length >= 5) return "<...>"; | |
var t = typeof(o); | |
if(t == "function" && (o.__name__ != null || o.__ename__ != null)) t = "object"; | |
switch(t) { | |
case "object": | |
if(o instanceof Array) { | |
if(o.__enum__ != null) { | |
if(o.length == 2) return o[0]; | |
var str = o[0] + "("; | |
s += "\t"; | |
var _g1 = 2, _g = o.length; | |
while(_g1 < _g) { | |
var i = _g1++; | |
if(i != 2) str += "," + js.Boot.__string_rec(o[i],s); else str += js.Boot.__string_rec(o[i],s); | |
} | |
return str + ")"; | |
} | |
var l = o.length; | |
var i; | |
var str = "["; | |
s += "\t"; | |
var _g = 0; | |
while(_g < l) { | |
var i1 = _g++; | |
str += (i1 > 0?",":"") + js.Boot.__string_rec(o[i1],s); | |
} | |
str += "]"; | |
return str; | |
} | |
var tostr; | |
try { | |
tostr = o.toString; | |
} catch( e ) { | |
return "???"; | |
} | |
if(tostr != null && tostr != Object.toString) { | |
var s2 = o.toString(); | |
if(s2 != "[object Object]") return s2; | |
} | |
var k = null; | |
var str = "{\n"; | |
s += "\t"; | |
var hasp = o.hasOwnProperty != null; | |
for( var k in o ) { ; | |
if(hasp && !o.hasOwnProperty(k)) { | |
continue; | |
} | |
if(k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__") { | |
continue; | |
} | |
if(str.length != 2) str += ", \n"; | |
str += s + k + " : " + js.Boot.__string_rec(o[k],s); | |
} | |
s = s.substring(1); | |
str += "\n" + s + "}"; | |
return str; | |
case "function": | |
return "<function>"; | |
case "string": | |
return o; | |
default: | |
return String(o); | |
} | |
} | |
js.Boot.__interfLoop = function(cc,cl) { | |
if(cc == null) return false; | |
if(cc == cl) return true; | |
var intf = cc.__interfaces__; | |
if(intf != null) { | |
var _g1 = 0, _g = intf.length; | |
while(_g1 < _g) { | |
var i = _g1++; | |
var i1 = intf[i]; | |
if(i1 == cl || js.Boot.__interfLoop(i1,cl)) return true; | |
} | |
} | |
return js.Boot.__interfLoop(cc.__super__,cl); | |
} | |
js.Boot.__instanceof = function(o,cl) { | |
try { | |
if(o instanceof cl) { | |
if(cl == Array) return o.__enum__ == null; | |
return true; | |
} | |
if(js.Boot.__interfLoop(o.__class__,cl)) return true; | |
} catch( e ) { | |
if(cl == null) return false; | |
} | |
switch(cl) { | |
case Int: | |
return Math.ceil(o%2147483648.0) === o; | |
case Float: | |
return typeof(o) == "number"; | |
case Bool: | |
return o === true || o === false; | |
case String: | |
return typeof(o) == "string"; | |
case Dynamic: | |
return true; | |
default: | |
if(o == null) return false; | |
return o.__enum__ == cl || cl == Class && o.__name__ != null || cl == Enum && o.__ename__ != null; | |
} | |
} | |
js.Boot.__init = function() { | |
js.Lib.isIE = typeof document!='undefined' && document.all != null && typeof window!='undefined' && window.opera == null; | |
js.Lib.isOpera = typeof window!='undefined' && window.opera != null; | |
Array.prototype.copy = Array.prototype.slice; | |
Array.prototype.insert = function(i,x) { | |
this.splice(i,0,x); | |
}; | |
Array.prototype.remove = Array.prototype.indexOf?function(obj) { | |
var idx = this.indexOf(obj); | |
if(idx == -1) return false; | |
this.splice(idx,1); | |
return true; | |
}:function(obj) { | |
var i = 0; | |
var l = this.length; | |
while(i < l) { | |
if(this[i] == obj) { | |
this.splice(i,1); | |
return true; | |
} | |
i++; | |
} | |
return false; | |
}; | |
Array.prototype.iterator = function() { | |
return { cur : 0, arr : this, hasNext : function() { | |
return this.cur < this.arr.length; | |
}, next : function() { | |
return this.arr[this.cur++]; | |
}}; | |
}; | |
if(String.prototype.cca == null) String.prototype.cca = String.prototype.charCodeAt; | |
String.prototype.charCodeAt = function(i) { | |
var x = this.cca(i); | |
if(x != x) return null; | |
return x; | |
}; | |
var oldsub = String.prototype.substr; | |
String.prototype.substr = function(pos,len) { | |
if(pos != null && pos != 0 && len != null && len < 0) return ""; | |
if(len == null) len = this.length; | |
if(pos < 0) { | |
pos = this.length + pos; | |
if(pos < 0) pos = 0; | |
} else if(len < 0) len = this.length + len - pos; | |
return oldsub.apply(this,[pos,len]); | |
}; | |
$closure = js.Boot.__closure; | |
} | |
js.Boot.prototype.__class__ = js.Boot; | |
$_ = {} | |
js.Boot.__res = {} | |
js.Boot.__init(); | |
{ | |
String.prototype.__class__ = String; | |
String.__name__ = ["String"]; | |
Array.prototype.__class__ = Array; | |
Array.__name__ = ["Array"]; | |
Int = { __name__ : ["Int"]}; | |
Dynamic = { __name__ : ["Dynamic"]}; | |
Float = Number; | |
Float.__name__ = ["Float"]; | |
Bool = { __ename__ : ["Bool"]}; | |
Class = { __name__ : ["Class"]}; | |
Enum = { }; | |
Void = { __ename__ : ["Void"]}; | |
} | |
{ | |
Math.__name__ = ["Math"]; | |
Math.NaN = Number["NaN"]; | |
Math.NEGATIVE_INFINITY = Number["NEGATIVE_INFINITY"]; | |
Math.POSITIVE_INFINITY = Number["POSITIVE_INFINITY"]; | |
Math.isFinite = function(i) { | |
return isFinite(i); | |
}; | |
Math.isNaN = function(i) { | |
return isNaN(i); | |
}; | |
} | |
{ | |
js.Lib.document = document; | |
js.Lib.window = window; | |
onerror = function(msg,url,line) { | |
var f = js.Lib.onerror; | |
if( f == null ) | |
return false; | |
return f(msg,[url+":"+line]); | |
} | |
} | |
js.Lib.onerror = null; | |
HelloHaxeTest.main() |
Name collision and sophisticated namespaces go hand in hand. I can't see how one could criticize the way that haxe does it, and then be perfectly fine with better.js modules. I can appreciate how better.js works efficiently with javascript, but I'm hoping you will agree with me that it is hardly elegant.
As far as performance goes, namespace access speed is less of an issue with more modern browsers, and can be optimized anyways (using local copies) with minimal effort. HaXe also helps you with simple things like avoiding accidentally leaving out var declarations.
Thanks for all of the links, I haven't seen some of them yet.
Also, considering that last blog about Dart, consider that Flash had "already won" as well. It was arguably installed in more browsers/devices than javascript was, and faster. And, you didn't need such strange approaches towards building complex applications. Granted, many things about Flash were horrible... the proprietary editor, the lack of typed Arrays, the closed nature of the whole eco-system, I could go on. Point is, it's now suddenly out of fashion.
I'm aware of the differences and the
--js-namespace
option and know that haXe needs the Std libs since it wants to provide a similar dev experience no matter the target language, which is an awesome feature BTW, just think that output could be way more optimized (execution performance, minification friendly, readable, etc).Name collision can be avoided by other ways (closures, hash table) and having deep lookup trees is a bad thing for execution performance and for minification.
I see haXe as an awesome language for cross-platform development but I can't see it being used on sites like BBC, Yahoo, GMail, or any other large site that cares a lot about page load performance or as a real replacement to JavaScript (since haXe libraries can't be used outside a haXe project)..
This post describes exactly how I fell about JavaScript nowadays: evolution of a prototypal language user
And this quote is also really good:
(from: Dart; or Why JavaScript has already won)
cheers.