On Fri, 20 Nov 2015 10:59 pm, BartC wrote: > On 20/11/2015 01:05, Steven D'Aprano wrote:
>> Here's another use for function defaults, as static storage: [...] >> This is a quick and easy way to memoise a function which would otherwise >> be horribly slow. And it only works because _memo is bound to a mutable >> object once, and once only. > > We're arguing at cross-purposes then since you are obviously interested > in these esoteric aspects, Memoisation isn't "esoteric", it is a simple, basic and widely-used technique used to improve performance of otherwise expensive functions. Quite frankly, to call it such demonstrates a considerable level of ignorance about basic programming idioms. Not just Python, but general purpose programming. Instead of being so judgemental, why don't you take this as an opportunity to open your mind to new programming styles? The purpose of learning a new language is to open our minds to new ways of solving problems. If all we are going to do is bitch and moan that the new language isn't exactly the same as the old one we already know, we might as well just stick to using the old one and not even bother learning anything new. > but all I want to do is avoid remembering a > long list of defaults. Here's an example from another language, a > function I'm working on at the minute: [...] > (Here, however, the language doesn't like you doing in-place > modification of a parameter unless the '&' is used, in which case you > wouldn't be able to assign a default value such as () as you can only > pass l-values.) It sounds to me like you have implemented something like Pascal's "var" parameters, is that right? I believe some languages (VB perhaps?) call them "output parameters". >> def test(arg=[]): >> arg.append(1) >> return len(arg) >> >> >> The binding arg=[] is NOT inside the body of the function. Therefore, it >> is NOT executed repeatedly, but only once. > > OK, so the "=" is misleading if not a lie. No. Why would you conclude that? If I called the function like so: test( [1, 2, 3, 4, 5] ) and got the result 6, would I conclude that the "=" is misleading if not a lie? After all, the function declaration clearly shows arg being assigned the value [], so why am I getting 6 as the result instead of 1? The whole point of parameter default arguments is that they are bound to the parameter *only* if the parameter otherwise isn't given a value. That's a separate issue from *when* the default expression is evaluated. It can be evaluated only once, or it can be evaluated every single time you call the function. Both are legitimate techniques, both have their uses, and both have their limitations. >>>>> That [] doesn't look like an object that could change. >>>> >>>> Of course it does. >>> >>> You've lost me know. > >> a = [] >> a.append(1) >> >> Are you shocked to learn that a is no longer an empty list? > > No. But I would be surprised if, after this point, [] is no longer an > empty list either! Of course [] is an empty list. But the question isn't what [] represents, it is what value `a` has. Since [] creates a list (not a tuple), and lists can be modified in place, anyone familiar with Python should expect that just because you see `a = []` somewhere doesn't mean that `a` will always be an empty list. `a` can change. (Of course, any variable can change if you re-assign it.) > No, forget that; by now, I wouldn't be surprised at all! > > (That [] isn't changed is probably thanks to [] being implemented with > the BUILD_LIST byte-code, which constructs a brand-new empty list each > time. So the next time [] is used, it will be a different one from the > one that has just been appended to. Right. That's not an accident either. There isn't a single global empty list shared between all Python variables. There *could be* (but probably isn't) a single global empty tuple, since tuples are immutable and anything set to the empty tuple must remain the empty tuple forever (or until re-assigned to something else), so there would be no harm in having all such variables share the same object. But lists don't work like that, because they are mutable. > In my language, a construct such as [10,20,30] is evaluated just once at > start-up. I don't understand that explanation. How does that work? Given: x = [10, 20, 30] y = [10, 20, 30] how does your language know what value y has if it doesn't evaluate the second construct? -- Steven -- https://mail.python.org/mailman/listinfo/python-list