Hacker News new | past | comments | ask | show | jobs | submit login
What Is the Switch-Case Equivalent in Python? (pakstech.com)
88 points by Sami_Lehtinen on April 3, 2021 | hide | past | favorite | 121 comments



"Pattern matching is the switch-case equivalent in Python 3.10 and newer"

Well, yes, but actually, no.

A switch operator, at least in most other languages, uses comparison to select a branch. Only comparisons are performed (either with each branch or optimized for direct access) but no other side effect. Pattern matching, as with other languages too, tries to 'match' the variable to the pattern. If it succeeds, then the branch is taken and the variables (if any) are assigned, which in python means that they are assigned to the whole current function. This is a big side effect.

And that's the main problem, the variable constants. Once you understand the issue it is relatively easy to fix, but for a newcomer this will probably be a few minutes of searching and debugging.

Python don't have a switch statement, at least not yet, pattern matching is just another similar feature that can be adapted to work similarly, like the chain of elifs and the lambdas dictionary. However if you want to say otherwise...at least give the warning of the constants at the beginning, not at the end.


> If it succeeds, then the branch is taken and the variables (if any) are assigned, which in python means that they are assigned to the whole current function. This is a big side effect.

Assignment is not generally a side effect, and even if it were, matched branches in a switch statement potentially having side effects or externally visible variable (re)assignments is normal in languages with switch. (Ironically, match-based assignments visible outside the pattern match expression aren’t typical in languages with pattern matching, so actually the behavior you describe is more typical of switch statements than pattern matching, which is typically a block-scoped expression with local bindings.)


Python doesn't have block-scoped variables?


Variables in Python are generally function-scoped instead of block-scoped, because the latter doesn’t work well with implicit variable declarations.

However, there are some special cases where variable scope is smaller than a whole function, e.g. within list comprehensions.


>However, there are some special cases where variable scope is smaller than a whole function, e.g. within list comprehensions.

Or we can think of a list comprehension as a function doing a loop/collect under the scenes.


No.


Nope! And unlike in JS theres no opt-in to them (let/const). But still js=bad python=good.


>But still js=bad python=good.

I don't really understand the logic behind this comment. You're pointing this out like it's some contradiction in people's opinion.

But it's not like "block scope" is the one and only determinant of whether a language is good or bad, so lack of that alone would negate the above statement.

js could be bad and python good, regardless of whether Python lacks block scope. Doubly so since js also lacks it by default, and has only sort of tacked-it on with let/const.

But the even better answer is that both are languages with different strenghts and tradeoffs, that JS did have several bad design decisions early on, that both have evolved, and x=bad, y=good is a fanboi reaction, not a developer reaction.


The rules for var and "hoisting" are so horrible that let and const are a justified language complication; now JavaScript variable scoping is decently usable. On the other hand, Python can afford to spend its language complication budget on something more useful than specialized mechanisms to end variable scope.

Since JavaScript tends to have many more unnamed functions defined in the middle of long functions, compared to Python (which tends towards named functions, classes, or comprehensions), block scoped variables (or more precisely simple and rigorous rules about scoping) are much more useful and important in JavaScript than they would be in Python, since if there is a part of a Python function where some variable shouldn't be visible it's probably a long and complex function which can and should have its variable scopes refactored apart.


Fanboi discussions and reactions are the norm in the Python community. But this what you get when maybe more than half of your community is made of non-devs, who never touched any other language and never will.


>But this what you get when maybe more than half of your community is made of non-devs, who never touched any other language and never will.

And this is supposed to be bad because?

They had a problem, used a language to solve it, they've solved it, end of story.

If they're satisfied with their solution, and it works for their purpose (and for their companies/organizations purposes), who is to day it's not OK?

Perhaps they are professionals doing a job, not dilettante nerds trying different languages and idioms for fun...


Ignoring the snark and elitism in this comment, it’s unclear to me to why even “actual developers” must touch other languages, if python satisfies their needs.

Programming is a tool, with the goal being building things that help the user.


