Hi,
I am having a problem creating multiple functions/methods using a one macro since this latter outputs either one function (via combinedef for example) or an array of expressions that could be used later to create the functions but they would live in the new world age.
any help is greatly appreciated.
julia> macro example(fprefix)
exs = [quote $(Symbol(fprefix, :_, i))() = $i end for i = 1:3]
@show exs
esc(Expr(:block, exs...))
end
@example (macro with 1 method)
julia> @example f
exs = Expr[quote
#= REPL[29]:2 =#
f_1() = begin
#= REPL[29]:2 =#
1
end
end, quote
#= REPL[29]:2 =#
f_2() = begin
#= REPL[29]:2 =#
2
end
end, quote
#= REPL[29]:2 =#
f_3() = begin
#= REPL[29]:2 =#
3
end
end]
f_3 (generic function with 1 method)
julia> f_2()
2
thank you jling for the quick reply.
that works. However, the functions are accessible only in Main (or wherever the macro was called from), and i need them to be accessible in my package. (sorry i did not mention that upfront). I guess now I am asking a new question
module module1
macro example(fprefix)
exs = [quote $(Symbol(fprefix, :_, i))() = $i end for i = 1:3]
esc(Expr(:block, exs...))
end
function integrate()
println(f_1())# UndefVarError: f_1 not defined
# Main.f_1() works but we would not know from where the macro would be called
end
end
module1.@example f
module1.integrate()
#---------------------------------------my original code that creates only one function-------------
module module1
using ExprTools
macro ode(odeExpr)
Base.remove_linenums!(odeExpr)
equation1=(odeExpr.args[1])
def=Dict{Symbol,Any}()
def[:head] = :function
def[:name] = :f1
def[:args] = [:(u::Vector{Float64})]
def[:body] = quote $equation1 end
combinedef(def)
end
function integrate()
println(f1([2.2,3.4]))
end
end#end module
#-------------------------user space-----------------------------------
module1.@ode begin
u[1]+2.0u[2]
u[2]-3
end
module1.integrate()
I can’t tell if you’re thinking about user evaluating functions into a module, or you’re the developer and want to define multiple functions, because it clearly works if you just call it in the module:
julia> module M
macro example(fprefix)
exs = [quote $(Symbol(fprefix, :_, i))() = $i end for i = 1:3]
esc(Expr(:block, exs...))
end
function integrate()
println(f_1())
end
@example f
end
Main.M
julia> M.integrate()
1
I am trying to create a package that solves differential equations. so basically the user has to enter the equations in main using a macro, and I need those equations separately in functions inside my package. many thanks for your time!
Probably you though already about this. But why don’t you ask the user to pass the functions directly as variables?
# User code
eqs = module1.@ode ...
module1.integrate(eqs)
The design you outline would it make impossible to define two systems at the same time.
‘eqs’ variable would hold the functions as an expression that could be used later to create the functions but they would live in the new world age…but also this could be solved in many ways:
*eval (requires the user to call another thing)
*GeneralizedGenerated
*mk_function
*RuntimeGeneratedFunctions
*invokelatest
*getfield(Main,…) using the solution of jling
as an initial comparison, it tooks like using the simple eval would do the job for me. thanks all for your help.