Is it possible with macros? Creating new, unique types?

141 views
Skip to first unread message

Alex Kolpakov

unread,
Jun 25, 2015, 1:55:01 AM6/25/15
to haxe...@googlegroups.com
I want to create a new type like this:

// The class/abstract/new type declaration
morph MyNewType
{
   public var name:String;
   public var someValue:Int;
   public var someOtherValue:Float;

   public function new()
   {

   }
}

And use it like this:

var a = new MyNewType();
a.name = "foo";
a.someOtherValue = 1.11;

a = 5; // implicit cast will set someValue to 5. variables name and someOtherValue will be preserved
trace( a.name == "foo"); // has to return true

As abstracts cannot grant such functionality I'm thinking to extend the language, but before messing with the back-end of the language I wanted to ask the gurus of macros if such a thing is possible.

Mark Knol

unread,
Jun 25, 2015, 3:49:01 AM6/25/15
to haxe...@googlegroups.com
Please use stackoverflow to answer this question http://stackoverflow.com/q/31003647/508029

Alex Kolpakov

unread,
Jun 25, 2015, 4:36:09 AM6/25/15
to haxe...@googlegroups.com
Why limit to only one site? Is there a reason I can't use mailing list?

And your answer to that question on stackoverflow is wrong anyway. It's just off point. I'd like to ask you to delete it if possible.
Message has been deleted

Juraj Kirchheim

unread,
Jun 29, 2015, 4:17:44 PM6/29/15
to haxe...@googlegroups.com
The short answer is that you cannot override assignment in Haxe without going out of your way. Is it really so important to have the `=` operator? Can't you just have a `set` method?

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.

aleksejs-...@altplus.co.jp

unread,
Jun 29, 2015, 9:25:40 PM6/29/15
to haxe...@googlegroups.com
Actually I thought it brings A LOT of utility if that would be possible. The main reason being is that we can pass an object to some calculator that wouldn't know anything about the object and treat it as an Int. Currently I use a common interface to decouple the parts of program, but it's still not as abstract as I'd like it to be.

I mean sure, we can do without it, but it's just something that I personally wanted for my programming Zen :)

So yes, it's mostly for academic purposes and to have it in my toolkit; but I really want it ^.^

Thanks,
Alex.

Marcelo de Moraes Serpa

unread,
Jun 29, 2015, 11:01:38 PM6/29/15
to haxe...@googlegroups.com
I don’t yet have the need for it, but I did override `=` quite a bit in my Ruby programs to create nicer abstractions, in the past. 

@Juraj — when you say “...you cannot override assignment in Haxe without going out of your way.”, you mean that it’s actually possible but hard or not possible at all? 

Cheers,

— Marcelo.

Juraj Kirchheim

unread,
Jun 30, 2015, 2:24:44 AM6/30/15
to haxe...@googlegroups.com
On Tue, Jun 30, 2015 at 5:01 AM, Marcelo de Moraes Serpa <fullofc...@gmail.com> wrote:
I don’t yet have the need for it, but I did override `=` quite a bit in my Ruby programs to create nicer abstractions, in the past. 

It's been a while since I used Ruby, but IIRC you don't override the operator itself, but simply use setters. A quick Google search only seemed to confirm that. Is there any documentation on that?
 
@Juraj — when you say “...you cannot override assignment in Haxe without going out of your way.”, you mean that it’s actually possible but hard or not possible at all? 

Technically, it doesn't take much to implement it with a global build macro, that will traverse all expressions and replace anything that matches `macro $lh = $rh` with `Assignment.make($lh, $rh)`, where `Assignment.make` is a simple expression macro that can decide to use the `=` operator or not, depending on the type of `'lh`.

The thing is, that it will most likely make your compilation time go through the roof. Also, it just doesn't sit right with the rest of the language:

```
abstract Custom {
   @:op(a = b) static function assign(a:Custom, b:Value):Return;
}

class HasCustom {
   public var custom(default, set):Custom;
}

var h = new HasCustom();
h.custom = new Value();
```

What does the last line do? Does it call `h.set_custom(new Value())`? Or does it call `Custom.assign(h.custom, new Value())`? This is rather ambiguous.

In C++ you wouldn't have the issue, because while you can override `=`, you can't define setters. Some language features are simply hard to combine.

Best,
Juraj

 

Marcelo de Moraes Serpa

unread,
Jun 30, 2015, 1:35:55 PM6/30/15
to haxe...@googlegroups.com
Interesting, even if not recommended, it’s nice to know it’s possible. Thanks for sharing.

It's been a while since I used Ruby, but IIRC you don't override the operator itself, but simply use setters. A quick Google search only seemed to confirm that. Is there any documentation on that?

Yes, you’re right. Technically you just define a setter with the = postfix. So, yeah, you’re not technically overriding an operator. I should have been more
specific. In my case, I mostly used it to override Array setters, like so:

class MyCustomArr < Array
 def []=(key, value)
  #Do something magic…
  puts “#{key} = #{value}”
 end
 # ...
end

Ruby then adds some syntactic sugar to allow you to call this method like so:

irb(main):006:0> MyCustomArr.new['foo'] = ‘bar'
foo = bar

In the case of setters, you’d just use attr_accessor (or attr_writer to create just the setter), most often. To manually create it:

class Bar
 def foo=(barz)
  puts bar
 end
end

And you can call it like: 

irb(main):006:0> Bar.new.foo = ‘Hello World'
Hello World


Maybe it would make more sense to create a macro that would allow you to call methods (maybe marked with some metadata) with this syntactic sugar instead of overriding all `=` instances? I’m not 100% what’s the OP use case, though.

Cheers,

— Marcelo

Marcelo de Moraes Serpa

unread,
Jul 1, 2015, 1:47:22 AM7/1/15
to haxe...@googlegroups.com
Ops! Just I guess nobody will actually override the []= array method and add a string accessor, since that would be a Dictionary/hash :) my bad.
Reply all
Reply to author
Forward
0 new messages