# Specifying that a function which can take a vector or scalar as input

I frequently find myself writing functions which are fundamentally not that different for scalars or vectors. Take this for example:

``````julia> function silly_print(x)
for i = 1:length(x)
println(x[i])
end
end

julia> silly_print(2)
2

julia> silly_print([2,4])
2
4
``````

Specifying that x is a Vector breaks this behaviour:

``````julia> function silly_print_vector(x::Vector)
for i = 1:length(x)
println(x[i])
end
end
silly_print_vector (generic function with 1 method)

julia> silly_print_vector(2)
ERROR: MethodError: no method matching silly_print_vector(::Int64)
Closest candidates are:
silly_print_vector(::Array{T,1} where T) at none:1
Stacktrace:
 top-level scope at none:0
``````

Is there a workaround for this, without writing two identical functions but for different types?

You can write it just for scalars and then use broadcasting. E.g.,

``````julia> println.(1:3);
1
2
3
``````
4 Likes

If you need more complex things than one `.`, it often works well to define say `silly_print(x::Number)`, and then `silly_print(x::AbstractArray)` which does some work (say it prints `summary(x)`) before iself calling the `::Number` method.

1 Like

If you really need a function that accepts both arrays and scalars, either don’t declare the argument type at all (there is no performance penalty in Julia for duck typing!) just use a `Union`: declare `function myfunction(x::Union{Number, AbstractVector}`, for example.

But if your function is that generic, you way want it to work for any iterable object anyway, in which case it is better to duck type and avoid indexing:

``````function myfunction(itr)
for x in itr
# do something with x
end
end
``````
3 Likes