Define Operator from a Macro

3 views
Skip to first unread message

Andrew Davey

unread,
Oct 24, 2008, 7:30:09 PM10/24/08
to Nemerle Forum
I'm trying to define the == and != operators from a macro.
Something like:

tb.Define(<[ decl:
public static ==(p1 : $t, p2 : $t) : bool
{
// compare the two parms...
}
]>);

However it won't compile the "==".
>> Error: parse error near operator '==': expecting type declaration
I can construct the function definition manually instead of using the
syntax lift, but that seems pretty annoying.

Any ideas? Thanks.

Dmitry Ivankov

unread,
Oct 25, 2008, 5:36:03 AM10/25/08
to nemer...@googlegroups.com
On Sat, Oct 25, 2008 at 5:30 AM, Andrew Davey <a.j....@gmail.com> wrote:

I'm trying to define the == and != operators from a macro.
Something like:

tb.Define(<[ decl:
public static ==(p1 : $t, p2 : $t) : bool
{
 // compare the two parms...
}
]>);

However it won't compile the "==".
Doesn't @== help?

Andrew Davey

unread,
Nov 3, 2008, 12:18:04 AM11/3/08
to Nemerle Forum
Thanks, that fixed it. It's strange because I thought I tried that,
but I must have missed something. Writing macros feels like trial and
error some of the time!

On Oct 25, 4:36 am, "Dmitry Ivankov" <divanor...@gmail.com> wrote:
> > Any ideas? Thanks.- Hide quoted text -
>
> - Show quoted text -

Andrew Davey

unread,
Nov 3, 2008, 12:20:48 AM11/3/08
to Nemerle Forum
If people are interested, here is the code for my ImplementEquality
macro.
The macro is applied to a class and takes a list of class members that
should be compared for an object to equal another.
It overrides the Equals, GetHashCode, == and != functions.

[MacroUsage(MacroPhase.BeforeInheritance, MacroTargets.Class)]
public macro ImplementEquality(typeBuilder : TypeBuilder, params
members : list[PExpr])
{
ImplementEqualityModule.AddEqualsMethod(typeBuilder, members);
ImplementEqualityModule.AddEqualityOperator(typeBuilder);
ImplementEqualityModule.AddInequalityOperator(typeBuilder);
}

module ImplementEqualityModule
{
public AddEqualsMethod(typeBuilder : TypeBuilder, members :
list[PExpr]) : void
{
def other = Macros.NewSymbol();
def comparisons = members.Map(m => {
def s = Splicable.Name(Name(m.ToString()));
<[ (this.$s).Equals($(other : name).$s) ]>
});

def b = comparisons.Tail.FoldLeft(comparisons.Head, (c,
acc) => <[ $acc && $c ]>);
typeBuilder.Define(<[ decl:
public override Equals(obj : object) : bool
{
match (obj) {
| null => false
| $(other : name) is $
(typeBuilder.ParsedTypeName) => $b
| _ => false
}
}
]>);

def hashCodes = members.Map(m => { def s =
Splicable.Name(Name(m.ToString())); <[ this.$s.GetHashCode() ]> });
def hashCode = hashCodes.Tail.FoldLeft(hashCodes.Head, (c,
acc) => <[ $acc ^ $c ]>);
typeBuilder.Define(<[ decl:
public override GetHashCode() : int
{
$hashCode
}
]>);
}

public AddEqualityOperator(typeBuilder : TypeBuilder) : void
{

typeBuilder.Define(CreateEqualityOperator(typeBuilder.ParsedTypeName,
false));
}

public AddInequalityOperator(typeBuilder : TypeBuilder) : void
{

typeBuilder.Define(CreateEqualityOperator(typeBuilder.ParsedTypeName,
true));
}

CreateEqualityOperator(typeRef : PExpr, invert : bool) :
ClassMember.Function
{
def op = Splicable.Name(Name(if (invert) "!=" else "=="));

<[ decl:
public static $op(p1 : $(typeRef), p2 : $(typeRef)) :
bool
{
def p1Null = object.ReferenceEquals(null, p1);
def p2Null = object.ReferenceEquals(null, p2);
match (p1Null, p2Null) {
| (true, true) => true
| (false, false) => $(if (invert) <[false ==
p1.Equals(p2)]> else <[p1.Equals(p2)]> )
| _ => false
}
}
]>
}
}

