Subject: [Json] Generators

From: Stefan Drees <[email-masked]>
Date: Mon, 10 Jun 2013 09:38:09 +0200

Starting this also as a new thread to not break symmetry (Parsers have 
been forked already by Paul).

Starting from my last proposal before fork at [1] I hereby propose to 
change the section on Generators from the OLD:
"""

5.  Generators

    A JSON generator produces JSON text.  The resulting text MUST
    strictly conform to the JSON grammar.

"""

into the NEW:
"""

5.  Generators

    A JSON generator produces JSON text that MUST strictly conform to
    the JSON grammar.

    Generators MUST NOT duplicate names in objects if they can avoid or
    detect such duplication.

"""

This is intended to be "flanked" by the proposal in the sister thread 
cf. [2].
As compared to [1] in the above proposal I have replaced the ". The 
resulting text" with a simple and equivalent " that" as compared to [1] 
and also threw a fine grained MUST into the ring pairing well, with the 
one in the Parsers section [2].
This "MUST NOT duplicate ... if" reads pretty soft for implementers, but 
should be the only consensual non-breaking way out of the historical 
dilemma of not enforcing it for generators in the first place.

What do the others think?

References:

[1]: http://www.ietf.org/mail-archive/web/json/current/msg00689.html
[2]: http://www.ietf.org/mail-archive/web/json/current/msg00700.html

All the best,

Stefan.

---

From: "Markus Lanthaler" <[email-masked]>
Date: Mon, 10 Jun 2013 11:49:02 +0200

>     Generators MUST NOT duplicate names in objects if they can avoid or
[...]
> This "MUST NOT duplicate ... if" reads pretty soft for implementers,
> but should be the only consensual non-breaking way out of the
> historical dilemma of not enforcing it for generators in the first place.

The "if" makes the MUST NOT conditional which is at odds with its definition

"""
1. MUST   This word, or the terms "REQUIRED" or "SHALL", mean that the
   definition is an absolute requirement of the specification.
"""

I would suggest to just drop the if-statement but can see why people would
disagree with that.

--
Markus Lanthaler
@markuslanthaler

---

From: Marcos Caceres <[email-masked]>
Date: Mon, 10 Jun 2013 11:10:31 +0100

> > A JSON generator produces JSON text that MUST strictly conform to

Please try to avoid "wish list" style conformance requirements. If you want "strictly" conforming documents generated (whatever that may mean), then please write the algorithm to produce such documents. For example:

"When generating JSON, as JSON generator MUST run the steps to generate JSON text.

The steps to generate JSON text are given by the following algorithm:  
1. …
2. …  
"

> > historical dilemma of not enforcing it for generators in the first place.

I agree. The above "if they can avoid [it]" if pretty lousy spec text. Please define the algorithm instead to produce the results you want.  

For excellent examples of how to write a specification using step-based conformance, please see the ES6 spec. See the parsing algorithm for JSON here - you basically want a language neutral version of that, right?:

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.12.2

HTH,  
Marcos Caceres

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 10 Jun 2013 12:24:01 +0200

On Jun 10, 2013, at 12:10, Marcos Caceres <[email-masked]> wrote:

> please write the algorithm

hixiefy (vt): Make a specification less useful but more apparently
"precise" by down-compiling readable English text that makes use of
some structure and certain unstated assumptions into barely readable,
ambiguous pseudo code based on the same unstated assumptions, but now
leaving recognizing the structure as an exercise to the reader.

I'm well aware that you sometimes have to give up writing an
interoperability specification and instead actually specify an 
algorithm, but that should be a last resort, never the approach 
from the outset.

> pretty lousy spec text.

Yep.

Grüße, Carsten

---

From: Stefan Drees <[email-masked]>
Date: Mon, 10 Jun 2013 12:59:10 +0200

On 2013-06-10 12:10 CEST, Marcos Caceres wrote:
> Please try to avoid "wish list" style conformance requirements. If you
> want "strictly" conforming documents generated (whatever that may mean),
> then please write the algorithm to produce such documents. For example:
>

if I only once had the power to write my wish lists that strong and 
concise, I would be a very happy man I guess :-)

