4 ms·
I really like some of Kotlin's decisions, but I prefer Haxe's approach to this. For single target code, you can prefix the class module with the platform tag (
by jdonaldson 9y ago
I really like some of Kotlin's decisions, but I prefer Haxe's approach to this.
For single target code, you can prefix the class module with the platform tag (e.g. "js" or "java"). These module names are reserved within the compiler and any code therein is restricted to their respective targets.
Another way is to use conditional compilation markers to indicate specific target-compatible boundaries. E.g.
#if java
public function print(s : String) java.lang.System.out.println(v);
#end
That method only exists on the java target, and the compiler will complain otherwise.
Conditional compilation also allows for more fine-grained support of multiple targets:
#if java
public function print(s : String) java.lang.System.out.println(v);
#elseif js
public function print(s : String) console.log(v); // as a simple example
#end
This makes a cleaner organizational distinction between extern code that must remain target specific, and true cross platform code that can be called on any of the supported targets. Editors can pick up on this very easily and provide early warnings as you are typing, and doc generators can also inspect these directives and show api availability between targets in the rendered docs.
(self-disclosure: Haxe compiler contributor)
- yole 9y agoIn Kotlin, every module contains either common code or platform-specific code. I'm not sure why you consider the module-level distinction to be less clean than being able to mix common and platform-specific code randomly within a single file. And your example shows that there is no way to verify that each module provides a consistent API.
- jdonaldson 9y ago> In Kotlin, every module contains either common code or platform-specific code. I'm not sure why you consider the module-level distinction to be less clean than being able to mix common and platform-specific code randomly within a single file. Module-level distinctions are per-target. It doesn't get any more clean and clear than that, does it? The trade off is that it's a bit limiting. Conditional compilation is where you can start to pick and choose targets/features and handle more sophisticated cases. > And your example shows that there is no way to verify that each module provides a consistent API. This is easy to do by providing a common interface definition and a simple build class that targets each language you're interested in. It's a good idea in a formal testing suite for a complex library. I only do that in a handful of projects though, most of the time cross-target code is just a few special exceptions. In that case, you'd call out the special case, and then use the #else directive for the rest: #if java public inline function print(s : String) java.lang.System.out.println(v); #else public inline function print(s : String) Sys.println(s); // most of the time basic ops are covered by std lib. #end FWIW I've "inlined" things here with the keyword. This lets you alias cross-platform methods like this without extra function call overhead.
- bitL 9y agoHow good is Haxe? What are its issues, pros/cons? I am looking for something similar; Kotlin was one choice though after today I am not sure about it anymore, so what do other frameworks offer?