On Friday, 22 March 2013 18:40:24 UTC+1, John Myles White wrote:
This is a suggestion I made long ago that Patrick, Toivo and Stefan suggested generalizing substantially. Unfortunately I didn't write very much code for it when I first demo'ed it out. Because it keeps coming up, I'll work on something today. It would be good to at least start an RFC that we can all work on. Toivo had a lot of ideas, but they seemed substantially more complex than what I was looking for.
Yeah, I can't take credit for the idea.
Anyway, what I'm most interested in is a syntax for delegation that is transparent. So far, I don't think there's any getting around specifying each function that you want to delegate by name. I guess that the simplest way would be by
@eval and
for loops. Toy example:
julia> type T
x
end
julia> import Base.sin, Base.cos
julia> for f in (:+, :- ) # delegate binary + and - to T.x
@eval $f(a::T, b::T) = $f(a.x, b.x)
end
julia> for f in (:sin, :cos) # delegate sin and cos
@eval $f(a::T) = $f(a.x)
end
julia> T(2)
T(2)
julia> T(2) + T(4)
6
julia> sin(T(3.14))
0.0015926529164868282
Most things that we could come up with would be fancier ways to write this kind of thing.
One thing to consider is that it seems hard to do this with a macro without
eval, at least if the list of functions to delegate to isn't listed literally in the macro arguments. Not sure if that's a problem, maybe there's a good reason to break the no-eval-in-macro rule in this case. (Strictly speaking, the macro could emit a call to
eval instead of calling it at expansion time, but then I guess it should be pretty clear from the macro name that it does that.)