Creating multiple functions (in a different or global scope) using a one macro

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 :smile:

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.