stdlib
stdlib copied to clipboard
Suggestion: Add `decode.number`
Context
Given that
- the
decodeAPI is used with formats like JSON, where there is no distinction between floats and ints, and - the target (Erlang vs ES) is a somewhat leaky abstraction when it comes to handling numbers,
it can be confusing that on the Erlang target decode.float will not accept e.g. 1, but requires 1.0 to work properly.
Suggestion
Add decode.number: Decoder(Float), which would work equivalently to
decode.one_of(decode.float, or: [decode.int |> decode.map(int.to_float)])
This would both make it more convenient to decode formats where there's no distinction between ints and floats, and act as documentation about the context outlined above.
If this sounds like a good idea, I'd be happy to create a PR for it.
Could be good! The plan is to let the stdlib and the new decoder API settle for a while so we can see how people find it before making any changes.
I also run into this issue. Sometimes JSON endpoints add a '.0' and sometimes they don't so I have to use the one_of func for it often
I'd argue that decode.float should just not fail on "0", I want a float, so it should just work.
~~I'd say explicitness is nice and thus could also imagine decode.number (which decodes into floats but takes any number)?~~
Edit: I should have read the title, changing what decode.float does sounds bad, but decode.number seem ok to me.
In general I'd agree. But here I find the behaviour quite surprising because we're often decoding from a format where a float is not expressed with a . if it doesn't have a decimal part.
Also I can't think of a reason why you'd want decode.float to ever fail on a valid number?
To be clear, I don't have avery strong opinion on this. I would be fine to go with the proposal, but let's add to the documentation then that float will fail on decoding numbers without decimals, and point to decode.number
In general I'd agree. But here I find the behaviour quite surprising because we're often decoding from a format where a float is not expressed with a
.if it doesn't have a decimal part.Also I can't think of a reason why you'd want decode.float to ever fail on a valid number?
The thing to take into account here is that while some string-based serialization formats like JSON go through Dynamic as an intermediate step, Dynamic can also be used for other purposes where the distinction could matter. So Dynamic doesn't know about a ., it just knows about the way the target represents numbers.
I'd argue that decode.float should just not fail on "0", I want a float, so it should just work.
How would you decode only a float in that case?
Remember we're not talking about JSON here.
I'm not sure what you mean.
I know we're not just talking JSON, but I might be missing some cases/I don't know any cases where you have a dynamic 0 and you decode it to float and you want it to fail?
Just to be clear maybe there are good reasons to fail in that case but I currently don't see/know them.
The case is any situation in which you want specifically a float and would reject an int. This is commonplace.