Sorry if Google Groups loses the indentation...

VladD2

unread,
Nov 6, 2008, 8:22:21 AM11/6/08
to nemer...@googlegroups.com
Excuse me, you know about StructuralHashCode and StructuralEquality macros?

2008/11/3 Andrew Davey <a.j....@gmail.com>:

--
С уважением,
Чистяков Владислав,
www.rsdn.ru

Andrew Davey

unread,
Nov 6, 2008, 9:49:34 AM11/6/08
to Nemerle Forum
I've not seem them documented anywhere! Nemerle really needs a
complete documentation of all available macros. I don't think digging
through the source code really counts.


On Nov 6, 8:22 am, VladD2 <v...@rsdn.ru> wrote:
> Excuse me, you know about StructuralHashCode and StructuralEquality macros?
>
> 2008/11/3 Andrew Davey <a.j.da...@gmail.com>:
> Чистяков Владислав,www.rsdn.ru- Hide quoted text -

VladD2

unread,
Nov 6, 2008, 2:07:06 PM11/6/08
to nemer...@googlegroups.com
6 ноября 2008 г. 17:49 пользователь Andrew Davey <a.j....@gmail.com> написал:

>
> I've not seem them documented anywhere! Nemerle really needs a
> complete documentation of all available macros.

Oh, you right! :( It's really problem.
Will be nice if someone help we make documentation more fulfilled.

> I don't think digging
> through the source code really counts.

But anyone can ask about its problems in this forum.

Andrew Davey

unread,
Nov 6, 2008, 4:16:46 PM11/6/08
to Nemerle Forum
I see macros as the main feature of Nemerle that set it apart from C#,
VB and F#.
It's the reason I use Nemerle.

What would be cool is a before and after style presentation of macros.
Where we show side-by-side the full code and the macro code. This
helps people see the power of macros and also provides a handy
reference for what the macro is doing.

On Nov 6, 2:07 pm, VladD2 <v...@rsdn.ru> wrote:
> 6 ноября 2008 г. 17:49 пользователь Andrew Davey <a.j.da...@gmail.com> написал:

VladD2

unread,
Nov 7, 2008, 3:47:42 PM11/7/08
to nemer...@googlegroups.com
2008/11/7 Andrew Davey <a.j....@gmail.com>:

>
> I see macros as the main feature of Nemerle that set it apart from C#,
> VB and F#.
> It's the reason I use Nemerle.

Macro is perfect feature, but Nemerle have many excellent feature
besides: functional programming, type inference, AlgTD (varints).

> What would be cool is a before and after style presentation of macros.
> Where we show side-by-side the full code and the macro code. This
> helps people see the power of macros and also provides a handy
> reference for what the macro is doing.

It's good idea, but it need lot of time.

Andrew Davey

unread,
Nov 8, 2008, 10:02:54 AM11/8/08
to Nemerle Forum
I took a proper look at those macros. They do not work together. This
code does not compile:

using System;
using Nemerle.Macros;

namespace MacrosDemo
{
[Record]
[StructuralEquality]
[StructuralHashCode]
public class Location
{
public Latitude : double;
public Longitude : double;
}

module Program
{
Main() : void
{
def l1 = Location(30, 70);
def l2 = Location(30, 70);

Console.WriteLine(l1.Equals(l2))
}
}
}

Any ideas?

Also, the == and != operators are not defined.

On Nov 6, 8:22 am, VladD2 <v...@rsdn.ru> wrote:

VladD2

unread,
Nov 8, 2008, 11:42:48 AM11/8/08
to nemer...@googlegroups.com
2008/11/8 Andrew Davey <a.j....@gmail.com>:

>
> I took a proper look at those macros. They do not work together. This
> code does not compile:

You should add
using Nemerle.Extensions;
into your test.

> Also, the == and != operators are not defined.

I see two variants how we can fix this problem:
1. We can create macro which implement this operators using Equals(object o).
2. Modify StructuralEquality macro.

You can send me patch which resolve this problem and I try apply it to
http://nemerle.org/svn/nemerle/trunk/macros/core.n

Reply all
Reply to author
Forward
0 new messages