We will not have a conformance section and we had until now no step by 
step description but only an "integral" check, where the result had to 
conform to the ABNF grammar of JSON.
So the following message is the best we can state:
If you are a wannabe X generator, ensure your output strictly conforms 
to our X grammar.

Retro-inventing of stepwise solutions/recipes simply not having been 
around for all these years and then acting as if they had, to me 
personally gives a strong smell and is far off the charter, isn't it?

> I agree. The above "if they can avoid [it]" if pretty lousy spec text.
> Please define the algorithm instead to produce the results you want.

I might be tempted to change the sequence to a more natural looking one 
"detect before avoid" but then, if an implementation is not able to 
avoid it, why should it bother to detect or not detect? So the strongest 
excemption is noted first: A policy or a use case hinders me in ensuring 
the "uniqueness wish" for names in objects.

On a personal note: If we avoid wordings like "pretty lousy spec text" 
in situations where many people are trying to retrofit best possible 
constraints into an area where these completely missed for years, to 
avoid further future "leakage" and without breaking reality that would 
be surely helpful, wouldn't it?

So IMO the terrain for the pair Generators/Parsers has three main 
boundary conditions:

a) the solutions for the generator / parser pair must match w.r.t.
    chaining the MUST/SHOULD/MAYs of each.

b) the generator in reality always transforms some storage pattern
    (JSON RFC is agnostic of that!) into a JSON text conforming to
    our JSON ABNF. Thus, the Generator has not to deal with invalid
    "input": piece of cake :-)

c) the parser in reality always transforms some JSON text into some
    storage pattern (JSON RFC is agnostic of that!). The parser has to
    deal with invalid input claiming to be JSON text!

in this thread we discuss b) and try to not mess with a).

Until now it has already been stated on this list, that in reality (and 
rightly so):

1. generator A can't detect duplicate names in objects

2. generator B uses duplicate names to annotate values with comments

3. generator C uses duplicate names to somehow stream, send historical
    data or deltas.

Given that A, B and C all are valid JSON implementations of Generators 
we will not retro-invalidate them.

In that light, the above MUST NOT ... if (describe the known exceptions) 
approximates best at least IMO the many variants proposed.

>
> For excellent examples of how to write a specification using
> step-based conformance, please see the ES6 spec. See the parsing
> algorithm for JSON here - you basically want a language neutral version
> of that, right?:
>
> http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.12.2 ...

Thank you for this nice description of the steps that a specific 
languages JSON Parser will have to perform to conform to that language 
specification.

No, I think we do not want a language neutral version of the JSON.Parse 
description in ES6.

Yes, we do want ES6s JSON expectations to remain valid if they were 
before, but we do not have a mandate to re-invent a step by step JSON 
Generator (or Parser) recipe, as that would need to be checked against 
all valid (as of now) implementation recipes of all existing parsers and 
would blow up this nice little successfull super star RFC quite a bit or 
two ;-)

All the best,
Stefan.

---

From: Stefan Drees <[email-masked]>
Date: Mon, 10 Jun 2013 13:26:46 +0200

>     definition is an absolute requirement of the specification.

that depends. If we act with care, we have to respect many boundary 
conditions. One is: There is only one term Generators in the spec we 
update minimally, but in reality many polarizing use cases drove 
implementations of such generators into existence (please also cf. [1] 
esp. where listing some of these and further motivate the concurrently 
proposed "UPPERCASE lowercase" selection).
So the if effectively offers a subclassification we are not allowed to 
enforce by say inventing a second class citizen like eg. a 
DupesGenerator ...

> disagree with that. ...

I personally would really wish to allow for trailing commas in arrays 
and objects, but our job - as I understand it - is to update the JSON 
RFC **and** keep the grown ecosystem intact thus defend the RFCs 
coolness, brevity and embracing functionality for all existing 
implementations of Generators, Parsers and combinations thereof. Some of 
these terms may not appear in the charter of the json wg, but might 
match those actually in there ;-)

All the best,
Stefan.

---

From: Marcos Caceres <[email-masked]>
Date: Mon, 10 Jun 2013 12:27:54 +0100

