[haXe] HaXe or a new language?

Shelby Moore shelby at coolpage.com
Mon Feb 1 20:41:22 CET 2010


I have some numbered suggestions for HaXe improvements near the bottom. 
Thank you in advance for any feedback.

MAJOR ISSUE: I am still stuck on whether function callbacks from Neko to
HaXe are feasible?  Why so far I get no feedback on this list to this very
important question?

http://lists.motion-twin.com/pipermail/haxe/2010-January/033284.html

Note see haxeToNeko(), not nekoToHaxe() in above post.  Also, why does
std.Neko.nekoToHaxe() throw an exception and not convert Neko tfunction,
given that std.Neko.Lib.load() does cast and return a tfunction to a
Dynamic?  Seems nekoToHave() should be fixed to convert a tfunction?

http://code.google.com/p/haxe/source/browse/trunk/std/neko/Lib.hx

Appears that std.neko.net.Socket (thus also haxe.Http and haxe.remoting.*)
is not asynchronous and instead uses chunked reading with a connection
timeout.  How to create robust real-time online applications that can
handle persistantly slow connections on Neko?  Whereas, I see that async
callback is supported for Javascript in haxe.Http, haxe.remoting.*, and
onreadystatechange callback in js.XMLHttpRequest.

I have started to work on my own new HaXe-like (static+dynamic typing)
language initially targetting Neko, primarily because there was no
response to the question about Neko to HaXe callbacks.

I would prefer to focus my efforts on HaXe (the concept of static+dynamic
is awesome), so as to not duplicate a huge amount of pre-existing work. 
But without callbacks from external languages (significantly C and Neko),
HaXe can not implement my goal for enabling a new more granular and
interoperable model for open source (cooperative programming).  In my
composability model (which I believe will exponentially win the future of
open source), it is just as important for languages to interopt on a
platform as it is for a language to target multiple platforms and
languages.

I wish I had a better understanding of the implementation of functions and
closures that HaXe is employing on Neko.  I suppose I could take the time
to set up an environment to build HaXe from sources and alter the HaXe
sources to not delete the .neko file after compilation to .n (why isn't
there already a compile flag for that general need? Could someone with a
build environment add the flag to help out?) so I can study the
implementation details, but may consume significant time and the lack of
feedback on this issue is discouraging me.

Function callback from implementation layer (e.g. Neko) to the HLL (e.g.
HaXe), need not be concerned with the implementation of class (method
lookup), only with the way the HLL implements the argument list and return
value.  It appears that the only difference between HaXe function and Neko
tfunction, is the arguments and return value have to converted with
haxeToNeko() <--> nekoToHaxe()?  Thus callbacks are feasible now?

Additionally, to interopt at the implementation layer on HLL class (i.e.
to offer potential cross-language OOP interoptability), the format in the
implementation layer must be documented. If class member lookup is not a
hash table of member names, then multiple inheritance of interfaces and/or
of class with virtual (override) methods, requires runtime change of the
virtual table pointer (prototype) on (even implicit) cast:

http://en.wikipedia.org/w/index.php?title=Virtual_method_table&oldid=330860854#Multiple_inheritance_and_thunks

The point is that HaXe FFI and class member lookup are documentable, and
thus then interoperable.  The problem right now is we have no
documentation on how these are implemented on the various platforms.  I am
willing to help out on .neko if someone can provide a build of HaXe that
will optionally compile to .neko and not .n.  Or, perhaps Nicolas might be
able to answer the question on HaXe FFI and class member lookup formats.

Tangentially if I proceed on my own language, I would eliminate virtual
methods (override) as it semantically subverts static typing (and virtual
inheritance is unnecessary when interface is available):

http://lists.motion-twin.com/pipermail/neko/2010-January/002717.html

I also realized that the keywords 'interface' and 'implements' are
unnecessary, as any class with partial implementation could be construed
to be an interface (and thus can not be instantiated).  This would add the
feature of partial implementation of interfaces.

The LL(1) NBNF parser generator and parser to AST for my new language is
nearly complete (I've chosen a name but don't ask me yet), so I can begin
to make some comments about possible improvements for HaXe, given I have
had to start the process of thinking deeply about such matters for my new
design.  I hope to get feedback on thought processes early as possible.  I
may decide to halt work on this new HLL to focus my efforts on HaXe, if I
can get some helpful feedback.


Additional HaXe issues I think can be improved:

1. Class variables types are not inferred from the constructor:

http://haxe.org/ref/oop


2. Dynamic types must be declared and can not be inferred:

var o : Dynamic = {};

Or:

class Object implements Dynamic {};
var o = new Object();

The following will not infer a dynamic object with unlimited fields,
because it is inferred to be an Anonymous/Structural static type (
http://haxe.org/ref/type_advanced ):

var o = {};
var oo = { x : 1, y : 2 };

Given preference for dynamic typing when execution speed is less important
than programming speed (which is 80% of the time in my experience), I
would prefer the less verbose default to infer Dynamic when assigning
{...} and add a Static type (which means "the type as inferred", so only
needs to be used for {...} and does nothing on cast).  I would not change
class to be Dynamic by default.  Untyped block is not a lower verbosity
solution because it applies to everything in the block, and thus untyped
has to be repeated perhaps at every var declaration.  Low verbosity is one
of the significant reasons why dynamic coding is more readable and thus
faster coding and learning/studying code.


3. Non-static class method can not be curried type safely (
http://haxe.org/ref/callback ) in following case, because there is no way
to use callback() to curry the following:

Lambda.map( ['string1','string2'], function( s ) { return s.charAt( 3 ); } );


4. Dynamic fields can not be accessed with bracket syntax
instance[String], instead must either use verbose Reflect api for or wrap
the code in 'untyped':

http://lists.motion-twin.com/pipermail/haxe/2008-December/021365.html
http://lists.motion-twin.com/pipermail/haxe/2008-December/021372.html
http://lists.motion-twin.com/pipermail/haxe/2008-December/021390.html

I do not understand what 'untyped' does.  Is 'untyped' code passed through
unaltered to the implementation layer, thus give different semantics on
different platforms?

We can use std.Hash<String> instead of Dynamic class, but still more
verbose than bracket syntax.


5. Am I correct that the following does not create a Javascript-like
coupling of an Object and Array with unlimited dynamic fields in addition
to the integer indexed array of dynamic buckets?

var o : Dynamic = new Array<Dynamic>();

Of course such a coupling could be simulated in HaXe as follows, but why
not make it automatic as it is often needed to store the elements of an
array in a companion hash table to speed lookup of index and to pass these
around together (and besides when one is writing dynamic typed code, they
care not much about speed or memory, but care most about code elegance and
low verbosity):

class Object implements Dynamic {};
var o = new Object()
o.array = new Array<Dynamic>();

However, we still have problem #4 above.


6. Verbosity (else runtime semantic errors) when comparing basic types
(Int, Float, Bool) to null on different platform targets, since must
remember to wrap in Null<BasicType> or declare Dynamic:

http://lists.motion-twin.com/pipermail/haxe/2008-November/021040.html
http://lists.motion-twin.com/pipermail/haxe/2008-November/021002.html

I thought I read some where that HaXe will not allow reading a local or
class var that was not set?  If true, the above only applies to Array (and
global variables?) of basic type.

HaXe could be "fixed" to output compiler warnings when comparing null to a
basic type that is not nullable (e.g. when Null<> is not used on Flash 9),
and add an optional compiler flag to force the default for basic types to
be Null<> on all platforms.



More information about the Haxe mailing list