# Types as Function Parameters

I feel like this is probably somewhere easily found in the documentation, but I haven’t figured out where, so I think I just don’t know the right vocabulary here.

Suppose I wanted to write the following silly function:

``````function parsestring(T::Type, s::AbstractString)
v::Union{Nothing,T} = tryparse(T,s)

return v
end

parsestring(Int, "3")
parsestring(Float64, "3.4")
``````

I’ve found the above is slow. Alternatively I could write:

``````function parsestringFloat64(s::AbstractString)
v::Union{Nothing,Float64} = tryparse(Float64,s)

return v
end

function parsestringInt(s::AbstractString)
v::Union{Nothing,Int} = tryparse(Int,s)

return v
end

parsestringInt("3")
parsestringFloat64("3.4")
``````

which is predictably fast. The question is if there is a more idiomatic way of writing and calling functions in the second case? Do I need to dispatch on values?

I should add that dispatching on values is very fast, although I still feel like I am missing a more idiomatic way to do this:

``````function parsestring(s::AbstractString, ::Val{T}) where T
v::Union{Nothing,T} = tryparse(T,s)

return v
end

parsestring("3", Val(Int))
parsestring("3.4", Val(Float64))
``````

Hi Clinton!

You can try the following:

``````function parsestring(::Type{T}, s::AbstractString) where {T}
v::Union{Nothing,T} = tryparse(T, s)
return v
end

parsestring(Int, "3")
parsestring(Float64, "3.4")
``````

This is a pattern that shows up fairly often in Julia code.

4 Likes

Thanks! That was exactly what I was looking for.

1 Like

alternatively:

``````#general case
function parsestring(::Type{T},s::AbstractString) where T
v::Union{Nothing,T} = tryparse(T,s) #the return is't necessary
end

#optimized case, for int64 and float64
function parsestring(::Type{Int64},s::AbstractString)
v::Union{Nothing,Int64} = tryparse(Int64,s)
end

function parsestring(::Type{Float64},s::AbstractString)
v::Union{Nothing,Float64} = tryparse(Float64,s)
end
``````
1 Like

The “optimized case” should not be necessary and does not actually affect performance, so there’s no need to go beyond the nice generic `where T` form:

``````julia> using BenchmarkTools

julia> function parsestring(::Type{T},s::AbstractString) where T
v::Union{Nothing,T} = tryparse(T,s) #the return is't necessary
end
parsestring (generic function with 1 method)

julia> @btime parsestring(\$Int64, \$("1"))
18.972 ns (0 allocations: 0 bytes)
1

julia> function parsestring(::Type{Int64},s::AbstractString)
v::Union{Nothing,Int64} = tryparse(Int64,s)
end
parsestring (generic function with 2 methods)

julia> @btime parsestring(\$Int64, \$("1"))
18.974 ns (0 allocations: 0 bytes)
1
``````
4 Likes

Lol, I forgot the interpolation when measuring 