My favorites | Sign in
Project Home Downloads Wiki Issues Source
READ-ONLY: This project has been archived. For more information see this post.
Search
for
  Advanced search   Search tips   Subscriptions
Issue 34: Repeated section should iterate over dictionaries and have special variables @name and @value
2 people starred this issue and may be notified of changes. Back to list
Status:  Accepted
Owner:  gtempacc...@yahoo.com


 
Project Member Reported by gtempacc...@yahoo.com, Sep 29, 2009
There are a few use cases for this, like generating code and command line
arguments.

Sep 30, 2009
#1 tim.sch...@gmail.com
Data:

{"dict": {"key1": "value1", "key2": "value2"}}

Template with your proposal:

{.section dict}
<dl>
    {.repeated section @}
    <dt> {$name} </dt><dd> {$value} </dd><!-- what is @ here? -->
    {.end}
</dl>
{.end}

Template with my proposal [1]:

{.section dict}
<dl>
    {.repeated key @}
    <dt> {key} </dt><dd> {@} </dd><!-- @ is same for object and array -->
    {.end}
</dl>
{.end}

With my proposal, you'd also dispense with the $index variable required for array
iteration.  Instead, the template designer would choose the name (e.g. {.repeated
index list}).  

And for iterating over elements in arrays and members in an object (in JSON terms,
they are referred to as objects, not dictionaries) you'd get the same pattern.  The
cursor assumes the value of the element in an array or the member in an object.  The
(optional) name used after the .repeated declaration assumes the index in an array
and the name of the member.

This aligns with what people might expect from other languages (for key in obj).  It
also dispenses with the extraneous "section" term in ".repeated section".  Finally,
if you really want to be concise and you don't need a reference to the array index or
member name in your template, you could not include a named argument in your
.repeated declaration.

E.g. for an array

<ul>
    {.repeated array}
    <li> {@} </li> <!-- cursor assumes value of element in array -->
    {.end}
</ul>

E.g. for an object

<ul>
    {.repeated object}
    <li> {@} </li> <!-- cursor assumes value of member in object -->
    {.end}
</ul>

All this (my alternate proposal) also allows any names to be used in the data
provided to the template ("$index", "$name", "$value", etc. are all free - and
perfectly valid in JSON).  I don't think it is necessary to reserve terms like those.

A number of your responses to similar inquiries are along the lines of "the
application should munge the data to fit my template language."  I think this is a
somewhat unnecessary constraint.  The template language could be made simpler and
work with data that is less specific to this language alone.  Template designers who
don't control all aspects of the application would be happier.  And application
developers who don't care squat about the constraints or limitations of the template
language would need to do fewer transforms on the data they pass along.

[1] http://groups.google.com/group/json-template/browse_thread/thread/e83c2a0af5396da7

Sep 30, 2009
Project Member #2 gtempacc...@yahoo.com
Right now sections and repeated sections require a name:

{.repeated section foo}
{.section bar}

I don't think we can get rid of "section" in repeated without breaking compatibility,
but assuming you can, what's the syntax?

{.repeated <subdict> <name> <value>}  # for objects
{.repeated <subdict> <index>}  # for lists

The <name> <index> <value> can't be first because they're optional.  If I just want
to iterate over a list with no index, I want to write:

{.repeated posts}

Not

{.repeated index posts}

And then ignore 'index'.  A lot of your proposal seems to break compatiblity unless
I'm missing something.  


Oct 1, 2009
#3 tim.sch...@gmail.com
Currently you can do this:

{.repeated section foo}

I'm suggesting allowing this:

{.repeated foo}

If one argument, it is the section name, if two, it is the repeat variable followed
by the section name:

{.repeated [<repeat_var>] <section_name>}

For objects, the repeat variable would be set to the name of each member in the
object.  For arrays, the repeat variable would be set to the index of each element in
an array.

Where things would break:

If someone is currently using referencing a member named "section" in a repeat block
in their template.

Data:

{"list": [{"section": "foo"}]}

Template:

{.repeated section list}
    {section}
{.end}

Currently produces:

    "foo"

With this proposal this would produce:

    0

I can't think of any other things that would break.  Basically, this proposal just
assigns meaning to the second term in the {.repeated section} directive.  Currently,
it's just an extra word, right?


Oct 1, 2009
#4 tim.sch...@gmail.com
I'm also curious what value the cursor assumes when iterating over elements in an
array in your proposal.

It seems to me like the pattern is the same for objects and arrays.  People commonly
iterate over members in an object and elements in an array.  In both cases, within
the repeat block, you need two references.  For objects, you need a reference to the
member name and the member value.  For arrays, you need a reference to the element
index and the element value.  Sometimes, you don't need a reference to the index for
an array.  And perhaps sometimes someone might not want a reference to the member
name in an object (though I wouldn't suggest this is very common).

You've already got the cursor (@).  It makes sense to me that this would become the
one thing people always need when iterating: member value for objects and element
value for array.  That leaves one variable name that needs to be determined.  You
suggest reserving names for it in the language ($index and $name).  I'm suggesting
letting the template designer pick the name - and taking advantage of the second term
you already require in your .repeated directive.

I have no idea how many adopters there already are for json-template.  And I don't
mean to neglect the importance of backwards compatibility.  If, however, the language
is still young, it would be unfortunate if it became unnecessarily awkward for the
sake of preserving backwards compatibility when that might not really be an issue
(also, version numbers are cheap).

Oct 1, 2009
#5 tim.sch...@gmail.com
Sorry, and I meant I'm curious what value the cursor assumes when iterating over
members in an object (in your proposal).
Oct 1, 2009
Project Member #6 gtempacc...@yahoo.com
OK I see the proposal now.  It is clever in repurposing the second word for the
index.  And there is some symmetry in that an array index can be thought of as a key.
 That is, an array is a special case of an associative array, where the keys are
contiguous integers.

Main problem: {.repeated index posts}  just reads badly.  It has poor grammar.

{.repeated section posts} doesn't read badly to me.  I don't think of "section" as an
"extra" word, any more than "static" is an extra word "static void foo()".  A
repeated section is a variant of a section.

The syntax follows Python's "read the words" style:

'for word in words'

better than

for (word : words)    (java)


[x**2 for x in 1,2,3,4]

better than

[x**2 | x <- [1,2,3,4]]  (haskell)


x = 3 if y > 2 else 5

better than

x = y > 2 ? 3 : 5;


Oct 1, 2009
Project Member #7 gtempacc...@yahoo.com
The cursor could either

1) remain unchanged (it will be the top-level object)
2) be undefined
3) be a length 2 array of [$name, $value]

{.repeated section flags}
  {@|unix-flag}
{.end}

unix-flag:  '--%s=%s' % (cursor[0], cursor[1])

Although I suppose it's better to do:

{.repeated section flags}
  --{$name}={$value}
{.end}

Oct 1, 2009
Project Member #8 gtempacc...@yahoo.com
Actually, to be consistent with both Python and JavaScript, @ should be the key. 
It's redundant with $name.

for var in obj:

for (var in obj) {
}

Oct 2, 2009
#9 tim.sch...@gmail.com
Right, so at least you notice the redundancy.  No reason to reserve words that are
redundant (this just forces more special processing of data structures that may
contain reserved words).

I imagine you'd also admit that there is symmetry among the following:

Python:

    for name in obj:

JavaScript:

    for (var name in obj) {

Template:

    {.repeated name obj}

I think most would argue that "for name in obj" is more intuitive than "repeated foo
bar," and personally, I don't see how "section" adds any clarity to the syntax. 
Given that you have chosen the word "repeated", I was only trying to propose some
logic for iterating over object members that would fit what people expect.

Oct 2, 2009
#10 tim.sch...@gmail.com
Also (apologies for pushing), consider this:

If you allow the template designer to choose variable names when iterating, they
actually don't need to even touch the (somewhat obscure) cursor or remember any
special $words.

Data:

    {
        "obj": {"key1": "value1", "key2": "value2"},
        "list": ["one", "two"]
    }

Template:

    Object members:
    {.repeated key obj}
        {key}: {obj.key}
    {.end}

    Array elements:
    {.repeated index list}
        {index}: {list.index}
    {.end}

Can you really hope to be more readable using @ and $?

Oct 2, 2009
Project Member #11 gtempacc...@yahoo.com
I don't see what you're getting at in the last example -- you want to iterate over
the values in the list typically, not the index.  You seem to be spelling it in 2
different ways.  The index is always 0..n.

'repeated name obj' is like 'for name in obj', but 'repeated index list' breaks down,
because you want to iterate over the items, not the indices.

Either way they don't read very well.  If the intention was to have 'for name in
obj', then we should spell it exactly like that.  The language has no variable
bindings now.  Adding variable bindings for a minor feature isn't worth it.

Here is an alternative:

Lists have {@index} and {@value}.

objects have {@name} and {@value}.

{@} just becomes a shortcut for {@value}.

This lessens the fear for reserved names, because $index is a valid variable name in
JavaScript, while @index is not.

At first I thought {@index} looks ugly for some reason, but it's growing on me. 
{$index} looks a little more traditional.  Also @foo means a vector in Perl.  But we
don't even have a Perl implementation.



Oct 3, 2009
#12 tim.sch...@gmail.com
Yeah, sorry, that last example was hastily written.

I was thinking bracket notation, not dot notation:

    Object members:
    {.repeated key obj}
        {key}: {obj[key]}
    {.end}

    Array elements:
    {.repeated index list}
        {index}: {list[index]}
    {.end}

But, as that is not supported, it doesn't make sense.

If the cursor is the element value for an array and the member value for an object,
this would read:

    Object members:
    {.repeated key obj}
        {key}: {@}
    {.end}

    Array elements:
    {.repeated index list}
        {index}: {@}
    {.end}

(And if you didn't need a reference to the element index or the member name, the
optional middle term could be omitted.)

I agree that what you typically want when iterating over an array is the element
value.  The free "section" term just looked to me like a place to assign the index
while you were at it.  And the cursor would assume the element value.  For objects,
cursor would assume the member value (as you also suggest).  And I was suggesting
that the space currently occupied by "section" (in .repeated section) could be a
place for the member name.

I'll stop being hung up on it now.  I am happy you're considering iterating over
object members now.  I still think you could get away with only reserving "@" (or
less) but I won't push it.

PS - In terms of valid identifiers, I wasn't referring to JavaScript or any other
language that might be used in an implementation.  I was referring to JSON.  "@name"
and "$name" are equally valid member names.  And, in JS, the following is perfectly
legitimate:

    >>> var o = {"@name": "value"}
    >>> o["@name"]
    "value"

I was thinking about how much care application developers have to put into ensuring
that the data they pass to the template doesn't contain member names that are
reserved by the language.  A JDIL (http://jdil.org/) structure will likely have
member names like "@value".  A data structure using JSON referencing will have member
names like "$ref".  The more member names you reserve for this language, the more
work people have to do to structure their data accordingly.  In my mind, a nice JSON
templating language could be used with any valid JSON.
Nov 14, 2009
Project Member #13 gtempacc...@yahoo.com
(No comment was entered for this change.)
Summary: Repeated section should iterate over dictionaries and have special variables @name and @value

Powered by Google Project Hosting