On Monday, June 10, 2013 at 11:24 AM, Carsten Bormann wrote:

> On Jun 10, 2013, at 12:10, Marcos Caceres <[email-masked] (mailto:[email-masked])> wrote:
> 
> hixiefy (vt): 
Personal attacks are not cool. I kindly ask that you refrain from doing that.  
> Make a specification less useful but more apparently

This was not what I was suggesting. It's why I pointed to ES6. It's algorithms are very clear and easy to follow for implementers. If you haven't already, I encourage you to read some ES6 - it's actually quite a delight to read and follow along to, even for someone that is not an expert (and certainly does not exhibit the language issues you mentioned above). Having said that, yes, the HTML5 spec is hard to read in places, but I would not blame any one individual for that - HTML5 is a very complex system that was specified from the messy organic growth of the Web: trying to standardize it with English is hard, but at least we have something that works fairly well now across user agent. 
> algorithm, but that should be a last resort, never the approach 

I don't understand? the end result of these specifications is code in some system (i.e., all specs are "interoperability specifications"). We want the code to be the same no matter what system it is run in (i.e., interoperable). Having a list of steps provides clear guidance for people to follow, and lets the implementer know exactly where and how to apply error handling (e.g., in the case of duplicate property names). It also helps users (developers) understand what is going on inside the system*. 

Having clear steps also allows for the creation of a more precise test suite: one can write a test for each step in the algorithm - thus getting more precise specification verification. 

*Having said that, it is not a requirement that implementers follow the specification as the algorithm is written - so long  as the end result is indistinguishable from that which would be achieved by following a given algorithm. 

-- 
Marcos Caceres

---

From: Stefan Drees <[email-masked]>
Date: Mon, 10 Jun 2013 13:30:21 +0200

Sorry, waited for the URL to be defined by IETF mail archiving, but then 
eventually hit send before entering the reference mentioned in the 
message below. Now here it is:

References:
[1]: http://www.ietf.org/mail-archive/web/json/current/msg00706.html

Stefan.
Am 10.06.13 13:26, schrieb Stefan Drees:
> match those actually in there ;-) ...

---

From: Marcos Caceres <[email-masked]>
Date: Mon, 10 Jun 2013 13:20:44 +0100

Hi Stefan,  

> personally gives a strong smell and is far off the charter, isn't it?

I haven't read the charter, tbh … I literally stumbled onto this list yesterday :)  However, I'm worried that overly simplistic or optimistic conformance requirements will just force people to go and look at ES6 to actually write the parsing and generation algorithms (or worst, they will just find some other random implementation out there and copy that). That could greatly diminish the value of this specification as it will leave implementers scratching their heads about how to implement either a parser or a generator.  

