4 ms·
> Well, functions in Python can take other functions as arguments. There's however no good way to set default value for such arguments I don't understand what
by dataangel 5y ago
> Well, functions in Python can take other functions as arguments. There's however no good way to set default value for such arguments
I don't understand what is special about functions? Why can't you set the default value for an argument called `foo` to be a function `bar` by writing `foo=bar`?
- elcomet 5y agoThis change will enable to have default values that are created at function call, not at function definition. For example I can define: def f(x, l=>len(x)): print(l) where the default value of l depends on the other variable x.
- dankle 5y agoOh my, that’s just terrible. Really hoping this pep wont make it all the way. 100% unreadable.
- samwillis 5y agoI’m not sure it’s unreadable to an experienced coder, someone learning the language though will be confused about the difference between = and => in the function argument definition. Also the “arrow” is clearly pointing the wrong way, it should be “<=“.
- kzrdude 5y agoIt adds up. It's right that we have gotten used to all of the other stuff, but it adds up. It's fair to be very critical of new additions.
- mrtranscendence 5y agoIt's fair to be critical, but calling this flat out awful and unreadable is way overselling it. Whether it helps add up to something less readable than preferable is arguable, but taken on its own this change is minimally invasive and frankly pretty readable.
- mrtranscendence 5y agoIt seems perfectly readable to me, honestly. It might be confusing to newcomers, but I don't see a problem with it.
- monkeybutton 5y agoMy immediate response to this is: WTF. Why not just do `l = len(x) if l is None else l`? With the new syntax can you define defaults computed from other defaults? What about side effects? Why is computation happening in function args at all?!
- mrtranscendence 5y agoHaving the default value be None isn't great for documentation, and it isn't great for static typing, because now your argument has to be of type Union[Foo, None]. I've written functions where there are reasonably long chains of stuff like if foo is None: foo = [] and it'd be nice to be done with that.
- monkeybutton 5y agoI see what you're saying about typing. As for the reasonably long chains of default initialization code. Well now its in the definition. You could have functions with more code defining the parameters than in body.
- tinalumfoil 5y agoLWN had a good article on this: https://lwn.net/Articles/875441/ https://lwn.net/Articles/875441/ Short answer is these downsides were discussed but the proposal went ahead anyway. Imo I'm with you. This type of syntax has a lot of implicit behavior where it's going to be difficult to find/fix bugs related to it.
- monkeybutton 5y agoThat was a great article, thank you for the link!
- dragonwriter 5y ago> Why not just do `l = len(x) if l is None else l`? Because dev tooling can “see” and present information from the argument list much more easily than analyzing downstream behavior. > What about side effects? Those happen whether or not the computation is visible in the signature (though its more obvious to the programmer of the consuming code if it is visible.)
- ryanianian 5y agoI've never really seen arg1 depend on arg0 like that in Python. However this comes up a lot for new engineers during programming interviews. It's very common to see recursive algos use empty lists as default/start-case args: def traverse(graph, seen_so_far=[]): # Incorrect .... seen_so_far.append(node) Subsequent calls to `traverse` will have state accumulated from earlier calls. The right solution is: def traverse(graph, seen_so_far=None): if not seen_so_far: seen_so_far = [] ..... This isn't obvious if you're new to Python. This PEP makes this (arguably) clearer with: def traverse(graph, seen_so_far=>[]):
- usrbinbash 5y agoBut how does => make it more obvious to someone who's new to python?
- dragonwriter 5y ago> This PEP makes this (arguably) clearer It's more concise when you are familiar with it, and it improves introspection and dev tooling when functions use it, but it is not fundamentally clearer.
- mb7733 5y agoThe author of the article missed the point entirely. The feature allows default arguments to be set to the _result_ of a function call (that may or may not depend on other arguments).
- mrtranscendence 5y agoNot sure I understand what he's going for here. The big issue that that PEP addresses is mutable default arguments, nothing about functions as arguments.
- klickverbot 5y agoThere isn't anything special about functions; the original article does not describe this correctly. Rather, the big conceptual difference is the point at which the expression is evaluated – once for the whole program (`=`), vs. at each call site (`=>`). I presume this got accepted because it fixes a well-known gotcha with default parameters in Python due to early evaluation, where, for instance, the dictionary instance in `def fun(args={}): …` would be shared between all invocations, leading to all sorts of fun bugs. This is especially pernicious as most Python programmers will know other languages as well, where this tends to be handled much more sensibly (e.g. in C++, D, …) and default arguments are evaluated at each call site.
- cuteboy19 5y agoI think this could have been fixed by always evaluating default args on each invocation. There is no reason why a default arg of all things should carry any mutable state. The people who would complain probably already had bugs in their code