Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a function inside a function depending on variable values

Tags:

julia

I'm writing a function that I would find easier to write and read if it could define another function differently depending on input or runtime values of variables (and then use that function). The following illustrates the idea (even if defining a function inside a function is of no advantage in this simple example):

julia> function f(option::Bool)
           if option
               g() = println("option true")
               g()
           else
               g() = println("option false")
               g()
           end
       end;
WARNING: Method definition g() in module Main at REPL[1]:3 overwritten at REPL[1]:6.

julia> f(true)
option false

julia> f(false)
ERROR: UndefVarError: g not defined
 in f(::Bool) at .\REPL[1]:7

Using the full function ... end syntax for g does not help either.

The question is: am I doing something wrong to get that warning and that unintended behavior, or Julia does not allow this for a reason? And if it can be done, how?

N.B. For my present need, I can just define two different functions, g1 and g2, and it seems to work; but what if there were many cases of g for just one task concept? I thought that a function, being a first-class object, could be manipulated freely: assigned to a variable, defined in a way or another depending on conditions, overwritten, etc.

P.S. I know I can compose a String and then parse-eval it, but that's an ugly solution.

like image 295
Felipe Jiménez Avatar asked Dec 05 '16 19:12

Felipe Jiménez


Video Answer


1 Answers

You want to use anonymous functions. This is a known issue (this other issue also shows your problem).

function f(option::Bool)
           if option
               g = () -> println("option true")
           else
               g = () -> println("option false")
           end
         g
       end

In v0.5 there's no performance difference between anonymous and generic functions, so there's no reason to not use anonymous functions. Note that there's also a sytnax for extended anonymous functions:

f = function (x)
    x
end

and you can add dispatches via call overloading:

(T::typeof(f))(x,y) = x+y

so there's no reason to not use an anonymous function here.

like image 196
Chris Rackauckas Avatar answered Oct 18 '22 06:10

Chris Rackauckas