I've recently upgraded the PatternDispatch.jl
<https://github.com/toivoh/PatternDispatch.jl> package to work with Julia
0.4, and am trying to figure out if I can make it work with Julia master as
well. However it seems that the functions overhaul will force me to find a
somewhat new approach. I'll try to describe my problem below in the hope to
get some ideas how it can be solved with a new Julia:
Example: Given pattern method definitions
@pattern f(x) = x
@pattern f(2) = 42
the package generates code along the lines of
const f = (args...)->dispatch(args...)
match1(x) = x
match2() = 42
dispatch(x::Any) = match1(x_1)
function dispatch(x::Int64)
if x === 2; match2()
else; match1(x)
end
end
The reason to create the closure f is to prevent the user from overloading
the pattern function with regular methods, which might break the dispatch.
Here's the problem: When should the code given above be generated and
compiled?
- The definition for the closure f has to be emitted already from the
first macro invocation, to associate the name f with the pattern
function.
- The rest of the code can't be generated before the last macro
invocation (@pattern f(2) = 42) has been encountered.
Ideally, we would like to generate the dispatch code the first time that f
is called.
In previous Julia versions, I was able to make an initial dispatch method
that would invoke code generation and then eval new overloads for the same
function, hiding the old method with the generated ones. But after the
function overhaul, I guess that f is compiled to use the old dispatch
method when it is first called, and doesn't care that it becomes overloaded
afterwards.
How can I make code generation happen the first time that f is called? The
first thing that comes to mind is making f call a generated function that
will generate the dispatch code. But as far as I can remember, there is no
guarantee that code generation for the generated function waits for the
first time that it is called. Would this be safe? Is there a better way?