34 ms·
Pattern matching accepted for Python
- oflannabhra 6y agoPattern matching is what I missed most when switching from Swift to Python a year ago. Really happy to see this day come!
- techdragon 6y agoI’ve followed these things over the years. Had many discussions with people, including a few Python luminaries, but I honestly never expected this day would come. I fell in love with pattern matching when I learned Erlang and Elixir and it’s bugged me ever since that I didn’t have any built in equivalent in Python, until now!
- macintux 6y agoPython 2 had pattern matching on tuples in function arguments; I was quite annoyed, coming from Erlang, when I discovered that was dropped in 3.0, in part because "no one uses it".
- toxik 6y agoThis is not truly Erlang style pattern matching. And Python can never have that either because of its design.
- kasperni 6y agoJava is also in proces of adding Pattern Matching over the next couple of releases [1]. [1] https://www.infoq.com/articles/java-pattern-matching/ https://www.infoq.com/articles/java-pattern-matching/
- VectorLock 6y agoInteresting discussions over on Twitter about the new parser might be letting out the complexity genie and how some think that might not be the greatest. https://twitter.com/ramalhoorg/status/1358168753100496907 https://twitter.com/ramalhoorg/status/1358168753100496907
- stickyricky 6y agoNot really. Its a string of preferences for Python's development. I hope the author pursues those endeavors and encourages others to join him. But they're not an argument against pattern matching.
- VectorLock 6y agoTalking about preferences still qualifies as interesting discussion.
- paulgb 6y agoAs someone who hasn’t been following closely, was the PEG parser necessary for pattern matching or is that an unrelated change?
- pansa2 6y agoIIRC one of Guido’s reasons for switching to a PEG parser was to enable the addition of pattern matching.
- erichurkman 6y agoAnd it allowed some non-intuitive parser limitations to be lifted, like full expressions in decorators (@buttons[0].click) and parentheses in context expressions (https://bugs.python.org/issue12782 https://bugs.python.org/issue12782).
- mjburgess 6y agoCan anyone confirm this is actual pattern matching and not the frankly ridiculous procedural version that was originally proposed? That proposal, to deliberately hobble pattern matching by making it a statement, was an egregious ideological campaign with genuinely absurd consequences.
- dflock 6y agoIt's this: https://www.python.org/dev/peps/pep-0634/ https://www.python.org/dev/peps/pep-0634/ - not sure which version that is?
- nneonneo 6y agoNot sure what you mean, but the accepted PEP does appear to be a statement. What was the alternative?
- the_duke 6y agoIn many languages match is an expression, so you can do things like `x = match y { ... }`, which is a very common use case. I don't write much Python these days, but it being a statement rather than an expression is disappointing It forces you to use a separate "output" variable or `return`.
- klyrs 6y agoI presume that the alternative to a statement is an expression. For example, the ternary operator x = (a if c else b) is an expression, where the conditional equivalent if c: x = a else: x = b is a statement.
- galkk 6y agomatch is a statement, but the syntax is very readable. https://www.python.org/dev/peps/pep-0636/#adding-conditions-to-patterns https://www.python.org/dev/peps/pep-0636/#adding-conditions-...
- chriswarbo 6y ago
- deleted 6y ago[deleted]
- hannibalhorn 6y agoThe accepted PEP is 634: https://www.python.org/dev/peps/pep-0634/ https://www.python.org/dev/peps/pep-0634/ and the tutorial has some examples: https://www.python.org/dev/peps/pep-0636/ https://www.python.org/dev/peps/pep-0636/ .
- JNRowe 6y ago[Expanding my comment from another post on this¹] Direct links to the PEPs themselves, to perhaps save others a little time. Although the LWN write up linked in TFA is a very nice introduction to the topic and its big discussion in the community. Accepted: Specification https://www.python.org/dev/peps/pep-0634/ https://www.python.org/dev/peps/pep-0634/ Motivation and Rationale https://www.python.org/dev/peps/pep-0635/ https://www.python.org/dev/peps/pep-0635/ Tutorial https://www.python.org/dev/peps/pep-0636/ https://www.python.org/dev/peps/pep-0636/ Rejected: Unused variable syntax https://www.python.org/dev/peps/pep-0640/ https://www.python.org/dev/peps/pep-0640/ Explicit Pattern Syntax for Structural Pattern Matching https://www.python.org/dev/peps/pep-0642/ https://www.python.org/dev/peps/pep-0642/ ¹ https://news.ycombinator.com/item?id=26073700 https://news.ycombinator.com/item?id=26073700
- aargh_aargh 6y agoAt first, I overlooked the excellent LWN writeup on the feature linked in TFA, so I'm linking it here: https://lwn.net/Articles/838600/ https://lwn.net/Articles/838600/
- jonnycomputer 6y ago... I'll take my down votes. Please move on opinionated HN-ers.
- deleted 6y ago[deleted]
- messe 6y agoBy that same logic wouldn’t def f(x): look too close to function invocation for your taste?
- deleted 6y ago[deleted]
- TrianguloY 6y agoCan't wait to see all the errors and questions when users start using this for the missing switch statement, and not realizing it doesn't work for non-dotted constants. Because if I didn't misunderstood, this is not correct, is it? NOT_FOUND = 404 OK = 200 match getCode(): case NOT_FOUND: return default() case OK: return response()
- AlexandrB 6y agoYup, that's what the PEP seems to suggest. This along with mutable default values is going to be one of the nastier Python warts.
- toxik 6y agoNot to mention that expressions after the case keyword have completely different semantics from expressions ANYWHERE else. a | b is not the bitwise or of a with b.
- vitus 6y agoYou can already define __or__ to do whatever you want! This is already special-cased in the standard library for, say, set union (where admittedly the concept is more similar to bitwise or).
- toxik 6y ago... except in case expressions Thanks for proving my point though!
- amirkdv 6y agoThis part is truly strange. This example from the tutorial drove it home for me: match event.get(): case Click(position=(x, y)): handle_click_at(x, y) case KeyPress(key_name="Q") | Quit(): game.quit() where `Click(position=(x, y))` is not at all what one would expect. What I still don't understand is: does the new syntax magically do this to a user-defined class? i.e. if I say foo = Click(position=(x, y)) vs ... case Click(position=(x, y)) those identical expressions, for the same value of Click, have widely different semantics? edit: typo fix
- pansa2 6y agoIMO the match statement has some very unintuitive behaviour: match status: case 404: return "Not found" not_found = 404 match status: case not_found: return "Not found" The first checks for equality (`status == 404`) and the second performs an assignment (`not_found = status`).
- rwmj 6y agoThat's how structural pattern matching works in ML-like languages, where it's been in use for 40+ years.
- AlexandrB 6y agoDon't those languages typically have immutable variables so you would not be able to rebind a constant by accident?
- deleted 6y ago[deleted]
- the_duke 6y agoThis is usually orthogonal to mutability. In other languages that support match, whether functional or not, you are not changing the value of the variable, but you are shadowing/rebinding the identifier inside the scope of the match clause.
- AlexandrB 6y agoA lot of early Python's appeal was in its simplicity. I miss that era. Soon Python is going to resemble C++'s bloated feature set where you're not supposed to use parts of the language because "that's the old way of doing things". Edit: Actually that's already true with string formatting.
- _jjkk 6y agoI agree completely. I hate how different reading C++0x and C++17 is. I hate reading a "C++ style guide" for a new project. I already feel that pretty soon, "Python Style Guide" will be a necessary evil...
- atoav 6y agoReally? I program Python for over a decade now and compared to other language it was always the one where style somewhat was the smallest issue with that language (compared to the C, C++, C#, Javascript, Java I have seen). Might be that the whitespace indentations focus the mind. Also: PEPs already act as style guides. And if you are worried to do it wrong, just run it through a code formatter like black. It really isn't that much of a problem IMO.
- roelschroeven 6y agoI think grandparent is talking about something else. Large C++ codebases often have a guide that says which parts of the language to use and not to use. That can be useful if you have a team with people with different levels of expertise in the language, or expertise in different parts of the language. C++ has grown to be a language with a lot of different parts to choose from. And it looks like Python is heading in the same direction. It's not difficult to imagine a future where some Python projects are going to want such guides too.
- atoav 6y agoThanks for the clarification.
- 6y ago
- theptip 6y agoDoes anyone have a usecase where they think this new syntax shines? I'm not really seeing anywhere in my projects that I'd use this, but it seems to be well-loved in Elixir?
- iso8859-1 6y agoThey have a dedicated PEP for motivation: https://www.python.org/dev/peps/pep-0635/ https://www.python.org/dev/peps/pep-0635/
- bjourne 6y agoPretty cute syntax, but not what I'd wanted. It takes something that is already trivial to write and makes it simpler. Not a lot of "bang for your syntax bucks" so to speak. E.g the interpreter example from the PEP could have been written: parts = command.split() if not (0 < len(parts) < 3): raise TypeError(...) cmd, arg = parts if cmd == 'quit': ... elif cmd == 'get': character.get(arg, current_room) elif ...: ... For more advanced examples, you'd use dictionary dispatch anyway. Will this syntax work with numpy?
- breuleux 6y agoYour code is buggy, though. It will only ever accept two parts because of `cmd, arg = parts`, so `["quit"]` will fail, and each command might accept a different number of parts, so you can't just test `0 < len(parts) < 3` for all of them. The pattern matching version is harder to get wrong.
- visarga 6y agowhat happens if len(parts)==1 ? in this case pattern matching would have helped
- fatcow 6y agoYour snippet would be condensed into 1 indentation block with pattern matching. In scheme it'd be even more explicit that we're deconstructing command, therefore much much easier to follow logic. No need to worry about cmd, args, etc. (match command (("quit") (display "Goodbye!")) (("look") (describe current-room)) (("get" obj) (character-get obj current-room)) (("go" dir) (set! current-room (room-neighbour dir))) (_ (display "Invalid command")))
- zepatrik 6y agoThe comments on LWN are just hilarious. > I'm going to submit a PEP to add a kitchen sink to Python. I personally would opt for the sink with the snake, as it is more Pythonic, despite not being the nicest and cleanest solution (is that a Pythonic property as well?).
- erichurkman 6y agoMozilla for a time had a kitchen sink (https://bugzilla.mozilla.org/show_bug.cgi?id=122411 https://bugzilla.mozilla.org/show_bug.cgi?id=122411) at about:kitchensink. It looked like this: https://www-archive.mozilla.org/docs/web-developer/samples/kitchensink.xml https://www-archive.mozilla.org/docs/web-developer/samples/k...
- c1ccccc1 6y agoEven better is the reply: "Python already has async"
- toxik 6y agoWow, this is perhaps the worst idea introduced to Python in a long time. So many ambiguities, so much inscrutable syntax. What a shame.
- superbcarrot 6y ago> There should be one-- and preferably only one --obvious way to do it. Unless we keep adding more ways to do the same thing of course.
- adamdusty 6y agoThere have always been 100 ways to do everything in python. People just constantly spout the zen thing to look smart.
- superbcarrot 6y agoThere have been multiple ways to do the same thing but that shouldn't be an excuse to keep adding features that don't contribute anything meaningful apart from expanding the syntax. The zen thing is cited so much because it's often inconsistent the language itself.
- naebother 6y agoMaybe this will grow on me, but at first glance this looks needlessly complex. I don't think I've even fully comprehended the syntax after staring at for a few minutes: https://www.python.org/dev/peps/pep-0634/#appendix-a-full-grammar https://www.python.org/dev/peps/pep-0634/#appendix-a-full-gr...
- ur-whale 6y agoAnd here I was thinking python was finally adding built-in, native, regex matching to the language, the one last reason I still use perl sometimes because of the quasi java-level verbosity and heavy-handedness of the re python package. But no, it's just about adding switch to python ... frankly, who cares.
- atoav 6y agoWhat do you mean with built-in native? Isn't `import re` kinda built-in? It is not an external dependency. So you could even run something like this from the terminal and get 1234 replaced by 2021: echo "1234foo" | python3 -c 'import re, sys; t=sys.stdin.read(); print(re.sub(r"(\d{4})", "2021", t))'
- SrslyJosh 6y agoI believe they mean adding a literal syntax specifically for regular expressions, ala perl and ruby, so you could write something like: print(/\d{4}/.sub("2021")) The backslash makes that example a little ugly, but maybe a delimiter other than "/" would work better. It's too bad that r"" is already taken for raw strings.
- nerdponx 6y agoCould be x"" for regeX or p"" for Pattern
- ur-whale 6y agoIn perl: print($1) if(/^hello (w[^d]+d)/); Do the same in python and pipe the code to wc -c Oh, and note the absence of any "import" statement or quotes in the perl code. Python is not has heavy-handed as C++ for regex parsing, but not by much.
- klmadfejno 6y agoThis was my train of thought as well. I think I'm ambivalent towards this. Handling different types of inputs like that is kind of fun. I don't really expect to need to know this one looking at coworkers code in the wild.
- pansa2 6y ago> The Python steering council has, after some discussion, accepted the controversial proposal to add a pattern-matching primitive to the language. Controversial is correct. A poll showed a majority (65%) of core developers opposed to this particular proposal, and a plurality (44%) opposed to pattern matching altogether. https://discuss.python.org/t/gauging-sentiment-on-pattern-matching/5770 https://discuss.python.org/t/gauging-sentiment-on-pattern-ma...
- adamdusty 6y ago> 34 voters
- pansa2 6y agoIs that not a reasonable sample of the 87 core developers eligible to vote? https://discuss.python.org/groups/committers https://discuss.python.org/groups/committers
- remram 6y agoIt is a rather poor sample, and a sign that either more people than those 87 should be allowed to vote or there is something wrong with how the vote was conducted. An explicit "do not care" or "none of the above" option in that poll would have shed more light into this.
- im3w1l 6y agoIf they randomly chose 34 people to poll it would be decent sample. But now it's not a sample at all. The responders are not representative of the non-responders.
- magnusmundus 6y agoIt's controversial, granted, but I don't think that's a fair reading of the poll. Here's another: * A majority (56%) of responders want some form of pattern matching. * Exactly half of all responders, forming nearly 90% of the above majority, are fine with that form being PEP 634. * There are differing opinions about supporting PEPs, but a supermajority (70%) of those who agree with PEP 634 are fine with it alone. The fact that it was possible to express more nuance when agreeing with PEP 634 shouldn't diminish their voice against those who reject the idea altogether.
- rossdavidh 6y agoSo, regardless of one's feelings on this particular feature, I think we can see what the loss of a BDFL means: feature bloat. It was once one of the core tenets of python that there be one, best way to do a given thing, because that meant that when you read _another_ programmer's code, you could usually understand it easily. This is as opposed to languages like Perl, javascript, or R, which for all their great traits are each essentially several different languages masquerading as a one. It's probably inevitable, once you do not have a single person to say no to new features for things that can already be done, that you end up with feature bloat. So, no need to rant about it. But it does effectively demonstrate what the impact of a BDFL is, and what is missing once you don't have one (or at any rate he's not really D any more).
- pmiller2 6y agoDid you notice that Guido was one of the authors of the pattern matching PEP?
- rossdavidh 6y agoha! Nope!
- jjice 6y agoI'm mixed on this one. While I love pattern matching in SML and Rust, I don't know if it's right for Python. Like other comments have said, I loved and learned a lot of Python from looking at a code base and understanding everything immediately because there wasn't much to learn on the language end of things. It was nice and small. Not that the addition of pattern matching is a death sentence for simplicity, but I fear that it may lead to some other extraneous features in the future. I like powerful, featureful languages, but I personally like Python as a simple language that anyone can learn 80% of in a busy weekend. Will I use pattern matching? Maybe. I'll definitely play around with it. Now if we could get some algebraic datatypes then I think I'd start contradicting myself...
- baby 6y agoTrue, but honestly pattern matching is so cool that all languages should have it and ditch switch statements.
- chriswarbo 6y agoThankfully Python has avoided switch statements. Hopefully pattern-matching will take the place of if/elif/elif/else chains, or dereferencing dictionary literals (e.g. `{case1:foo, case2:bar, ...}[myVal]`)
- fmakunbound 6y ago> After much deliberation, the Python Steering Council is happy to announce that we have chosen to accept PEP 634, and its companion PEPs 635 and 636, collectively known as the Pattern Matching PEPs This is why I'm still enamored with Lisp. One doesn't wait around for the high priests to descent from their lofty towers of much deep pontification and debate with shiny, gold tablets inscribed with how the PEPs may be, on behalf of the plebes. One just adds new language feature themselves, eg. pattern matching[1] and software transactional memory[2]. 1. https://github.com/guicho271828/trivia https://github.com/guicho271828/trivia 2. https://github.com/cosmos72/stmx https://github.com/cosmos72/stmx
- bluefox 6y agoNot only that, but we also know that no one pattern matcher fits all: with or without segment patterns? how to designate pattern variables? should it be extendable? what would we actually be matching? should we actually use a unifier? etc. Pattern matchers are easy to write, anyway. We also know that they don't always make things clear, so we don't use them everywhere. Programmers using languages that have a pattern matcher "built in" tend to use it all the time, and it's not always a pretty sight. I conjecture that with this addition, Python codebases will become dichotomized: either it will be used everywhere, or it will not be used at all. The latter obviously has a head start :)
- cutler 6y agoFine for solo work but what happens if your team all come to work in the morning ecstatic about what they just added to the language? Now you have n problems where n is the number of members in your team.
- ivirshup 6y agoThis is what code review is for though, right? I think any reviewer worth their salt is going to be pretty skeptical about a new language feature being the right way to solve a problem. New syntax is often a bad idea, but sometimes it's a really good idea. It'd be good to allow experimentation in the wild, and potentially upstream these features later once they've been proved out. This is why I suggested macros as the feature I'd like to see most in the last python developer survey. Most of the time, defining a macro is bad idea and is a code smell, but sometimes they add very useful language features.
- bob1029 6y agoI just took a look at this and I am confused as to the actual practical utility of pattern matching in a language that is not strongly-typed to begin with. My initial take upon stumbling upon the controversy was "why would pattern matching be bad?" because I have only experienced it through the lens of C# 9.0. Upon reviewing PEP 622 and looking at some examples of usage... I am in agreement with the detractors. This just doesn't seem to make sense for python, but I would certainly hate to get in the way of someone's particular use case as long as the new feature doesn't fundamentally cripple the language for others. IMO, Microsoft nailed it with their pattern matching implementation: https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching#when-clauses-in-case-expressions https://docs.microsoft.com/en-us/dotnet/csharp/pattern-match...
- frou_dh 6y agoPython is strongly-typed. With its built-in type annotation syntax and a checker like mypy or pyright, it is statically-typed, too.
- josalhor 6y agoMy experience with mypy has been pretty negative. Not because mypy is bad per se, but it just doesn't flow into a Python workflow naturally. Every time you try to interact with an external module without these annotations you immediately lose all the advantages of statically typed programs. For me, Python with annotations just doesn't make sense, at that point I would prefer to program in Rust or Java.
- Varriount 6y agoFor external modules, you can generate stub files that contain inferred and/or manually supplied annotations[0]. [0] https://mypy.readthedocs.io/en/stable/stubgen.html https://mypy.readthedocs.io/en/stable/stubgen.html
- adsharma 6y agoA bonus for writing strongly typed code and using a small/safe subset of python is that you can transpile it to languages like rust or kotlin
- antman 6y agoPeople complain on external corporate capture e.g. Microsoft’s embrace, extend, extinguish but I see a more common pattern of introducing internal corporate complexity driving socially powered projects to oblivion. Drupal’s extension system a few years back, Firefox addon ecosystem destruction, Python features after 3.8 and many others. People that contribute are not infinite and those initial more active contributors get demoralized supporting work over a moving foundation. Why not put up an effort on speeding things up, removing the GIL. Important and stale issues of the language that users really care about. F strings where good tho. That’s it. Async syntax? Less good. This pattern matching thing? Have fun debugging this.
- jjoonathan 6y ago> Firefox addon ecosystem destruction I _love_ that I can install an extension without restarting, and as much as I sympathize with the pet projects that got dumped, I think it would have been a huge mistake to hold that up just to keep dead extensions in zombie mode rather than grave mode.
- coldtea 6y ago>I _love_ that I can install an extension without restarting Why? How many times do you install extensions that restarting the browser to see them would be a concern?
- stjohnswarts 6y agoA lot of us use url/cookie/etc cleaners and restarting the browser forces us to log back in to sites that we'd rather not want to during the current browser session. OR have the browser set to just delete everything at close.
- _ZeD_ 6y ago1) if you want to keep the session, why do you use a session cleaner? 2) how hoften do you install new extensions? Is this really a problem?
- Barrin92 6y agoI absolutely love it. Pattern matching is one of my favourite things about ML type languages and I'm glad that it's gradually making its way into other languages. I don't share the concerns about simplicity. It is easy to read in my opinion and adds a lot of expressiveness in a relatively straight forward way.
- sireat 6y agoSo the same idea as pattern matching in Scala? If it can be used as switch case on steroids then I am all for it. Why Python never got switch case is an interesting question.
- chriswarbo 6y agoSwitch is a strange relic of C. According to https://en.wikipedia.org/wiki/Switch_statement#Fallthrough https://en.wikipedia.org/wiki/Switch_statement#Fallthrough the fallthrough behaviour is due to it being implemented as a thin veneer over computed GOTOs. It seems to have infected a surprising number of languages, probably due to a mixture of C's popularity, cargo-culting and Stockholm syndrome. I'm very glad Python never got C-style switch. As for Scala, its pattern-matching (among other things!) ultimately comes from ML in the 1970s (its modern descendents being StandardML and Ocaml, and to a lesser extent Scala, Haskell and Rust).
- properdine 6y agoI am so excited for this. I love Python, but as of 2016, I was missing: 0. Pattern matching 1. Easy support for types & type-checking (thanks mypy + annotations) 2. Better string formatting (yay f-strings) And the nice part is that these are all relatively opt-in features. So excited to be able to using pattern matching as part of the language!
- heavyset_go 6y agoYou can test out pattern matching now if you compile Python. Now I just want multi-lined anonymous functions.
- thidr0 6y agoPattern matching is one of my favorite things about Haskell. But seeing it done here in a dynamically typed language is a more than little clunky (three indents needed to get to an expression). It would be better to be matched on the parameter list, but again Python’s typing would make that too difficult.
- ben509 6y agoThe two-space compromise might work: def handle(command): match command.split(): case ["quit"]: print("Goodbye!") quit_game() case ["look"]: current_room.describe() It'll be a bit odd, though.
- rytill 6y agoI have never really pushed hard on style in my software journey. But this is different. That code sample is horrifying.
- arnvald 6y agoI think it works very well in Elixir which is also dynamically typed. It was there since the beginning though and it's more than just a "match/case" construct, it's built deep into the core of the language, so maybe that makes a difference
- eli_gottlieb 6y agoWell this is some exciting news! algebraic-data-types is my most commonly imported "optional" pip, after the stuff that's strictly necessary for my domain (ie: PyTorch, matplotlib, and such). I guess combined with dataclasses, I can basically finally write ADTs properly in "native" Python.
- bede 6y agoCore dev Larry Hastings [0] puts it well. The cost-benefit case for this complicated language feature is limited. "I dislike the syntax and semantics expressed in PEP 634. I see the match statement as a DSL contrived to look like Python, and to be used inside of Python, but with very different semantics. When you enter a PEP 634 match statement, the rules of the language change completely, and code that looks like existing Python code does something surprisingly very different. It also adds unprecedented new rules to Python, e.g. you can replace one expression with another in the exact same spot in your code, and if one has dots and the other doesn’t, the semantics of what the statement expresses changes completely. And it changes to yet a third set of semantics if you replace the expression with a single _. I think the bar for adding new syntax to Python at this point in its life should be set very high. The language is already conceptually pretty large, and every new feature means new concepts one must learn if one is to read an arbitrary blob of someone else’s Python code. The bigger the new syntax, the higher the bar should become, and so the bigger payoff the new syntax has to provide. To me, pattern matching doesn’t seem like it’s anywhere near big enough a win to be worth its enormous new conceptual load." This while we have elephants in the room such as packaging. Researching best practices to move away from setup.py right now takes you down a rabbit hole of (excellent) blog posts, and yet you still need a setup.py shim to use editable installs, because the new model simply doesn't yet support this fundamental feature. I can't afford to spend days immersing myself in packaging to the point of writing a PEP, but would help pay someone to do it well. I can see no way to fund packaging efforts directly on the PSF donations page (edit: see comment). It's great to see Pip improving but there is still not even a coherent guide that I can find for packaging using up-to-date best practices. This appears to be because the best practices are currently slightly broken. [0] https://discuss.python.org/t/gauging-sentiment-on-pattern-matching/5770/21 https://discuss.python.org/t/gauging-sentiment-on-pattern-ma...
- 1337shadow 6y agoDid you try the "Sponsor" link in pypi.org ? It will take you there: https://pypi.org/sponsor/ https://pypi.org/sponsor/ > The Python Software Foundation is receiving $407,000 USD to support work on pip in 2020. Thank you to Mozilla (through its Mozilla Open Source Support Awards) and to the Chan Zuckerberg Initiative for this funding!
- dionian 6y agothings like this and f-strings make me want to use python more and more. if only i could have a bit better OOP syntax.
- pansa2 6y agoWhat’s wrong with the OOP syntax?
- heavyset_go 6y agoSyntax for writing constructors, getters/setters and information hiding is lacking.
- burntcaramel 6y agoI’m writing a TypeScript package for pattern matching by using generator functions. https://github.com/RoyalIcing/yieldpattern https://github.com/RoyalIcing/yieldpattern It’s amazing to me how much pattern matching, well, matches how I think. A conditional if statement means I have to explicitly read properties off an object or inspect an array to check for what I want. Whereas pattern matching means asking ‘I want something that looks like this’ and do the work for me.
- stakkur 6y agoAnother step away from the beautiful clarity that Python embodies. Yes, I get what it does, but mostly I see the consequences. The past few years of Python language 'development' have been somewhat alarming to me.
- Ericson2314 6y agoHahaha between this, data classes, and the new optional type checkers Python and Ruby are slowly realizing they should have been ML all along. I'm quite pleased and also laughing my ass off. Vindication!
- robomartin 6y agoAh, nuclear-powered "switch" statement. Good. Like it. (Yes, I know it isn't "switch"...and yet...) What remains to be seen is what the execution-time hit might be when compared to other approaches.
- nautilus12 6y agoThis makes my year
- adav 6y agoI'm no Pythonista but a lack of pattern matching is always the first thing I miss when switching back and forth from Scala.
- rtpg 6y agoSuper mixed feelings about this. I feel like the binding stuff in particular could have been solved with some sort of prefix symbol (like "this is referring to a binding location") without introducing a bunch of semantic weirdness. But like... hey, finally get a case statement! I imagine the community will coalesce a bit around best practices. And stuff like pylint will catch name shadowing (at least in theory). Almost all pattern matching mechanism have name shadowing issues and it's definitely annoying, but they are able to figure it out.
- doubleunplussed 6y ago`case _:`? I definitely would have gone for `else:`. `_` is already used by convention for variables you don't care about, but it's kind mixing things to use it for this too.
- tbe 6y agoNot at all since "case _:" is assigning to a variable you do not care about.
- doubleunplussed 6y agoIf it's actually assigning, then I'm happy! The tutorials made it look like `_` is a special case, not just what you would expect putting any arbitrary name there to match no matter what.
- ben509 6y agoI like it. I was just trying to do some simple "parsing" of a pyproject.toml file. So I wrote the standard crud of, "is it a dictionary? If so, does it have a specific key? What if it's just a string? If so, ..." Having a dedicated syntax would mean someone could look at the patterns I'm matching and see clearly what the format of the input should be. This seems ideal for handling various user-friendly toml/yaml/json configuration formats and other semi(poorly)-structured data. I think it also addresses a real weakness in OO: to add behavior per class you either lard up classes with not-really-relevant methods, or create a proxy class, or do the inevitable if/elif isinstance chain.
- johndoe42377 6y agoIt is too late, but I think they should have adopted the ML family approach of uniform pattern matching (in function clauses and parameters as well). Uniformity is a big deal. Ok, Scala or Rust got a chance. Partial functions (clauses), currying and patterns complement each other remarkably and it is well-researched and formalized for decades.
- codesnik 6y agoBut what if you want to match to value of some variable in the scope? I see no "^pinning" of variables or stuff like that. There's "dotted" syntax, but it works only for constants and fields, not local variables, right? Am I missing something?
- danohuiginn 6y agoIMO the obvious solution would be to allow a bare dot, like .local_variable But I don't see that, or any other solution for local variables, in the PEP
- nikisweeting 6y agoThis looks cool but I want dictionary unpacking (or "destructuring") more than pattern matching, hard to live without it after JS: >>> {a, b, z} = {"a": 1, "b": 2, "c": 3, "z": 4} >>> print(a, b, z) 1 2 4 # to get object attrs we can just do >>> {someval} = SomeObject(someval=42).__dict__() >>> print(someval) 42
- iamevn 6y agoTechnically I think this feature would do unpacking for you, just more verbosely, like so: d = {"a": 1, "b": 2, "c": 3, "z": 4} match d: case {"a": a, "b": b, "z": z}: print(a, b, z) o = SomeObject(someval=42) match o: case SomeObject(someval=someval): print(someval) from https://www.python.org/dev/peps/pep-0636/#going-to-the-cloud-mappings https://www.python.org/dev/peps/pep-0636/#going-to-the-cloud... and https://www.python.org/dev/peps/pep-0636/#adding-a-ui-matching-objects https://www.python.org/dev/peps/pep-0636/#adding-a-ui-matchi... it's more verbose but lets you easily add a default case to catch and handle when a key you expected to be in the dict isn't or the object doesn't actually match the object you expect.
- wraptile 6y ago> There should be one-- and preferably only one --obvious way to do it. I honestly don't see what this adds over if statements. You save typing `match ==`? I guess indent block is visually more clear than series of ifs/elifs? That's kinda already solved with pep8 styling of separating logic blocks with newlines. match response.json()["status"]: case "500": raise DeadServer() case "404": raise BanServer() vs status = response.json()["status"] if status == "500": raise DeadServer() elif status == "404": raise BanServer() there's some clarity here but at the same time it's an extra indent layer, soon we'll have: class Client: def download(url): with open_connection() as session: while True: response = session.get(url) match response.json()["status"]: case "500": raise BadServer() case "200": return response.json() As much as I love python's indentation this is getting a bit out of hand, isn't it? Did we run out of things to add to python?
- dguaraglia 6y agoPattern matching isn't just about having a switch statement, but about what you can do in the 'case' part of the statement: match complex data and extract variables. A good example of how pattern matching simplifies code is given in the 'Patterns and Functional Style' section of PEP 635 [1]: match json_pet: case {"type": "cat", "name": name, "pattern": pattern}: return Cat(name, pattern) case {"type": "dog", "name": name, "breed": breed}: return Dog(name, breed) case _: raise ValueError("Not a suitable pet") The equivalent if statement would be kind of gross: if 'type' in json_pet: if json_pet['type'] == 'cat' and 'pattern' in json_cat: return Cat(json_pet['name'], json_pet['pattern']) elif json_pet['type'] == 'dog' and 'breed' in json_pet: return Dog(json_pet['name'], json_pet['breed']) raise ValueError("Not a suitable pet") One can imagine extending that to parse 6 or 7 types of messages. Another example is matching tuples or sequences: the equivalent if statement requires checking the length of the sequence, then extracting the variables, etc. The 'case' statement does all of that in one line. In other words, as one of my university professors would put it: 'there's nothing that can't be written using plain ifs, adds and jumps, but that doesn't mean we all want to write in assembly with just 3 instructions'. [1] https://www.python.org/dev/peps/pep-0635/#patterns-and-functional-style https://www.python.org/dev/peps/pep-0635/#patterns-and-funct...
- davesque 6y agoHonestly I'm not sure what all the fuss is about. I just skimmed over PEP 634 and PEP 636 (the accompanying tutorial) and I'm actually kind of excited to use this. I've missed this feature after using langs like Rust, Haskell, and Scala. People have pointed out some surprising edge cases such as this: NOT_FOUND = 404 match get_status(): case NOT_FOUND: # this actually assigns to the global NOT_FOUND # and is effectively the default case case _: # this never gets triggered Yeah, I agree that's a bit ugly. But you can apparently do this: class Status(Enum): NOT_FOUND = 404 match get_status(): case Status.NOT_FOUND: # works as expected ... And really how is any of that more ugly than this? def func_with_default(foo={}): if "bar" not in foo: # "bar" is set in the module-level dict that # was initialized when the func def was parsed, # not in a dict that is created per call foo["bar"] = ... ... And we've been living with that one for years. These are just the things that you have to learn when you start using Python, just like any other language. I, for one, am excited to start using this syntax.
- codesnik 6y agomodule-level dict?... why...
- davesque 6y agoUh...that's my point. Everyone new to Python has to eventually learn not to do that.
- PartiallyTyped 6y agoThe folk over at openAI do something similar in order to create a registry, so that you can initialize objects using a name.
- carapace 6y agoIt's a simple rule: Default arguments are evaluated at function definition time (when the interpreter reaches the 'def' statement) not at the time the function is called. It's not a "module-level dict", you can create functions inside other functions: def foo(): def bar(a={}): ... return bar Each instance of bar gets its own dict when you run foo() and the "def bar(...): ..." statement gets executed. The dict is packaged up inside the function object (sort of like a closure except that the dict and it's name aren't from the enclosing scope of the function, and of course you can "shadow" it by passing in an argument for the parameter. https://en.wikipedia.org/wiki/Closure_(computer_programming) https://en.wikipedia.org/wiki/Closure_(computer_programming) )
- deleted 6y ago[deleted]
- choeger 6y agoI just read the part about the name binding and its ... totally bonkers. Sorry, but I have no other words for this: > The implementation may choose to either make persistent bindings for those partial matches or not. User code including a match statement should not rely on the bindings being made for a failed match, but also shouldn't assume that variables are unchanged by a failed match. This part of the behavior is left intentionally unspecified so different implementations can add optimizations, and to prevent introducing semantic restrictions that could limit the extensibility of this feature. That's basically dynamic scoping instead of lexical scoping only inside the match blocks and only for pattern variables. Who in their right mind comes up with a design like that? That's the javascript route! I get it that proper binding would have been difficult but if language design is too difficult, you should stop and not go one like you don't care about the consequences! This decision will waste thousands of developer hours when searching bugs!
- jnxx 6y ago> This part of the behavior is left intentionally unspecified so different implementations can add optimizations, and to prevent introducing semantic restrictions that could limit the extensibility of this feature. Isn't this more or less what was the argument to allow more undefined behaviour in ANSI C ? (Edit: I think this also comes from the tension caused by integrating features from functional languages into an imperative language, like explained in more detail here: https://news.ycombinator.com/item?id=26086863 https://news.ycombinator.com/item?id=26086863 )
- varjag 6y agoUnlike Python, C has the excuse of runtime efficiency as a plausible rationale. Python is big time SLOW, there's a ton of untapped optimisation potential before wandering into UB for sake of speed territory.
- pfalcon 6y agoThey went for "UB" exactly because they understand the current behavior is not ideal, and to allow for better implementation and to change it later.
- mcdevilkiller 6y agoAdding pattern matching to a language as big as Python is not only good for Python, but for smaller languages with the feature, as it introduces people to the concept. Imo.
- qwerty456127 6y agoGreat. I just hope we won't have to wait 30 more years for immutable (single-assign) values to arrive.
- Havoc 6y agoMakes me wonder whether to invest time in python or rust going forward. Different applications but still...my time is limited
- nilradical 6y agowonderful! hopefully this addition helps people to wake to the reality that python is a convoluted , unprincipled, unintelligent sluggish steaming pile of turd of a language . Python and javascript need to die.
- onlydeadheroes 6y agoPython started as a language with one correct way to do any task (more or less, but still). Over time people have added all the other ways and called it progress. What we need is a python fork that trims most of this crap and makes a faster implementation. And gets rid of this horrifying steering committee or whatever is currently butchering python. No wonder Guido had to leave the scene, to cry himself to sleep probably.
- carapace 6y agoProf. Wirth, when designing the Oberon language, adopted this heuristic: a new feature could only be added to the compiler if it reduced the time it took to compile itself. Now this doesn't quite apply to cPython, of course, and even PyPy is written in RPython, not Python 3, (correct me if I'm wrong on that, eh?) so it doesn't quite apply to that either. Every time newfangled geld like this comes down the Py3 turnpike I think of all the other Python implementations that either have to implement it also or get left behind: PyPy, Cython, Jython, Brython, Skulpt, Stackless, Pyjs, IronPython, PythonNet, MicroPython, Nuitka, ShedSkin, Transcrypt, etc., not to mention tools like Snakefood or PySonar or MyPy. (I'll shut up now, you don't want to hear it. I read the tutorial on the new matching and by the end I found myself chanting under my breath "Cthulhu fhtagn! Tekeli-li! Tekeli-li!")
- butt_hugger 6y agoDoes anyone use Oberon?
- carapace 6y ago"There are dozens of us!" Yep. You can even get a very nice dev system based on it that's commercially supported: https://astrobe.com/ https://astrobe.com/ > Astrobe is a complete integrated embedded software rapid development system running on Windows. It includes a multi-file, fully featured, syntax-aware programmer's editor, native code compiler, linker and builder, program uploader and a serial terminal. Use it to develop reliable software to run on the powerful 32-bit ARM Cortex-M3, Cortex-M4 and Cortex-M7 families of microcontrollers. You can try out the original Oberon OS workstation in your browser here: https://schierlm.github.io/OberonEmulator/ https://schierlm.github.io/OberonEmulator/ thanks to a JS emulator for the RISC chip!
- EddieLomax 6y agoUsing _ might be problematic for Django devs, who usually use it for translation, e.g. from django.utils.translation import gettext as _