==


You can override a comparison operator which means it’s potentially unbounded (not simple) exactly the same way as matching is.


but

1) it's "opt in" (you need to explicit implement the dunder method) and

2) it's only for specific classes, you cannot change the behavior of 1 == "one"


But you can't do that for pattern matching either.


> it's only for specific classes, you cannot change the behavior of 1 == "one"

More clearly because builtins are protected from monkey-patching, you can’t change the behavior of == where both operands are builtins. “Only for specific classes” implies the scope of applicability is much narrower than it is.


In practice I never try to replicate switch/case in Python but prefer what the author lists as "Dictionary" method.

Namely matching an item in a dictionary based on either key or perhaps more advanced matching a value inside the dict. Maybe even using re to match it.

Either way, I find using a dictionary is the most Pythonic and clean way to do it. Defining the actions first, how to match them and anything else they might need.


I believe this is more generally known as table-driven methods, and I also enjoy using them. They feel more ergonomic than conditional statements, and they're also more flexible—you can dynamically modify the conditions and actions by modifying the data structure which contains them.


I can't believe languages are still adding switch/match statements (as opposed to expressions). Has it it not filtered through to everyone yet that everything that can possibly be an expression should be?


This idea was briefly addressed in PEP 635 [0]:

> _Statement vs. Expression._ Some suggestions centered around the idea of making `match` an expression rather than a statement. However, this would fit poorly with Python's statement-oriented nature and lead to unusually long and complex expressions and the need to invent new syntactic constructs or break well established syntactic rules. An obvious consequence of match as an expression would be that case clauses could no longer have arbitrary blocks of code attached, but only a single expression. Overall, the strong limitations could in no way offset the slight simplification in some special use cases.

[0]: https://www.python.org/dev/peps/pep-0635/


Python makes a conscious decision to embrace statement-oriented code, for better or worse. There's a case to be made that it makes things more readable in an intuitive sense, while of course it also opens you up to more statefulness/side-effects. If nothing else, I respect the dedication to consistency.

To give a concrete reason: Python's significant whitespace makes nested expressions much trickier to write/parse


Either everyone involved with language design has never heard of Lisp or there are inherent tradeoffs with "everything that can possibly be an expression should be" that you are either ignoring or wilfully ignorant of in order to score internet points.

I know which one I would bet my money on.


> Either everyone involved with language design has never heard of Lisp or there are inherent tradeoffs with "everything that can possibly be an expression should be" that you are either ignoring or wilfully ignorant of in order to score internet points.

Entirely seriously, what are the trade-offs? I've heard general defences of it, for example nchammas's quote from van Rossum in a sister post to yours, but they all seem quite general—"it'll complicate things", but in a way that seems only to boil down to "it's unfamiliar and I don't like it." Which, to be fair, is van Rossum's prerogative to say—but it doesn't seem persuasive in light of general language design.


Some constructs are more natural (e.g. easier to read and write) as statements, others as expressions. It's never good to have rigid rules about programming style as each problem domain is different.

There are many situations where you want lots of branching because that's the problem domain, and trying to hide the essential aspect of the problem domain isn't helpful for code readability or maintainability.

If you are writing an interpreter, case statements are a natural thing. Yes, you can write that intepreter with expressions that are statements in disguise, but just because something can be done doesn't mean that it should be done. An interpreter is just a dispatcher waiting for some trigger from the outside and then firing off a command handler depending on the trigger. Just like a UI. GUIs are are also natural things to write with event driven patterns. If user clicks on box A, then do X, if User clicks on box B, do Y. That is a big case statement in disguise except the underlying framework handles that for you and you just write the code for X and Y. But if you didn't have that UI toolkit doing heavy lifting you would find yourself writing event loops and case statements to implement it as the most natural (non-ideological) solution.

Similarly, there are many situations where you want to handle exceptional conditions separately in a clear way that allows you to easily understand what the exceptional logic is and change it without touching the main processing flow at all. It all depends on the problem domain. Or the problem domain may require feedback where the handler tells the dispatcher to change the dispatch algorithm.

