On Sun, Nov 6, 2016 at 5:06 AM, Eric V. Smith <e...@trueblade.com> wrote: > Creating a new thread, instead of hijacking the PEP 532 discussion. > > From PEP 532: > >> Abstract >> ======== >> >> Inspired by PEP 335, PEP 505, PEP 531, and the related discussions, this >> PEP >> proposes the addition of a new protocol-driven circuit breaking operator >> to >> Python that allows the left operand to decide whether or not the >> expression >> should short circuit and return a result immediately, or else continue >> on with evaluation of the right operand:: >> >> exists(foo) else bar >> missing(foo) else foo.bar() > > Instead of new syntax that only works in this one specific case, I'd prefer > a more general solution. I accept being "more general" probably seals the > deal in killing any proposal! > > I realize the following proposal has at least been hinted at before, but I > couldn't find a specific discussion about it. Since it applies to the > short-circuiting issues addressed by PEP 532 and its predecessors, I thought > I'd bring it up here. It could also be used to solve some of the problems > addressed by the rejected PEP 463 (Exception-catching expressions). See also > PEP 312 (Simple Implicit Lambda). It might also be usable for some of the > use cases presented in PEP 501 (General purpose string interpolation, aka > i-strings). > > I'd rather see the ability to have unevaluated expressions, that can later > be evaluated. I'll use backticks here to mean: "parse, but do not execute > the enclosed code". This produces an object that can later be evaluated with > a new builtin I'll call "evaluate_now". Obviously these are strawmen, and > partly chosen to be ugly and unacceptable names and symbols in the form I'll > discuss here.
If we're considering options along these lines, then I think the local optimum is actually a "quoted-call" operator, rather than a quote operator. So something like (borrowing Rust's "!"): eval_else!(foo.bar, some_func()) being sugar for eval_else.__macrocall__(<unevaluated thunk of foo.bar>, <unevaluated thunk of some_func()>) You can trivially use this to recover a classic quote operator if you really want one: def quote!(arg): return arg but IMO this way is more ergonomic for most use cases (similar to your '&' suggestion), while retaining the call-site marking that "something magical is happening here" (which is also important, both for readability + implementation simplicity -- it lets the compiler know statically when it needs to retain the AST, solving the issue that Greg pointed out). Some other use cases: Log some complicated object, but only pay the cost of stringifying the object if debugging is enabled: log.debug!(f"Message: {message_object!r}") Generate a plot where the axes are automatically labeled "x" and "np.sin(x)" (this is one place where R's plotting APIs are more convenient than Python's): import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 10) plt.plot!(x, np.sin(x)) What PonyORM does, but without the thing where currently their implementation involves decompiling bytecode...: db.select!(c for c in Customer if sum(c.orders.price) > 1000) Filtering out a subset of rows from a data frame in pandas; 'height' and 'age' refer to columns in the data frame (equivalent to data_frame[data_frame["height"] > 100 and data_frame["age"] < 5], but more ergonomic and faster (!)): data_frame.subset!(height > 100 and age < 5) (IIRC pandas has at least experimented with various weird lambda hacks for this kind of thing; not sure what the current status is.) Every six months or so I run into someone who's really excited about the idea of adding macros to python, and I suggest this approach. So far none of them have been excited enough to actually write a PEP, but if I were going to write a PEP then this is the direction that I'd take :-). -n -- Nathaniel J. Smith -- https://vorpus.org _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/