Search code examples
functionmethodsjuliadispatch

Julia: Same function for multiple types?


I have this big function that I defined on a vector, but I'd like it to work also with a single value. I'd like the type of the first argument to be either a vector or a number.

I triend the following:

function bigfunction(x::Vector, y::Float64=0.5)

  # lots of stuff
  z = x .+ y
  return z
end


bigfunction(x::Number) = bigfunction()

The function works on a vector, but not on the number.

bigfunction([0, 1, 3])
bigfunction(2)

Should I do something with Union{} as I've seen sometimes? Or redefining the method in a different way?


Solution

  • This question and the responses help illustrate for me the points made at the great blog post by Chris Rackauckas on type dispatch in Julia.

    I have collated the responses into the following code:

    # I ran this only in Julia 1.0.0.
    
    ## ========== Original function ==========
    ## function bigfunction(x::Vector, y::Float64=0.5)
    ##     # lots of stuff
    ##     z = x .+ y
    ##     return z
    ## end
    ## bigfunction(x::Number) = bigfunction()
    ## println(bigfunction([0, 1, 3]))
    ## println(bigfunction(2))
    ## ---------- Output has ERROR ----------
    ## [0.5, 1.5, 3.5]
    ## ERROR: LoadError: MethodError: no method matching bigfunction()
    
    
    # ========== Answer Suggested by Picaud Vincent in comments ==========
    # Note use of Union in function signature.
    function bigfunction(x::Union{Vector, Number}, y::Float64=0.5)
        # lots of stuff
        z = x .+ y
        return z
    end
    println(bigfunction([0, 1, 3]))
    println(bigfunction(2))
    ## ---------- Output Okay ----------
    ## [0.5, 1.5, 3.5]
    ## 2.5
    
    
    # ========== Answer Suggested by Robert Hönig in comments ==========
    # Note change in line right after function definition.
    function bigfunction(x::Vector, y::Float64=0.5)
        # lots of stuff
        z = x .+ y
        return z
    end
    bigfunction(x::Number) = bigfunction([x])
    println(bigfunction([0, 1, 3]))
    println(bigfunction(2))
    ## ---------- Output Okay ----------
    ## [0.5, 1.5, 3.5]
    ## 2.5
    
    
    # ========== Answer Suggested by Chris Rackauckas ==========
    # Note change in function signature using duct typing--no type for x.
    function bigfunction(x, y=0.5)
        # lots of stuff
        z = x .+ y
        return z
    end
    println(bigfunction([0, 1, 3]))
    println(bigfunction(2))
    ## ---------- Output Okay ----------
    ## [0.5, 1.5, 3.5]
    ## 2.5