Is there a way to declare types for all arguments in a function?

syntax
#1

Let’s look at this function

function foo(a::Int, b::Int, c::Int)::Int 
    return a + b +c
end

Is there a way to say all of a, b and c are Ints instead of repeating? Or is the “right” way to put the arguments in an array and pass the function that instead?

Edit: Ops, completely wrong section at first sorry.

#2

You can do:

julia> function foo(aa::Vararg{Int,3})
       a,b,c = aa
       return a + b +c
       end
       
       
foo (generic function with 1 method)

julia> foo(1,2,3)
6

julia> foo(1,2)
ERROR: MethodError: no method matching foo(::Int64, ::Int64)
Closest candidates are:
  foo(::Int64, ::Int64, ::Int64) at REPL[25]:2
Stacktrace:
 [1] top-level scope at none:0

julia> foo(1,2,3,4)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64, ::Int64)
Closest candidates are:
  foo(::Int64, ::Int64, ::Int64) at REPL[25]:2
Stacktrace:
 [1] top-level scope at none:0

but unless there are very many arguments, I find the Vararg less clear.

2 Likes
#3

If you just want to avoid repetition, you can use a type parameter restricted to a concrete type, eg

function foo(a::T, b::T, c::T)::T where {T <: Int}
    return a + b +c
end

But (as we are in First steps), recall that there is no advantage from declaring types for reasons other than dispatch (broadly). So most experience users of Julia would write

foo(a, b, c) = a + b + c
4 Likes
#4

Yeah that was kind of what I was looking for thanks! Although you might be right it’s not obvious what’s the clearest.

#5

Good point. Although I still find it slightly confusing when types matter and when they don’t. You haven’t seen the last of me here in first steps to put it like that.

#6

Types in function arguments are generally not related to performance. Think of them as a filter, saying which methods are called for which arguments.

In your example above, your type declarations have zero impact on performance, they just limit your foo to Int arguments. And your return-type declaration is redundant because the compiler can already infer it.

(The whole point of Julia is that you can write type-generic code that is still fast.)

4 Likes
#7

Simple rule of thumb: put concrete type (or type parameter) annotations on your struct fields, otherwise they are optional.

4 Likes
#8

Thanks guys, helpful tips. I find it better to go a bit overboard at first, since I’m not used to thinking about types at all. My specialty is slow matlab code with bugs in it so this is new stuff for me. It gives me a sense of accomplishment knowing my bug at least is an Int now.

1 Like