[stringtemplate-interest] dealing with empty list values
Joshua Royalty
royalpeasantry at gmail.com
Wed Feb 10 12:38:36 PST 2010
Yeah, its because $if(bool)$ is $ifTrue()$ but is $ifNotNull(object)$ when
object is not a boolean. Thus null and false are 'identical' to the $if$
statement, but the iterator doesn't strip out booleans.
I don't mind nulls being stripped automatically, it makes a lot of sense for
a template language (especially for smaller querys, like 'SELECT $columns;
separator= ", "$ from TABLE'), but null=false is not intuitive (or
consistent) whereas $strip(values)$ is, and I will take consistency over
convenience every day. Not to mention automatically stripping nulls
encourages writing sloppy code and can hide actual problems... How easy
would it be to debug code that uses the above statement if one of the
elements in columns was null and should not have been? The SQL query would
be functionally correct so it would execute correctly and most frameworks
would simply return null when the field was asked for.. as long as the
field wasn't required to be non-null its entirely likely that the problem
would never be noticed. Whereas if the null wasn't skipped the code would
blow up immediately when the SQL query was made, and even if the error
wasn't 'Invalid Syntax' the first thing I would do is print out the query..
Plus.. what if you have a list of booleans and you want to do something if
they are true, something else if they are false, and yet something else if
they are null? This currently isn't possible with the current 'if'
statement anyway, but if it ever was made possible null=false doesn't
work.. false != null even if the if statement currently treats them that
way. One example that is possible with the current framework.. $false$
isn't the same as $null$, nor are $template(false)$ and $template(null)$.
On Wed, Feb 10, 2010 at 7:06 AM, Jonathan Buhacoff <jonathan at buhacoff.net>wrote:
> Oops I got it backwards.
>
> The default mode is like $strip(values):{ ... }$ and with null=false it's
> what Joshua expects when he writes $values:{ ... }$
>
> Right?
>
> On Feb 8, 2010, at 7:11 PM, Joshua Royalty wrote:
>
>
>
> On Mon, Feb 8, 2010 at 1:51 PM, Terence Parr <parrt at cs.usfca.edu> wrote:
>
>> On Feb 7, 2010, at 5:02 PM, Joshua Royalty wrote:
>> Hi Terence,
>> > If $foo$ is 'missing', then
>> '<tr>$if(foo)<b>$foo$</b>$else$MISSING$endif$</tr>' will still print
>> '<tr>MISSING</tr>', but $values:{ v |
>> <tr>$if(v)<b>$v$</b>$else$MISSING$endif$</tr>}$ will not print
>> '<tr>MISSING</tr>' if one of the values is 'missing'.
>>
>> unless you use the null option, right?
>>
>
> is null=false the intended way to do this? If so it.. works, but it
> doesn't seem like a clean solution. First you end up with lists with
> multiple types of values.. which is just generally not a good idea.
> Second.. it is nice that it preserves backwards compatibility, and its
> relatively easy to implement.. but it really seems like a solution tacked on
> at the last minute and its not intuitive at all to a programmer.
>
>
>>
>> > Obviously in the first case ST does not know what text it should skip
>> and the user obviously intended it to print <tr>MISSING</tr>, and I contend
>> that ST also cannot know if it should skip in the second case and that the
>> user obviously intended it to print <tr>MISSING</tr> for values that were
>> 'missing'. When I use a list iterator I intuitively expect it to iterate
>> over every value in the list, it should be the same as repeating the code
>> inside the template for every value in the list, even if that value is
>> 'missing'.
>>
>> Well, if foo is missing then $foo:blort()$ should not evaluate blort() and
>> it doesn't. Therefore when foo his multi-valued, it should skip any empty
>> values to be consistent, right?
>>
>
> Depends on how you think about it.. See below
>
>
>>
>> > Also, length(values) return the length of the list with the nulls
>> included, and in order to get the length without them you need to call
>> length(strip(values)).
>>
>> You're right. that is inconsistent. on the other hand, given that you
>> might be using the null option, there has to be a way to figure out how many
>> total elements you're going to have.
>>
>
> Again, the inconsistencies make it seem like this was tacked on instead of
> integrated into the framework.. And that makes it harder to remember and
> use.
>
>
>>
>> > To be consistent with the current ST list iterator length(values) should
>> automatically strip nulls... However, another fix would be to not
>> automatically skip nulls in the list iterator. This would fix both of the
>> inconsistencies and be much more intuitive. If people want to skip the
>> nulls entirely when iterating they can use strip as a shortcut,
>> $strip(values):{ v | <tr><b>$v$</b></tr>}$. For backwards compatibility /
>> convienience you can add a global 'AutoStripLists' option if you think its
>> necessary.
>>
>> I understand what you're saying, but what about the case when foo a single
>> value that I have above? should it invoke blort()?
>>
>
> I think I may have found the communications disconnect. I've been treating
> ':' as the 'list iterator' operator... you seem to be treating it as the
> 'apply template'/'expand list and apply template' operator..
>
> If you think of ':' as the 'list iterator' operator (which is how the cheat
> sheet describes it..), then actually, no, blort should not be invoked
> because by using the 'list iterator' operator (instead of the 'invoke
> template' ($<template>(<attr>)$) operator) you are implying that it is a
> multi-valued attribute. (so $<attr>:<template>$ is a shortcut for
> $if(<attr>)$$<template>(<attr>)$$endif$ when <attr> is single valued...
> (though personally I would spell it out the second way..))
>
>
>
> I guess the real question it comes down to is what is more important..
> convienience in the case that you want to not want to apply the template to
> null items in a list or having a consistent (and thereby intuitive)
> framework. Needing to skip null elements in a list seems like a pretty
> uncommon case to me.. (I could be wrong), and its the only piece that would
> not be backwards compatible. If people really need to skip nulls, they
> could simply use 'strip'.. or there could be a global 'UseStripIterator'
> setting..
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>
>
>
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20100210/85b16aa5/attachment.html
More information about the stringtemplate-interest
mailing list