0

You probably know this construct in some languages, like in PHP and Perl:

var $a = ["Apple", "Banana", "Pear", "Orange"];
list($p1, $p2, $p3, $p4) = each($a);
echo $p1;  // Apple
echo $p2;  // Banana
echo $p3;  // Pear
echo $p4;  // Orange

It is often used in while loops, e.g. while (list($key, $val) = each($fruit)) echo "$key: $val;". But not only in loops.

In one line you could affect two or three variables coming from different columns of a row in a database, or taking scalar values from an array like in above example.

Another usage of it is in conjunction with split, especially in scripts:

list($a, $b, $c) = split("/", "papa/tango/charlie");    // this is PHP code again.

Is it possible to achieve that or something similar with Haxe?

For instance, supposing with had a static function assignTo (probably a macro), we could imagine this usage:

using ArrExt;

class Test {
    public static function main() {
        [13, "Bobby Fisher", "USA"].assignTo(age, name, country);  // macro would *define* those vars, no declaration needed
        trace(age);
        trace(name);
        trace(country);
    }
}

I'm more looking for an Haxe 2.10 solution, but an Haxe 3 solution would be welcome to so it can be useful to everyone.

the_yellow_logo
  • 675
  • 5
  • 13
  • 1
    If it was possible, it would need to be done using macros. I don't know of any pre-existing ones, though Nadako has one that looks close: https://github.com/nadako/haxe-thingies#unpack – Jason O'Neil Aug 19 '14 at 13:49
  • I had a go at this, but it looks like you would have to use a build macro, meaning rather than having "using ArrExt" you would need any class using it to have "implements ArrUnpacker" and process the code on every class where you want to use the syntax. So it would be possible, but at that point it's more effort than it's worth IMO. – Jason O'Neil Aug 20 '14 at 02:15
  • Out of curiousity, is this due to the fact we're writing `using`? What if we wrote `ArrExt.assignTo([13, "Bobby Fischer", "USA"], age, name, country);` instead? I'd like to have a go as well but I'm scared installing Haxe 3 in parallel on my machine could break anything, and writing it in Haxe 2 is beyond my understanding of its macro system. – the_yellow_logo Aug 20 '14 at 11:11
  • I might have been doing something wrong, but whether calling the macro explicitly, or through "using", I was running into `unknown identifier age` errors, despite the macro creating a `var age=13, name="Bobby Fisher";` type statement in the code - I guess the compiler checks identifiers before running macros? I may have been doing it wrong though... ask on the mailing list for an expert opinion :) – Jason O'Neil Aug 21 '14 at 07:18
  • Logically macro "expansion" should be pass 1, then comes checking identifiers comes 2nd, as part of the compilation pass. My guess is the problem is the macro creates the vars inside a **block**, i.e. inside `{ ... }` , then it's like creating a local variable inside that block, invisible for outside. – the_yellow_logo Aug 21 '14 at 09:18

2 Answers2

1

The feature is called destructuring assignment, or sometimes unpacking. Instead of writing a macro function, there is a simpler way... use pattern matching (in Haxe 3)!

switch ["Apple", "Banana", "Pear", "Orange"] {
    case [p1, p2, p3, p4]:
        trace(p2); //"Banana"
}

It looks different, but functionally it is the same.

Andy Li
  • 5,894
  • 6
  • 37
  • 47
0

list() on the left hand of an assignment is a PHP language construct, not a function(!). If the haxe language does not support this feature, it will not work.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • I'm asking because I'm wondering if any original answer will come. I somehow wonder if that's really impossible considering what some people manage to do with macros. – the_yellow_logo Aug 18 '14 at 17:17
  • Ok, sure. I'm not an haxe expert, just wanted to point out, that `list()` isn't a lamda function. A macro might work. Please note that I've edited your question, because in PHP, `list()` can't be used in `for` loops (syntax error), but in `while` loops. – hek2mgl Aug 18 '14 at 17:20