Implementation questions about "_" in Positron

2013-06-10

When you write a loop in Positron::DataTemplate or the upcoming Positron::Template, the individial elements of the list you're looping over become a new child environment of the current environment. Provided the elements are all hashes, that is. If not, the special expression "_" should access the complete element. This allows things like:

['@list', 'next:', '&_'] with environment { list => [1, 2, 3 ] }
↳ ['next:', 1, 'next:', 2, 'next:', 3 ]

I've found some questions with this approach, or rather one question and one consequence:

Where to implement it?

I could implement this directly in the templating system, i.e. Positron::DataTemplate, as a special case when including the expression "_" from the environment. This would allow me to do exactly the above, but not much more. In addition, I'd have to implement it once per template language.

I could implement this in the expression language, i.e. Positron::Expression: the special expression "_" always refers to the complete environment. This is similar to the above, except I'd only need to implement it once, but in a place where it does not really fit.

I could also start treating the environment lookup "_" as "return the entire data" in Positron::Environment::get. This is the most heavy-handed approach, and fits even less semantically, but it would make for a nice, compact implementation, with little to no corner cases. I'll probably do this, as well as augmenting Positron::Environment::set with the possibility to overwrite the entire data.

User-supplied "_" keys

A user-supplied key "_" could no longer be accessed this way, at least not directly. One could always use the expression "_._", which accesses exactly this, with one exception: inheritance. Positron::Environment objects can refer to a parent environment. If any child environment knows nothing about a given key, it will ask its parent. This is useful in loops: the contents of the row being looped over becomes the environment, except that all "global" keys are still available unless masked. With "_._", though, the second "_" would not be looked up in a parent, since the first one accesses a simple hash.

Further use: assignments

Another planned feature for Positron is assignments: an assignment node / element creates a new environment in which the given identifier points to the result of the given expression, with the original environment as its parent. Any expressions under or within this node use this new alias.

Assigning an expression (hash valued) to "_" basically peels off one or more layers. Instead of accessing content.title you could now access title. Assigning "_" to an identifier, on the other hand, basically adds one layer. Instead of accessing title, you could access content.title.

These peeling / unpeeling assignments may seem odd, or at best useful to save on typing, but they are very powerful in combination with includes. I've sometimes seen an inclusion (with another templating language) which assumed a certain container for the data, or lack of it. It will be interesting to see how well this assignment works.