jessealama / ejs

Exact JSON library for Racket
ISC License
6 stars 1 forks source link

Valid EJS expressions are not always valid JSON numbers #2

Open jackfirth opened 5 years ago

jackfirth commented 5 years ago

I'm confused about the precise nature of the relationship between ejs and JSON. Specifically, the package description for ejs says this:

A no-compromises implementation of RFC 8259 in which all numbers are rational

And the README says this:

EJS does not extend the official language of JSON.

However, RFC 8259 cannot represent rational numbers like 1/3 that do not have a finite base-10 fractional part. This is checked for in the ejsexpr->string function:

> (ejsexpr? #e1/3)
#t
> (ejsexpr->string #e1/3)
error: Number has no finite decimal representation: 1/3

This is reasonable, but it seems at odds with this part of the README:

For all EJS expressions E, (string->ejsexpr (ejsexpr->string E)) = E

So I'm confused about what ejs is intending to represent. Is the set of EJS numbers supposed to be "RFC 8259 numbers", where 1/3 is disallowed and 0.2 is read as 1/5? Or is it supposed to be "exact rationals", thus EJS expressions are a strict superset of JSON where (and/c ejsexpr? number?) does not imply ejsexpr->string will succeed? Either choice seems valid to me, but I think ejs should be clearer about which stance it's taking.

jessealama commented 5 years ago

The main use case for EJS is JSON Schema. Indeed, the only reason EJS exists is to support equality checking of JSON numbers. Here's an issue with Argo that motivated the development of EJS.

If Racket's built-in JSON support supported arbitrary precision numbers (so that, say, (string->jsexpr "1.0") were not equal to (string->jsexpr "1.000000000000000000000000000000000001"), EJS could be abandoned. I thought about simply doing this change, but I backed away from doing it when I considered potential performance impacts.