Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extern Array<T> class #32

Closed
RealyUniqueName opened this issue Aug 15, 2016 · 13 comments
Closed

Extern Array<T> class #32

RealyUniqueName opened this issue Aug 15, 2016 · 13 comments
Labels

Comments

@RealyUniqueName
Copy link
Owner

RealyUniqueName commented Aug 15, 2016

See #28 for details

Implemented asnon-extern class in 09f84aa

@mockey
Copy link

mockey commented Aug 15, 2016

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.

@RealyUniqueName
Copy link
Owner Author

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?

@mockey mockey mentioned this issue Aug 15, 2016
@mockey
Copy link

mockey commented Aug 15, 2016

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

@RealyUniqueName
Copy link
Owner Author

Hmm... This one leaves no option :)

@mockey
Copy link

mockey commented Aug 15, 2016

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

@mockey
Copy link

mockey commented Aug 15, 2016

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...

@benmerckx
Copy link

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...

@mockey
Copy link

mockey commented Aug 15, 2016

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)

@benmerckx
Copy link

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.

@mockey
Copy link

mockey commented Aug 15, 2016

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...

@benmerckx
Copy link

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.

@mockey
Copy link

mockey commented Aug 15, 2016

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.

@mockey
Copy link

mockey commented Aug 17, 2016

@benmerckx:
#37 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants