Creating abstract for n-element array. Code generated by implicit cast seems unnecessarily verbose.

51 views
Skip to first unread message

Domagoj Štrekelj

unread,
Jan 4, 2016, 10:30:56 AM1/4/16
to Haxe
Hello,

I was toying around with abstracts and wrote an abstract for an n-element array that will automatically "trim" superfluous elements on cast. Essentially, here's how I go about it:

class Test {
    static function main() {
        var x : Array2 = [2, 4, 6, 8, 10];
        trace(x);
        var y : Array2 = [1, 3];
        trace(y);
    }
}

abstract Array2(Array<Int>) {
    public inline function new(x : Int, y : Int) {
        this = [x, y];
    }
    
    @:from static inline function fromArrayInt(a : Array<Int>) : Array2 {
        return new Array2(a[0], a[1]);
    }
    
    @:to inline function toArrayInt() : Array<Int> {
        return [this[0], this[1]];
    }
}

The idea is that only the first two elements of an array that is being cast from is taken into consideration by the Array2 abstract. However, I noticed that the generated JavaScript code is a bit wordier than I expected it to be.

Here's the JavaScript output generated by Haxe 3.2.1 using the -dce full flag:

(function (console) { "use strict";
var Test = function() { };
Test.main = function() {
var x;
{
var a_0 = 2;
var a_1 = 4;
var a_2 = 6;
var a_3 = 8;
var a_4 = 10;
x = [a_0,a_1];
}
console.log(x);
var y;
{
var a_01 = 1;
var a_11 = 3;
y = [a_01,a_11];
}
console.log(y);
};
Test.main();
})(typeof console != "undefined" ? console : {log:function(){}});



For comparison, I decided to try the same with Haxe 3.2.0. Here's the result:

(function (console) { "use strict";
var Test = function() { };
Test.main = function() {
var tmp;
tmp = [2,4];
var x = tmp;
console.log(x);
var tmp1;
tmp1 = [1,3];
var y = tmp1;
console.log(y);
};
Test.main();
})(typeof console != "undefined" ? console : {log:function(){}});


If you're interested, here it is on try.haxe.org.

Seems to me that the Haxe 3.2.0 result is much cleaner even though it's using avoidable temporary variables. Is there an advantage to the new (3.2.1) way of code generation? I mean, JavaScript doesn't have a block-level scope, so there doesn't seem to be a reason to format code this way other than readability. For a larger number of array elements, wouldn't the initialization of variables be wasteful? Is there a way to optimize the output without digging into compiler sources?

Sorry if these are all silly questions. I had this idea that an n-element abstract array would end up performing better than a "dedicated" class. Wouldn't surprise me to learn I'm wrong!

Thank you for any thoughts you care to share!

Domagoj

Simon Krajewski

unread,
Jan 4, 2016, 10:37:07 AM1/4/16
to haxe...@googlegroups.com
I don't know why there's a difference between 3.2.0 and 3.2.1 because I thought it was a pure bugfix release. Are you sure you compared that correctly?

Anyway, this is what you get on current development with -D analyzer:

```js
Main.main = function() {
    var x = [2,4];
    console.log(x);
    var y = [1,3];
    console.log(y);
};
```

Simon

Domagoj Štrekelj

unread,
Jan 4, 2016, 11:32:50 AM1/4/16
to haxe...@googlegroups.com
You're right about the difference between 3.2.0 and 3.2.1 - I didn't compare them correctly! Completely forgot to use -D analyzer when running 3.2.1. Now both outputs look the same.

I apologize for the confusion. It was my fault. Sorry!

And thank you for showing the result of the current development build. It is in line with what I expected the generated code to look like. Once again, thanks!

--
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 a topic in the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages