Overloading ()

Dear all,

I am trying to overload the () operator in order to simulate executability of an object type.
Basically, this is what I got:

import Base: ()

Base.:()(L::Lagrangian{F}, q::Vector{G}, v::Vector{G}) where {F<:Real, G<:Real}
	eval(L, q, v)
end

and the first line fails with syntax: invalid "import" statement: expected identifier, which suggest to me that the ()operator/function is not imported that way. As such, my question would be: Is there a way to overload the parentheses? And if yes, how?

Please note that there are probably two different parentheses, namely the ones for expression grouping (a + b) + c and the “function call” parentheses f(). I am only interested in the latter.

PS. I realize this may be an extremely naive question so sorry in advance if I should have looked elsewhere before posting.

() is not an operator and not an identifier. It’s just syntax which, depending on what else is written, may denote a function call (such as f()) or construct a tuple (such as (1,2,3)).

1 Like

I see, so the unfortunate takeaway is that I cannot do this?

I think you want to do the following

julia> struct A
           x
       end;

julia> (a::A)() = a.x

julia> t = A(1);

julia> t()
1

Is this what you want? It sounds like it.

function (L::Lagrangian{F})(q::Vector{G}, v::Vector{G}) where {F<:Real, G<:Real}
	eval(L, q, v)
end

See Methods · The Julia Language

OP should definitely not be using eval. eval is pretty much never the solution someone is looking for and is indicative of an XY problem.

1 Like

The eval is redundant - in that definition, you can just write your code however you’d like and still have access to L, q and v.

Oh, I didn’t even catch that OP used eval. They should definitely not use that. I think they just called their function eval, unaware of the fact that every module already defines an eval function that does something that is probably unrelated to what they want to do.

That is indeed what I wanted, thank you for the link as well.

@pdeffebach Any chance you could expand? I am familiar with the XY problem but I fail to see how this is it… Although I don’t doubt that having both the functor definition and the eval function is redundant

True enough, but should Multiple Dispatch not take care of it? Or did I understand that wrong?

Your three-argument eval method and the original one-argument one can coexist, it should not cause problems. However, it may be confusing to add methods to eval instead of using a new function name, since your usage is unrelated to the original purpose of the eval function.

1 Like

I have just remembered what eval was originally for and I realize that you guys make a very good point, so I shall remove the eval() function in favour of the functor behavior. Thank you very much for explaning!

2 Likes