On 9 April 2010 21:30, Hanno Schlichting <ha...@hannosch.eu> wrote:
> Sure. I think the approach we took was good. It gave as a hugely
> successful, stable and performant engine. I just have the feeling that
> the current model has become somewhat convoluted and hinders us to do
> any more optimizations. I certainly don't want to go anywhere near
> what Spitfire did with its four different optimization stages. There
> are things which are better left to JIT compilers like Unladen
> Swallow.


> RepeatNode
> \-- AssignNode
> \-- ConditionNode
> \---- ContentNode

That's what I tried to do, but failed because of poor approach. I
think it's possible to redo this in a sane way, e.g. establish an AST
not for Python code, but for template primitives such as the ones you

I think part of the problem was scope creep; suddenly we had i18n in
there along with metal and various other concepts.

> or something similar "high-level". For the repeat variable case, I'd
> then want to take each RepeatNode and traverse it's inner nodes. If
> the "repeat" variable is accessed the RepeatNode would get a flag set
> and generate the corresponding code at a later stage. For this to
> work, you need to be able to ask each Node for the variables it's
> operating on.

Really, what we need is something like:

> Scope
> -- RepeatNode
> ...

Such that the code generator will take care of backing up scope
variables, when necessary, e.g. when it's not temporary variables
within the scope.

Similar, the code generator should generate temporary variable names itself.

> Maybe you could also optimize the above tree to move the AssignNode
> outside the loop, if it isn't dependent on the loop variable of the
> RepeatNode. There's plenty other things you can do. I don't know which
> ones of these make sense to have and which ones are better left to
> Python itself.

I'd say that all refactoring should be left to independent AST
optimization logic, whether this be in the JIT-compiler, in CPython or
tentatively in a Python library.

> <ul tal:repeat="item items">
>  <li tal:condition="view.useIcons()">
>    icon
>  </li>
>  <li tal:condition="not view.useIcons()">
>    text
>  </li>
> </ul>

One problem here is that you don't know that ``view.useIcons()`` is
static. That said, I think we could have a flag
``treat_calls_as_static`` which would enable such optimizations.

But isn't it symptom treatment? Shouldn't the language instead be better:

>  <li tal:condition="view.useIcons()">
>    icon
>  </li>
>  <li tal:condition="not previous">
>    text
>  </li>

Maybe introducing node variables such as ``this``, ``next``,
``previous``, and ``parent`` would make sense.

There's always the option of going inline:

> ``if view.useIcons():``
> <li>icon</li>
> ``else:``
> <li>text</li>

I find that double backticks are much more readable than <! -- !> or
other such combinations; and nobody uses them for prose.

To group, either use a tag from the default namespace, or ``tal`` (or whatever):

> ``if some_condition:``
> <tal:group>
> ...
> </tal:group>

Personally, I kind of feel that ``tal:content`` and ``tal:attributes``
and friends are awkward because they mix Python and attributes. On the
contrary, I don't mind ``i18n`` because it's declarative.

For ``metal``, it's even problematic to require tag usage because of
oddballs like DOCTYPE. I'll have to think about that one; it's only
``use-macro`` that requires Python, the rest is declarative.

Repoze-dev mailing list

Reply via email to