-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
parsing APIs that indicate whether something was possible, rather than raising an error? #5704
Comments
See also #3631. |
Parsing is definitely a bit different since it tends to occur with external inputs where it's more normal not to know what the correct type for something is. We could also have a "data parsing" API that parses something, figuring out what the most conservative type for it is – integer, floating-point, big int, big float, string. Something like that. Probably want to throw dates in there too. I don't think it needs to be an expandable list, but it should cover the kinds of basic data that data frames might want to be able to read and automatically determine the type of. I suspect the logic for some of this already must exist in DataFrames. |
So it seems like the idioms under consideration are: A
B
C
Regarding A, As @JeffBezanson mentions often there's considerable code duplication and inefficiency in checking whether you can do something before doing it. It also exposes the user of the API to race conditions if the data you're operating on is mutable (or for instance checking whether you have permission to write to a file before opening it for writing). B doesn't have those problems, but according to the SO thread exception catching is slow. Is that a long-term thing or an artifact of some current implementation details? It also sounds like this pattern is discouraged as not idiomatic Julia. Returning a tuple that includes a status field addresses those issues, but it feels like the exception throwing idiom is more general and cleaner to me. I'm definitely biased from python experience though. |
There is also
This pattern is already used in several places in Julia (e.g. |
Exceptions certainly could be faster, but you often need to parse huge numbers of text values and it can easily be a bottleneck. Exceptions might not ever be fast enough for that. |
I did a quick benchmark, comparing the exception-based
(Note: of course, the loops could be short-circuited as soon as a
|
FWIW, DataFrames uses the following return values:
|
@stevengj you are still short-circuiting via |
I'll also add that basically all of the time spent when throwing an exception is for collecting a stack trace. Switching
Removing backtrace collection gives:
Painful, indeed! The best way to work around this would be to know in advance which exception handlers want backtraces, which is a bit awkward. |
If we did a better job of generating code for union types, would it be possible to return a different type if parsing fails? Then you could either check for that or have your code throw when you try to use the value. |
@JeffBezanson, whoops, I meant to write
|
would be closed by #9316 (comment) Nullable{Float64} maybefloat64() suggestion |
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces following methods that parse a string as the indicated type and return a `Nullable` with the result instead of throwing exception: - `maybeint{T<:Integer}(::Type{T<:Integer},s::AbstractString)` - `maybefloat32(s::AbstractString)` and `maybefloat64(s::AbstractString)` Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces the tryparse method: - tryparse{T<:Integer}(::Type{T<:Integer},s::AbstractString) - tryparse(::Type{Float..},s::AbstractString) - a few variants of the above And: - tryparse(Float.., ...) call the corresponding C functions jl_try_strtof, jl_try_substrtof, jl_try_strtod and jl_try_substrtod. - The parseint, parsefloat, float64_isvalid and float32_isvalid methods wrap the corresponding tryparse methods. - The jl_strtod, jl_strtof, ... functions are wrappers over the jl_try_str... functions. This should fix JuliaLang#10498 as well. Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces the tryparse method: - tryparse{T<:Integer}(::Type{T<:Integer},s::AbstractString) - tryparse(::Type{Float..},s::AbstractString) - a few variants of the above And: - tryparse(Float.., ...) call the corresponding C functions jl_try_strtof, jl_try_substrtof, jl_try_strtod and jl_try_substrtod. - The parseint, parsefloat, float64_isvalid and float32_isvalid methods wrap the corresponding tryparse methods. - The jl_strtod, jl_strtof, ... functions are wrappers over the jl_try_str... functions. This should fix JuliaLang#10498 as well. Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
Introduces the tryparse method: - tryparse{T<:Integer}(::Type{T<:Integer},s::AbstractString) - tryparse(::Type{Float..},s::AbstractString) - a few variants of the above And: - tryparse(Float.., ...) call the corresponding C functions jl_try_strtof, jl_try_substrtof, jl_try_strtod and jl_try_substrtod. - The parseint, parsefloat, float64_isvalid and float32_isvalid methods wrap the corresponding tryparse methods. - The jl_strtod, jl_strtof, ... functions are wrappers over the jl_try_str... functions. This should fix JuliaLang#10498 as well. Ref: discussions at JuliaLang#9316, JuliaLang#3631, JuliaLang#5704
|
See http://stackoverflow.com/questions/21595246/try-catch-or-type-conversion-performance-in-julia. We have lots of integer, float, expression parsing code that all just raises exceptions rather than indicating whether they succeeded or not, but we discourage try/catch as control flow. Should we provide non-error-raising versions of all of these functions that people can use to test whether some string is a valid float, for example?
The text was updated successfully, but these errors were encountered: