[racket] JSON module: why symbols for object keys? lists for arrays?

From: Erik Pearson (erik at adaptations.com)
Date: Tue Apr 23 17:10:56 EDT 2013

Thanks, Greg. Practical experience from a seasoned programmer is priceless.

And so much depends on how you use the thing. A json object may be
read, parsed, used for one value, thrown out. Or it may be stored in
shared memory and used millions of times over months. One may decide
to stick with the generated json representation, or just use it to
populate your own internal object. There really is no one size fitting
all, but I guess there also is a very very good enough.

The initial motivation for the original post was curiosity about the
design decisions, and a bit of trepidation at building dependencies on
the details of the jsexpr type.

I had a recent experience that built up that fear in my mind. I had
used a couple of different json implementations in Erlang, settled on
the most graceful one, but shortly found a hidden flaw. This flaw
required special case coding to work around, but was rare enough that
most code didn't seem to care, and I had worked for a week or so
without noticing it, and after a few hours was very tired of the
workaround. That was extra work and a source of bugs, so I knew
something had to change, yet the maintainer was not about to change
the library (and for good reason),  so just created my own json
module, use tagging (basically a structure with the first element a
symbol acting as a type tag) to mark each json element. Because the
data representation no longer had to serve the dual purpose of holding
the json data and designating the corresponding json data type, the
internal data representation could the best for the job (most natural,
efficient, easy to use, easy to build, etc.). The entire structure
then becomes opaque, and only accessed through an api.

I quickly found (well I knew this would be an issue, but I ran
headlong into it) that not only my code but other libraries relied on
internal details of the json implementation (and this happened with
other libraries as well), so to swap json implementations, I had to
fork EVERYTHING. What a drag that was, and a continuing maintenance
problem to keep my forks in sync.

Its not a new story, but it is the story of the source of my trepidation.


On Tue, Apr 23, 2013 at 11:35 AM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> I've used the JSON library with various web APIs and found the design
> decisions to make sense in practice.
>
> 1. Arrays vs. lists: In Racket lists are the de facto thing for this.
> Anyway, I don't think the objective of JSON is to be faithful to
> Javascript per se. (If it were, shouldn't the choice be a dictionary,
> since IIUC that's what JS arrays really are? ;) )
>
> 2. Symbols for dict keys: Although this struck me as odd, at first,
> too, after a very short while it made sense. A couple small practical
> points: You're saving some typing (leading ' instead of " and ").
> Plus, symbols are colored differently than strings, making it easier
> to visually parse the keys and values. IMO.
>
> If after using it a bit it doesn't click, for you, you certainly could
> try Neil's library, or fork your own variation. I'm definitely not
> saying you're wrong to want it to work differently. I just wanted to
> chime in and say it works well, for me.
>
>
> On Mon, Apr 22, 2013 at 3:46 PM, Erik Pearson <erik at adaptations.com> wrote:
>> Hi,
>>
>> I've just starting playing with JSON in racket. The goal is to use
>> JSON + Mustache-like templates to generate content. I've done this
>> lots with CL and Javascript, now trying the Racket approach. I'm
>> wondering about a couple of design decisions for the JSON module. For
>> one, I was a bit surprised but not shocked to see json object property
>> keys implemented as symbols. I assume it is for performance reasons? I
>> know there is be a trade off between the cost of converting strings to
>> symbols, the efficiency of symbol-based eq hash tables vs string equal
>> hash tables, etc. For me there is also the increase in complexity when
>> translating from JSON to jsexpr -- when components of JSON are
>> translated into different objects in the host language it is yet
>> another thing to remember, multiple forms of symbols, another layer of
>> coding. With some very relaxed testing (using code that would be
>> typical of my application), I've actually found string equal hash
>> tables to be a tad faster.
>>
>> There is a similar issue with lists being used to represent JSON
>> arrays, over the more obvious choice of Racket vector. Maybe this is
>> because there are more core functions for dealing with lists compared
>> to the limited number for vectors (for data processing type things
>> like foldl). I suppose it is YMMV depending on how you use the data.
>> Random element access, simple iteration, or more complex folding, etc.
>>
>> Anyway, I was hoping the authors or associates could comment on these
>> design decisions. A related topic is whether the approach of the JSON
>> module to allow specification of implementation for NULL, for
>> instance, could be extended to Objects and Arrays. On the other hand,
>> maybe it is better to fork a new JSON module with different and
>> specific implementation details, either for personal use or as part of
>> the standard library (it takes about 5 minutes to make the necessary
>> changes.)
>>
>> Thanks,
>> Erik
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users



-- 
Erik Pearson
Adaptations
;; web form and function

Posted on the users mailing list.