It's an interesting idea, and has come up occasionally before. It probably stems from Lisp, where it's common practice (IIRC control flow like 'if' is defined this way). I believe it's called quoting there -- I've never heard the term NSE before. (Is that term specific to R?)
I'm glad you start out by proposing dedicated syntax -- automatically inferring that a particular function takes (some or all) auto-quoted arguments would be hard because it's the parser that would need to know, but the parser doesn't have access to imported function definitions. A dedicated syntax doesn't have this problem (though it might have other problems). A few problems include: - The `x` syntax is pretty ugly -- in Python 2 this was a shorthand for repr(x), and we removed it in Python 3 because backticks are hard to read (it looks like about two pixels on my screen). Also, these days `x` is pretty commonly used as indicator for "code" (e.g. markdown). (OTOH I don't have a better suggestion.) - The ast module is exempt from the usual backwards compatibility guarantees across minor versions -- if we need to change the AST structure to accommodate a new type of expression or a new feature of the compiler, we will do his without worrying too much about backwards compatibility. (As an example, in Python 3.8 the AST uses Constant for all literal node types (numbers and strings), whereas in previous versions there are separate Num and Str node types.) - If you want to evaluate a quoted expression, there are a few different choices depending on the use case: you might want to evaluate it in exactly the environment where it was first written (i.e. the caller's environment, including nonlocals), or you might want to evaluate it in a context provided by the function that's evaluating it. I *think* you are accounting for this, but I wanted to make sure it was on your radar. - We need a function that, given an expression, returns a reasonable string. We have such a function, thanks to PEP 563, although it's not exposed (it's written in C and used only internally to construct the strings that go into the __annotations__ dict). It also doesn't preserve whitespace exactly. Now, in order to evaluate the expression we don't need the whitespace, but if you want to get the string and use that as an axis label it could become somewhat ugly. With all that in mind, and without any promises, I do think it would be cool if you could code up a prototype and see how it feels. Good luck! --Guido On Sat, Jul 13, 2019 at 12:36 PM Nima Hamidi <ham...@stanford.edu> wrote: > Hello all, > > > I would like to briefly share my thoughts on non-standard evaluation > (NSE), why this is useful, and how, potentially, it can be added to Python. > In most languages, functions have access only to the *value* of their > arguments, and not to the expressions that yielded those values. However, > sometimes it is useful to have access to the expressions as well. For > example, let plot(x, y, ...) be a function that draws the scatter plot of y > against x and adds labels for the x- and y-axes. Currently, there is no way > to distinguish plot(x, *z*, ...) from plot(x, *y*, ...) from within the > function. As such, one needs to pass the names of the variables to the plot > function to be used as the axes' labels. Using NSE, though, the function > can look at the expressions in the method call and use those as the default > value for labels. In R, this idea is used widely to make the syntax simpler. > > > In the following, I sketch how I think this can be implemented: > > > 1. Let BoundExpression be a class containing an ast.Expression as well > as locals and globals dictionaries. BoundExpression can also have an eval > method that evaluates its expression using its locals and globals > dictionaries. > 2. Let `x` be the short form for BoundExpression("x", locals(), > globals()). Then, the plot function can be implemented in a way that > plot(`x`, `y`) draws scatter plot of x and y *and also,* labels the > axes correctly. No need to provide labels explicitly anymore. > 3. A more challenging idea is to let developers decide whether their > functions need NSE or not. For example, when a function is defined as def > f(`x`), for any method call like f(x), the first argument should be wrapped > with a BoundExpression instance. > > I would appreciate any feedback on these ideas. > > Best, > Nima > > > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@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/QE5OTQSEQHBBWWAQVIA66YUKGK5M6QDL/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him/his **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@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/FV3IUH56CFVMODNPNACPH3EQNGUUFKS6/ Code of Conduct: http://python.org/psf/codeofconduct/