Also, given the legacy of JSON, it should be possible to see which parser behavior "won" (e.g., Doug's original JSON.js?) - and model this spec off that.  

Additionally, I suspect few people actually implement an ABNF parser - whatever is expressed in ABNF will have to be translated into code for a specific implementation. You can essentially shortcut that by specifying the algorithm and making implementer's lives easier.  That's not to say that the ABNF should not be there (it helps the reader understand components of the JSON grammar) - but the reality of the situation should be acknowledged (ABNF is an editorial aid, but rarely, AFAIK, a tool used in implementations in it's pure form to do syntactical checking).   
   
> be surely helpful, wouldn't it?

Yes, I'm sorry; I didn't mean any offense. I just meant that it was a conditional MUST, and that's not how MUST should be used (as it means one parser can do one thing and another can do another thing … which is an interoperability anti-pattern). This would, obviously, be bad if I'm sending one JSON representation from the client and it gets transformed into a different one on the server and the spec says that this behavior is ok.   

On the other hand, if the spec has to say, "well, that's the reality right now… and here are some guidance on how to avoid that problem without breaking clients and servers:" that might have to do.  

> we will not retro-invalidate them.

Agree. Whatever is specified needs to be backwards compatible on the parser side. Perhaps it's futile to assume a "generator", because most of the time it's people who are writing JSON by hand (so it doesn't make any sense to use RFC2119 language relating to any "generator" because people can't be a conformance class). Best you can do with generators is to assume some "best practice" acknowledging that JSON is used in the scenarios A, B, C, and possibly others to help dictate the behavior of the parser.  

> approximates best at least IMO the many variants proposed.

Thanks for the context. It's indeed a tough one :)  
> would blow up this nice little successfull super star RFC quite a bit or  

Ok, looks like I need to find the charter. However, concerns about the size of the spec should not ever enter the discussion - if it needs to be a long, bloated spec, to achieve interoperability and clarity - then that is the "right thing to do" (tm)… or, put another way, please make the spec only as long as it needs to be to achieve interoperability and the goals, and no longer :)

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 10 Jun 2013 14:26:30 +0200

I apologize for what can be read as a cheap shot.

ECMAscript actually is a demonstration that you can write a quite useful specification in this way, and I can say that I have always enjoyed reading it, even if some of it is pretty much a puzzle that needs to be solved before you can derive some of the simplest properties (maybe I just enjoy programming puzzles :-).

However, JavaScript is a procedural programming language, so specifying its behavior in English-language pseudo-code is at least natural.  (Also, the ECMAscript editors are much less guilty of unspecified assumptions than I have seen in other places.)

It is not the natural mode for specifying a data interchange format.

> I don't understand? the end result of these specifications is code in some system (i.e., all specs are "interoperability specifications"). We want the code to be the same

Actually, no.

> no matter what system it is run in (i.e., interoperable).

That is the one we want.

> Having a list of steps provides clear guidance for people to follow, and lets the implementer know exactly where and how to apply error handling (e.g., in the case of duplicate property names). It also helps users (developers) understand what is going on inside the system*. 

This almost always leads to overspecification, combined with underexplanation with respect to the reasons why some path was chosen and not another, and what choices are actually available.  Keeping that knowledge behind closed doors in the committee, and only delivering the equivalent of compiled code, is also one of the major kinds of misconduct in standardization work.

> Having clear steps also allows for the creation of a more precise test suite: one can write a test for each step in the algorithm - thus getting more precise specification verification. 

That works if those steps are actually exposed, in which case there may be even more overspecification.

> *Having said that, it is not a requirement that implementers follow the specification as the algorithm is written - so long  as the end result is indistinguishable from that which would be achieved…

Comparing two algorithms is much harder (even for humans) than checking an implementation against assertions.
Even more so if one of them is written in English, so it cannot even be executed unambiguously.

Don't get me wrong:  Adding a pseudocode example can do a lot to aid understanding (and to disambiguate poorly worded assertions).  However, turning English language pseudocode into the default mode of explaining things is a major mistake (and going full FDT is almost always worse, except for small elements such as ABNF).  I'm not going to repeat what can be read as another copy of the cheap shot (and even implicitly blaming a single person for such an outcome is always wrong, mea culpa), but I think you are well aware what might count as exhibit A.  Let's not go there.

Douglas' tight prose in RFC 4627 is actually something I would recommend to emulate.
The "ambiguities" we are discussing are either the result of very "creative" use or were left in deliberately (SHOULD...).
That's why I'm a bit unhappy that we seem to have started wordsmithing before getting some of the decisions done.

Grüße, Carsten

---

From: Marcos Caceres <[email-masked]>
Date: Mon, 10 Jun 2013 14:02:39 +0100

> Even more so if one of them is written in English, so it cannot even be executed unambiguously.

Right, but this is why we have test suites - i.e., to provide unambiguous computationally-verifiable testable assertions of what the English is saying. Personally, the primary motivation for me to see the algorithms is so that we can make sure we have a consistent way of testing everything in the spec. In my experience, the algorithms also help identify the gaps - particularly as you try to test and code against them. Yes, this also means having very competent people writing the tests so to make sure edge cases are also captured.     
> Don't get me wrong: Adding a pseudocode example can do a lot to aid understanding (and to disambiguate poorly worded assertions). However, turning English language pseudocode into the default mode…

My experience has been different, I admit. I'm mostly involved with specs at the W3C and we exclusively do algorithmic specs. I won't claim that one approach is better than the other, as I can only speak from my personal experience. I've jotted down some of those thoughts here:

http://www.w3.org/TR/test-methodology/

> That's why I'm a bit unhappy that we seem to have started wordsmithing before getting some of the decisions done.

You are probably right. Like I said in a previous email, I just joined the list and have no idea at what stage you all are at - but I'm happy to try to help. 

-- 
Marcos Caceres

---

From: John Cowan <[email-masked]>
Date: Mon, 10 Jun 2013 09:22:55 -0400

Marcos Caceres scripsit:

> Yes, I'm sorry; I didn't mean any offense. I just meant that it was
> a conditional MUST, and that's not how MUST should be used (as it
> means one parser can do one thing and another can do another thing
> … which is an interoperability anti-pattern). 

