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.
