-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stricter types for evaluate!! methods #629
Conversation
Pull Request Test Coverage Report for Build 9909759705Details
💛 - Coveralls |
Looks good! Feels like there might be some hidden implications, so let me take a look now. |
My reading of the issue is this: sometimes user confuse the "model creating function" with the functor In this case, Line 865 in 72cfd15
Lines 912 to 914 in 3b3840d
At this time, infinite recurse will occur, because no other evaluate!! will be type-matched.
Current proposed resolution works, but I wonder maybe we can just combine the two functions above, i.e., modifying Line 865 in 72cfd15
(model::Model)(args...) = first(evaluate!!(model, Random.default_rng(), args...)) Would this be cleaner? I am not sure. Additionally, the thrown error will be something like ERROR: MethodError: no method matching evaluate!!(::Model{…}, ::Vector{…}, ::Vector{…})
The function `evaluate!!` exists, but no method is defined for this combination of argument types.
Closest candidates are:
evaluate!!(::Model, ::AbstractVarInfo, ::AbstractContext)
@ DynamicPPL ~/DynamicPPL.jl/src/model.jl:888
evaluate!!(::Model, ::Random.AbstractRNG)
@ DynamicPPL ~/DynamicPPL.jl/src/model.jl:898
evaluate!!(::Model, ::Random.AbstractRNG, ::AbstractVarInfo)
@ DynamicPPL ~/DynamicPPL.jl/src/model.jl:898
... which, arguably is still not great. Because it exposes the un-exported |
With Is your main wish here to have the error message be clearer, or for the code to be cleaner? Even if we change the relation of |
I don't have objections to type-restrict |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be cleaner and more correct to just write out the varargs we want to support? For instance, args:::Union{AbstractVarInfo,AbstractSampler,AbstractContext}...
will allow to specify multiple contexts or samplers etc., which is not useful at all (and will error in the next step in the evaluate!!
pipeline). Similarly, instead of arbitrary numbers o f contexts as specified by ::AbstractContext...
we actually only want 0 or 1 contexts.
I agree @devmotion, but I wonder if we embark on that we should actually rework the method definitions generally to make the whole definition of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harmonizing with @mhauru, I agree we can improve the evalaute!!
function interface. But it will have to be a future PR. For now, I think the fix is okay.
72cfd15
to
2baff61
Compare
function AbstractPPL.evaluate!!(model::Model, args...) | ||
function AbstractPPL.evaluate!!( | ||
model::Model, args::Union{AbstractVarInfo,AbstractSampler,AbstractContext}... | ||
) | ||
return evaluate!!(model, Random.default_rng(), args...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, maybe
return evaluate!!(model, Random.default_rng(), args...) | |
return AbstractPPL.evaluate!!(model, Random.default_rng(), args...) |
Addresses TuringLang/Turing.jl#2182
The earlier
could lead to infinite recursion. Restricting the types of the varargs solves that.
I would have wanted to rework the method definitions of
evaluate!!
more generally because I find it hard to understand what all the valid ways of calling it are. I thought about it for a bit and couldn't come up with a good solution though, so maybe later.