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).

3 Likes

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)
4 Likes

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

Method extensions are “global”.

4 Likes