LWN: Comments on "From late-bound arguments to deferred computation, part 2" https://lwn.net/Articles/904900/ This is a special feed containing comments posted to the individual LWN article titled "From late-bound arguments to deferred computation, part 2". en-us Thu, 18 Sep 2025 16:28:21 +0000 Thu, 18 Sep 2025 16:28:21 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906513/ https://lwn.net/Articles/906513/ tialaramex <div class="FormattedComment"> I think you&#x27;ve got muddled about From and Into, your description suggests we can take From&lt;T&gt; but I&#x27;m pretty sure we would actually write Into&lt;FinalScore&gt; instead<br> <p> This is one of those mirror image situations, you should implement From&lt;SoccerMatch&gt; on your FinalScore type, but you don&#x27;t write From&lt;T&gt; or From&lt;SoccerMatch&gt; in the function signature which eventually might need the score, you write what you wanted, Into&lt;FinalScore&gt; instead. We&#x27;re going to have a line like:<br> <p> score: FinalScore = Into::into(some_parameter);<br> <p> ... so you can see some_parameter&#x27;s type needs to be Into&lt;FinalScore&gt; to match.<br> <p> This is idiomatic for the iterators, hence IntoIterator but it would be unusual to ask for Into&lt;FinalScore&gt; rather than just FinalScore unless you&#x27;d specifically designed all of the API this way. As I understand it, what the deferred computation people want for Python is a type which does not require you to be explicit up front in this way.<br> <p> And that&#x27;s why I don&#x27;t think either C++ or Rust fit the bill. They can explicitly do this, but they aren&#x27;t really designed to be able to implicitly defer computation, everybody involved needs to agree up front to this arrangement.<br> <p> </div> Wed, 31 Aug 2022 01:58:33 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906432/ https://lwn.net/Articles/906432/ Wol <div class="FormattedComment"> <font class="QuotedText">&gt; You are right that theoretical computer science exists for a reason. It exists the same reason as pure mathematics: intellectual stimulation. That is its sole purpose.</font><br> <p> No. A major purpose is research and &quot;blue-sky thinking&quot;. Theoretical Physics is pretty much all pure mathematics.<br> <p> The problem arises when people start thinking that maths PREscribes the way the world behaves. It doesn&#x27;t. Different maths defines different universes, and we need to do experiments to find out which maths actually applies. That&#x27;s the step most people don&#x27;t bother with ...<br> <p> Cheers,<br> Wol<br> </div> Tue, 30 Aug 2022 10:15:27 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906429/ https://lwn.net/Articles/906429/ milesrout <div class="FormattedComment"> Default arguments do not make things less explicit. <br> <p> Frankly I find that the Zen of Python is cited more by non-Python programmers as an attempted &quot;gotcha!&quot; based on Python violating their interpretations of it. I rarely see it referred to by Python programmers these days. The whole point of it is meant to be that most of the points are followed by a counterpoint that says &#x27;but don&#x27;t take it too far&#x27;.<br> <p> &#x27;Simple is better than complex&#x27; is immediately followed by &#x27;complex is better than complicated&#x27; and personally I think it would be overcomplicated to need to write range(0, n) everywhere instead of range(n), even if it&#x27;s a little &quot;complex&quot; that range has a default argument that comes *before* its normal arguments. No Python beginner that I&#x27;ve ever taught has found that particular point difficult or confusing.<br> </div> Tue, 30 Aug 2022 09:36:40 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906428/ https://lwn.net/Articles/906428/ jem <blockquote>Python is huge as a language for teaching programming. This point in particular is one of the most unintuitive aspects of one of the most intuitive programming languages.</blockquote> <p> The root of this problem is the existence of argument defaults in the first place. Without them Python would be an even more intuitive programming language for beginners. In the <a href="https://en.wikipedia.org/wiki/Zen_of_Python">Zen of Python</a> the second principle is "Explicit is better than implicit.". Also: "Simple is better than complex.", "Readability counts.", and "There should be one – and preferably only one – obvious way to do it.".</p> Tue, 30 Aug 2022 08:39:26 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906426/ https://lwn.net/Articles/906426/ milesrout <div class="FormattedComment"> Arrogant and offensive comment from someone that clearly thinks he is smarter than he really is.<br> <p> You are right that theoretical computer science exists for a reason. It exists the same reason as pure mathematics: intellectual stimulation. That is its sole purpose.<br> </div> Tue, 30 Aug 2022 07:46:24 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906425/ https://lwn.net/Articles/906425/ milesrout <div class="FormattedComment"> <font class="QuotedText">&gt;Suppose you add the =&gt; notation because it&#x27;s OK for the feature you want - that is, the expression is evaluated when the function is called. Then two years later you want to add a small variation - the argument is evaluated when it&#x27;s used within the function.</font><br> <p> Slippery slope is not always a fallacy, but it is here. We&#x27;re talking about adding a feature that people have requested for many years, and you&#x27;re basically saying &quot;oh but what if people then want to add a feature nobody has ever asked for&quot;. Then say no at that point to any change? And what is the result? Well, the useful feature is included and not the useless feature.<br> <p> <p> </div> Tue, 30 Aug 2022 07:44:57 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906419/ https://lwn.net/Articles/906419/ edeloget <div class="FormattedComment"> In some contexts I would agree with you. But then we deal with the evolutions of a language, and that must be done very carefully. Or, to be blunt, the average developper/language user is wrong and don&#x27;t really know what he wants.<br> <p> Suppose you add the =&gt; notation because it&#x27;s OK for the feature you want - that is, the expression is evaluated when the function is called. Then two years later you want to add a small variation - the argument is evaluated when it&#x27;s used within the function. You&#x27;ll then add another keyword or another operator (say, =:&gt; because this one looks fun). Continue this way and soon, you&#x27;ll get twenty four operators for doing things that are semantically similar but not functionnaly identical. Developpers are lost, nobody remembers the difference between |=?&gt; and ?==&gt; (yeah, I don&#x27;t know either and I just invented them), programs are full of bugs and users no longer use these programs.<br> <p> That&#x27;s pretty much the reason why this so-called bike shedding exists (to be fair, I don&#x27;t believe this is bike shedding): to avoid doing changes that would make future evolutions more difficult. The python developpers have an obligation to see farther than just &quot;this would be useful, let&#x27;s do it quickly&quot;. <br> <p> (I cannot believe I just somewhat defended the python developpers ; I still consider that a language that let you multiply arrays of strings is dangerous for mental health). <br> </div> Tue, 30 Aug 2022 06:27:17 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906395/ https://lwn.net/Articles/906395/ NYKevin <div class="FormattedComment"> <font class="QuotedText">&gt; The C++ implicit constructor behaviour means this can be invisible (and hence surprising, and hence a footgun) but it is still a constructor.</font><br> <p> You say &quot;constructor,&quot; I say &quot;function that happens to initialize some memory as a side effect.&quot; Either way, it&#x27;s an implicit function call.<br> <p> <font class="QuotedText">&gt; It does this when the function is called, even if the function implementation actually checks the team names and discards any matches not involving Liverpool without using their FinalScore.</font><br> <p> That&#x27;s not really what I&#x27;m getting at. Your function could take SoccarMatch instead of FinalScore, and then call a private helper function which takes FinalScore if and when it actually wants to evaluate it. You *choose* to put FinalScore at the API boundary, which may make sense for your particular application, but C++ doesn&#x27;t force you to do it that way. You could even do it both ways using templating... which is exactly what Rust&#x27;s From&lt;T&gt; facilitates (i.e. you could accept a From&lt;T&gt; as an argument, then pass it as a T to some other function, and never worry about the conversion at all).<br> <p> <font class="QuotedText">&gt; Rust does have some silent conversions as traits, but they&#x27;re explicitly not intended to be expensive. Deref and DerefMut are intended solely to make smart pointers work as you&#x27;d want them to, and you&#x27;re cautioned not to do something silly (they&#x27;re safe Traits, so this can&#x27;t make your program unsound, but e.g. misfortunate::Double deliberately has a silly implementation of these Traits and it hurts your head) AsRef strongly cautions you that it&#x27;s intended to be cheap. For example AsRef allows us to take a String (which remember is just a Vec of bytes but we&#x27;ve promised it&#x27;s UTF-8 text) and get a read only view into those bytes. Cheap.</font><br> <p> I never said this was a Good Idea, and in fact specifically called out that it might not be. Nevertheless, it is a thing that you can do if you really want to.<br> </div> Mon, 29 Aug 2022 17:55:30 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906323/ https://lwn.net/Articles/906323/ tialaramex <div class="FormattedComment"> <font class="QuotedText">&gt; You can probably do this sort of thing with C++&#x27;s implicit single-argument constructors (and, I would imagine, with Rust&#x27;s From&lt;T&gt; trait)</font><br> <p> I don&#x27;t really see how?<br> <p> The C++ implicit constructor behaviour means this can be invisible (and hence surprising, and hence a footgun) but it is still a constructor.<br> <p> Suppose I have types FinalScore (a simple named pair of integers) and SoccerMatch (potentially sophisticated modelling parameters for a game of football). In C++ we can write a function which takes the names of two teams as string_views, and then a FinalScore, but pass it parameters for two strings, and a SoccerMatch. The compiler will implicitly construct the string_views, and the FinalScore, calling a constructor on FinalScore which takes a SoccerMatch (if there isn&#x27;t one this code doesn&#x27;t type check).<br> <p> It does this when the function is called, even if the function implementation actually checks the team names and discards any matches not involving Liverpool without using their FinalScore.<br> <p> Rust&#x27;s From&lt;T&gt; (and its cousins Into, TryFrom, and TryInto) are explicit, so you&#x27;d need to call the from() function (or the into() function etc.) to actually invoke the thunk. You could once again do this for function arguments, but now it&#x27;s explicit what&#x27;s happening (we might just as well call SoccerMatch::simulate here) and you still don&#x27;t get lazy evaluation.<br> <p> Rust does have some silent conversions as traits, but they&#x27;re explicitly not intended to be expensive. Deref and DerefMut are intended solely to make smart pointers work as you&#x27;d want them to, and you&#x27;re cautioned not to do something silly (they&#x27;re safe Traits, so this can&#x27;t make your program unsound, but e.g. misfortunate::Double deliberately has a silly implementation of these Traits and it hurts your head) AsRef strongly cautions you that it&#x27;s intended to be cheap. For example AsRef allows us to take a String (which remember is just a Vec of bytes but we&#x27;ve promised it&#x27;s UTF-8 text) and get a read only view into those bytes. Cheap.<br> </div> Mon, 29 Aug 2022 11:08:03 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906311/ https://lwn.net/Articles/906311/ tnoo <div class="FormattedComment"> Exactly my feelings. The language becomes overloaded with stuff that is hard to understand, and worse, unintuitive.<br> <p> </div> Sun, 28 Aug 2022 19:50:11 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906298/ https://lwn.net/Articles/906298/ k8to <div class="FormattedComment"> Yes, I remember this fully. While there were significant changes going on, the surface area to the usual programmer changed extremely little, and pretty much all my deployed python from 1.4 and 1.5 continued blissfully on without trouble. Some complexity existed in that engineering work, but it wasn&#x27;t pushed onto most users.<br> <p> That old way of doing things, just making a language that worked, is pretty superior.<br> <p> <p> </div> Sun, 28 Aug 2022 00:47:51 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906273/ https://lwn.net/Articles/906273/ NYKevin <div class="FormattedComment"> To my mind, there are three basic ways of going about it:<br> <p> 1. Everything is implicitly lazy all the time, and order of evaluation is totally up to the implementation. For this to work, the entire language has to revolve around it, like Haskell does. Everything has to be referentially transparent and pure, you have to have some sort of &quot;escape hatch&quot; for I/O (which may or may not end up looking like a monad, but it had better exist, unless your language is really domain-specific like CSS), and so on. If you don&#x27;t do those things up front, then you&#x27;re going to end up back-solving for them after the fact, and your language is going to be really painful to use.<br> 2. Explicitly constructed and implicitly evaluated thunks. For this to work, you probably need some kind of mandatory static typing, so that the compiler can disambiguate between &quot;I want to invoke the thunk now&quot; and &quot;I want to pass the thunk along to somebody else.&quot; You can probably do this sort of thing with C++&#x27;s implicit single-argument constructors (and, I would imagine, with Rust&#x27;s From&lt;T&gt; trait), but that doesn&#x27;t necessarily mean that it&#x27;s a Good Idea. Python supports a limited subset of this functionality using the descriptor protocol (see for example some of the Django code [1]), but implicit evaluation is restricted to foo.bar expressions, where foo has already been eagerly evaluated at least to some extent. The lack of static typing means that there are all sorts of weird things that can happen if you try to introspect foo or take it apart when bar has not yet been evaluated.<br> 3. Completely explicit thunks. In other words, lambdas (as well as related stuff like functools.partial). Python already has these, and they work reasonably well. There&#x27;s not much to improve here (people complain about the lack of statement-lambdas, but that&#x27;s just minor syntactic salt, and you can use a regular def to get around it).<br> <p> [1]: <a href="https://docs.djangoproject.com/en/4.1/_modules/django/utils/functional/">https://docs.djangoproject.com/en/4.1/_modules/django/uti...</a><br> </div> Sat, 27 Aug 2022 00:52:08 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906272/ https://lwn.net/Articles/906272/ marcH <div class="FormattedComment"> <font class="QuotedText">&gt; Overall, it would seem that a lot more thought and work will need to go into a deferred-computation proposal before it can really even get off the ground. It is a popular feature from other languages, especially functional languages, but there may not be a real fit for it in the Python language.</font><br> <p> I always thought &quot;core&quot; features of a language like lazy evaluation must be _all_ designed from the start, as a consistent whole. I&#x27;m very far from a language expert but my gut feeling tells me that bolting on something that fundamental that late in the game is doomed to fail in various ways.<br> </div> Sat, 27 Aug 2022 00:04:19 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906268/ https://lwn.net/Articles/906268/ rjones <div class="FormattedComment"> As a guy who used python extensively as a sort of utility language to &quot;do things&quot;...<br> <p> I am very happy Golang exists.<br> <p> <p> </div> Fri, 26 Aug 2022 23:10:31 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906156/ https://lwn.net/Articles/906156/ ballombe <div class="FormattedComment"> Python is a good language for beginners and some of them become advanced programmers, but instead of moving to more powerful languages, some of them attempt to extend python to cover their use case, while python is lacking the necessary foundation for that. Duck typing will only bring you so far. Theoretical computer science exists for a reason.<br> </div> Fri, 26 Aug 2022 20:58:02 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906259/ https://lwn.net/Articles/906259/ NYKevin <div class="FormattedComment"> Eh, Python spent its first 10 years or so building out descriptors and modern classes (remember &quot;classic&quot; classes?), which were rather substantial overhauls of the language&#x27;s syntax and semantics (especially when you consider metaclasses in their full generality). But nobody cared, because these things were relatively abstruse and could be quietly ignored if you just wanted to write a 10-line script, and if you were writing a larger program, the old way of doing things was obviously inferior in a number of ways.<br> </div> Fri, 26 Aug 2022 20:52:13 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906249/ https://lwn.net/Articles/906249/ lonely_bear <div class="FormattedComment"> I don&#x27;t think the feature of &quot;late-bound function argument default&quot; has value. Just to save a few key stoke? When the default value could changed according to input, then it is not default, they should be expressed fully.<br> </div> Fri, 26 Aug 2022 17:20:06 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906134/ https://lwn.net/Articles/906134/ smitty_one_each <div class="FormattedComment"> IIUC, the point here is to make python lazier, i.e. more Haskell-like?<br> <p> I thought that lambda expressions could do some of this, at the expense of looking a bit ugly.<br> <p> Maybe there are some specific use-cases for this feature, but it gets at the general concern that python may succumb to &quot;featuritis&quot;, and start adding too many niche features whose additional complexity juice just isn&#x27;t worth the squeeze.<br> </div> Fri, 26 Aug 2022 02:48:42 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/906115/ https://lwn.net/Articles/906115/ roc <div class="FormattedComment"> When you derail a discussion by proposing an alternative that ends up not even being usable for the original use case, I think you owe a lot of people an apology.<br> <p> Also, just gotta say, I&#x27;m prejudiced against anyone who writes &quot;, PhD&quot; after their name. (And I have one.)<br> </div> Thu, 25 Aug 2022 21:25:32 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905977/ https://lwn.net/Articles/905977/ anton <blockquote> Every time a simple and valuable little feature is suggested to be added to Python, is this going to happen? Somehow the proposals for adding huge syntactic complexity to the language in the form of async/await and the constant type annotation changes are fine, but adding `=&gt;` to clean up one of the BIGGEST hurdles in teaching the language is not? </blockquote> Welcome to the <a href="https://en.wikipedia.org/wiki/Law_of_triviality">law of triviality</a>. It not only points out that the committee discusses the material of the bike shed at undue length, but also that it approves the plans for a reactor without much discussion. Unfortunately, I don't know any way to fix this state of affairs. Thu, 25 Aug 2022 11:34:04 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905962/ https://lwn.net/Articles/905962/ k8to <div class="FormattedComment"> Yes, certainly it&#x27;s the overall trend, but python navigated like its first 10 years or so in a pretty healthy manner, which is relatively unusual. <br> </div> Thu, 25 Aug 2022 10:27:20 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905957/ https://lwn.net/Articles/905957/ NYKevin <div class="FormattedComment"> This is completely standard bikeshedding. You see it in every large software project (FOSS or corporate). It is not peculiar to Python.<br> </div> Thu, 25 Aug 2022 07:11:45 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905954/ https://lwn.net/Articles/905954/ pwfxq <div class="FormattedComment"> I think that could be said about many languages. They start simple and slowly add features until they become a Gordian Knot. We must be due a new language soon...<br> </div> Thu, 25 Aug 2022 06:57:04 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905951/ https://lwn.net/Articles/905951/ clay.sweetser@gmail.com <div class="FormattedComment"> At this point I consider Python the language to be fairly complete. The improvements I want mainly center around packaging and distribution. Oh well.<br> </div> Thu, 25 Aug 2022 06:10:39 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905943/ https://lwn.net/Articles/905943/ k8to <div class="FormattedComment"> Python used to be simple, and pretty good at maintaining comprehensibility. That&#x27;s gone in practice and gone culturally.<br> </div> Thu, 25 Aug 2022 03:32:47 +0000 From late-bound arguments to deferred computation, part 2 https://lwn.net/Articles/905939/ https://lwn.net/Articles/905939/ milesrout <div class="FormattedComment"> This is so frustrating to watch unfold. The average Python programmer, in my opinion, wants one simple little feature: the ability to write something like &quot;def foo(x=[])&quot; or &quot;def foo(x, l=len(x))&quot; and have it work properly, the way it was intended, preferably indicated by a small but visually apparent syntactic change like an extra character in there somewhere (=&gt;, or whatever). It is unnecessary to spend months and years discussing amorphous &quot;generalised deferred computation&quot;.<br> <p> This is exactly the same as people distracting from (x := 1) assignment expressions by making a never-ending stream of &quot;oh but why can&#x27;t we just generalise it to allow statements inside expressions?&quot; suggestions. After all, it would be more elegant to allow such a thing. But it would not actually solve the original problem (because the main problem was allowing assignment in an expression without making (x = 1) into an assignment---getting an error when you mistype (x == 1) is a valuable feature of Python) and is a huge distraction. Same thing here: the proposals don&#x27;t even solve the original problem and they&#x27;re a huge distraction.<br> <p> So now we get to watch the same thing unfold again, I guess? Every time a simple and valuable little feature is suggested to be added to Python, is this going to happen? Somehow the proposals for adding huge syntactic complexity to the language in the form of async/await and the constant type annotation changes are fine, but adding `=&gt;` to clean up one of the BIGGEST hurdles in teaching the language is not? Like come on. Python is huge as a language for teaching programming. This point in particular is one of the most unintuitive aspects of one of the most intuitive programming languages. It sticks out like a sore thumb and the &quot;solution&quot; requires creating ugly sentinel objects and writing several extra lines of code. Just fix it already...<br> </div> Thu, 25 Aug 2022 01:53:16 +0000