JS extern problem: arrays of mixed type

77 views
Skip to first unread message

Jeff Ward

unread,
Jun 16, 2016, 8:06:58 AM6/16/16
to Haxe
Hi,

I'm having trouble coming up with a JS extern for a library interface that has a couple oddities... Alright, I think the interface is actually the antithesis of type-safety. Here's my example code:


1) First, I can't seem to describe a static accessor from one extern class to another (to get to MJ.Hub.Queue). The error is:

Test.hx:16: characters 8-20 : Class<Hub> has no field Queue

I'm sure I just did something dumb.

2) Second, the Queue function signature is a real pain. It operates on (a variable number of) arrays of mixed type... and each of those arrays has a variable number of args and comes in two flavors, either [String, Dynamic, ...args] or [Function, ...args]

The above example runs great, until you uncomment that little untyped keyword. Then the compiler explodes in anger.

It would be nice to get as close to the existing function signature as possible, but I can't imagine how to retain it and get type safety. Here's what I could maybe come up with:
  • Lose the outer ...args on Queue and just call it multiple times, with either flavor with @:optional.
  • Create two different type-safe helper functions to load up an Array<Dynamic> one element at a time, or
  • Use a macro that intelligently type checks the args for me, or
  • give up and stick with untyped :(
None seems like an ideal choice. I just want to be sure I'm not missing something obvious wrt specifying Arrays of mixed type.

Thanks!
-Jeff

Juraj Kirchheim

unread,
Jun 16, 2016, 8:22:31 AM6/16/16
to haxe...@googlegroups.com
Why not this? http://try.haxe.org/#36Ac5

Best,
Juraj

--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.

Jeff Ward

unread,
Jun 16, 2016, 8:43:56 AM6/16/16
to Haxe
You made Queue a member function of Hub? Hmm, that side-steps issue #1, I suppose that's fine. Is it impossible for a class reference to be expressed as a static member of another class?

Any thoughts on #2 -- typing Queue? I realized I can't use a macro (and probably the root of the inability to specify mix-type Arrays) -- there are no Array contents at compile time. Hmm... Perhaps you could type check array literals. It seems like something should be possible here.

Best,
-Jeff

JLM

unread,
Jun 16, 2016, 12:33:14 PM6/16/16
to Haxe
You can store mixed type using enums.
var l2 = new List<GenericEnum>();
http://old.haxe.org/doc/cross/more_on_enum
Perhaps you could create different structs or typedefs for each value of the enum.
http://old.haxe.org/manual/struct
There are some macro tuples around which might help
I don't know the macro stuff well but just glancing it seems a lot of dynamic you need to consider the functional structures of haxe better and avoid as much dynamic, if you know the possible structures that can be used.
But really have not looked closely at Juraj or your code really closely, so really sorry if my answer is not helpful.

Jeff Ward

unread,
Jun 16, 2016, 1:23:50 PM6/16/16
to Haxe
Hi Justin,

I don't need to store anything, I'm just talking JS externs. I think my only type-safe solution is to write a function that proxies the call into a dynamic array.

This almost exactly illustrates the struggle between dynamic and static languages. You can't (easily? possibly?) describe this API in a single type-safe function. A Haxe dev sits and ponders for hours, whereas in JavaScript, the author just wrote it and moved on with his application.

Hmm...

Ah, here's what I'm trying to express. If Haxe can infer the type of a, b, and c, why can't it infer and enforce [a, b, c] as Array<AType, BType, CType> instead of Array<Dynamic> ?

Best,
-Jeff

Justin L Mills

unread,
Jun 16, 2016, 3:35:36 PM6/16/16
to haxe...@googlegroups.com
Jeff

> Array<AType, BType, CType>
When I said Tuple I ment

https://github.com/deltaluca/goodies/blob/master/goodies/Tuple.hx

But I am not sure if that covers your use. If you need several AType's,
and several BType's but you know all the types you need then create an
enum for them then put the instance in the enum via inferance and then
into the array. Probably more complex than that, if you don't have any
idea what types you want in your array then maybe your approach needs
wider thought most functional problems have been solved before but
sometimes we frame the problem so they don't fit them.

Best

Justin



Jeff Ward

unread,
Jun 16, 2016, 6:24:02 PM6/16/16
to Haxe
Gotcha, I'll check that out, thanks!

Juraj Kirchheim

unread,
Jun 16, 2016, 6:47:01 PM6/16/16
to haxe...@googlegroups.com
On Thu, Jun 16, 2016 at 2:43 PM, Jeff Ward <jeff...@gmail.com> wrote:
You made Queue a member function of Hub? Hmm, that side-steps issue #1, I suppose that's fine. Is it impossible for a class reference to be expressed as a static member of another class?

Exactly. `Class<T>` means a class that when instantiated (through `Type.createEmptyInstance`) yields a `T`. All infos about the class object itself are gone.

There are a few workarounds for this, but I don't really see why that would be needed here.

Any thoughts on #2 -- typing Queue? I realized I can't use a macro (and probably the root of the inability to specify mix-type Arrays) -- there are no Array contents at compile time. Hmm... Perhaps you could type check array literals. It seems like something should be possible here.

An abstract would do the trick. With 3.3 you should be able to write an `@:from macro` that would allow you sticking to the old syntax.

In the end, I guess it depends on what you're after. My suggestion for this particular case is to create a clean interface that makes sense from a Haxe perspective and then write an adapter that calls down to the lib.

Best,
Juraj
Reply all
Reply to author
Forward
0 new messages