On the other hand, fluent APIs work well with streams of data that are processed sequentially. There the natural approach is to apply a sequence of functions to the stream. You want to avoid lots of nesting of case statements as the code would be ugly.

It boils down to minimizing complexity. You could write that event driven dispatcher as a function that takes as its inputs all the possible callbacks and the state of the world and spits out a specific callback. But that would be a more complex program that is harder to read and write, and thus is more error prone, regardless of the fact that in theory it is easier to refactor and unit test by dropping in a different function. In practice, it is not easier, it is harder. So when someone like Guido says, "it will complicate things", no it doesn't boil down to "I'm unfamiliar and don't like it", what it means is "I've spent a couple of decades writing code, have been up and down this road more times than you have, and I know it's a harder road to travel".


> Some constructs are more natural (e.g. easier to read and write) as statements, others as expressions.

Yes but imo, Haskell (which has do notation) and Rust (where most things are expressions, but you still write them as expression statements when writing imperative code) actually have solutions to this problem. On the other hand, Python has a sharp divide between expressions and statements, so it needs strange duplicate forms of statements as expressions, like ternaries (if expressions but in a really weird order!) and lambdas (function expressions but your body is just an expression!)

> So when someone like Guido says, "it will complicate things"

Yes, it would complicate Python, which already has this division. In other languages, it's perfectly simple.


In Rust, some expressions (e.g. `while`) always evaluate to `()`. What’s the benefit of that compared to making `while` a statement?


I can't think of a benefit (besides consistency, which might be nice for some macros) but is it doing any harm?

And, in the future, if Rust does get some kind of return-via-break for while loops (like it has for `loop`s) then there'll be less syntax to change.


Python has some non-expression statements and you wouldn't be able to use them in match expressions.


Sure, in an existing language like Python, it can be a poor fit to make everything an expression, but what are the tradeoffs for a new language? For example, Rust makes (almost) everything an expression, and I don't think it's suffered at all for it.


>Has it it not filtered through to everyone yet that everything that can possibly be an expression should be?

No, as it's just an ideology, and not some absolute engineering truth.


Hey, it's still a new idea, only introduced in 1958. Give people time to adjust!


I'm really worried for the long term health of python.

The philosophy of python is there should be only one pythonic way of doing things.

But more and more features are being added that give too many options with minor benefit

How is case different from the elif pattern? What does the walrus operator do that we really need.

Each one of these things on their own if fine but I'm worried together it's going to make python increasingly idiosyncratic to each developer and, consequently, harder to read.

Python's Zen beat out perl's TMTOWTDI. But python seems to try to be more and more like perl with every release: more appealing to hackers playing code golf than long term readers of the code base


> How is case different from the elif pattern?

Pattern matching is often conflated with switch-case by people who are unfamiliar, because pattern matching subsumes switch-case, but they're very much not the same thing. Structural pattern matching is much more powerful than checking a series of boolean conditions. It allows you to not only check the structure of a value, but bind parts of that structure to variables. It allows you to express logic that would would otherwise be fairly complex in a straightforward and transparent way.


> If the implementation is hard to explain, it's a bad idea.

> If the implementation is easy to explain, it may be a good idea.

Pattern matching is extremely complex, and for what?


Python already has (limited) pattern matching. Example:

    for foo, (bar, baz) in nested_tuple_list:
        ...
This works as expected. The current 3.10 implementation is just half-baked. They should have expanded the existing pattern matching facilities (added support for data structure destructuring).

Presumably then you could just have used the existing walrus operator inside the already existing if-else constructs.

That would have been the obvious path of least surprise. What we got instead seems inadequate.


So you would turn something like this:

    match command.split():
        case ["north"] | ["go", "north"]:
            current_room = current_room.neighbor("north")
        case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]:
            ... # Code for picking up the given object
In to this:

    if (["north"] | ["go", "north"] := command.split()):
        current_room = current_room.neighbor("north")
    elif (["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"] := command.split()):
        ... # Code for picking up the given object
