[Python-ideas] Pattern Matching Syntax

Chris Angelico rosuav at gmail.com
Thu May 3 14:57:15 EDT 2018


On Fri, May 4, 2018 at 4:40 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Fri, May 04, 2018 at 04:01:55AM +1000, Chris Angelico wrote:
>> On Fri, May 4, 2018 at 3:18 AM, Ed Kellett <e+python-ideas at kellett.im> wrote:
>
>> > def hyperop(n, a, b):
>> >     return match (n, a, b):
>> >         (0, _, b) => b + 1
>> >         (1, a, 0) => a
>> >         (2, _, 0) => 0
>> >         (_, _, 0) => 1
>> >         (n, a, b) => hyperop(n-1, a, hyperop(n, a, b-1))
>> >
>> > versus:
>> >
>> > def hyperop(n, a, b):
>> >     if n == 0:
>> >         return b + 1
>> >     if n == 1 and b == 0:
>> >         return a
>> >     if n == 2 and b == 0:
>> >         return 0
>> >     if b == 0:
>> >         return 1
>> >     return hyperop(n-1, a, hyperop(n, a, b-1))
>>
>> I have no idea what this is actually doing
>
> It is the Hyperoperation function.
>
> https://en.wikipedia.org/wiki/Hyperoperation
>
> n is the parameter that specifies the "level" of the operation, and a, b
> are the arguments to the operation.
>
> hyperop(0, a, b) returns the successor of b (a is ignored) -- e.g. the
> successor of 1 is 2, the successor of 2 is 3, etc.
>
> hyperop(1, a, b) returns a+b (addition, or repeated successor);
>
> hyperop(2, a, b) returns a*b (multiplication, or repeated addition);
>
> hyperop(3, a, b) returns a**b, or a^b in the more usual mathematical
> notation (exponentiation, or repeated multiplication);
>
> hyperop(4, a, b) returns a^^b (tetration: repeated exponentiation; e.g.
> 3^^4 = 3^3^3^3 = 3^3^27 = 3^7625597484987 = a moderately large number);
>
> hyperop(5, a, b) returns a^^^b (pentation: repeated tetration, and if
> you thought 3^^4 was big, it's nothing compared to 3^^^4);
>
> and so forth.

Oh. So... this is a crazy recursive way to demonstrate that a Python
integer really CAN use up all your memory. Cool!

> While this is really useful to mathematicians, in
> practice we're going to run out of memory before being able to calculate
> any of the larger values. If we converted the *entire universe* into
> memory, we'd still run out. So while it's a fascinating example for
> maths geeks, in practical terms we might as well re-write it as:
>
> def hyperop(n, a, b):
>     raise MemoryError("you've got to be kidding")
>
> which aside from a few values close to zero, is nearly always the right
> thing to do :-)

Got it. Well, I don't see why we can't use Python's existing primitives.

def hyperop(n, a, b):
    if n == 0: return 1 + b
    if n == 1: return a + b
    if n == 2: return a * b
    if n == 3: return a ** b
    if n == 4: return a *** b
    if n == 5: return a **** b
    if n == 6: return a ***** b
    ...

This is a MUCH cleaner way to write it.

ChrisA


More information about the Python-ideas mailing list