Hi. Just curious: Is it possible to harness the Julia dispatcher as an inference engine by placing restrictions on function arguments to create a rule-based program? So for example I might implement the Greatest Common Denominator function gcd like this:
gcd(a,b) = gcd(b,mod(a,b))
gcd(a,0) = a
Clearly this code won’t work, but every now and then I get the feeling there might be some way of doing it using type restrictions, so I thought I’d ask.
struct IntNotZero
x::Int
end
struct IntZero
x::Int
end
function myMod(a::IntNotZero,b::IntNotZero)
if a.x==0
return IntZero(0)
elseif mod(a.x,b.x)==0
return IntZero(0)
else
return IntNotZero(mod(a.x,b.x))
end
end
gcd(a::IntNotZero,b::IntZero) = a
gcd(a::IntNotZero,b::IntNotZero) = gcd(b,myMod(a,b))
The downside of this is that Julia compiles a new version of your function for each value you pass, which produces highly optimized code for that value but has a lot of compiler overhead. It doesn’t really make sense to do this for something like gcd.
I hope it is clear that this is just fun and not something which should be really done like this (Val or Types doesn’t matter). It will get clunky really fast.
Isn’t Prolog or Erlang better suited for problems like this?
Another attempt in julia can be perhaps some kind of DSL (domain specific language) but I don’t know much about this.
Oh yes, I’m aware of that. I’m just kind of musing out loud. I’m thinking that the dispatcher is using some form of backtracking, which is the basis of the resolution logic in Prolog, and it struck me that that could make it possible to set up rulebases, or maybe even the high-performance pattern-matching of Mathematica.
As for whether it should be really done like this, I think that’s more a question of whether the idea fits the Julia compiler. If it does, that’d be an interesting new way of using it, but I must admit that converting every integer into a new type is probably not exactly what I had intended!