Multiple dispatch for methods of a class in Julia
Asked Answered
K

1

6

My question is how can I overload certain method within a certain class in Julia?

In other words suppose I have a following definition of a class:

type Sometype
    prop::String

    setValue::Function

    # constructor
    function Sometype()
        this = new ()

        this.prop = ""

####### v1 #######
        this.setValue = function(v::Real)
            println("Scalar Version was Invoked!")
            # operations on scalar...
            # ...
        end

####### v2 #######
        this.setValue = function(v::Vector{Real})
            println("Vector Version was Invoked!")
            # operations on vector...
            # ...
        end

####### v3 #######
        this.setValue = function(v::Matrix{Real})
            println("Matrix Version was Invoked!")
            # operations on Matrix...
            # ...
        end

        return this
    end
end

So when I say in my main code:

st = Sometype()
st.setValue(val)

depending on whether val is a scalar, vector or matrix it would invoke the corresponding version of a setvalue method. Right now, with definition above, it overrides definitions of setvalue with the last one (matrix version in this case).

Kruse answered 23/9, 2015 at 0:12 Comment(3)
setValue is a variable with type Function and can be overridden just like other common variables. for now, it seems julia doesn't support multiple dispatch for anonymous functions.Roxie
The fact that it is overriding setValue is the problem here. I want to code it in such way that it will instead compile all versions of a setValue and one of those to get called appropriately to the type of the passed input valKruse
you can use generic function, try to give those functions the same name e.g. function foo(v::Real), function foo(v::Vector{Real}),function foo(v::Matrix{Real}). However, this is not julia-style, see @David's answerRoxie
E
10

This style of Object-Oriented Programming (OOP), in which the functions live inside objects, is not used in Julia.

Instead, in Julia we just define methods outside the object definition. E.g.:

type Sometype
    prop::String
end

Sometype(v::Real) = ...

function Sometype{T}(v::Vector{T})  # parametric type
    ....
end

Note that the first definition is an example of the short-hand way of defining simple functions on a single line, and the second example is for more complicated functions.

As pointed out by @GnimucKey, instead of v::Vector{Real}, you should use v::Vector{T} with the function parametrised by T. I have changed my answer accordingly. An argument specified as v::Vector{Real} will never match an argument, since it is impossible to create objects of the abstract type Real, and the invariance of types means that an object like Vector{Float64} is not a subtype of Vector{Real}.

Eustoliaeutectic answered 23/9, 2015 at 5:11 Comment(3)
i think function Sometype{T<:Real}(v::Vector{T}) ... end is better. cause Vector{Int} <: Vector{Real} will return a false, which is ​prone to getting some unexpected errors.Roxie
The behaviour of <: on parametric composite types @GnimucKey mentions is explained thoroughly in the docsPuttee
@GnimucKey Yes, you're right, good point. I'll change my answer.Eustoliaeutectic

© 2022 - 2024 — McMap. All rights reserved.