Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia automatically generate functions and export them

I want to automatically generate some functions and export them automatically. To have some concrete example, lets say I want to build a module, which provides functions that take a signal and apply a moving average/maximum/minimum/median... to it.

The code generation already works:

for fun in (:maximum, :minimum, :median, :mean)
  fname = symbol("$(fun)filter")
  @eval ($fname)(signal, windowsize) = windowfilter(signal, $fun, windowsize)
end

Giving me functions

maximumfilter
minimumfilter
...

But how do I export them automatically? e.g. I would like to add some code to the above loop like

export $(fname)

and have each function exported after creation.

like image 933
Jan Weidner Avatar asked Jul 09 '15 09:07

Jan Weidner


1 Answers

You could consider using a macro:

module filtersExample

macro addfilters(funs::Symbol...)
  e = quote end  # start out with a blank quoted expression
  for fun in funs
    fname = symbol("$(fun)filter")   # create your function name

    # this next part creates another quoted expression, which are just the 2 statements
    # we want to add for this function... the export call and the function definition
    # note: wrap the variable in "esc" when you want to use a value from macro scope.
    #       If you forget the esc, it will look for a variable named "maximumfilter" in the 
    #       calling scope, which will probably give an error (or worse, will be totally wrong
    #       and reference the wrong thing)
    blk = quote
      export $(esc(fname))
      $(esc(fname))(signal, windowsize) = windowfilter(signal, $(esc(fun)), windowsize)
    end

    # an "Expr" object is just a tree... do "dump(e)" or "dump(blk)" to see it
    # the "args" of the blk expression are the export and method definition... we can
    # just append the vector to the end of the "e" args
    append!(e.args, blk.args)
  end

  # macros return expression objects that get evaluated in the caller's scope
  e
end

windowfilter(signal, fun, windowsize) = println("called from $fun: $signal $windowsize")

# now when I write this:
@addfilters maximum minimum

# it is equivalent to writing:
#   export maximumfilter
#   maximumfilter(signal, windowsize) = windowfilter(signal, maximum, windowsize)
#   export minimumfilter
#   minimumfilter(signal, windowsize) = windowfilter(signal, minimum, windowsize)

end

when you load it, you'll see the functions are automatically exported:

julia> using filtersExample

julia> maximumfilter(1,2)
called from maximum: 1 2

julia> minimumfilter(1,2)
called from minimum: 1 2

See the manual for more info.

like image 187
Tom Breloff Avatar answered Sep 27 '22 17:09

Tom Breloff