4 ms·
your comment assumes that features and functionality are a good thing. "worse is better" does not apply here. "worse is better" is people putting up with foot
by throwawaymaths 1y ago
your comment assumes that features and functionality are a good thing. "worse is better" does not apply here.
"worse is better" is people putting up with footguns like this in python, because it's percieved easier to find a python job:
def fun(a = []):
HN is very much "less is better", not "worse is better".
- zoogeny 1y agoI'm not sure what you mean? The literal quote from the Wikipedia article on "worse is better" is: > It refers to the argument that software quality does not necessarily increase with functionality: that there is a point where less functionality ("worse") is a preferable option ("better") in terms of practicality and usability. For that reason, I think I am applying the term precisely as it was defined. The irony of my comment, which dang picked up, is that the original idea was a criticism against Lisp, suggesting that the bloat of features was a part of the reason its adoption had lagged behind languages like C. 1. https://en.wikipedia.org/wiki/Worse_is_better https://en.wikipedia.org/wiki/Worse_is_better
- 90s_dev 1y agoYou're both saying the same thing: fewer features = higher quality. Swiss army knives are not as good at being screwdrivers as screwdrivers are.
- quinnirill 1y agoIn general: yes. But I’ve certainly had to use swathes of screwdrivers that are worse at being screwdrivers than my Swiss army knife is. Same I believe applies here: there’s a relation, but it’s nuanced. The same screwdriver is a better screwdriver when carried in a hand than in a toolbox full of other high-quality tools, but worse for everything else.
- throwawaymaths 1y agohuh. til i actually thought "worse is better" is more recent than that but it stems from an era where feature count was the measure of quality. how times have changed!! thanks!
- 7thaccount 1y agoI've written Python for 14 years and have never seen code like that. It certainly isn't a perfect language, but this doesn't look like a common concern. People write a lot of Python, because the language is easy to get into for a lot of non computer-science folks (e.g., engineers and scientists) and the ecosystem is massive with libraries for so many important things. It isn't as conceptually pure as lisp, but most probably don't care.
- tredre3 1y agoIt's a common need to have an empty array be the default value to an argument. In any programming language, really. I don't know what to make of the fact that you've never seen that in the wild. Maybe you were blessed with colleagues, for the past 14 years, that all know about how dangerous it is to do it in Python so they use workarounds? That doesn't negate the fact that it's a concern, though, does it?
- dannymi 1y agoThere's always tension between language simplicity (and thus cognitive load of the programmers) and features. Compare Scheme with Common Lisp. The idea in Python is: 1. Statements are executed line by line in order (statement by statement). 2. One of the statements is "def", which executes a definition. 3. Whatever arguments you have are strictly evaluated. For example f(g(h([]))), it evaluates [] (yielding a new empty list), then evaluates h([]) (always, no matter whether g uses it), then evaluates g(...), then evaluates f(...). So if you have def foo(x = []): ... that immediately defines foo = (lambda x = []: ...) For that, it has to immediately evaluate [] (like it always does anywhere!). So how is this not exactly what it should do? Some people complain about the following: class A: x = 3 y = x + 2 That now, x is a class variable (NOT an instance variable). And so is y. And the latter's value is 5. It doesn't try to second-guess whether you maybe mean any later value of x. No. The value of y is 5. For example: a = A() assert a.__class__.x == 3 assert a.x == 3 a.__class__.x = 10 b = A() assert b.x == 10 succeeds. But it just evaluates each line in the class definition statement by statement when defining the class. Simple! Complicating the Python evaluation model (that's in effect what you are implying) is not worth doing. And in any case, changing the evaluation model of the world's most used programming language (and in production in all countries of the world) in 2025 or any later date is a no go right there. If you want a complicated (more featureful) evaluation model, just use C++ or Ruby. Sometimes they are the right choice.
- Spivak 1y agoPython made a choice to have default values instead of default expressions and it comes with positive and negative trade-offs. In languages like Ruby with default expressions you get the footgun the other way where calling a function with a default parameter can trigger side effects. This kind of function is fine in Python because it's unidiomatic to mutate your parameters, you do obj.mutate() not mutate(obj). So while it's a footgun you will be writing some weird code to actually trigger it.
- 0xDEAFBEAD 1y ago>In languages like Ruby with default expressions you get the footgun the other way where calling a function with a default parameter can trigger side effects. Seems fine to me. If the default expression causes side effects, then that's what I would expect. >This kind of function is fine in Python because it's unidiomatic to mutate your parameters, you do obj.mutate() not mutate(obj). I first wrote Python over 10 years ago and I never learned this. How would you idiomatically write a function/method which mutates >1 parameter?
- biorach 1y agoThey are referring to a convention, not a language restriction. If you want to mutate two parameters just pass them to a function like you normally would. It's sloppy and a bad habit, I would not let it pass a PR in production code. Probably OK for a throwaway script.
- int_19h 1y agoIt's just plain wrong. For example, next() is a builtin function which mutates the iterator passed to it. And, in general, given that Python doesn't have extension methods or anything similar, if you want to write a helper that works on mutable objects of some type, it'll have to be a free function.
- Spivak 1y agonext() is just sugar for iter.__next__() A common case where you would have a free function which mutates its parameter would be a function which takes a file handle but it's also the case that you wouldn't have a mutable default for this value.
- jaza 1y agoAh yes, the ol' default empty list Python gotcha, it bit me I think about 10 years ago, and ever since, sadly I've written code like this so many times it's not funny: def fun(a = None): _a = a if a is not None else []