Supporting JavaScript-style template literals, specifically tagged templates, could be generally useful. If we look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates, it's a really simple idea:

The tag function is called with the following arguments: the strings from the template (the raw string is also available), plus any evaluated expressions referenced by that string. This idea can be equivalently expressed in a number of ways in Python. So this might be:

```
from some_html_templating_library import html_template_function as h

num = 42
constraint = "A number >  40"

html_text = h"<b>{num}</b> complies with the constraint <i>{constraint}</i>" 
```

which results in `html_text` being set to `h(template, 42, "A number >  40")`, where `template` is some object that contains at the very least the original raw string as well as the non-expression strings.

Notably such tagged template literals - so just like JavaScript tagged templates - are not restricted to HTML or even to returning strings, but instead could be used for a variety of additional purposes, that I won't work out this moment:

* Logging strings which don't have to format their expressions - so similar to current logging when not using f-strings, but with the easy interface of f-strings, including desired formatting of expressions in simple logger scenarios
* Internationalization of strings
* SQL queries with sanitization of expressions (to avoid "Bobby Tables" injection)
* Object literals - something like D"10.2" instead of the somewhat longer D("10.2"), assuming for the latter `from decimal import Decimal as D` (this is a pretty weak argument on the face of it, but I can see the possibility of being more restrictive in the use of monkey patching namespaces with such literals to avoid unnecessary function call overhead...)
* Code (or AST) construction, following the quasiquote idea from Lisp
* Latex and other minilanguages (is Latex properly a minilanguage? ;) )

For some of these use cases, ideally we don't use `sys._getframe` if this were to be implemented - assuming f-string style expressions, it's perfectly feasible to use a lambda to capture any variables as desired using lexical scoping instead of the dynamic scoping of `sys._getframe` AND we need deferred evaluation of the expression. Some shorthand for the lambda keyword could be nice however.
  
I should mention that when I looked at some similar ideas last summer (https://github.com/jimbaker/fl-string-pep/, useful for some experiments on lexical scoping), in part with Guido, I was thinking that an implicit lambda should be used for all such expressions in tagged template literals. But my feeling now is that this would not be so Pythonic - we explicitly mark such usages now, and we should continue to do so. Just need to find the right character sequence for such shorthand!

On Sat, Jun 12, 2021 at 5:51 AM Jeff Allen <ja.py@farowl.co.uk> wrote:
On 10/06/2021 15:46, Ricky Teachey wrote:

Makes me wonder if stepping back and thinking, instead, about a way to automatically (optionally?) put the current calling context dictionary(ies) somewhere that a called function can get at it/them, so it can do what it wants with the context.

I think that would violate the expectation that a function call means the same thing in different contexts, hence f-strings work by supplying values at the "call site" not variables. I know you will find exceptions (like import context), but they are not as all-consuming as snapping the entire namespace. If you really want to, there's sys._getframe.

Jeff

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/DUEB3HLOW3LI4RXTLZN7JQFFX44FBWSJ/
Code of Conduct: http://python.org/psf/codeofconduct/