Difference between f (x :: Real) and f {T <: Real} (x :: T)?

Is there a difference between defining functions with f(x::Real) and f{T <: Real}(x::T) ?

@code_warntype gives the same result for

 function f(x::Real) x^2 end function g{T <: Real}(x::T) x^2 end 
+5
source share
2 answers

The parametric type T is not really used to express any relationship between types, so there is little excuse for using it, which just adds unnecessary complexity.

Here is an example where you need to use a parametric type:

 function pow{T <: Real}(base::T, exponent::T) base^power end 

In this case, T needs to ensure that both base and exponent the same type with the restriction that this type must be a subtype of Real .

The constrast here uses the same function without using the parametric type:

 function pow(base:: Real, exponent:: Real) base^power end 

Now these functions require both base and exponent be subtypes of Real , but there is no type relationship that ensures that both are of the same subtype of Real .

+5
source

Prefers f(x::Real) . Additional unnecessary type parameters complicate the work of the compiler and slow down the dynamic dispatch, not to mention the more difficult to read for other people.

See style guide :

Do not use unnecessary static parameters

Functional Signature:

 foo{T<:Real}(x::T) = ... 

should be written as:

 foo(x::Real) = ... 

especially if T is not used in the function body. Even if T is used, it can be replaced with typeof (x), if convenient. There is no difference in performance. Please note that this is not general caution against static parameters, and not against use where they are not needed.

Note that container types, in particular, may need type parameters in function calls. See the FAQ. Avoid fields with abstract containers for more information.

+5
source

Source: https://habr.com/ru/post/1267297/


All Articles