Caching function values




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

The idea is to have a function that uses this information to avoid computations, as in

function myFun(point::GraphPoint)
  return x.fx

function myFun(x::AbstractArray)
  # compute something with x
  return something

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?

Thank you.

Way to cache output from immutable input?

This is called “memoization.” If it helps, there’s already a package:


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.

Thank you again!


Sure, if you’ll need that value in many places, it’s entirely reasonable to carry it around. Good luck!


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

    @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...)

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)