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/

Reply via email to