Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia function with different parameter subtypes

In Julia I can define a function that accepts all subtypes of Type by doing

function foo{T<:Type}(bar::T, arg::T) end

But this imposes that bar and arg be the same subtype of Type. Is there a shorthand to define a function that accepts different subtypes of Type for bar and arg? I know I can do

function foo{T<:Type, S<:Type}(bar::T, arg::S) end

But for a function with several parameters, it becomes quite cumbersome.

like image 498
Mauricio Avatar asked Sep 03 '26 14:09

Mauricio


1 Answers

When the type used on the left hand side of T<:Type is an abstract type, then the function argument(s) that are declared to be of type T will accept all things that belong to that abstraction, including things that belong to a subordinate (inheriting) abstraction.

For most purposes, these things are realizations of a concrete type, instantiations of the type. A concrete types may have an abstract type as its supertype, and that abstract type may have a another, more abstract type as its supertype, and so on. Any is the most super supertype, root of the abstract type tree.

In the example

 function foo{T<:Type}(bar::T, arg::T) ... end

At each invocation of foo, T takes on exactly one of the subtypes of Type or remains Type itself. That is why bar and arg must share the same specific type for this version of foo to be matched and called. And it explains why the next example matches and is called

 function foo{T<:Type, U<:Type}(bar::T, arg::U) ... end

when foo and bar are each subtypes of Type but are realizations of two distinct concrete types (e.g. Int32 and Int64 share the abstract supertype Integer).

There is no general shorthand for using parameters that you intend to accept different sorts of things; that the different sorts share a common abstract type is useful information and allows you to define both the first and the second ways to call foo. That flexible way of managing algorithmic specification often simplifies implementation. That is some of the strength that Julia's multidispatch offers.

There are situations where the use of typealias may simplify writing a function signature. typealias works well to selectively dispatch using nonoverlapping collections of subtypes that share a supertype.

typealias FastInt Union{ Int32, Int64 }  # division is fast
typealias SlowInt Union{ Int8, Int128 }  # slightly slower

foo{T<:Integer}(a::T, b::T) ... end; # default/fallback 
foo{T<:FastInt}(a::T, b::T) ... end; # specialized for fast types
foo{T<:SlowInt}(a::T, b::T) ... end; # specialized for slow types

```

like image 61
Jeffrey Sarnoff Avatar answered Sep 05 '26 17:09

Jeffrey Sarnoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!