There are two kinds of conditional MUSTs.

A conditional MUST of the form "The program MUST do such-and-such if 
thus-and-so is true" is perfectly fine.  But a conditional of the form
"The program MUST do such-and-such if it can", which is what we have
here, needs to be rewritten as "The program SHOULD do such-and-such."

-- 
What has four pairs of pants, lives             John Cowan
in Philadelphia, and it never rains             http://www.ccil.org/~cowan
but it pours?                                   [email-masked]
        --Rufus T. Firefly

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 10 Jun 2013 16:00:01 +0200

On Jun 10, 2013, at 15:22, John Cowan <[email-masked]> wrote:

> But a conditional of the form

That is not quite what SHOULD means:

3. SHOULD   This word, or the adjective "RECOMMENDED", mean that there
   may exist valid reasons in particular circumstances to ignore a
   particular item, but the full implications must be understood and
   carefully weighed before choosing a different course.

So "SHOULD" = "MUST unless it can be determined appropriate not to", and we typically try to explain those circumstances and implications in the draft.

The fact that you cannot do such-and-such may not at all make it appropriate not to do such-and-such!
(After all, not being able to do something is typically the result of a design decision, and that decision simply may have been inappropriate in the first place; the SHOULD does not exculpate you here.)

Grüße, Carsten

---

From: John Cowan <[email-masked]>
Date: Mon, 10 Jun 2013 10:18:07 -0400

> appropriate not to do such-and-such!

I think it does; otherwise we get paradoxes like this one:

1) It is my moral duty to prevent the world from being destroyed and
every person on it killed (for example by Vogons);

2) It is impossible for me to stop the world from being destroyed
by Vogons;

3) Therefore, it is my moral duty to do the impossible.

> (After all, not being able to do something is typically the result of
> a design decision, and that decision simply may have been inappropriate
> in the first place; the SHOULD does not exculpate you here.)

That sounds more like MUST to me.  A major purpose of including SHOULDs
is to allow implementation tradeoffs to exist.  If it comes to that,
not even MUST is truly absolute: a processor spec might say that on
encountering a certain opcode, the processor MUST add the r2 register
to the r1 register, but this requirement is not generally held to apply
when the processor is on fire.  There are things that airplane engines
MUST do even when they *are* on fire, however.

-- 
John Cowan   [email-masked]
    "Mr. Lane, if you ever wish anything that I can do, all you will have
        to do will be to send me a telegram asking and it will be done."
    "Mr. Hearst, if you ever get a telegram from me asking you to do
        anything, you can put the telegram down as a forgery."

---

From: Paul Hoffman <[email-masked]>
Date: Mon, 10 Jun 2013 10:35:45 -0700

<no hat>

>   A JSON generator produces JSON text that MUST strictly conform to

This would be more definitive as "...the JSON grammar from Section 2 of this document".

>   Generators MUST NOT duplicate names in objects if they can avoid or

+1 to the others who have said "yuck" to the poor use of 2119 MUST here. Further, this is a significant change from both RFC 4726 and ECMAScript. Proposed new wording:

Generators SHOULD NOT create objects that have duplicate names because objects with duplicate names can be interpreted in different ways by conformant JSON parsers.

--Paul Hoffman

---

From: Tatu Saloranta <[email-masked]>
Date: Mon, 10 Jun 2013 10:39:13 -0700

