Excellent, thank you for the quick and helpful responses. 

One more related question.

If I were to define a function that could either on an Array{T} where T <: 
Number or on T itself, is there any reason not to do this:

typealias ScalarOrArray{T} Union(T, Array{T})

function bar{T}(x::ScalarOrArray{T}, y::ScalarOrArray{T}) = x+y

My real question is would there be performance penalties for using Union in 
this way?

Would it help the compiler at all to define this as

function bar{T}(x::Array{T}, y::Array{T}) = x+y

function bar{T}(x::Array{T}, y::T) = x+y

function bar{T}(x::T, y::Array{T}) = x+y

function bar{T}(x::T, y::T) = x+y

?

On Tuesday, August 19, 2014 11:45:10 AM UTC-7, Johan Sigfrids wrote:

Performance wise it makes no difference. The JIT will produce the same code 
> for all three:
>
> foo1(x::Real, y::Real) = x + y
>
> foo2{ T<: Real}(x::T, y::T) = x + y
>
> foo3{T <: Real, S <: Real}(x::T, y::S) = x + y
>
> You can verify it by running @code_native on all of them. They will all 
> result in the same machine code for the same input types.
>
> @code_native foo1(1, 1)
>
>       .text
> Filename: none
> Source line: 1
>       push    RBP
>       mov     RBP, RSP
> Source line: 1
>       add     RCX, RDX
>       mov     RAX, RCX
>       pop     RBP
>       ret
>
>
> The one difference is that foo2 requires both x and y to be of the same 
> type:
>
> foo2(1, 1.0)
>
> `foo2` has no method matching foo2(::Int64, ::Float64)
>
>
> You can mix and match Real types with foo1 and foo3.
>
> On Tuesday, August 19, 2014 9:30:42 PM UTC+3, Spencer Lyon wrote:
>>
>> Suppose I am defining a function that operates on any two real numbers. 
>> Which of the following ways of specifying types is preferred (in terms of 
>> idomatic Julia and performance considerations) and why?
>>
>> ```julia
>>
>> function foo1(x::Real, y::Real) = ...
>>
>> function foo2{ T<: Real}(x::T, y::T) = ...
>>
>> function foo3{T <: Real, S <: Real}(x::T, y::S) = ...
>> ```
>>
>> ​

Reply via email to