4

The Julia docs state that functions are first class objects. I understand that to mean that I ought to be able to use and define them in the same way I would plain old data types.

I'm therefore surprised that

function a(b::Int64)
    if b > 0
        c = 1
    else
        c = -1
    end
end
a(2)

works beautifully, whilst

function d(e::Int64)
    if e > 0
        println("Positive argument")
        function f()
            println("Return positive")
            return e
        end
    else
        println("Negative argument")
        function f()
            println("Return negative")
            return e
        end
    end
    return f
end

works when used, but does something very counter intuitive:

>>> g = d(2)
Positive argument
(::f) (generic function with 1 method)
>>> g()
Return negative
2

Or alternately:

>>> g = d(-2)
Negative argument
ERROR: UnderVarError: f not defined

which is perhaps more useful than returning something unexpected, but none the less is even more confusing.

I would expect that the version of f from the appropriate branch would be returned. Where has my understanding of how function definitions in Julia work gone wrong?

hjab
  • 163
  • 6

2 Answers2

6

I can show you how to solve the problem, but the actual behavior you describe is a known issue https://github.com/JuliaLang/julia/issues/15602.

In general if you do this:

function d(e::Int64)
    if e > 0
        println("Positive argument")
        f = function()
            println("Return positive")
            return e
        end
    else
        println("Negative argument")
        f = function()
            println("Return negative")
            return e
        end
    end
    return f
end

all works fine. The difference is that you create an anonymous function and assign it to a variable.

Bogumił Kamiński
  • 66,844
  • 3
  • 80
  • 107
0

In your code, you have define the same function f twice, even though it was in different part of the "if then else" structure

I think you can solve it by doing this

function d(e::Int64)
    if e > 0
        println("Positive argument")
        function Alpha()
            println("Return positive")
            return e
        end
        return Alpha
    else
        println("Negative argument")
        function Beta()
            println("Return negative")
            return e
        end
        return Beta
    end
end
Steven Siew
  • 843
  • 8
  • 11