You could also use a macro:

module MetaFoo

export Foo, ops, @foo_op

type Foo{T<:Number}
    x::Vector{T}
end

const ops = [+, -, *, /]
const syms = [symbol(op) for op in ops]

for sym in syms
    dot_sym = symbol(".$sym")
    docstr = "`$sym` also works for `Foo` types!"
    @eval begin
        @doc $docstr ->
        function Base.$sym(a::Foo, b::Foo)
            Foo($dot_sym(a.x, b.x))
        end
    end
end

macro foo_op(op)
    dot_op = symbol(".$op")
    docstr = "`$op` also works for `Foo` types!"
    quote
        function Base.$op(a::Foo, b::Foo)
            Foo($dot_op(a.x, b.x))
        end
        @doc $docstr Base.$op
        Base.$op
    end
end

end

Use:

help?> +
search: + .+

  +(x, y...)

  Addition operator. x+y+z+... calls this function with all arguments, i.e.
  +(x, y, z, ...).

julia> include("MetaFoo.jl")
MetaFoo

julia> using MetaFoo

help?> +
search: + .+

  +(x, y...)

  Addition operator. x+y+z+... calls this function with all arguments, i.e.
  +(x, y, z, ...).

  + also works for Foo types!

help?> ^
search: ^ .^

  ^(x, y)

  Exponentiation operator.

  ^(s, n)

  Repeat n times the string s. The repeat function is an alias to this
  operator.

  julia> "Test "^3
  "Test Test Test "

julia> @foo_op ^
^ (generic function with 46 methods)

help?> ^
search: ^ .^

  ^(x, y)

  Exponentiation operator.

  ^(s, n)

  Repeat n times the string s. The repeat function is an alias to this
  operator.

  julia> "Test "^3
  "Test Test Test "

  ^ also works for Foo types!

julia>


El martes, 15 de diciembre de 2015, 10:28:53 (UTC-6), ami...@gmail.com 
escribió:
>
> 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(+)
>
> 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