Parsing Strings as Strings

I was playing around with parse the other day and was a bit surprised by,

julia> str = "foo"
julia> parse(String, str)
ERROR: MethodError: no method matching parse(::Type{String}, ::String)

and similarly,

julia> str = "foo"
julia> sstr = SubString(str, 1, 2)
julia> parse(String, sstr)
ERROR: MethodError: no method matching parse(::Type{String}, ::SubString{String})

IMHO, having a parse function that can handle these two cases seems like a reasonable behavior and can be easily implemented with,

parse(::Type{String}, str::String) = str
parse(::Type{String}, str::SubString{String}) = String(str)

With that said, I trust there is a reason this is not implemented. My question is, what is that reason?

Parse is not conversion, it is not supposed to be no-op.

And what does parsing to string even mean? The closest meaning will be unquoting a string syntax, which isn’t a no-op. It is not very universal and very syntax dependent though (different language have very different quoting and escape rules).


How to implement this kind of operation, without resorting to the above mentioned extension of parse?

map(x -> parse(x...), zip((Int64,Float64,Float64),("123","234","234.7")))
map(x -> parse(x...), zip((Int64,Float64,String),("123","234","234.7")))

The first line is executed correctly but the second one has this corner case of parsing one String into a String.

I stumbled upon this when using a regex. Can I somehow type annotate regex capture groups to automatically parse certain groups as integers or floats?

A clean solution would be to implement a new function:

my_parse(T, x) = ((T <: AbstractString) && (x isa AbstractString)) ? x : parse(T, x)
map(x -> my_parse(x...), zip((Int64,Float64,String),("123","234","234.7")))
1 Like

Would it be ok to import Base.parse in my own module and then extend it with

parse(String, str::AbstractString) = str

or would that cause some issues? I am not exactly sure how the namespaces work in this situations.

That would be a bad idea, see Style Guide · The Julia Language. Just use the little wrapper function or define you own:

custom_parse(T, x::AbstractString) = parse(T, x)
custom_parse(::Type{T}, x::AbstractString) where {T <: AbstractString} = T(x)

Ah, I wasn’t sure if my extended function “leaks” outside of my module. Thank you both.

Method extensions are “global”.