And the walrus operator would assign to 0-many values as required? It kind of breaks it's current meaning and makes the lines very complex, I don't think this version would be more liked...


Yes. The second version is "pythonic" and follows the principle of least surprise.

The first version is certainly cleaner, but introduces, effectively, a new DSL sublanguage.


The second version also effectively introduces a new DSL sub-language, it just puts a walrus operator at the end of it.

I agree the matching is complex, you only have to see what a portion of the grammar file it takes up: https://docs.python.org/3.10/reference/grammar.html

But embedding the match constructs inside existing Python symbols wouldn't reduce the amount of new grammar it would require.


The walrus operator is not the point; the existing constructs should be expanded, that way things make sense and are composable.

E.g., pattern matching of this sort

    for ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"] in list_of_get_commads:
        ...
IMO should have "just worked".

But now we have two different and incompatible versions of pattern matching in Python.


That's not an existing construct, it's a LHS assignment language like the match statement but it's embedded inside a for-loop.

Which means you have to implement all the grammar of the current match and it restricts to only works on iterables.

How would you implement this for an object that isn't iterable?


The example is misconceived to begin with? Why are you hard coding an interactive fiction game in Python? You should make an interactive fiction engine, of which there are already a million examples, and then write the script in a language made for IF, not Python.


I took the example from the PEP itself, feel free to list out a different one.


Appealing to nothing but the zen of python is not an acceptable argument.

Pattern matching is not (necessarily) extremely complex as it exists in a multitude of languages these days. Powerful does not automatically imply complex.


Acceptable to whom?

Anyhow, read the PEP. It is an extremely complex new language feature.


To many in the core team, for one. It’s a cutesy easter egg at best not a mission statement.

I’ve read the pep. The nature of peps are complete by design. The concept is not overly complex especially since it exists in a number of other languages.


I would say it's much more powerful than switch-case, but it's only moderately more ergonomic than elif. The reason for the former being that switch-case only ever checks exact equivalency; if you need to do anything slightly more nuanced, you have to bail out to something more flexible.


Yeah, Perl’s been there a long time ago. Initially, Perl did not have a native switch/case statement. However, early on Perlers started to obsess about emulated switch constructs and so Perl 5.10 shipped given/when which was supposed to become the language‘s official switch implementation. But it never really quite took of. While part of it was due to a subtle bug I‘d argue nobody actually needed it. 99% of the time if/elsif/else is good enough and otherwise you might want to consider a dispatch table if the number of cases is large. Beyond Perl this is true in most languages: If you find yourself in a situation to need an extensive if/else chain and to wish for C-like switch/case you’re either writing a parser or you should really rethink about your software‘s architecture (maybe in terms of OOP).


>The philosophy of python is there should be only one pythonic way of doing things.

The philosophy of anything (python, unix, etc) is usually just cargo cult early bogus idealism.

What happens later is that reality and pragmatism come into play.

People don't want simple languages, people want more features.


The walrus operator was definitely a mistake. But type annotations, pattern matching, attrs/dataclasses, and f-strings are significant improvements.


See though, this is the issue. What you see as a useful or mistaken feature is likely a different set to another user, just as we’ve seen above.

I think it’s a mistake to defer to the zen of python without considering the PEPs themselves which do discuss trade offs. (I’ll note that you didn’t make that claim but GP did).


Tbh I think a consensus of expert Pythonistas would agree with me. Walrus only got through because of the "dictatorship".


Perhaps :)

That’s not a hill I’m willing to die on but I agree with the positives from your list.

And the small handful of times I’ve used walrus have been nice, but not game changing.


Language features of this type should be nice and not game changing. It's how spoken word languages evolve. If every change was game-changing, it'd only be a few mutations until a dialect became a language in its own right. In reality, you get countless dialects frequently with features that eventually die off and new languages rarely and only in the aggregate.


