# Smuggery: Python 3.10 has match! gasp!

**URL:** <https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942>\
**Category:** General\
**Created:** [May 12, 2023, 7:29pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942 "2023-05-12T19:29:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [May 12, 2023, 7:29pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/1 "2023-05-12T19:29:54Z")

</div>

I've been looking into Python a bit lately because a lot of my friends use it. I was delighted to find that Python's `match` statement is quite similar to Racket's `match` statement. I use `match` a lot, so having it carry over was good news.

Then, out of curiosity, I checked when the feature was added to both languages.

Python: v3.10, released October 2021  
Racket: v5.0, released June 2010 (might have been earlier but 5.0 is the earliest version listed on [Racket: All Versions](https://download.racket-lang.org/all-versions.html))

Python is adorable!

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [May 12, 2023, 7:59pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/2 "2023-05-12T19:59:46Z")

</div>

Actually, match has existed since at least 2005, according to [https://github.com/racket/racket/blob/017d151d5929b49f01d83f9e41995b035cad23de/collects/mzlib/match.ss](https://github.com/racket/racket/blob/017d151d5929b49f01d83f9e41995b035cad23de/collects/mzlib/match.ss) which was the oldest I could quickly find online. If the SVN history goes back further, I might be able to find older with the Git CLI. Anyway, I think it might have been "PLT Scheme" then, too, since 5.0 was the rename to Racket?

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [May 12, 2023, 8:00pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/3 "2023-05-12T20:00:11Z")

</div>

Oh, and ML had it first 🙂

---

<div class="post-metadata">

**Author:** ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)\
**Post date:** [May 12, 2023, 8:06pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/4 "2023-05-12T20:06:30Z")

</div>

You can find the older version control history here: [GitHub - racket/old-plt: The very old history of Racket](https://github.com/racket/old-plt/)

Racket has had pattern matching almost since the beginning in 1995. There's a history in my paper here: [[1106.2578] Extensible Pattern Matching in an Extensible Language](https://arxiv.org/abs/1106.2578)

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [May 12, 2023, 8:20pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/5 "2023-05-12T20:20:40Z")

</div>

I am completely unsurprised that it's been there since before v5. 😁 That was simply the earliest I could find in 20 seconds of searching.

---

<div class="post-metadata">

**Author:** ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)\
**Post date:** [May 12, 2023, 8:59pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/6 "2023-05-12T20:59:31Z")

</div>

Racket’s `match` is derived from Scheme 84’s, which I started in 1984.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [May 13, 2023, 1:45pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/7 "2023-05-13T13:45:51Z")

</div>

Please no smuggery. 😉

Here's a bit more context on why it's less attractive to have `match` in Python.

**A `match` statement maybe isn't a good fit for Python, at least not as much as `match` in Racket.**

Racket and other FP languages usually have `match` _expressions_, whereas Python has a `match` _statement_ (which is understandable since Python is primarily an imperative language). Also, different from Racket, Python in general uses a single scope for everything defined in a function or method. Therefore, a `match` statement in Python isn't a good fit for the language, different from the `match` expression in Racket.

Here's how it plays out. First, let's see a Racket example. (I'm not going into details, I only want to show how Python differs.)

```scheme
#lang racket

(define (func)
  (define a 1)
  (define b '(2 3))
  (match b
    [(list a b)
     (displayln "matched!")])
  ; 1
  (printf "a = ~a~n" a)
  ; '(2 3)
  (printf "b = ~a~n" b))

(func)

```

The `match` expression (used here like a statement) defines it's own scope. The values `a` and `b` in the `match` expression don't affect anything outside the `match` expression.

On the other hand, this is how it looks in Python:

```python
def main():
    a = 1
    b = (2, 3)
    match b:
        case (a, b):
            print("matched!")
    # 2 (was 1)
    print("a =", a)
    # 3 (was (2, 3))
    print("b =", b)

main()

```

Here, the `case` assigns new values (2 and 3, respectively) to the variables `a` and `b` - and this change is visible outside the `match` statement!

**Python has become a complex language, and not everyone wants it to become even more complex.**

Despite the superficial appearance, Python has become rather complex over the years. For example, look at the currently supported [special method names](https://docs.python.org/3/reference/datamodel.html#special-method-names). I'm not going into details, but many people (me included) think that Python has accumulated already too much complexity, so it wouldn't be advisable to add even more, for example in form of the `match` statement with its own "sub-language" rules. Larry Hastings [explains it well](https://discuss.python.org/t/gauging-sentiment-on-pattern-matching/5770/21). Here's [some more discussion](https://news.ycombinator.com/item?id=26080760) along these lines.

Note that this is a different line of thought from whether someone personally likes the `match` concept. For example, I do like `match` in Racket and Rust, but I'm still skeptical whether it should have been added to Python.

---

<div class="post-metadata">

**Author:** ![dstorrs](https://avatars.discourse-cdn.com/v4/letter/d/898d66/32.png) [@dstorrs](https://racket.discourse.group/u/dstorrs)\
**Post date:** [May 14, 2023, 12:11am UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/8 "2023-05-14T00:11:05Z")

</div>

> [@sschwarzer](#):
>
> Please no smuggery. 😉

🎶 It's my ~~party~~ thread and I'll ~~cry~~ smug if I want to, smug if I want to, oooh... 🎶 (Sorry, couldn't resist.)

Yeah, after reading through the Python documentation and playing around with it a bit I see what you mean about complexity. On the other hand, it's all pretty familiar. It's basically "Let's take Perl and make whitespace significant, get rid of the punctuation and associated semantic value, context awareness, AUTOLOAD dispatch, and default value return, then make OOP class data public by default, then jam in a bunch of stuff from Lisp and call it a day."

.

Being more serious and less smug: I've known for a long time that Python was impressive, I've simply never gotten around to learning it. Now that I'm looking at it, I see that it has earned its enormous market share. It's easy to get started with and it's got a lot of depth, plus it has some excellent libraries and frameworks.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [May 14, 2023, 2:35pm UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/9 "2023-05-14T14:35:38Z")

</div>

> [@dstorrs](#):
>
> Being more serious and less smug: I've known for a long time that Python was impressive, I've simply never gotten around to learning it. Now that I'm looking at it, I see that it has earned its enormous market share. It's easy to get started with and it's got a lot of depth, plus it has some excellent libraries and frameworks.

I agree! 🙂

Python certainly has its downsides, but if you avoid the more obscure stuff 😉 , it's quite straightforward and expressive. There used to be the expression for Python "pseudo code that actually runs." (I think it still holds, but I think the expression is nowadays used less than it used to be.)

---

<div class="post-metadata">

**Author:** ![aanastasiou](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/aanastasiou/32/1126_2.png) [@aanastasiou](https://racket.discourse.group/u/aanastasiou)\
**Post date:** [May 23, 2023, 10:02am UTC](https://racket.discourse.group/t/smuggery-python-3-10-has-match-gasp/1942/10 "2023-05-23T10:02:36Z")

</div>

And could I also add:

1. Python does not (at the moment) have a way of doing `list-rest` (If you try to capture more than one "multiple" terms using more than one `*` you get a "multiple starred names in sequence pattern" syntax error)

2. Python does not (officially) have tail calls. So although you can match, you still have to write additional code to handle recursion when required. With Racket's `match` you can recursively match-\>evaluate and it is all viewed as one (maybe long) function invocation. The result simply flows.
