This may be silly. I would like to understand whether this is a viable design pattern in Julia. I want to define a new type GraphPoint <: AbstractArray that joins together a point and a function value at that point (like a cache, to avoid re-evaluating a function if you will). I would do it pretty much like this:
immutable GraphPoint <: AbstractArray
x::AbstractArray
fx::Real
end
The idea is to have a function that uses this information to avoid computations, as in
function myFun(point::GraphPoint)
return x.fx
end
function myFun(x::AbstractArray)
# compute something with x
return something
end
GraphPoint objects are created somewhere. It’s not relevant by whom or when. The point is, I would like to naturally extend all other functions defined on AbstractArray to my new type GraphPoint, by simply redirecting them to the x field of the structure. Say, I would like to do matrix-vector products with A::AbstractMatrix and an object point::GraphPoint by doing A*point.x.
Is there a way to naturally extend all functions defined on AbstractArrat to my new type GraphPoint in this sense?
Wow, that’s really interesting, thank you. I will definitely look into it. The reason why I was thinking of a structure like the one I described, is that in my case the value of the function may be obtained somewhere else than by calling the function itself: in that instant, I would like to store such value along with the point.
It is possible though that I could combine memoization into my scenario, to obtain what I need.
Not that I know of, but there are various delegation macros floating around that have a similar effect. I use
""" `delegate(f, typfield)` delegates `f(::T, args...)` to `f(t.field, args...)`
type AA
a
end
@delegate(Base.length, AA.a)
length(AA([1,2,3])) # -> 3
"""
macro delegate(f, typfield)
@assert typfield.head == :.
typ = typfield.args[1]
field = typfield.args[2].args[1]
:(function $(esc(f))(obj::$(esc(typ)), args...; kwargs...)
# Not sure why, but using @inline caused an error on Julia 0.4
$(esc(Expr(:meta, :inline)))
$(esc(f))(getfield(obj, $(esc(Expr(:quote, field)))), args...; kwargs...)
end)
end
Memoize.jl might work, but AFAIK it doesn’t use weak-key dictionaries, so it’ll keep your objects arrays until you explicitly clear the memo. That’s not a problem with the GraphPoint.fx solution (I would use a Nullable there)