odoo/owl

clean up variable scoping semantics

sdegueldre opened this issue · 0 comments

Currently we have a few different tools that we use to control variable scoping: Object.create, ctx[isBoundary], capture(ctx), captureExpression, hasSafeContext, and maybe others.

This is in part because we initially wanted to preserve the Python QWeb implementation's semantics with regards to t-set, partly because we wanted to have JS-like ergonomics for lambdas (eg arrow-function event handlers), but in some places these are fundamentally incompatible and it causes some rough edges.

In this playground example, commenting or uncommenting the t-set changes the behavior completely for example.

Slots are essentially lambda functions, and we would want them to close over their rendering context at the point of definition, but capture(ctx) is a poor man's way to do that, since instead of actually closing over the variable bindings, it closes over a frozen copy of the value. The same problem exists with captureExpression: #1451

In the next major version, it would be nice if the templating language's semantics could mirror those of JS, in particular:

  • many constructs create block scopes (if, foreach/for, slots)
  • there is a way to differenciate a variable assignment from a declaration so that variables can be shadowed
  • t-call doesn't inherit the caller's context and works like a function call, everything needed in t-call is passed explicitly
  • loops create a new binding for the loop variable on each iteration (let/const semantics)
  • function definitions both explicit (arrow function in expression) and implicit (slot definition) close over the context at the point of definition (not a frozen copy).