On Wednesday, October 21, 2015 at 11:57:08 AM UTC-4, Jonathan Malmaud wrote:
>
> Just to add to Spencer's answer: Is there a particular reason to have your 
> function arguments have type annotations at all in the function definition? 
> You could just write 
>
> function f(x)
>   y= x[3:5] # or whatever
>   z = length(x)
> end
>
> and now someone could call f with any kind of object that supports 
> indexing and "length" and it will work. This is "duck-typing", if you're 
> familiar with that term, and is the dominant paradigm in Julia precisely 
> since it makes generic programming easier.
>
>>
I agree that duck typing is often a good practice, but there are three good 
reasons to declare argument types:

* Correctness: the code might work but give unexpected results if you pass 
the wrong types.   e.g. fib(n) = n < 2 ? one(n) : fib(n-1)+fib(n-2) is a 
function that computes the Fibonacci numbers only for integers — it gives 
an answer for floating-point n, but the answer is probably not what you 
want.

* Clarity: sometimes it is a useful hint to the caller if you indicate the 
expected type.  

* Dispatch: you want to do different things for different types, so you use 
the argument types as a filter to indicate which methods should work when.

However, in all cases the trick is to declare the widest applicable 
argument type.   e.g. use fib(n::Integer), not fib(n::Int), so that any 
integer type will be accepted, rather than the concrete type Int.

In the case of functions accepting vectors, you should almost always 
declare the type as AbstractVector or AbstractArray, not Vector or Array.   
That will let you handle any array-like type.   In particular, ranges are a 
subtype of AbstractVector.

Reply via email to