Seems to me the 'sweet spot' for a language is a careful balance of continuing to evolve - slowly, carefully - and to not become so large as to 'not fit into one head'. Python3.9 is not yet at the 'too big for one head'; but 3.xx could be. Perhaps old-style features need to be removed, and only available via some sort of "from __past__ import old-feature-set"


It's hard for me to separate a language from what it is used to accomplish, and from that perspective, Python has been far too large to fit in one head for a good long time. Perhaps that is why I don't find any compulsion for language purity.


> too large to fit in one head

is it? I don't think the core language is that big. The libraries are big of course.


An example of core language complexity: if asked, could you explain what all of these do?

https://twitter.com/raymondh/status/1280988785841278976


The only one I didn't know was text_signature.


I'm very curious why is this downvoted?


They could just deprecate without removing.


>Walrus only got through because of the "dictatorship".

Well, then again I wouldn't consider anybody a more expert Pythonista than Guido.


I can think of some.


Such as?


I don't want to get into that kind of argument, but if you've been in python for a while you can probably think of people.


Can you explain why you don’t like the walrus operator? I personally love it.


- Languages should only make special syntax for very common or very important needs. Neither applies here.

- It violates the longstanding Python rule that assignments don't escape the enclosing scope.


> It violates the longstanding Python rule that assignments don't escape the enclosing scope.

But doesn't that violate the longstanding Python rule that A Foolish Consistency is the Hobgoblin of Little Minds ?


The trick is tell when striving for consistensy is foolish and when it isn't. Otherwise you would always be able to fall back on this quote to justify creating unuseable code/frameworks/projects/languages.


No. Assignment leaking into enclosing scope is a bad idea.


Don’t assignments already escape scope?

if True: x = 1 print(x)


`if` blocks don't make a scope. Comprehensions do.


The "as NAME" phrasing already existed. No need to invent a third confusing colon syntax to assign variables.


>The walrus operator was definitely a mistake.

Was it tho? It's one of my favorite improvements, and has no actual downside.


Right there with you!

I get it, languages have to grow or fix mistakes. I read about Python long before I attempted to program in it and even I (not a language designer or that special) knew that their handling of division as being integer division as a default was a long-term problem that would eventually be changed one way or another. And so it was.

I absolutely agree on the walrus operator. It's too terse and while on its own it only makes two steps into one, it's not used alone, making each line of code with it that much harder to unpack.

I don't know enough about pattern matching but my feeling is that we got along without it so far ...


> The philosophy of python is there should be only one pythonic way of doing things.

That ship has sailed more than a decade ago.

(And if we're on a crusade to make Python pythonic again, let's start with the bigger fish - like the sync/async function distinction. Somehow Python managed to fall into the red/blue function trap the hardest.)


> the red/blue function trap

What should have been done here?


Python doesn't need a special keyword to distinguish functions that 'yield' from those that don't. Why should async functions be different?


I think it’s pretty wild that people are worried about the addition of a coding pattern to a language. What a thing to stress about. Nobody’s taking your Python away from you. I promise everything’s gonna be ok.


the "problem" (not for me, I personally am pretty "meh" on the feature) is that now you'll have a new pattern to read (and decode) in the others code.


> The philosophy of python is there should be only one pythonic way of doing things.

Thiiis really hasn't been my experience with the Python community. Every place I've worked on a Python codebase has done it a different way, and none of them have agreed on what is "pythonic".

Each team has claimed that _their_ approach is the most python-y way to do it, but they've all celebrated Python as not being "restrictive" like "other" languages. It's really weird.


> Thiiis really hasn't been my experience with the Python community. Every place I've worked on a Python codebase has done it a different way, and none of them have agreed on what is "pythonic".

Exactly my experience from day one. It's a laughable statement that the Python community keeps repeated with almost no basis in reality.


Compared to C++ and Perl I find python code to be really consistent across projects. I agree the language isn't perfect at it but why do anything to make it worse?


True, because that was already a hard problem by itself. And it got even worst with the recent additions.


Now people are getting worried Python may become like Perl :).

