6 ms·
It's a good repo, but remember a lot of those are "A Good Thing™". The first snippet is a very good example: a := "wtf_walrus" doesn't work while: (a
by BiteCode_dev 7y ago
It's a good repo, but remember a lot of those are "A Good Thing™".
The first snippet is a very good example:
a := "wtf_walrus"
doesn't work while:
(a := "wtf_walrus")
works.
It's a fantastic design decision.
Python took a long time before getting this operator, because it's a language that favors being readable, easy to use, and above all, to learn.
But in many other languages, the very same operator is often misused as, or confused for, the operator for equality or assignation.
We, as a community, didn't want people to wonder why there are several ways to do assignation (we have this problem with string templating already). Instead, we wanted to be sure that people could ignore the existence of ":=" for some times during their learning process.
And so the decision has been taken to make is very easy to distinguish it from "=" and "==", forcing parenthesis when necessary to make it clear this is a completely different use case. Also to hint people at using it only when necessary.
If you like scripting in Python because it's so easy to go from an idea to code, it's not random luck. It's because the language is a collections of thousands of such decisions.
- deleted 7y ago[deleted]
- fxj 7y agoin the zen of python (import this) it says: there should be one-- and preferably only one --obvious way to do it. sadly this is not true for a while in python now. Python became a language that can be really hard to read now.
- xscott 7y agoYeah, current versions of Python feel like Guido and the rest changed their minds about what they wanted.
- BiteCode_dev 7y agoPython is a very old language. First version in 1991! This is no surprise Guido evolved with it, and changed his mind about a few things. People are never happy. On the other side of the fence, you have others crying the language is not moving fast enough.
- xscott 7y agoI understand why people are willing to defend it or make apologies for it, but there really are some lessons to be learned from the mistakes it made, and dismissing legitimate criticism just ignores the opportunity.
- BiteCode_dev 7y agoI agree, there is a long list of things I would change in Python. And believe me when I say people involved in the community listen to this very carefully. This is why we had Python 3 in the first place. Because text handling was such a cause of pain. This is why we have type hints in the first place. Because big projects using Python felt let down. And Python 3 and type hints are also a huge source of criticism (I was the first one to do so). It's never ending. People will complain. People will be unhappy. Things, also, will be imperfect, as we are limited in resources and are submitted to many constraints. Not to mention taste and opinion, that are used to request changes. But I'm not answering to dismiss valid concerns. I'm answering because as a very experienced Python dev, I now have a good grasp of what is due to culture, lack of experience, or a real deal. E.G: - := forcing parenthesis. Has not been a real problem in my experience, at least as of today. - Packaging still more complicated that necessary. A real problem in the field (although 50% of it is a teaching problem: https://twitter.com/bitecode_dev/status/1188130895653416966 https://twitter.com/bitecode_dev/status/1188130895653416966).
- FartyMcFarter 7y ago> Because big projects using Python felt let down. Why big projects started using Python in the first place is a very good question, given that this language had not been designed for them...
- goto11 7y agoBecause big projects often start as small projects?
- avip 7y ago
- bakery2k 7y agoI think Python’s direction changed when Guido moved to Dropbox. Suddenly he was working on a million-line Python codebase, and started working to make the language more suitable for programming in the large.
- xscott 7y agoYeah, that certainly fits.
- BiteCode_dev 7y ago> there should be one-- and preferably only one --obvious way to do it. Yes, this has been one of the hardest balance to find. And believe me when I tell you the community tries very, very hard. But it's a difficult problem: making the language evolves fast enough, but keeping it solid and stable. Very difficult indeed. > Python became a language that can be really hard to read now. Not in my experience. My job involve going a lot from company to company. I see a lot of code, from a lot of different people. The way people write Python hasn't change much during the last 15 years. In fact, I'd say because of Python 3, there is less cruft all in all. You do have a few heavy stuff. E.G: asyncio or the type hints. But how many code out there uses that ? Very little. Mostly, the code that needs it. Which is good. This is what we want.
- fxj 7y agoThe new walrus operator now makes indentation obsolete. You can write averything within one line as an array and it is hard to read. This in combination with syntactic sugar, operator overloading and unicode variables can make the language very hard to read. e.g. # compute pi 1000000 >> ψ( ψ(χ>>op("(x**2+y**2)**0.5<1")@rlµ<<χ)>>Σ*4>> _/_) or this: # 10 fibonacci numbers [x:=[1,1]] + [x := [x[1], sum(x)] for i in range(10)] is valid python code. (for the first see my github jamitzky/iverson). Not that I wouldnt like it, but python3 has changed and the zen of python is not valid for some time now.
- BiteCode_dev 7y agoYou could do that with a lambda since Python 2.4. E.G, calculating primes: >>> print(list(filter(None,map(lambda y:y*__import__('functools').reduce(lambda x,y:x*y!=0, map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000))))) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997] As for the unicode caracters as variables... Remember you could do that in Python 2 ? # -*- coding: rot13 -*- cevag "Relax" But people don't do it. Just like they don't use "import *" everywhere, or monkey patch methods like it's going out of style the way Ruby loved it 15 years ago. Because such capabilities are restricted (one line lambda, parenthesis for walrus, not all unicode is allowed as var names or everywhere...), introduced slowly, and the community culture is to value readability, Python stays Python. I was against the walrus personally, for the reasons you mention. But while I do see Raymond Hettinger trolling twitter regularly with his latest crazy walrus magic, in production we see no such thing. Not to say it never happens. It does, I've seen monstrosities in the field. Like with every tech. I mean, you can start a fire with a water hose if you try hard enough. But it's rare.
- masklinn 7y agoDespite what many apparently think, this line very specifically does not say "there should be one way to do it", it is much more restrictive. And as far as I'm concerned, the walrus operator breaks it in no way whatsoever: an assignment statement is the one obvious way to perform an assignment, and it's a syntax error to use a walrus as an assignment statement.
- michaelcampbell 7y agoAs a relative newcomer to Python (compared to most, but I do use it professionally every working day for a year, and some non-working days for personal stuff), I find this to be the case. At work I have to use Django, and it's almost a chore to find anything explicit or obvious in it. Its level of abstraction is "Too Damn High" as the meme goes, IMO. It feels like saving boilerplate for the sake of it which just makes obvious, readable code into magic incantations where shit happens and you don't know why or how or where to look.
- deleted 7y ago[deleted]
- nickserv 7y agoThis is the danger with high level frameworks, everything is abstracted away, and with a dynamic language like python the black magic can go very deep. If you've ever taken a look at something like Flask or Cherrypi, the difference is very apparent. That said, I've been doing some Rails lately, after years of Django, and I'm finding the experience to be worse from a readability point of view. Metaprogramming everywhere, modifications of language constructs ... It gets very confusing very quickly. Could be simply a lack of experience of course. In parallel, I've also been using Go and the experience could not be any different. So much easier to understand what is going on, but so much boilerplate code! It doesn't look like it's possible to have both ease of use and explicitness...
- michaelcampbell 7y agoThanks; I've glanced at Flask and it makes a lot more sense to me, but this is a project of immense size and age, and not under my control, so I just have to live with it. Overabstraction for the sake of it seems to be Django's mantra. Then there's Django Rest Framework, and the 3-4 different filtering mechanisms. It's really a nuisance.
- at_a_remove 7y agoThe many, many ways to print variables inside of a string are testament to that. I remember feeling kind of a chill when the number of methods hit three. Two is an acceptable number of methods if you are transitioning from one form to another as kind of a nod to the growing pains of a language, but at three you have hit some kind of watershed.
- doteka 7y agoThere's actually five now! 1. manual string concatenation 2. the old, printf-style. Still heavily used in e.g. stdlib logging module. 3. .format() 4. f-strings 5. string.Template in the stdlib Yup, I definitely see this as one of the bigger failures in Python's design.
- BiteCode_dev 7y agoIt's a problem, but not a failure in design. The language is old. It started with features from that times and evolved to add more modern ones. Removing the old ones would break the world. Why do you thing you can still use == and declare vars without keywords in JS ? Even in the p3 transition, the community screamed to not remove them. Did you know we removed % for a few versiond ? We had to put it back because of all the complaints.
- guitarbill 7y agoin practice it's 3. and 4. though. we outright ban 2. through a linter. it not only looks ugly, but is inconsistent. e.g. it has the tuple pitfall with a (language?) hack to make it work with one variable. even for logging, it's possible to use the `.format` style - although this isn't default. i've never seen `string.Template` actually used, except for niche use-cases with untrusted input, where a full-blown templating engine was overkill.
- jakear 7y agoWhy should people only use it when necessary? Why not say “the walrus operator is the exact same as the assignment operator, but it can be used in expressions and thus is spelled a bit differently in order to better distinguish it from the equality operator. Feel free to use it in all places you’d previously use the assignment operator.”. Simple, easy to understand, easy to learn, and most importantly (though python folks might disagree, given 2 => 3), easy to adopt. (Find and replace all single equals with colon equals and you’re done). Instead, they’ve chosen the narrative: “the walrus operator is a lot like the assignment operator, but it is able to be used in expressions, cannot be used as a statement, and it sits below the comma operator in precedence instead of above it. We understand that this is super confusing, so use it sparingly”. One way you have two operators for people to learn, with the understanding that there is a third legacy operator that works pretty much the same as one of them. The way they chose you have three operators for people to learn, with two of them behaving pretty similarly but not interchangeably, and with subtle yet important differences.
- BiteCode_dev 7y ago> Why should people only use it when necessary? Because we have experience with things such as easy of learning, cognitive load, writing simple to read code, making it hard to introduce bugs... This comment show how little experience one can have with it, and yet make a quick judgment to offer to "fix" things. E.G: > eel free to use it in all places you’d previously use the assignment operator.”. Simple, easy to understand, easy to learn, and most importantly (though python folks might disagree, given 2 => 3), easy to adopt. Well because in many languages, people do this: while (foo = bar): While they mean this: while (foo == bar): Even experienced devs do this by mistake from time to time. It's hard for tooling to find out if you are doing something stupid or smart. Beside, you don't use tooling when you learn the language or do a quick script. Designing a language is not a 15 days job in a rush. Usually.
- jakear 7y agoI don’t think you’ve actually understood my proposal, and the snide remarks about completely unrelated languages don’t help your argument. To reiterate, my proposal is that the walrus operator has the exact same semantics as the assignment operator, but creates an expression rather than a statement. A linter rule could then be added prohibits the assignment operator, and converts all instances of it to the walrus operator. The codebase now has only the two operators. Language reference books need only explain the two operators, and simply note that the legacy assignment operator behaves the same as the walrus operator but cannot be used in expressions. This is easy to learn. What the language creators have done instead is add a whole new operator with all new semantics, leading to all new sources of confusion. (See TFA). This is not easy to learn. Side note: It’s funny that you appeal to the authority of the language creators with phrases like: Python is easy because “the language is a collections of thousands of such decisions”, yet ignore the fact that the actual creator of the language was so against the addition of this operator that he saw the community’s insistence on it as reason to step down as BDFL.
- Pimpus 7y agoI thought this walrus thing looked esoteric and ridiculous. Two words which also describe Python. I think it's prime time for the scripting languages to be disrupted. Twould be nice to have one as well designed and consistent as Rust.
- Lendal 7y agoOnly problem with the walrus operator is we still can't use it until linters support it. Now we're at 3.8.1 and still no linter support.
- phlakaton 7y agoA contrarian's point of view: > The very same operator is often misused as, or confused for, the operator for equality or assignation. It will still be confused, I'm afraid. It's just a little less likely that that confusion will be silently accepted by the interpreter. > Also to hint people at using it only when necessary. Let's be clear: the walrus operator was never, ever, necessary. It's syntactic sugar to avoid extra lines of code. The hope is that it will be convenient and obvious enough that folks will prefer it to both extra lines of code and repeated sub-expressions, but the very advice that beginners ought to "ignore the existence of := for some time" (_plus_ the intentional deviation from other languages) suggests that this is not going to be nearly as obvious or convenient as its proponents might have wished.
- BiteCode_dev 7y agoI think given the noise it has made, we will be alright :)
- ktm5j 7y agoDid you get far past the first example? Because a lot of these seem just plain unacceptable.. How about this from the second example: >>> a, b = "wtf!", "wtf!" >>> a is b # All versions except 3.7.x True >>> a = "wtf!"; b = "wtf!" >>> a is b # This will print True or False depending on where you're invoking it (python shell / ipython / as a script) False Or this from further down >>> a = 256 >>> b = 256 >>> a is b True >>> a = 257 >>> b = 257 >>> a is b False
- kevincox 7y agoI agree. I wonder how confusing it would be to make `is` not allowed on integers or strings. Or define it to be equivalent to `==` for those types. Using `is` in these situations is almost always a big, if for whatever reason you really need it you can do `objectid(x) == objectid(y)` which is usefully explicitly.