What about instead of number = match x: 1 => "one" 2 => "two" 3 => "three" 10 => "ten" _ => "anything"
number = { 1 => "one" 2 => "two" 3 => "three" 10 => "ten" }.get(x, "anything") No magic syntax with blocks starting inside an assignment, just to start with. On 3 May 2018 at 09:41, Robert Roskam <raiderrob...@gmail.com> wrote: > Hi Everyone, > > Never posted in here before, so I hope that I'm not violating any particular > procedure for intros or something. > > Over time, there have been various switch or match statement proposal; some > that have gotten as far as PEPs: > > 2001 Nov - https://www.python.org/dev/peps/pep-0275/ > > 2006 Jun - https://www.python.org/dev/peps/pep-3103/ > > 2014 Apr - > https://groups.google.com/d/msg/python-ideas/J5O562NKQMY/DrMHwncrmIIJ > > 2016 May - > https://groups.google.com/d/msg/python-ideas/aninkpPpEAw/wCQ1IH5mAQAJ > > However, I don't see that the conversation ever really resolved, so I'd like > restart the conversation on some kind of pattern matching syntax in Python. > > The main objections I've seen are in the following buckets: > > One--and Preferably Only One--Obvious Way. Basically, we have if/elif and > that's all we need, so this is syntactical sugar bloat. I'd submit that > there are specific cases where this kind of syntax would be the obviously > correct way to do something > Specific Syntax Objections. There have been several specific objections that > usually come down to "unreadable" or "ugly", which are subjective statements > that don't really bring any good way to continue the discussion in a > productive manner. > > I cannot handle all syntax objections ahead of time, but I can handle the > "only way" objection. At high level, pattern matching provides similar > syntactical sugar to list comprehensions. We could argue that they are > unnecessary since we have for loops. But more importantly, pattern matching > is powerful for what it restricts you to. More specifically: > > Assignment. Many of the implementations offer the ability to immediately > assign the value from the matching pattern. However, assignment is prevented > in the middle of all of the patterns, which is possible in if/elif. > No Fall Through. Once a pattern is matched, there's no way to break to try > another branch. Prevents having to look at multiple cases to figure out how > something resolved. If/elif can have this happen, of course, but even more > confusing sometimes breaks will be mixed with returns or other control > flows, which makes figuring how large if/elifs are resolved. > Automatic Unpacking. Some implementations offer the ability unpack a > dictionary equivalent automatically into keys or select ranges of values > like slicing. Compared to if/elif, this is tremendously more DRY than doing > the "does the key exists?" and then "what is that keys value?" > Guards. Often times you can embed another check to go along with the simple > pattern matching. Absolutely possible with if/elif, but crucially are > implementations generally happen after the pattern check. Again, keeps code > DRY and improves readability. > > I figured maybe a good way to continue the discussion is to offer a > straw-man example syntax: > > # Simple pattern matching > x = 1 > > number = match x: > 1 => "one" > 2 => "two" > 3 => "three" > 10 => "ten" > _ => "anything" > > print(number) # one > > > # Final Pattern that matches anything > x = 3 > > number = match x: > 1 => "one" > 2 => "two" > _ => "anything" > > print(number) # anything > > > # Pattern matching without any match returns None > number = match x: > 1 => "one" > 2 => "two" > > print(number) # None > > > # Pattern matching with guards > x = 'three' > > number = match x: > 1 => "one" > y if y is str => f'The string is {y}' > _ => "anything" > > print(number) # The string is three > > > # Pattern matching with multiple values > x = 1 > > number = match x: > 1, 2, 3, 4 => "one to four" > _ => "anything" > > print(number) # one to four > > > # Pattern matching with types > x = 1. > > number = match x: > x:int => f'{x} is a int' > x:float => f'{x} is a float' > x:str => f'{x} is a string' > > print(number) # x is a float > > > # Supports destructuring dicts > > x = {'foo': 1} > > number = match x: > {'foo': 1} => "foo is 1" > _ => "anything" > > print(number) # foo is 1 > > > # Supports binding with destructuring dicts > > x = {'foo': 1, 'bar': 2} > > number = match x: > {'foo': y} => f'got foo {y}' > {'bar': z} => f'got bar {z}' > {'foo': y, 'bar': z} => f'got foo {y} and bar {z}' > _ => "anything" > > print(number) # got foo 1 and bar 2 > > > # Supports destructuring other types too > > class Point(): > def __init__(self, x, y): > self.x = x > self.y = y > > point = Point(1,2) > > number = match point: > Point(x,y) => f'point has an x of {x} and y of {y}' > _ => "anything" > > print(number) # point has an x of 1 and y of 2 > > > As a continued defense for this specific syntax choixe, lets see how two > other languages with this feature handle it. I'm going to try to offer as > nearly as possible similar examples. > > Scala https://docs.scala-lang.org/tour/pattern-matching.html > > val x: Int = 1 > > def makeMatch(x: Any) = x match { > case 1 => "one" > case 2 => "two" > case _ => "anything" > } > > val number = makeMatch(x) > > Rust https://doc.rust-lang.org/1.5.0/book/match.html > > let x = 1; > > let number = match x { > 1 => "one", > 2 => "two", > _ => "anything", > } > > And for the sake of completeness, here are other languages with similar > syntax features and their associated documentation > > F# > https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching > > Elixir https://elixir-lang.org/getting-started/case-cond-and-if.html > > Clojure https://github.com/clojure/core.match/wiki/Basic-usage > > JavaScript (ES2018?) https://github.com/tc39/proposal-pattern-matching > > Haskell https://en.wikibooks.org/wiki/Haskell/Pattern_matching > > Swifthttps://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html > > > > > > > > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/