On Mon, Jun 10, 2013 at 5:20 AM, Marcos Caceres <[email-masked]> wrote:

> I haven't read the charter, tbh … I literally stumbled onto this list
> yesterday :)

Make sure you then read preceding discussions. Many of the concerns have
been discussed in considerable length. It appears bit arrogant to start
commenting on "should leave all these loopholes" when there are solid
reasons for not mandating things that various implementation can not
support in practice. Practice based on existing significant use cases, as
discussed on the list.

> However, I'm worried that overly simplistic or optimistic conformance
> requirements will just force people to go and look at ES6 to actually write
> the parsing and generation algorithms (or worst, they will just find some
> other random implementation out there and copy that). That could greatly
> diminish the value of this specification as it will leave implementers
> scratching their heads about how to implement either a parser or a
> generator.
>
> Also, given the legacy of JSON, it should be possible to see which parser
> behavior "won" (e.g., Doug's original JSON.js?) - and model this spec off
> that.
>
>
Which is what has been discussed in detail as well; and is what lead to
current proposal of "if only one of duplicate values used, it shall be the
last one".

> Additionally, I suspect few people actually implement an ABNF parser -
> whatever is expressed in ABNF will have to be translated into code for a
> specific implementation. You can essentially shortcut that by specifying
> the algorithm and making implementer's lives easier.  That's not to say
> that the ABNF should not be there (it helps the reader understand
> components of the JSON grammar) - but the reality of the situation should
> be acknowledged (ABNF is an editorial aid, but rarely, AFAIK, a tool used
> in implementations in it's pure form to do syntactical checking).
>
> Yes, I'm sorry; I didn't mean any offense. I just meant that it was a
> conditional MUST, and that's not how MUST should be used (as it means one
> parser can do one thing and another can do another thing … which is an
> interoperability anti-pattern). This would, obviously, be bad if I'm
> sending one JSON representation from the client and it gets transformed
> into a different one on the server and the spec says that this behavior is
> ok.
>

But this is reality: the only way to guarantee, for example, uniqueness of
keys leads to constraints that make it impossible to process JSON content
without tracking all names of currently open JSON objects in memory. In
worst case this is comparable to just holding on to the whole logical JSON
tree representation.

>
> On the other hand, if the spec has to say, "well, that's the reality right
> now… and here are some guidance on how to avoid that problem without
> breaking clients and servers:" that might have to do.
>
>
which is what I understand specification tries to say.

-+ Tatu +-

---

From: Nico Williams <[email-masked]>
Date: Mon, 10 Jun 2013 13:00:49 -0500

> +1 to the others who have said "yuck" to the poor use of 2119 MUST here. Further, this is a significant change from both RFC 4726 and ECMAScript. Proposed new wording:

Agreed.  If we want a MUST then we need to distinguish types of
encoders/parsers ("non-streaming ... MUST ...; streaming ...
MAY/SHOULD ...").  That, I think, is why it might be valuable to
distinguish types of encoders/parsers: so we can apply requirements to
one common implementation type that we cannot to the other.

The RFC2119 approach to this is to say SHOULD/SHOULD NOT and explain
what exceptions might be made.

Six of one, half a dozen of the other... I'd prefer a construction
that ends up having a MUST because I suspect it will be understood
more readily by future implementors, but either construction will do
in the end.

Although, to be extra careful here, since this sub-thread is about
encoders, I'm not sure that a non-streaming encoder can be expected to
detect duplicates in a has table (which would normally be an error at
insertion time, but let's say it's happened).  And so perhaps we can't
really distinguish *encoder* types, only parser types.

Nico
--

---

From: Vinny A <[email-masked]>
Date: Mon, 10 Jun 2013 21:19:18 -0500

> Generators SHOULD NOT create objects that have duplicate names because objects with duplicate names can be interpreted in different ways by conformant JSON parsers.

+1

Mr. Crockford and others have already stated that a SHOULD is mandatory in regards to duplicate keys - there's so many implementation and archive headaches with parsers that a MUST or MUST NOT is never going to fly.

-----------------
Vinny
www.jsontest.com