With all due respect to your (otherwise perfectly valid) argument, "there's more than one way to do it" was never a real problem with people using Perl. I dare say it's fully possible to write difficult-to-read code in any language.

Perl was expressly never interested in erecting glass walls and force people this or that way. Not saying that this is good or bad. But it's the way the people who are making Perl want it.


Too bad ruby didn't take the place of python for popularity but I still see strong fan base around ruby.

Maybe people got into python when Google took it for a serious use just like people got into git because of Linus but figured it wasn't the best tool a decade later but the ecosystem is already there it is too late to swap.


The Zen is not inconsistent with there being different obvious ways to do different, closely related things, and Python has always had those.

The Zen is against alternatives for the sake of alternatives, but not for facilities focussed on different use cases. Though as the use cases get more finely divided, the difference is less peeceptible.


So what is the current one and only one pythonic way when you need a switch statement (like having a lot of cases to handle). I see two possibilities:

1.a lot of 'if'-statement 2.using a dict and the value is a function you call if the key matches

Or what else?


There's one that's even closer to c-like switches: a list/tuple of functions or values, indexed by a small int. If you're feeling extremely cheeky, it can even handle negative cases. You'll have to implement fallthrough yourself, though.


> There's one that's even closer to c-like switches: a list/tuple of functions or values, indexed by a small int.

That sounds like a desperate plea to get stuck with a bug-riddled unmaintainable mess of a module.

If all you want to do is pick one of a finite set of possible code paths, it is never a good idea to generate a hash to pick from a map/array.

Even chained if/else if statements are cleaner than that mess.


I've seen it used in ways that make sense. They were small and well-contained, and definitely didn't involve computing a hash.

For a not-small example, if you want to switch on an ascii character in a parser, you can make a 256-element list to implement your jump table, and index into it with ord.

If you're performance-minded enough for this to make a lick of sense, you'll take care to only build the jump table once.

And yeah, chained if/else is cleaner because it's the only tool that the language provides. The GP was asking for alternatives. They exist, but you'll hate them.

Granted, you can speed the 256-long if/elif mess up with a binary if/else tree 8 levels deep. But it probably won't beat the jump table.

If you truly find this upsetting, know that it's a practice that results from the language not supporting a switch statement.


I'm not sure that the second option is a very pythonic way to do it, but that's subjective of course. I'd imagine the original commenter views using a lot of ifs and elifs as the pythonic way to do it


I have used this dict solution before in scripts and I am not proud of it.


Why not? What’s wrong with this pattern?


Not the parent commenter, but I use that pattern all the time, mainly to match CLI flags/args/options to an action.

Say you have a program like "docker-compose". It has multiple subcommands. Each subcommand is a dict string key and the appropriate action to take is its value, a callable. This also plays well with argparse's parser "choices" argument.

The by far biggest downside is then that all callables mustn't take arguments, or take all the same ones. You cannot dispatch to a callable and dynamically assign what arguments to call it with without losing the prior benefits. Then it gets awkward (like having to throw around args and kwargs all over the place). But up to that point, I find the pattern useful in this case.


Same. The only useful addition was type hints.

Now, every two releases they add a "language feature". Some library maintainers jump in the bandwagon, and WOOSH! : half the ecosystem depends on CPython to run. Bye Jython, Cython, PyPy, Micropython, etc and bye the code analysis and code transformation tools : all outdated until more funds or voluntary dev are willing to fix them

In an ideal world, the community should fork Python 2.7, rename it and add type hints. But that's too late, all the dev time was spent on making libraries compatible only with some recent versions of CPython


And another person might not care at all for type hints, consider them detrimental and against the spirit of pure dynamic Python, and ask for their favorite feature (e.g. async, unicode handling, whatever) to be the "one" feature "they should have added".


I had said this some weeks ago, in reply to a tweet by Guido:

https://mobile.twitter.com/vasudevram/status/132736428179752...


My perspective on this is totally different. I don't like python because I find it to be a simple language. I like python because it's powerful, expressive, flexible, and gets out of my way while I express my intent. I quite like rust as well (for different reasons), and after using pattern matching in it, I am so excited to see it in Python. I can't think of a single change to the language that has been made that I would consider questionable, but I keep hearing complaints about them. Nothing specific to the features themselves though, the complaints are less targeted about how specifically this feature does not belong in the language as a whole, but just general noises about how peoole are worried about changes. It's quite tiresome, I must say, to have it come up in literally every discussion of Python on this forum.


I too am getting tired of having to tell people to make sure they fully read and understood my point before replying. Just had another such incident recently. But bigger point is, there is such a trend to make fly-by comments, maybe with the aim of showing off or putting down the person to who they were replying. IOW, pretty much trolling, even if done unconsciously. Or just mental laziness.

Anyway, sick of arguing about such meta points. That is not what I come to HN for. I come for intelligent discourse via which I can learn from others' experience and share mine.

I'll just end by saying that I made specific points in that Twitter thread, such as BDD and RDD influencing the language's direction undesirably. To me, that is specific enough a complaint. A language is much more than just a bag of features. YMMV.


It seems that your comment was targeted towards me, but it failed to desribe my behavior at all, so I'm left not totally sure that it was targeted at me. If so, I don't know why you have the impression that I didn't read what you wrote (even you Twitter thread) or that I'm somehow trolling. You have no specific complaints whatsoever here or in your Twitter thread apart from complexity and implying that new steering committee are just trying to pad their resume. How are generic insults specific criticism?

How do the language features not fit? What does "influence undesirably" actually mean? What language features specifically have been added that do not fit, and how have they made the language worse or harder to read or use? That would be an interesting conversation to have.


You have said multiple things compactly in a couple of paragraphs in your above comment. I think at least one or two are wrong, or at the very least, misunderstandings or misinterpretations of things I said - and said in pretty clear and simple language, so it surprises me that you got them wrong. But I don't want to reply right now, because I want to check well your replies vis-a-vis my statements, see who I think is right or wrong, and why, point by point, and then give one single consolidated answer, and also want to revisit my tweets to GvR and recollect what specific background incidents I saw, motivated me to make those statements. I only half recollect right now, since it is a while. But I know there were some reasons, because even if they were my impressions, those were on the basis of facts I had observed.

But one thing I can say right now is that you are wrong on two points: it was not insults[1], and it was not directed at the steering committee.

[1] Saying that something I said is an insult, without clearly understanding it, is itself an insult - by you, to me :) Do you really think I have nothing better to do than go around insulting Python people? Wrong! Heck, I am one of them. Although not on the core team, I have done a fair amount of work in the Python ecosystem, outside of the core language, have blogged a lot about Python (with many programming example, got consulting and training work directly attributable to my blog and my published Python software - the clients said this), and have published a couple of articles about Python in sites and magazines. I've also consulted to companies on Python and trained people and orgs on it.

Those two points you were wrong on (what I said just above the footnote "[1]") are clear from my tweets themselves. So you clearly have misinterpreted, or not read the tweet thread fully. An irrefutable fact: there are at least 9 tweets in that thread, apart from GvR's original one at the top, with many by me, and two or so by Cameron Laird, another veteran Pythonista, who is much more known than me (to some people), for many more years than me, for all his work, including tons of articles, and getting a community award. Check them out, including his thanking me for "that cogent distinction":

https://mobile.twitter.com/Phaseit/status/133025441131101388...

Some of your statements clearly show you either did not read or did not grok some simple points I made in them.

For example, you repeatedly talked in both your first and second reply to me, questioning me on specifics of what language features and their overall fit I thought were wrong, although I have not said a single word in my tweets there or comments here, about any specific feature being wrong or not fitting. (I only talked about other points, like RDD and BDD, and overall language complexity, caused by steadily adding many features to the language. (Cameron later agreed on that, too, in a tweet, after I clarified a point of mine he got wrong.) And you don't get to unilaterally decide what arguments about Python are relevant. If so, I can think the same. (As in, "It's, like, just your opinion, man".) If you keep insisting on questioning me on language features and fit, when my arguments are about other issues, then you are clearly wrong, misunderstanding me, or trolling.

More complete answer after a while. in fact, I've already said many of my points above, but will add any needed others.

I know my answer here was long, but I claim Pascal's Amendment on that :) Making it more concise or better worded, needs more time, which I don't want to spend on this matter right now.


You don't like it because it's simple? I can somewhat relate, but imagine if everyone adopted that mindset. The world would be a complicated, toxic mess. Simplicity is beautiful!


looks around

To my eyes the world does look like a complicated toxic mess. YMMV.


Sometimes simplicity can be harder to achieve than complexity.



I love how Scala does case match with case classes. You can essentially unpack the attributes of a case class and match on them and put additional guards. Example:

bob match {

  case Person("bob", _) => println("hi bob!")

  case _ => println("I don't know you")
}

I think its important that match returns something so you can use outside of a function which this doesn't do.

val greeting = bob match { ... }

I thought it would be a fun exercise to write case classes in python, kind of like an improved immutable data class with a match that returns.

https://mleverything.substack.com/p/scalas-case-class-in-pyt...


the "problem" with scala and case classes is that it's very cumbersone when you have case classes with 30+ fields (and you'll have it, expecially if they came from some SQL table) and you want to match only a sigle field.

as they are positional-only - and you also need to specify all the other placeholders, makes reading the match very difficult


In the proposed case then why not just:

    case x:Bar if x.foo = ... =>

?


“ It will take a long time until any library code can safely adapt this new functionality since Python 3.9 will reach its end of life approximately in October 2025”

Not true - for example, Black had been requiring python 3.6+ even before 3.5 and older were fully deprecated / unsupported.

Just declare the minimum version your library requires in setup.py and let users decide.


So switch like statements and branched execution are the enemy of caches and especially in the light of recent CPU predictive execution vulnerabilities I guess that is not an ideal syntax. What’s a better way to guide the programs flow based on some input?


Looks powerful, but really messy and full of corner cases and gotchas. I hope they rethink this before releasing it as definitive.


Looks like they were warned about those, and they decided, we don't care, let's just ship whatever.


There’s only 1 month left before the 3.10 feature freeze. I’d be surprised if the `match` statement gets anything more than minor tweaks before it’s released.


Random question.

What is meant to be the benefit of not explicitly writing down types in python?

I have used C, C++, GL, and C# most of my career, but recently I have been helping a friend of mine who is learning to code with her python assignments. Things still have types when the code runs, and type errors can cause all sorts of bugs and problems, but the types are not actually written down by you in the code so u have to remember them all. It just seems to add so much more mental load on the programmer + potential for weird hard to find bugs not being caught by compiler and slipping under the radar. It seems objectively worse to me. But I assume there is supposed to be some benefit. What is it supposed to be?

PS Bonus comment: whitespace controlling the flow of the program? Lets make characters that are invisible really important to how the program runs. Thats just plain dumb, that could only be the result of a weird fetish of the originator of the language.


  What actually happens is that the variable REGION_EU will now contain the string "NA" and the case will match!
Isn't this the kind of unintuitive behavior that php got criticized for all this time?


One of the biggest strengths of switch statement, falling through to the next case, unless there's a break, is missing. Of course, I can't think of a good example right now, but I've used it.

Of course, I've also used switch statements in do { .. } while (false), so maybe I just need to be voted off the island.


Falling through case statements bydefault has been the cause of so many bugs over the years.

Fall-through can be a useful behaviour, but it's definitely a foot-gun.



Breaks are always automatically added? Well that sucks, It can be very useful to do one thing for several cases in a switch statement.


Just for fun, and not meant as an exact match (pun noticed :), I had written a simple simulation of C's switch statement in Python, a while ago:

Simulating the C switch statement in Python:

https://jugad2.blogspot.com/2016/12/simulating-c-switch-stat...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: