[Python-ideas] Delay evaluation of annotations
אלעזר
elazarg at gmail.com
Sat Sep 24 15:21:13 EDT 2016
Thank you all for your feedback. I will try to respond to it in a way that
will not waste your time, But to do that I still need an example for the
stromgest issue raised - bacwards compatibility. It is not just the mere
change that is incompatible, since _any_ visible change is incompatible in
some way, or otherwise it wasn't visible.
Again, I assume ".__annotations__" access evaluates them in the original
context.
I couldn't find any useful example yet.
Elazar
בתאריך שבת, 24 בספט' 2016, 22:07, מאת Stephen J. Turnbull <
turnbull.stephen.fw at u.tsukuba.ac.jp>:
> אלעזר writes:
>
> > But _some_ people (medium-level, Steven, whose main language is
> > probably not Python) will not even know [function names are looked
> > up at runtime, and so the called function may not be why you think
> > it is] is the case.
>
> And the dinosaurs will have returned by independent evolution by the
> time it matters to them (unless it's a deliberate attack, in which
> case people at that level would be toast anyway).
>
> But I think you're completely missing what people are trying to tell
> you. You shouldn't be so concerned with refuting their arguments
> because it doesn't matter. No matter how many points you amass for
> technique, you're going to get creamed on style points anyway. It's
> like this:
>
> (1) Python is a "consenting adults" language, and that is presumed by
> its development culture. The goal is not to stop people from
> creating "functions that look like recursions but aren't" on
> purpose; it's to make it easy for them to write recursive
> functions if they want to. From your example, that goal is
> obviously satisfied. Nobody who matters wants to go farther than
> that in Python.
>
> The reason one can create "functions that look like recursions but
> aren't" is because another of Python's goals is to ensure that all
> things -- specifically including functions -- are objects that can
> be manipulated "the same way" where appropriate -- in this case,
> saving off the original function object somewhere then rebinding
> the original name to something else.[1] Granted, we don't go so
> far as Lisp where expressions are lists that you can manipulate
> like any other list, but aside from the fact that the code itself
> is an opaque object, functions are no different from other
> objects. Even builtins:
>
> Python 3.6.0a4 (default, Sep 3 2016, 19:21:32)
> >>> def help(*ignored, **paid_no_attention):
> ... print("Ouch, you just shot off your foot!")
> ...
> >>> help(help)
> Ouch, you just shot off your foot!
> >>>
>
> Shooting off your opposite extremity by redefining builtin classes
> is left as an exercise for the reader.
>
> All of this is a matter of the general attitude of pragmatism and
> bias toward simplicity of implementation (both enshrined in the
> Zen of Python).
>
> (2) You keep talking about others being lost in terminology, but in
> the context of Python discussions, you have a really big problem
> yourself. You use the phrase "just an annotation" as though that
> means something, but there is nothing like a "just an <anything>"
> in Python discourse, not in the sense that "once we introduce
> <anythings>s, they can be anything we want". The Language
> Reference defines what things are possible, and truly new ones are
> rarely added.
>
> This is deliberate. Another design principle is Occam's Razor,
> here applied as "new kinds of thing shall not spring up like
> whiskers on Barry's chin." Yes, function annotations need new
> syntax and so are a new kind of thing to that extent. *Their
> values don't need to be,* and even the annotations themselves are
> implemented in the preferred way for "new things" (a dunder on an
> existing type). Since it's new syntax, it's language-level, and
> so the values are going to be something already defined in the
> language reference. "Expression resolving to object to be saved
> in an attribute on the function" seems to be as close to "anything
> you want" as you're gonna get without a new kind of thing.
>
> (3) Python has a very simple model of expressions. The compiler turns
> them into code. The interpreter executes that code, except in the
> case where it is "quoted" by the "def" or "lambda" keywords, in
> which case it's stored in an object (and in the case of "def",
> registered in a namespace).
>
> As Nick admits, you could indeed argue that initializations and
> annotation values *could* consistently be turned into "thunks"
> (stored code objects, we already have those) in attributes on the
> function object. But
>
> (1) that's an extension of the model (admittedly slight since
> functions, which already do that for their bodies, are
> involved -- but see Nick's reply for the hidden difficulties
> due to normal handling of namespaces in Python), and
>
> (2) it's a clear pessimization in the many cases where those
> values are immutable or very rarely mutated, and the use case
> (occasional) of keeping state in mutable values. The thunk
> approach is more complex, for rather small benefit. Re "small
> benefit", IMHO YMMV, but at least with initialization Guido is
> on record saying it's the RightThang[tm] (despite a propensity
> of new users to write buggy initializations).
>
> (4) Chris argues that "compile to thunk" is incoherent, that
> expressions in function bodies are no different than anywhere else
> -- they're evaluated when flow of control reaches them. AFAICS
> that *still* doesn't rule out having the compiler recognize the
> syntax and produce code that returns thunks instead of ordinary
> values, but Chris's point makes that seem way too magical to me.
>
> (5) This points up the fact that Python is thoroughly dynamic. It's
> not just that types adhere to objects rather than variables, but
> the whole attitude toward language design and implementation is.
> A variable not defined because it's on the path not taken, or even
> a function: they just don't exist as far as the interpreter is
> concerned -- there's no way to find them from Python. That's not
> true in say C: if you have a powerful enough debugger, you can
> even call a function defined, but never referenced, in the code.
>
> So while we'd be happy for people familiar with "statically-typed
> languages" to enjoy the benefits of using Python for some of their
> work, we can't help them if they can't shake off that attitude
> when using Python. Making things seem intuitive (which here
> translates to "familiar", as usual) to them is just misleading.
> Python doesn't work that way, and often enough, that matters.
>
> (6) As you point out: of course, thunks are more general than values
> (in fact, without instructions that move them around, in computers
> a value is just a tree falling in a forest with noone to hear).
> But maximum generality is not necessarily an important goal, even
> if it makes some things prettier. Allow me to quote the late
> Saunders Mac Lane: "[G]ood general theory does not search for the
> maximum generality, but for the right generality."
>
> (7) Re Nick's comment about backward compatibility on the high bar
> having a G degree of difficulty, I'm sure you don't disagree with
> the principle of avoiding compatibility breaks.
>
> But while that's probably the argument that defeats this proposal
> here, I think that even looking forward from the time before
> releasing Python 3.0, the decision would be the same. That is, I
> think the decision to go with the simpler "evaluate to object"
> model was one of the right decisions at that time, for the reasons
> above. Your proposal of "evaluate to thunk" (possibly
> incorporating the property-based magic Alexander proposed) might
> be right *too*, but it's far from obviously better to me. I see
> nothing there that would be likely to have dissuaded the authors
> of PEP 3107, or Guido when he designed default initialization,
> from "evaluate to object".
>
> If you don't like that philosophy, or somehow don't think it applies
> here, keep trying, you may have a point. But in this thread, IMO
> you're trying to ski up a slope that's barely able to hold snow, and
> wasting everybody's time. And even if I'm wrong about wasting time
> with the feature, you'll be way more persuasive if you argue in terms
> of Python as it is designed (mostly deliberately so), which is the way
> most of us mostly like it. Although we do change our mind every 18
> months. :-)
>
>
> Footnotes:
> [1] For maximum humor, rebind it to a different recursive function!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160924/39020f95/attachment-0001.html>
More information about the Python-ideas
mailing list