RealyUniqueName / haxe

Haxe - The Cross-Platform Toolkit

Home Page:http://haxe.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Extern Array<T> class

RealyUniqueName opened this issue · comments

See #28 for details

Implemented asnon-extern class in 09f84aa

First of all: Real nice effort @RealyUniqueName and great work so far!

As this is is the top issue ATM I'll start with arrays here.

My ideas concerning arrays:

  • IMO Array<T> should remain a wrapper class in haxe because native PHP arrays behave very differently from haxe arrays. A direct extern is not a good idea. Also there are indexed and associative arrays which map to different things in haxe.
  • I would introduce something like NativeArrayI<T> (indexed) and NativeArrayA<T> (associative) as abstracts (and an underlying @:coreType abstract NativeArray), so haxe arrays/structs/maps can be auto-cast to and from native php arrays. I wrote some macro code for this once, which worked pretty good.
    Especially associative arrays are mostly used like structs in PHP for passing options e.g.
    So you would be able to do this in a typed manner:
var opt:NativeArrayA<{prop1:String, prop2:Int}> = {prop1: "foo", prop2: 2};
var arr:NativeArrayI<Int> = [1, 2, 3];

generates:

$opt = array('prop1' => "foo", 'prop2' => 2);
$arr = array(1, 2, 3);

So it should be possible to use native arrays, but only when explicitly declared.

Good point. And yet i wish we can use native php arrays for Array<T>. It's a huge performance boost especially in terms of JSON parsing/encoding.
Maybe we can prohibit implicit Array<T> <-> NativeArray parsing to make sure thrid party php code will not affect haxe-generated one?

Consider this. e.g.:
[1, 2, 3] == [1, 2, 3]
PHP: true, Haxe: false.

Hmm... This one leaves no option :)

Be prepared for other surprises :-) This dynamic stuff is extremely terrible.

Also I think a light wrapper Array class with inlined array functions where possible should be not so expensive in terms of performance. And some clever abstracts can give you native array access if needed. Just my 2 cents of course...

commented

Having a wrapper class works fine while in haxe context, but creates terrible situations when interfacing with native php code. I'd happily work around some edge cases if that means being able to pass arrays along without a conversion step. Having the NativeArray classes doesn't really help when trying to write cross platform code, as it restricts your target to php.
I guess everyone has different use cases...

Having the NativeArray classes doesn't really help when trying to write cross platform code

Of course not. For cross-platform code use Array. It should be a light as possible wrapper to make it work cross-platform.

A lot of targets have an additional NativeArray class, that's not without a reason.
Also [1, 2, 3] == [1, 2, 3] is no edge case, this is general array behaviour (a.k.a. PHP weirdness)

commented

What I mean is.. I like to use and write cross platform haxe code. Which means I'll be using Array. Which also means any native php code interfacing with my code will need to have any array passed in converted to the wrapper. And another conversion to a native array if the return value is an array as well. And a check to see if I'm calling the method from the haxe or php side, because an array which is already wrapped doesn't need to be wrapped another time. Which means any public facing method which could be used from php needs a lot of conversion. I've implemented this as a macro solution in my current codebase, but it's something which I would ideally like to scrap completely. There's too many things which can slip through the cracks, and the conversion steps just don't feel right. I could use some NativeArray solution but that just means the conversion would be done elsewhere, as any general haxe lib will be using Array.
The equality might not be an edge case. I just can't recall ever trying to check equality on arrays - hence I did not even know the behaviour of either haxe or php.
I think I just feel a bit too strong on this subject, so I better refrain from further discussion :) I'll leave this up to you guys.

Which also means any native php code interfacing with my code will need to have any array passed in converted to the wrapper. And another conversion to a native array if the return value is an array as well.

More or less, yes, that's the cost of cross-platform.

And a check to see if I'm calling the method from the haxe or php side, because an array which is already wrapped doesn't need to be wrapped another time. Which means any public facing method which could be used from php needs a lot of conversion.

I don't understand. Consider an abstract NativeArrayI which auto-casts to and from the underlying php array. You'd do:

var arr1 = [1,2,3]; //haxe Array<Int>;
var arr2:Array<String> = PhpInterface.nativeCall(arr1); // auto-wraps and unwraps native array
// php interface:
extern PhpInterface {
  function nativeCall(arr:NativeArrayI<Int>):NativeArrayI<String>;
}

which would generate (more or less):

$arr2 = new _hx_array(PhpInterface::nativeCall($arr1->a));

It's just a matter of the right interface definitions (native types on the PHP side, haxe types on the haxe side), no?
Additionally I added a macro @:from call that translates literal [1,2,3] to array(1,2,3), so no wrapper at all in this case (when you call PhpInterface.nativeCall([1,2,3]))

I think I just feel a bit too strong on this subject, so I better refrain from further discussion

Actually I had this idea as well, using native array directly...

commented

I'm using it mostly the other way around. Exposing my haxe classes for use in php. But you're right I might be able to ease the situation with an abstract over NativeArray whith a @:to array. In any case I'll revisit that implementation once this new target is finished.

I'm using it mostly the other way around. Exposing my haxe classes for use in php.

This should work just the same. You'd have a haxe function expecting a NativeArray from PHP, which is automatically wrapped and returning a NativeArray to PHP (the haxe array unwrapped).

But you're right I might be able to ease the situation with an abstract over NativeArray whith a @:to array.

You'll need @:from as well for bidirectional communication. I'll put my implementation on github later this week. It's pretty cool for associative arrays as well, which get cast to structs in haxe.