Added +inf.0 and -inf.0 support to json
I don't know that inf is part of the json standard, but this allows us to pass +inf.0 and -inf.0 values and seems to work in practice. (string->jsexpr (jsexpr->string +inf.0))
I don't like this technique of overflowing the parser.
I think it would be better to encode +inf and -inf as the JavaScript "properties" Infinity and -Infinity. Python does this:
$ python3.5
Python 3.5.1 (default, Apr 18 2016, 11:46:32)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.29)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> json.dumps(float('inf'))
'Infinity'
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.loads('Infinity')
inf
>>> json.loads('-Infinity')
-inf
But I think it would be even better to not support +inf and -inf. According to the JSON RFC4627, Section 2.4:
Numeric values that cannot be represented as sequences of digits (such as Infinity and NaN) are not permitted.
The Ruby 2.0 'json' library seems to implement this:
$ ruby --version
ruby 2.0.0p645 (2015-04-13 revision 50299) [universal.x86_64-darwin15]
$ irb --version
irb 0.9.6(09/06/30)
$irb
irb(main):001:0> require 'json'
=> true
irb(main):002:0> JSON.parse('Infinity')
JSON::ParserError: 757: unexpected token at 'Infinity'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/json/common.rb:155:in `parse'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/json/common.rb:155:in `parse'
from (irb):2
from /usr/bin/irb:12:in `<main>'
irb(main):003:0> JSON.generate(Float::INFINITY)
JSON::GeneratorError: 807: Infinity not allowed in JSON
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/json/common.rb:224:in `generate'
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/json/common.rb:224:in `generate'
from (irb):3
from /usr/bin/irb:12:in `<main>'
Also, this StackOverflow answer suggests that un-parsing Infinity on a website can be a security problem:
https://stackoverflow.com/a/1424034/5237018
(I guess un-parsing 1e9999 wouldn't have that problem. Anyway this is my 2c --- don't support +inf etc.)
Very good points. Thank you for your efforts in researching this.
This hack makes me a little uncomfortable as well, but I pass a lot of numerical data between the web server and browser, so for me inf support is quite useful. For me, the usefulness outweighs the icky factor.
I do see your point about sticking to the json standard, which doesn't support infinite values. I see this as an unfortunate limitation, so this was an easy workaround that I would think would be parsable by most existing json parsers. I prefer 1e999 over 'Infinity' because I think more parsers might support it, but I don't know for sure. Technically 1e9999 is a valid json number (since the float type is not defined), but infinity is not.
What about adding some keyword (#:allow-infinite? #t) and in the docs making it explicit that by allowing infinite numbers we're going outside of the json specification?
I like the keyword idea. How about going one step further, and passing an "illegal value converter" through a keyword argument? Something like #:write-expr f where write-json will call f with any value it doesn't know how to convert.
Then, depending on the #:write-expr function, people could extend write-json to handle +inf.0 and +nan.0 and 0+1i and (vector 1) ... and maybe also the issues in #1878 and #1878 ... in a way that makes sense for their programs.