HaXe Language Nuances
From dis-Emi-A
Contents |
Nuances / Dangers
This is a list of the nuances found while using haXe. Some are annoying, and some are actually quite dangerous.
- inline has semantic meaning
- inline is not like in C++, it is not guaranteed to be a safe operation and can change the semantic meaning of the code using it. It additionally changes the typing of the function which poses problems for inheritance and type inference. In some cases the use of inline can lead to runtime errors that would not have otherwise occurred.
- fundamentals and null not platform independent
- fundamentals, like Int, are handled differently on some of the target platforms. One has to be aware of the target while programming and use them appropriately. This has an annoying impact on generics which may use fundamentals and non-fundamentals.
- iterator behavior wrt remove is not clear
- Some iterators fail to operate correctly if an object is removed from the iterated collection. There is no clear description as what is to happen.
- iterators are strictly duck-typed and not implementable
- This nuance means that you can't explicitly say you are implementing an iterator -- and benefit from quick compiler checking on correctness. The duck-typed nature is good, but the lack of strict iterator definition is slightly annoying.
- typedef inferencing fails with inheritance
- Attempting to create and assign types with typedefs requires many cast operations.
- language is loosely specified, often regression
- Since the language is loosely specified and faces many changes, there are often regressions which occur in the compiler. We try to keep our own language tests now, but occasionally new things come up.
- closures require syntax hack to use current object
- The infamous "var me = this;" appears in any case where you need to use the current instance in a closure.
- limited use variables in interfaces
- Variables in interfaces are good, but they are quite strict in that you cannot specify getters/setters for the variable in an implementation of that interface.
Unusual
- irreducible error in MatrixUtil / possible typing problem
- In our seedFill class we have a redundant line "var q = sx" which if not present will result in runtime VerifyError 1068. I have been unable to reproduce via a smaller example.
- compiler emits errors in the wrong location
- in several situations if you have a problem with an imported, or base class, the compiler will emit errors where the class is used instead of the source file for the class. This effectively leaves you in the dark as to where the problem actually is.
Limitations
- generics, not generalized parametric functions/class
- The generics system very closely models Java's and thus suffers all the same shortfalls, the most significant of which is the inability to call a static on the type, or to instantiate new objects of that type.
- lack of string formatters
- Currently there is no equivalent to sprintf, <<, or php string expansion. Working with strings can thus be a chore.
- lack of a Byte fundamental
- There is no haXe proper way of working with Binary data.
- type inferencing is primarily RValue limited
- That is, it in general works like the proposed C++ "auto" keyword. In some cases the types of function parameters can be inferred, but in my experience this often leads to typing problems (in particular when inline is used).
- no type overloading, no infix functions
- Thus simple operations on a Point class become very difficult to read (as do operations on the standard Int32 class)
var q = a.sub( c.mul( 3 ) ) var q = a sub ( c mul 3 ) var q = a - ( c * 3 )
- collections library is weak
- Only a limited number of collections are available and the available functions is extremely limited.
- #line directive does not support file
- thus while a preprocessor is partially supported, cross-file inclusions will not be reported correctly with errors and in stack traces
- static fields are not inherited
- a derived class must access static fields of a parent as though it were unrelated to that class
Minor Inconsistencies
- Int32.toInt arbitrarily restricts use to 31bit values even on platforms that support more
- enums cannot be compared directly, you must use Type.enumEq
- as with Java, the flow detection is wrong sometimes and forces you to assign unused values to variables
Feature Requests
- regex replace function
- replacing parts of a string with a regular expression is somewhat bulky and would be improved by having a callback mechanism as in PHP or Ruby.
