On Tue, Dec 15, 2015 at 11:28 AM,  <[email protected]> wrote:
> Hello,
>
> I have a type M and I would like to redefine all the operations *, +, -, /
> etc. over it. Since it would be everytime the same operations and since I
> want my code to be concise I thought about using a macro to define them,
> such as:
>
> type M
>     a
>     b
> end
>
> macro operator_obs(name)
>     return quote
>         function $name(m1::M, m2::M)
>             return M($name(m1.a, m2.a), $name(m1.b, m2.b))
>         end
>     end
> end
>
> @operator_obs(+)

Whenever you assign something in a macro, it is replaced with a
generated unique symbol so that it won't collide with other symbols in
the scope you expand the macro. In this case, you are defining a
function `$name` so the macro expander assumes it should not override
anything in the scope of the expanded macro and replaces it with a
gensym instead.

You can see this if you check the result of the macro in REPL

```
julia> @operator_obs +
#2#+ (generic function with 1 method)
```

The solution to this is to escape your function name, i.e. replace all
`$name` with `$(esc(name))`. Also, since you are extending a base
function, you should write `function Base.(+)` instead of `function
+`.

>
> m1 = M(2.0,3.0)
> m2 = M(4.0,5.0)
>
> +(m1, m2)
>
> But this doesn't seem to work. What did I do wrong?
>
> Many thanks,

Reply via email to