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_l..., 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/DUEB3H... Code of Conduct: http://python.org/psf/codeofconduct/