[HN Gopher] Pattern Matching Accepted for Python
___________________________________________________________________
Pattern Matching Accepted for Python
Author : eplanit
Score : 214 points
Date : 2021-02-09 18:16 UTC (4 hours ago)
(HTM) web link (lwn.net)
(TXT) w3m dump (lwn.net)
| jjice wrote:
| I'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...
| toxik wrote:
| Wow, this is perhaps the worst idea introduced to Python in a
| long time. So many ambiguities, so much inscrutable syntax. What
| a shame.
| superbcarrot wrote:
| > 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 wrote:
| There have always been 100 ways to do everything in python.
| People just constantly spout the zen thing to look smart.
| superbcarrot wrote:
| There 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.
| jonnycomputer wrote:
| ...
|
| I'll take my down votes. Please move on opinionated HN-ers.
| [deleted]
| messe wrote:
| By that same logic wouldn't def f(x):
|
| look too close to function invocation for your taste?
| [deleted]
| fmakunbound wrote:
| > 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
|
| 2. https://github.com/cosmos72/stmx
| antman wrote:
| People 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 wrote:
| > 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.
| marcinzm wrote:
| >Firefox addon ecosystem destruction
|
| Firefox suffered greatly in marketshare because they didn't
| pull the plug soon enough but rather gained a reputation for
| slowness and bugginess. Doing nothing isn't a viable strategy
| when you have competitors (ie: Chrome) who are doing something.
| oflannabhra wrote:
| Pattern matching is what I missed most when switching from Swift
| to Python a year ago. Really happy to see this day come!
| mjburgess wrote:
| Can 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 wrote:
| It's this: https://www.python.org/dev/peps/pep-0634/ - not sure
| which version that is?
| nneonneo wrote:
| Not sure what you mean, but the accepted PEP does appear to be
| a statement. What was the alternative?
| the_duke wrote:
| In 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 wrote:
| I 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 wrote:
| match is a statement, but the syntax is very readable.
|
| https://www.python.org/dev/peps/pep-0636/#adding-conditions-...
| techdragon wrote:
| I'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!
| toxik wrote:
| This is not truly Erlang style pattern matching. And Python can
| never have that either because of its design.
| macintux wrote:
| Python 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".
| [deleted]
| hannibalhorn wrote:
| The accepted PEP is 634:
| https://www.python.org/dev/peps/pep-0634/ and the tutorial has
| some examples: https://www.python.org/dev/peps/pep-0636/ .
| JNRowe wrote:
| [Expanding my comment from another post on this1]
|
| 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/
|
| _Motivation and Rationale_
| https://www.python.org/dev/peps/pep-0635/
|
| _Tutorial_ https://www.python.org/dev/peps/pep-0636/
|
| Rejected:
|
| _Unused variable syntax_
| https://www.python.org/dev/peps/pep-0640/
|
| _Explicit Pattern Syntax for Structural Pattern Matching_
| https://www.python.org/dev/peps/pep-0642/
|
| 1 https://news.ycombinator.com/item?id=26073700
| properdine wrote:
| I 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!
| TrianguloY wrote:
| Can'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()
| vitus wrote:
| Correct.
|
| > Patterns may use named constants. These must be dotted names
| to prevent them from being interpreted as capture variable:
|
| NOT_FOUND would always match as a capture variable, so you'd
| always return default().
|
| I fully expect this to be covered by linters, but not with
| further language support.
| mvolfik wrote:
| yeah, I would also expect the linters to catch this. has some
| way to allow use of non-dotted constants been considered?
| something like window.global_variable in JavaScript? Or would
| I need to do something like this:? NOT_FOUND
| = 404 m = {"NOT_FOUND": NOT_FOUND} match value:
| case m["NOT_FOUND"]: pass
| TrianguloY wrote:
| I may be wrong, but after reading the grammar I think your
| example is a syntax error. You can't access an element! A
| pattern syntax is completely different to a normal
| expression, and there is apparently no array access.
| mvolfik wrote:
| hmm, so I would need to use some namespace class https://
| docs.python.org/3.8/library/types.html#types.SimpleN...
| [deleted]
| AlexandrB wrote:
| Yup, 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 wrote:
| Not 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 wrote:
| You 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 wrote:
| ... except in case expressions
|
| Thanks for proving my point though!
| eli_gottlieb wrote:
| Well 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.
| rossdavidh wrote:
| So, 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 wrote:
| Did you notice that Guido was one of the authors of the pattern
| matching PEP?
| rossdavidh wrote:
| ha! Nope!
| pansa2 wrote:
| IMO 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`).
| _nosewings_ wrote:
| This is how pattern matching works in any language (except for
| some niche languages that allow nonlinear patterns, like
| Curry).
|
| Many of the comments here reveal a bizarre parochialism.
| [deleted]
| dpritchett wrote:
| Are you sure the second one isn't just declaring not_found as a
| stand-in for 404 so the case statement two lines below can
| refer to business logic rather than a "magic" constant?
|
| I would NOT expect for the line "case not_found:" to reassign
| the status variable to 404 regardless of what it was before.
|
| I can't see how or why that would be intended behavior.
| dpritchett wrote:
| I'd like to believe that the reassignment doesn't apply in
| cases where
| [deleted]
| danaliv wrote:
| Oh, yikes. I understand what's happening here but this is going
| to bite a lot of people.
|
| I might be misreading the grammar but it looks like you can
| produce the desired effect by using an attribute, e.g. the
| following would perform an equality check, not an assignment:
| match status: case requests.codes.not_found:
| return "Not found"
|
| The tutorial seems to confirm this: "This will work with any
| dotted name (like math.pi). However an unqualified name (i.e. a
| bare name with no dots) will be always interpreted as a capture
| pattern"
| [deleted]
| TrianguloY wrote:
| Yes, apparently your example will work correctly.
|
| Now think what will happen if you need to move that not_found
| variable to the same file as that code (so it will no longer
| be a dotted name). If you do it manually you need to be extra
| careful, if you use an automatic tool either it will reject
| the change or will need to create a dummy class or something
| in the process.
| The_rationalist wrote:
| Why is it performing an implicit assignment instead of an
| equality check?
| SrslyJosh wrote:
| A bit part of the appeal of pattern matching in other
| languages is support for destructuring, where you implicitly
| assign variables to members of a data structure you're
| performing a match on. For example, in ML-ish pseudocode:
|
| len([]) = 0 len([first|rest]) = 1 + len(rest)
|
| That's a trivial example. The second PEP (pattern matching
| tutorial) has several other examples:
|
| https://www.python.org/dev/peps/pep-0636/#matching-
| multiple-...
|
| So, if you use a variable in a pattern, it's an implicit
| assignment. If you use a literal, it's a value to be matched
| against.
|
| I agree that the trivial case (a single variable with no
| conditions) may be confusing before you know what's going on,
| but I think the alternative, where a single variable is a
| comparison but multiple variables (or a structure) is an
| assignment isn't necessarily better.
| [deleted]
| breuleux wrote:
| That's not too bad if it would be a syntax error to either set
| or shadow an existing variable with the match statement.
| Apparently it isn't, which is concerning. Personally I think I
| may have preferred something like: match
| status: case == not_found: # Check for equality
| ... match status: case as not_found:
| # bind status to variable not_found ...
|
| At least the former should be an option instead of using a
| dotted name IMO.
|
| You know, a lot of potentially confusing behavior would be
| avoided if programming languages had the sense to make
| variables read-only by default and disallow variable shadowing
| altogether.
| willcipriano wrote:
| I've been scanning the docs and this syntax is hard for me to
| understand, however your version makes sense right on first
| glance. I'd go with that.
| antman wrote:
| That looks pretty counter intuitive even after this explanation
| frou_dh wrote:
| I think the general criticism of the match statement is just
| baggage from C overexposure. See the keyword "case" and the
| brain immediately snaps to thinking we're in a bog-standard
| C-style switch statement.
|
| It's not a switch! Nowhere does it say switch. It's structural
| pattern matching!
|
| EDIT: The lack of block scoped variable thing does seem like a
| wart right enough.
| brianberns wrote:
| OK, but from a functional programming point of view (where
| structural pattern matching comes from), "case" should bind a
| value to a name, not mutate the value of an existing
| variable. That seems nuts to me.
| thomasahle wrote:
| Does it shadow the outside variable or mutate it?
| pansa2 wrote:
| Mutates it. Python `match` statements do not introduce a
| new scope.
| hmry wrote:
| I don't get it, isn't that exactly what it's doing here?
| magnusmundus wrote:
| It's mutating (not shadowing) `not_found` with the value
| of `status`. That can cause trouble if you rely on
| `not_found` keeping the initial value later somewhere.
| Which you would, e.g. with the global constant of
| `NOT_FOUND`.
|
| Honestly I think the issue is so troublesome only if
| there's a single case to match, though. With more
| expected cases it should cause pretty obvious bugs (easy
| to catch).
| [deleted]
| [deleted]
| airstrike wrote:
| Yes, and this is incredibly disappointing.
|
| Couldn't we achieve the same functionality with a little less
| ambiguity using the following syntax?:
| not_found = 404 match status: case
| not_found: return "Not found"
| case _ as foo: do_something(foo)
| return "Match anything"
|
| it even works for the example in PEP 365
| match json_pet: case {"type": "cat", "name": _ as
| name, "pattern": _ as pattern}: return
| Cat(name, pattern) case {"type": "dog", "name": _
| as name, "breed": _ as breed}: return Dog(name,
| breed) case _: raise
| ValueError("Not a suitable pet")
| rwmj wrote:
| That's how structural pattern matching works in ML-like
| languages, where it's been in use for 40+ years.
| [deleted]
| AlexandrB wrote:
| Don't those languages typically have immutable variables so
| you would not be able to rebind a constant by accident?
| [deleted]
| the_duke wrote:
| This 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.
| pansa2 wrote:
| Python `match` statements do not introduce a new scope.
|
| The second example does indeed change the value of
| `not_found`.
| the_duke wrote:
| That's a very problematic design decision, imo...
| rwmj wrote:
| Oh dear, that is indeed very bad.
| mbo wrote:
| What's the rationale for not introducing a new scope?
|
| The only clause I can find in the PEP is
|
| > A capture pattern always succeeds. It binds the subject
| value to the name using the scoping rules for name
| binding established for named expressions in PEP 572.
| (Summary: the name becomes a local variable in the
| closest containing function scope unless there's an
| applicable nonlocal or global statement.)
|
| This seems... incredibly bad.
| deathanatos wrote:
| That works the same as the rest of the language, doesn't
| it?
|
| (That is, for, if, while, etc. _also_ don 't introduce
| new scopes.)
| magnusmundus wrote:
| It's consistent with how scoping works in loops and
| `with` clauses. Agreed that it's more problematic here,
| though.
| pdw wrote:
| "Introducing a new scope" is not a concept that exists in
| Python, you only have function scope and module scope.
| pansa2 wrote:
| There are some exceptions to this - for example, the
| iteration variable(s) in a list comprehension are only in
| scope within the comprehension.
| [deleted]
| TrianguloY wrote:
| I just wrote a comment with the same complain and similar
| example!
|
| I also think the same as you wrote, the second check will be a
| hard to spot mistake
| magnusmundus wrote:
| I think your example makes it clearer that it won't be a very
| subtle a bug to find, but rather completely broken behaviour
| where only the first case is ever triggered. That should be
| much simpler to test against. Granted, this breaks down if
| you're matching by the number of values, possibly other
| cases.
|
| To be honest, I feel I like the (sort-of-) "forced
| namespacing" of matching constants this brings. It should be
| an easy habit to discipline too, the rule being very simple:
|
| "if you don't want to use literals in your matching, you
| _must_ plug them in an enumeration "
|
| Too bad that enumeration can't be a PEP 435 enum without
| adding an ugly `.value` accessor to each case, though.
| Barrin92 wrote:
| I 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.
| AlexandrB wrote:
| A 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.
| 01100011 wrote:
| Maybe the problem with C++ is that it tries too hard to
| preserve backwards compatibility? I think it makes some of the
| newer features clunkier. If the C++ standards folks did
| something like Google's Abseil and provided an upgrade tool
| while discontinuing old features they might have ended up with
| a better language. I understand something like that might not
| work for everyone, but from what I've gathered in talking to
| other devs, there is a strong distaste for the current state of
| C++.
| 74d-fe6-2c6 wrote:
| I need to justify six digits in Germany - we're not the Bay
| Area.
| _jjkk wrote:
| I 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 wrote:
| Really? 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 wrote:
| I 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.
| 533474 wrote:
| grandparent?
| roelschroeven wrote:
| The parent comment of the parent of my comment, and by
| extension the writer of that comment.
| atoav wrote:
| Thanks for the clarification.
| nickysielicki wrote:
| Already true with string formatting, map/filter versus
| comprehensions, plenty of other things.
|
| Find me a modern language where that isn't true, though.
| scatters wrote:
| And packaging!
| superbcarrot wrote:
| It's difficult to balance it out correctly. F-strings were a
| significant improvement and I still think it was a great idea
| to include them and trade off some of the language simplicty
| for the added convenience. This new pattern matching... I'm not
| convinced yet.
| roelschroeven wrote:
| Personally I don't feel f-strings are an improvement at all,
| but I think I can see why people prefer them. But a
| significant improvement, that I don't see at all. Can someone
| explain why e.g. f'gcd({a}, {b}) =
| {math.gcd(a, b)}'
|
| is so much better than 'gcd({}, {}) =
| {}'.format(a, b, math.gcd(a, b))
|
| In the .format() version, the formatting and the values are
| separate and that makes it more clear to see both the
| formatting and the values. I really like that separation.
| When the expressions get more complex, .format() doesn't
| really lose any clarity while f'' gets pretty unreadable
| quite fast IMO. Yes, you can simplify by assigning the
| expressions to variables, but .format() doesn't even need
| that.
| cjohnson318 wrote:
| Once you get over five arguments in str.format(), it gets
| weird. I reverse engineered a product that required a lot
| of string formatting, and f strings made things more
| readable and debuggable.
| superbcarrot wrote:
| I find the f-string version better because I read from left
| to right and find it unnatural when my eyes need to jump
| around several times over the same expression in order to
| parse it. In your example that effect isn't too strong
| because there isn't a lot of additional text in the string
| and it's very clear what's going on either way.
| IanCal wrote:
| > In the .format() version, the formatting and the values
| are separate and that makes it more clear to see both the
| formatting and the values.
|
| It makes it harder to see which values actually go where
| though. I really dislike the separation.
| thaumasiotes wrote:
| > It makes it harder to see which values actually go
| where though.
|
| You can name the variables in the format string and then
| pass the expressions as keyword parameters.
| ju_sh wrote:
| Thank goodness we still have both ;)
| roelschroeven wrote:
| > I really dislike the separation.
|
| That's obviously a pretty fundamental difference in
| point-of-view. And it looks like your point-of-view is
| shared by a large majority.
|
| "The reasonable man adapts himself to the world. The
| unreasonable man persists in trying to adapt the world to
| himself. Therefore, all progress depends on the
| unreasonable man." -- George Bernard Shaw
|
| I try to be reasonable, so I guess I should try to come
| to terms with f-strings. In any case please don't depend
| on more progress.
| not_knuth wrote:
| Obligatory Bjarne Stroustrup quote:
|
| _" There are only two kinds of languages: the ones people
| complain about and the ones nobody uses."_
|
| I think it's an interesting point you make, because Python is
| actually one of the few languages that tried to break away from
| its past (the whole 2.7 to 3.7 fiasco), but it seems the need
| for a language to be stable is just much, much greater - so
| features are just piled onto the existing standard instead.
|
| If COBOL taught me one thing, it's that I'm pretty sure in 60
| years time there will still be critical infrastructure running
| on Python 2.7.
| neysofu wrote:
| That quote is seriously overused, to the point where valid
| criticisms will be met with disapproval simply because the
| language falls under condition (1).
| cjauvin wrote:
| I understand your feeling and I would tend to agree for things
| in other domains.. but for a programming language, I find that
| if:
|
| (1) It doesn't make the language less efficient
|
| (2) The new feature is coherent with the rest of the language
|
| (3) It doesn't make learning the language harder
|
| (4) It brings joy in my life (as f-strings do)
|
| Then.. it's ok :-)
| rement wrote:
| I have never seen f-strings! It's my lucky day!
| https://xkcd.com/1053/
|
| Time to refactor the project I am currently working on that
| is loaded with `str.format()`
| ZephyrBlu wrote:
| f-strings are truly amazing. They're very painless. The
| only gotcha I've run into is accessing a dict from inside
| one. You need to watch out for you quotations :).
| chriswarbo wrote:
| There are some 'invisible' downsides to adding new features,
| which often get overlooked:
|
| - Tooling, code analysers, etc. have to be updated to
| understand the new features. Tools which are dead or
| "finished" may stop working.
|
| - The _possibility_ that someone _might_ use a new feature
| can break guarantees that are relied upon by existing code.
| An obvious example would be adding try /catch to a language:
| in languages without this, a function call is guaranteed to
| either return control to us, or to run indefinitely.
| Libraries might rely on this to clean up file descriptors,
| etc. afterwards. Such libraries would be broken by the mere
| _existence_ of try /catch; even if we never actually use it.
|
| That said, I'm a big fan of pattern-matching, so it would be
| nice to have in Python, rather than crude approximations like
| '{pattern1: A, pattern2: B, pattern3: C, ...}[myVal]'
| 0xbadcafebee wrote:
| If developers actually knew what simplicity was they'd stop
| worshipping it.
|
| Brainfuck is an extremely simple language. I mean, it's
| perfect. Only 8 instructions! Only 1 pointer! Turing complete!
| Why isn't everyone writing their code in this language?
|
| A bicycle attached to a wheelbarrow is extremely simple
| transportation. You can get anywhere you need to go, you can
| carry heavy loads, it's easy to use, easy to fix, cheap. Why
| would you use anything else?
|
| Wood is a great building material. You can build a building
| several stories tall, it's cheap, plentiful, easy to work with.
| We should just standardize all construction on wood.
|
| Water is the simplest beverage. It's clean, healthy, easy to
| ship, easy to store. We don't need to drink anything else.
| whalesalad wrote:
| String formatting with f"" has been the new sheriff in town for
| a while and it is really killer.
| pletnes wrote:
| Yes, and it also takes approx 11 seconds to learn, since
| str.format already had exactly the same syntax, just slightly
| more verbose.
| leadingthenet wrote:
| I never understood why they didn't remove the previous
| ones.
|
| Isn't there supposed to be only one obvious way of doing
| these things?
| elisaado wrote:
| You can't just remove things, that'd break stuff!
| leadingthenet wrote:
| This is why the language is getting bloated. People
| shouldn't be so obstinately against breaking changes.
| spockz wrote:
| That is why scala has scalafix[1] where library
| maintainers can provide rules along with newer versions
| of libraries that can be used to automatically, either at
| build time or out of band on the source, translate old
| constructs/patterns in the new.
|
| See it as deferred refactoring for library maintainers.
| Library maintainers that work in a monorepo with their
| users get this refactoring feature for free.
|
| [1]: https://scalacenter.github.io/scalafix
| linkdd wrote:
| greeting = "hello {}" greet = partial(str.format,
| greeting) greet("world")
|
| How would you pass a variable format string to f"" ?
| nokko wrote:
| I mean, if you're comfortable with `functools.partial`,
| lambdas are no great stretch:
| greet_fstring = partial(lambda _,s: f"hello {s}",
| greeting)
| eljost wrote:
| You can use variables in the formats. >>>
| flt = 1.2345 >>> two = 2 >>> f"{flt:.{two}f}"
| '1.23'
| thaumasiotes wrote:
| That is the opposite of the problem being posed. The
| question is how you define `greet` using f-strings.
| sumzup wrote:
| greet = lambda x: f"hello {x}"
| thaumasiotes wrote:
| Why is the example greet =
| partial(str.format, greeting) greet("world")
|
| as opposed to just
| greeting.format("world") ?
| sumzup wrote:
| greet = lambda x: f"hello {x}"
| pletnes wrote:
| Or read the string to be formatted from a file, to name
| another use case.
| notatoad wrote:
| Python already broke backwards compatibility once. It
| didn't got over well
| agumonkey wrote:
| I believe it's been a cause of care for very easy and
| expressive string formatting syntax in other languages
| roelschroeven wrote:
| And probably other situations, like perhaps corporate
| environments, where you're not supposed to use the new more
| advanced parts because not everyone on the team knows them.
| Python is evolving into several different languages. "There
| should be one-- and preferably only one --obvious way to do
| it." Yeah right. I'm waiting for a PEP that deprecates PEP 20,
| "The Zen of Python". It's become more and more clear that the
| core developers don't follow it all anymore.
| mrfusion wrote:
| I thought I'd learn Perl once so I started reading a book on
| it. I was shocked that literally the bottom half of every
| page was footnotes. I gave up after a few pages.
|
| Too much mental overhead. Other people love that kind of
| stuff though.
| ghshephard wrote:
| I was a Perl developer/scripter for the better part of 3
| years - wrote a 2-way LDAP<-> HRIS synchronization system
| in it, complete with customizeable Schemas. Then, 3 or so
| years into my Perl experience, in which I still needed to
| look at template code every time I did a
| HashOfArray/ArrayOfHash, I tripped across some python code
| explaining how everything was objects.
|
| Within a few seconds I tested that theory, by populating a
| list with dicts and voila - just worked. Close to the last
| day I ever touched Perl.
|
| The python language expansions that have come recently,
| f-strings, walrus operator, and now matching - are great in
| that they _don 't make the language more complex_ - all
| three of these are easily explainable in a few minutes to
| the novice, and once they understand it, they can quickly
| (and profitably) incorporate it into their code.
|
| I _wan 't_ there to be a steady drumbeat of these
| improvements that let me write more elegant code, more
| concisely.
|
| Try and find a _single_ python developer who would give up
| their f-strings now.
| adamc wrote:
| Yeah, this. I love Python, and I hated Perl. Even Java
| was a pleasure compared to Perl.
|
| At one time, a trainer was trying to tell us Ruby was the
| new hotness (2009 or 2010, I think). I liked Ruby OK, but
| Python seems cleaner and we stuck with it. I have not
| felt the slightest regret.
| 0xbadcafebee wrote:
| This is the first time in the history of the internet that
| anyone has complained about too much documentation.
| adamc wrote:
| I programmed in Perl 5 for several years. Ugh. That
| language was hard to read, and some of the features (list
| vs. scalar context, for example) were awful. I have never
| wanted to write another Perl program. Capable, but painful
| to maintain.
| make3 wrote:
| I think this comment is super exaggerated. In my experience
| pretty much all features in Python 3 by far are really
| welcome. The only features you're usually not supposed to use
| are very obvious ones, inspect, metaclasses and nested
| comprehensions, which are super uncommon and feel like dark
| magic that you would obviously not want to use, or just shit
| ugly code in the case of nested comprehensions.
| cjohnson318 wrote:
| Yes, I think the general consensus on metaclasses is that
| if you don't already know what they are, then you probably
| don't need to use them. There's some metaclasses in Django,
| but it's pretty easy to see how you're expected to use them
| from examples, and you don't need to _really_ understand
| what 's going on.
| enriquto wrote:
| What's the problem with nested comprehensions? How else do
| you create bi-dimensional stuff?
| pmart123 wrote:
| I agree with this up through Python 3.7. The recent updates
| though seem to be unnecessary or have obtuse syntax.
| pizza wrote:
| This feature could make a lot of code that people write quite
| often a fair amount simpler, though. I'm looking forward to
| this feature quite a bit.
| adamc wrote:
| I don't really agree. I helped steer my organization to Python
| more than a decade ago -- its mix of capability and readability
| made it a great fit, and it remains so. Nothing I saw in this
| made me worried that people would struggle to read it.
| F-strings are great, a huge improvement on needing to say
| .format() all the time, and format was an improvement on the
| original use of % (more descriptive).
|
| C++ is a wholly different beast. Template metaprogramming
| achieves great things, but at significant cost to readability.
| cjohnson318 wrote:
| I think str.format() was an improvement on from % formatting,
| and that the f strings are an improvement on str.format(). It's
| readable, concise, and it's familiar from other scripting
| languages.
|
| I think the advantage of switch statments and pattern matching
| is that you know the scope of the thing you're switching or
| matching on, but you don't have that restriction in
| if/elif/else blocks. There's nothing keeping me from adding a
| condition like, `elif day == "Tuesday":`, that has nothing to
| do with the task at hand. When I see switch or match, I feel
| like I know what I'm getting into.
| asah wrote:
| sorry for the downvote: please propose solutions that allow the
| language to evolve and not stagnate.
|
| example: pylint-type tools that flag old ways of doing things,
| and suggest replacement syntax (e.g.
| https://pycodequ.al/docs/pylint-messages/r1717-consider-usin...
| )
| sireat wrote:
| So 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.
| naebother wrote:
| Maybe 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-gr...
| theptip wrote:
| Does 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 wrote:
| They have a dedicated PEP for motivation:
| https://www.python.org/dev/peps/pep-0635/
| ur-whale wrote:
| And 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 wrote:
| What 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 wrote:
| I 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 wrote:
| Could be x"" for _regeX_ or p "" for _Pattern_
| ur-whale wrote:
| In 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.
| kasperni wrote:
| Java is also in proces of adding Pattern Matching over the next
| couple of releases [1].
|
| [1] https://www.infoq.com/articles/java-pattern-matching/
| bjourne wrote:
| Pretty 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 wrote:
| Your 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.
| bob1029 wrote:
| I 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-match...
| frou_dh wrote:
| Python is strongly-typed. With its built-in type annotation
| syntax and a checker like mypy or pyright, it is statically-
| typed, too.
| pansa2 wrote:
| > _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-ma...
| thomasahle wrote:
| Maybe adding new syntax should require a 2/3 majority or more.
| adamdusty wrote:
| > 34 voters
| pansa2 wrote:
| Is that not a reasonable sample of the 87 core developers
| eligible to vote?
|
| https://discuss.python.org/groups/committers
| magnusmundus wrote:
| It'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.
| pansa2 wrote:
| > _Exactly half of all responders, forming nearly 90% of the
| above majority, are fine with that form being PEP 634._
|
| That half includes those who voted for "accept 634 + 640" or
| "accept 634 + 642", whom I doubt are entirely happy with the
| decision to accept PEP 634 _and reject 640 & 642_.
| magnusmundus wrote:
| My point was that you cannot claim "65% of responders
| opposed this particular proposal". I understand, they're
| possibly not entirely happy. The poll is flawed that way:
| "accept 634" should not mean "reject 640 & 642".
|
| That said, I interpret this part:
|
| > PEP 642's proposed syntax does not seem like the right
| way to solve the jagged edges in PEP 634's syntax
|
| to mean that this is merely an initial spec. Those unhappy
| with the syntax can avoid using it for now, there are no
| breaking changes. It took a couple iterations to refine the
| async syntax too, remember, and (IMHO) we arrived at a
| clean-enough version of it. I have hope!
| zepatrik wrote:
| The 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 wrote:
| Mozilla for a time had a kitchen sink
| (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/k...
| VectorLock wrote:
| Interesting 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
| stickyricky wrote:
| Not 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 wrote:
| Talking about preferences still qualifies as interesting
| discussion.
| paulgb wrote:
| As someone who hasn't been following closely, was the PEG
| parser necessary for pattern matching or is that an unrelated
| change?
| pansa2 wrote:
| IIRC one of Guido's reasons for switching to a PEG parser was
| to enable the addition of pattern matching.
| erichurkman wrote:
| And 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).
___________________________________________________________________
(page generated 2021-02-09 23:00 UTC)