-
Notifications
You must be signed in to change notification settings - Fork 2
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
Bug with low-level interface and generate_interface macro #26
Comments
I got this import AtomsCalculators: @generate_interface, calculate, Energy, Forces, Virial
abstract type ASEcalculator end
@generate_interface function calculate(::Energy,
system, calc::ASEcalculator, parameters=nothing, state=nothing; kwargs...)
# ...
end Giving this ERROR: LoadError: Possible typo (or other issue) in function definition. Could not determine the type of calculation (energy, forces or virial...).
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:35
[2] var"@generate_interface"(__source__::LineNumberNode, __module__::Module, expr::Any)
@ AtomsCalculators ~/.julia/packages/AtomsCalculators/pKMDb/src/utils.jl:43
in expression starting at REPL[10]:1
caused by: type Symbol has no field head
Stacktrace:
[1] getproperty(x::Symbol, f::Symbol)
@ Base ./Base.jl:37
[2] determine_type_calculation(expr::Expr)
@ AtomsCalculators ~/.julia/packages/AtomsCalculators/pKMDb/src/utils.jl:114
[3] var"@generate_interface"(__source__::LineNumberNode, __module__::Module, expr::Any)
@ AtomsCalculators ~/.julia/packages/AtomsCalculators/pKMDb/src/utils.jl:41 Line 114 in utils reads if expr.args[1].args[1].head != :.
error("function definition is not correct")
end This part will check that the call is So, calling @generate_interface function AtomsCalculators.calculate(::Energy,
system, calc::ASEcalculator, parameters=nothing, state=nothing; kwargs...)
# ...
end works. As a note. In the initial draft for AtomsCalculators there was discussion of wheter the definition need to be That being said the error message here should be better. Also the documentation should explain better the macro use. |
I agree. In any case I would argue that it is confusing to standard Julia programmers that extending the function |
I ran into the same error message (albeit for different reasons) during the JuliaCon hackathon when trying to get Cedric's branch to work (see CedricTravelletti/DFTK.jl#4, which I think might be unnecessary now so I can probably close it?) awhile back, so seconded that this error could be better. I'm not so experienced with some of this metaprogramming stuff, but it seems that one should be able to write a more flexible/less hardcoded kind of check than what's there now... |
Here is a little bit more on the functionality of the macro. You can do following just fine using Unitful
import AtomsCalculators: @generate_interface, calculate, Energy, Forces, Virial
abstract type MyCalc end
function calculate(::Energy, sys, calc::MyCalc, pr=nothing, st=nothing; kwargs...)
## ....
return 0.0u"eV"
end You then would need to generate the high-level interface. The macro in practice wraps the low level call to following function AtomsCalculators.potential_energy(sys, calc::MyCalc, kwargs...)
tmp = AtomsCalculators.calculate(AtomsCalculators.Energy(), sys, calc::MyCalc, nothing, nothing; kwargs...)
return tmp.energy
end If you run that code in the same context using Unitful
import AtomsCalculators: @generate_interface, calculate, Energy, Forces, Virial
abstract type MyCalc end
function calculate(::Energy, sys, calc::MyCalc, pr=nothing, st=nothing; kwargs...)
## ....
return 0.0u"eV"
end
function AtomsCalculators.potential_energy(sys, calc::MyCalc, kwargs...)
tmp = AtomsCalculators.calculate(AtomsCalculators.Energy(), sys, calc::MyCalc, nothing, nothing; kwargs...)
return tmp.energy
end this will fail because We could have all the individual functions in the scope, but that would pollute the scope, and we want to keep it small as possible also. Thus the best option is to have only Currently the macro checks that using AtomsCalculators # or import AtomsCalculators
import AtomsCalculators: @generate_interface, calculate, Energy, Forces, Virial
@generate_interface function calculate(::Energy,
system, calc::ASEcalculator, parameters=nothing, state=nothing; kwargs...)
# ...
end This way we could have better error messages also. |
I'm definitely in favor of anything that facilitates better error messages! |
I also like your last suggestion @tjjarvinen. Also related to #27, I am wondering if instead of annotating functions with a macro, a simpler solution could be to have two generate macros, one for the high-level implementation pattern and one for the low-level implementation pattern. My idea is that you define all methods you want to specialise and then call |
Yes we can do that. After giving it a little though, this will be a better way and I can add other functionality too. I will make a PR for it. Thanks for the idea! |
I am in the process of updating ASEconvert to v0.2 (mfherbst/ASEconvert.jl#21)
This works:
but this does not
and (related to #23) gives the rather cryptic error message
from which it took me a while to find out what I had to change to the function definition to make the macro work.
@tjjarvinen Could you take a look?
The text was updated successfully, but these errors were encountered: