haXe operator overloading tool

487 views
Skip to first unread message

Dima Granetchi

unread,
Feb 28, 2012, 1:12:02 PM2/28/12
to haxe...@googlegroups.com
Hi, list.

I studied macros in haXe and during study I wrote some library for operator overloading.
Demo, tests and small tutorial are here https://github.com/profelis/overload-operator

This is just my experiments, but maybe it's be usefull to someone.

Dima

Simon Krajewski

unread,
Feb 28, 2012, 1:30:32 PM2/28/12
to haxe...@googlegroups.com

It works with 2.08, but fails with current svn:

src/test/OverloadTestComplex.hx:23: characters 27-38 : Warning :
Overriding existing method +:
src/test/OverloadTestComplex.hx:32: characters 29-36 : Cannot add
deep.math.Complex and deep.math.Complex

I'm not sure what's going on there yet.

Simon

Dima Granetchi

unread,
Feb 28, 2012, 1:35:32 PM2/28/12
to haxe...@googlegroups.com
hm, looks like macros api are changed or bug :)

If you need svn support I can test it and fix.

Juraj Kirchheim

unread,
Feb 28, 2012, 1:42:25 PM2/28/12
to haxe...@googlegroups.com
Very nice!

Please note however: Overloading assignment operators is a slippery
slope. Most importantly it will not work well on properties, i.e.:

class A {
public var float(default, set_float):Float;
public var point(default, set_point):Point;
}
class Point {
@op("++") static public inline function add(p:Point):Point {
p1.x += 1;
p1.y += 1;
return p1;
}
}

And now myA.float++ will call the accessor, while myA.point++ won't.

However, this can be circumvented by handling OpAssingOp(op)
differently, by examining the left hand side and acting accordingly.
Valid left hand expressions for assignment are EField, EType, EArray,
EConst(CIdent(id)) and EConst(CType(id)).

So what you basically do is this (+ stands for any operation here):

1. <owner>[<index>] += <value> becomes:
{
var owner = <owner>, index = <index>, value = <value>;
//declare variables to avoid duplicate evaluation, declare for *all*
subexpressions to avoid collision
owner[index] = owner[index] + value;
}
- owner.field += value becomes:
{
var owner = owner, value = value;
owner.field = owner.field + value;
}
- ident += y merely becomes ident = ident + y ... no magic here

And then feed the resulting expression into your normal
transformation. This should cover all cases by composing assignment
operations logically and thus would also work with properties. Also
one wouldn't have to define + and += separately ;)

Either way, great work so far! ;)

Regards,
Juraj

> --
> To post to this group haxe...@googlegroups.com
> http://groups.google.com/group/haxelang?hl=en

Dima Granetchi

unread,
Feb 28, 2012, 1:55:37 PM2/28/12
to haxe...@googlegroups.com
Thanks.

Now I support only simple assign then left side are identifier. But you are right, and I'l try to support all cases.

@op("+", true) inline static public function add(a:Complex, b:Complex):Complex   // complex + complex
@op("+=", true) inline static public function iadd(a:Complex, b:Complex):Complex 

Overloading are strongly typed

@op("+", true) inline static public function add(a:Complex, b:Complex):Complex   // complex + complex
@op("+", true) inline static public function addFloat(a:Complex, b:Float):Complex // complex + float and float + complex too (commutative)
for complex + int need to be separately method too :)

Simon Krajewski

unread,
Feb 28, 2012, 1:58:18 PM2/28/12
to haxe...@googlegroups.com
Am 28.02.2012 19:35, schrieb Dima Granetchi:
hm, looks like macros api are changed or bug :)

If you need svn support I can test it and fix.

Fear not, I come to the rescue. The problem is that the field method types are evaluated as TLazy, which is why your key signature in addMath is wrong. You can fix this by replacing line 97 with this:
    switch (Context.follow(method.type))

Simon

Dima Granetchi

unread,
Feb 28, 2012, 2:02:03 PM2/28/12
to haxe...@googlegroups.com
I suspected that "follow" needed everywhere. Because I use --remap.
I fix it now and push after some minutes.

Simon Krajewski

unread,
Feb 28, 2012, 2:24:57 PM2/28/12
to haxe...@googlegroups.com

By the way Juraj, could tink's MemberTransformer be (ab)used to create
some sort of expression level preprocessor for this? I'm thinking
instead of using OverloadOperator.calc() with a block argument, have a
class implement IOperatorOverload<ComplexMath>, with IOperatorOverload
being an @:autoBuild that transforms all member function expressions to
support operator overloading.

Simon

Dima Granetchi

unread,
Feb 28, 2012, 2:55:53 PM2/28/12
to haxe...@googlegroups.com
I thought about @:autoBuild . This is next step. calc method is more simple and you can use where you want. See calc() as some assembler code injection.

Juraj Kirchheim

unread,
Feb 28, 2012, 3:21:00 PM2/28/12
to haxe...@googlegroups.com
> By the way Juraj, could tink's MemberTransformer be (ab)used to create some
> sort of expression level preprocessor for this? I'm thinking instead of
> using OverloadOperator.calc() with a block argument, have a class implement
> IOperatorOverload<ComplexMath>, with IOperatorOverload being an @:autoBuild
> that transforms all member function expressions to support operator
> overloading.
>
> Simon

That's exactly what MemberTransformer is for ;)

Dima Granetchi

unread,
Feb 28, 2012, 3:38:59 PM2/28/12
to haxe...@googlegroups.com
hm, I doesn't support overload assign operation :) only += -= ...etc.
I'm not sure that it;s necessary.

In what cases it's necessary?

I see only one case:

a = b; // overload to a = b.clone();

but you can simple write
a = b.clone(); // if you really need clone

Stephane Le Dorze

unread,
Feb 28, 2012, 5:51:21 PM2/28/12
to haxe...@googlegroups.com
I don't know if everybody realize how important being able to create parenthesis free algebraic libraries based on this is.
Congrats!!

Marcelo de Moraes Serpa

unread,
Feb 28, 2012, 6:31:44 PM2/28/12
to haxe...@googlegroups.com
Ruby style! Nice one :)


On Feb 28, 2012, at 12:35 PM, Dima Granetchi wrote:

hm, looks like macros api are changed or bug :)

If you need svn support I can test it and fix.

Benjamin Dubois

unread,
Feb 28, 2012, 11:05:01 PM2/28/12
to haxe...@googlegroups.com
Thank you.

Ben

Dima Granetchi

unread,
Feb 29, 2012, 6:57:23 AM2/29/12
to haxe...@googlegroups.com
small example using overload operator

source on github

Dima Granetchi

unread,
Feb 29, 2012, 4:18:16 PM2/29/12
to haxe...@googlegroups.com
You wrote



Valid left hand expressions for assignment are EField, EType, EArray,
EConst(CIdent(id)) and EConst(CType(id)).


Give me example for EType and EConst(CType(id)) left side.

I know only :(
typedef ShortName = org.com.test.LongName;

Dima Granetchi

unread,
Feb 29, 2012, 5:42:04 PM2/29/12
to haxe...@googlegroups.com
Added test method for left side
Test left side for OpAssignOp and expr of EUnOp.

for example:

c+=b; // unfolding -> c = ComplexMath.iadd(c, b);

a--; // -> a = AnotherMath.posDecrement(a);

For best performance will be great unfold only when necessary.

Ekstazi

unread,
Mar 1, 2012, 3:51:52 PM3/1/12
to haXe
Молодец, не ожидал что меня земляк так порадует. На haxe.ru отпостился
уже ?

Dima Granetchi

unread,
Mar 1, 2012, 3:57:18 PM3/1/12
to haxe...@googlegroups.com
думал о haxe.ru, но пока не решил. Можешь отписать сам :) я разрешаю. А по либе надо побольше тестов написать.

Ekstazi

unread,
Mar 1, 2012, 4:48:34 PM3/1/12
to haXe
Ок, запостю. Документации маловато у тебя как и примеров + на haxelib
запость.

Dima Granetchi

unread,
Mar 1, 2012, 4:56:11 PM3/1/12
to haxe...@googlegroups.com
либа еще очень сырая. Очень спорны моменты при переопределении операции присвоения += -= и т.д. Вложенные вызовы затрудняют инлайнинг и он срабатывает только на самом последнем вложении, что на нет сводит весь профит от инлайнинга операций. Жду помощи от back2dos комментом выше. Далеко не все методы покрыты тестами. В общем в haxelib ей еще очень рано.

Ekstazi

unread,
Mar 2, 2012, 6:20:24 AM3/2/12
to haXe
Понял.

Ekstazi

unread,
Mar 2, 2012, 2:24:00 PM3/2/12
to haXe
Посмотрел внимательней код. Вот что могу отметить:
1) Нет описания у методов через /** */ и так далее.
2) У тебя половина кода из реализации доступа к БД в haxe. Это не есть
гуд. Но это не страшно.
Решение первого пункта позволит тебе организовать автодокументацию по
коду, второй - Николас должен решать и вынести в Context метод для
генерации кода из Expr. Есть один трюк с генерацией AST из строки, но,
здесь пока не вижу ему применения.

Benjamin Dasnois

unread,
Mar 2, 2012, 4:35:27 PM3/2/12
to haxe...@googlegroups.com

Hi,

Please, this is an international list and as much as I'd like to understand and speak a lot of languages, I have to admit that I can only speak French and English fluently enough. So as I bet French is not really spoken by everybody, could you please switch back to English?

No offense here, this is with all due respect to everyone.

Regards,

On Fri, Mar 2, 2012 at 11:20 AM, Ekstazi <ekst...@gmail.com> wrote:
Понял.



--
DASNOIS Benjamin
http://www.benjamindasnois.com

Juraj Kirchheim

unread,
Mar 2, 2012, 5:00:26 PM3/2/12
to haxe...@googlegroups.com
I agree with Benjamin. It's in fact less a matter of respect, than
simple pragmatism.

If you discussed this in English, then we all could try to participate
and thus help you and learn from what you have to share ;)

Regards,
Juraj

Philippe Elsass

unread,
Mar 2, 2012, 5:21:52 PM3/2/12
to haxe...@googlegroups.com
Well Ekstasi is being finicky with Dima's code & tests and they are discussing further cooperation :)

Please guys tell us your conclusions in english regularly so everybody can follow.

I'm all for tolerance here - the list is in english and all, but it happens that many motivated people have a very difficult time explaining things in english. 
Philippe

Ekstazi

unread,
Mar 2, 2012, 5:35:30 PM3/2/12
to haXe
Ok, i told Dima that the code needs some enhancements:
1) Documentation, the library has a little examples.
2) Haxedoc, it hard to understand a code without comments and haxedoc
3) haxelib
4) He must add news in haxe.ru (but I'll do it).
5) He reproduce part of the haxe db realization (and hxsl also), but
this problem can be resolved only by Nicolas.

We are from same city and i have difficulty with english, so i try to
explain my thouth in my native language. Also I reproduce my ideas on
english.
P.S. In the future i'll comment both in english and russian.

Tarwin Stroh-Spijer

unread,
Mar 2, 2012, 5:56:52 PM3/2/12
to haxe...@googlegroups.com
Thanks Ekstazi for sharing in English. Embarrassingly it's the ONLY language I speak so I can understand how hard it must be to talk technically in English for you. It does help us help you though (I know a lot of the people here are native French speakers so I'm sure they feel the same way).

Regards,


Tarwin Stroh-Spijer
_______________________

Touch My Pixel
http://www.touchmypixel.com/
cell: +1 650 842 0920
_______________________


Simon Krajewski

unread,
Mar 2, 2012, 5:57:18 PM3/2/12
to haxe...@googlegroups.com
Am 02.03.2012 23:35, schrieb Ekstazi:
> and i have difficulty with english

Your English is fine, don't worry about it. It's definitely better than
our Russian! ;)

Simon

back2dos

unread,
Mar 3, 2012, 9:18:08 AM3/3/12
to haxe...@googlegroups.com
Actually the distinction between "identifier" and "type" is more of a historical one. It's mainly about an uppercase letter, that's all ;)
See here:

package ;

class Main {
static function main() {
var Foo = 5;
test(Foo);//{ expr => EConst(CType(Foo)), pos => #pos(src/Main.hx:7: characters 7-10) }
}
@:macro static function test(e) {
trace(e);
return e;
}
}

Regards,
Juraj

Dima Granetchi

unread,
Mar 3, 2012, 9:44:53 AM3/3/12
to haxe...@googlegroups.com
Thanks!
Reply all
Reply to author
Forward
0 new messages