It seems to me that Djula is assuming that variable names are symbols.
The function returned by COMPILE-TEMPLATE expects keyword arguments
that define the 'top level' variables in the template, so that's how
the top level variables got their symbol names. The requirement of
symbol names continues into deeper variables.
It's not just symbols, they seem to be symbols that are case
insensitive (so not using |'s to define them).
Is there a reason for this? Is this really a good idea?
Thanks,
Bob
On 4-Aug-08, at 9:35 AM, Nick Allen wrote:
> On Sun, Aug 3, 2008 at 2:57 PM, Bob Hutchison <hutch...@recursive.ca
> >wrote:
>
>>
>> Hi,
>>
>> It seems to me that Djula is assuming that variable names are
>> symbols.
>>
>> The function returned by COMPILE-TEMPLATE expects keyword arguments
>> that define the 'top level' variables in the template, so that's how
>> the top level variables got their symbol names. The requirement of
>> symbol names continues into deeper variables.
>>
>> It's not just symbols, they seem to be symbols that are case
>> insensitive (so not using |'s to define them).
>>
>> Is there a reason for this? Is this really a good idea?
>>
>
> Bob,
>
> It is indeed expecting variables to be symbols [keyword symbols to be
> exact]. what do you see as the downside? I made variables represented
> internally as symbols...
>
> 1. ...because lookups keyed by symbols are faster than those on
> strings
No arguing with facts :-) But you're also using plists rather than
hashtables -- there are all kinds of design issues here, but if the
time of comparison matters then the number of things being compared
must also matter -- I'm not questioning your use of plists over
hashtables, I made a similar decision in my project. At least in my
case, the time we are talking about here is going to be dwarfed by the
time taken to generate the data for the template, and the IO
associated with handing the output of applying the template to the
data, and I suspect the time taken to actually execute the template.
BTW, what's that #1=... #1# stuff in the .getf-v-plist anyway? It
looks like something clever I'd want to know about :-)
>
> 2. ...to be able to stick with the "keyword argument"/keyword plist
> convention, which is something that has consistently been used in lisp
> libraries since dinosaurs walked the earth (and people used lisp
> machines)
internally alists are supported too, and assoc takes a test function.
>
> 3. ...so that the lisp reader could be used to read dictionaries and
> devel dictionaries
Hmm.
Okay, my concern... The keys in the data I use are not really in my
control. They are extracted from the data entered in by the user. This
data might even contain spaces. It is often case sensitive (doesn't
matter what I tell people, they still do stuff like that, and they
like putting spaces into URLs too). On top of that, there are cases
where I'd be introducing hundreds of thousands, possibly millions, of
keyword symbols.
Cheers,
Bob
>
>
> take care
>
> Nick
>
> >
it's a terrible terrible habit i have that no one should pick up.
if you assign something to a number like #1=foo then any subsequent
occurrences of the number like #1# will be interpreted by the reader
as the exact same thing. so
(eq #1="foo" #1#) -> T
since this is done at read-time it can be used as some sort of
shorthand syntax. so
(do ((c #1=(read-char in nil nil) #1#))
....
is the same as
(do ((c (read-char in nil nil) (read-char in nil nil)))
...
it's not a good habbit
> Okay, my concern... The keys in the data I use are not really in my
> control. They are extracted from the data entered in by the user. This
> data might even contain spaces. It is often case sensitive (doesn't
> matter what I tell people, they still do stuff like that, and they
> like putting spaces into URLs too). On top of that, there are cases
> where I'd be introducing hundreds of thousands, possibly millions, of
> keyword symbols.
um... hrm... how exactly is user-inputted logic bleeding into your
templates? this sounds like a weird situation to me...
Nick
>
>>
>> BTW, what's that #1=... #1# stuff in the .getf-v-plist anyway? It
>> looks like something clever I'd want to know about :-)
>>
>
> it's a terrible terrible habit i have that no one should pick up.
Okay :-) I thought I knew what that meant, I'd just never considered
using it with code.
>
>> Okay, my concern... The keys in the data I use are not really in my
>> control. They are extracted from the data entered in by the user.
>> This
>> data might even contain spaces. It is often case sensitive (doesn't
>> matter what I tell people, they still do stuff like that, and they
>> like putting spaces into URLs too). On top of that, there are cases
>> where I'd be introducing hundreds of thousands, possibly millions, of
>> keyword symbols.
>
> um... hrm... how exactly is user-inputted logic bleeding into your
> templates? this sounds like a weird situation to me...
Could easily be weird :-)
The application I'm working on is a weird (as in 'uncommon', certainly
unconventional, possibly unique) kind of content management system.
There are two parties involved: the authors and the designers/
developers. The authors use my application to write what can be a
fairly significant volume of content. The designers use, at the
moment, Liquid (a Ruby templating system that is very similar to
Djula), to transform the content written by the author into something
specific (normally html, but not always, sometimes a program,
sometimes a template in a different templating language (e.g. PHP,
rhtml, etc)). Consequently there is definitely 'logic' in the
templates, but it isn't the logic of my application.
Generally speaking, the templates rummage through the context data
looking for interesting things and when it discovers something,
produces some kind of output.
The context data is generated once. The application re-arranges that
data (basically equivalent to redefining the plist passed to COMPILE-
TEMPLATE to point into interesting bits of the entire contxt) for each
unit of work and runs several templates against the context. The
specific project that's motivating me to look at Djula has about 14MB
of content and 120MB of other stuff (e.g. images) that generates just
short of 7000 pages of html and xml. That's not the biggest project
either. The data would have 4 or 5 templates run against it about
10,000 times (sometimes nothing needs to be done). The amount of cross-
referencing going on can be very high, and is crucial. The application
does not limit what can be used to define a cross reference. And this
is how, in Djula, I get many many thousands of keywords whose values
are not under my control.
I guess the templates are treated as a programming language that can't
do anything dangerous (that's why I asked about the safe subset a few
days ago).
I should note that with Liquid/Ruby I use hashtables, as does Django.
This, of course, gives a pretty much arbitrary mapping of strings to
data.
Cheers,
Bob
>
>
> Nick
>
> >
To me the most important feature of Djula is the ability of the {%
devel-dictionary %| / {% devel-value %} tags to fake running data
(since cl-terrace's "view only mode" is integral to our workflow
making lisp-powered websites) and I'm not willing to do anything that
would break the functionality provided by these tags. but I've thought
about it and I think hashtable/string support could be added to Djula
without breaking anything.
what I could be done (I think) is make it possible to use strings in
places where there might be spaces, case sensitivity, etc, using the
"" syntax
so you could do something like
{{foo}}
{{"also a variable"}}
{{foo."funny key".1}}
(funcall template :foo value)
(funcall template "also a variable" value)
and extend the :. "splice" operator to take a plist or a hashtable, so
(funcall template :. (list foo x bar y))
(funcall template :. hashtable1 :. hashtable2)
lookups would be done by STRING= with symbols being coerced to up- or
down-case strings, would this satisfy the needs of your project?
Nick