On Thu, Dec 13, 2018 at 11:35 AM John Cowan <co...@ccil.org> wrote: > > > > On Thu, Dec 13, 2018 at 9:31 AM Thompson, David <dthomps...@worcester.edu> > wrote: > >> * They have no read syntax >> * They use a procedural, mutable API >> * They are slower than alists when the number of keys is small, which >> is 99% of the time when dealing with serializing objects > > > I agree with these objections. > >> >> Why not do something like Racket does and use vectors for JSON arrays >> and alists for JSON objects? > > > In fact Racket uses hash tables, but it provides a (non-standard) lexical > syntax for them: #hasheq followed by an a-list.
Ah, okay. I missed this detail in the docs. (I've never actually used Racket) >> It's not the ideal API IMO, but this way >> only core data types with read syntax are used and is an improvement >> over using hash tables. > > > My objection to using vectors for JSON arrays is that they are often built up > element by element, which JavaScript arrays support but Scheme vectors > do not. So in practice you would create a list and then convert it to a > vector. Yes, I agree. For my own uses, I have avoided vectors for this reason, and also the reason that typically, when serializing, the user has a list of something, not a vector of something. > While the same thing is sometimes done with objects, it is more common > for an object to have a reasonably fixed structure, which can be well > represented as a vector of pairs, the vector equivalent of an alist. > When the elements of the object are variable, they can be built up > as an alist and then converted with list->vector. > > So given that we are changing the structure anyhow, I recommend this > approach. I think I understand what you are saying, but to me it has similar shortcomings as other options due the need of a something->vector procedure. An approach I've used in the past is to tag alists with a special symbol so that they can be distinguished from regular lists. Something like this: '(@ ("foo" . 1) ("bar" . 2)) The assoc-ref procedure will happily work with this structure, so reading parsed data requires nothing special. And for serialization procedures it is simple to add the '@' tag. I'm almost always using quasiquote in my serializers: `(@ ("foo" . ,(thing-foo thing)) ("bar" . ,(thing-bar thing))) There's an old patch of mine to add JSON to the Guile standard library that uses this approach. Unfortunately I was never able to get the code to meet the standards for merging. - Dave