Skip to content

Instantly share code, notes, and snippets.

@apg
Created May 22, 2014 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save apg/5b86abd86fcaefc8607f to your computer and use it in GitHub Desktop.
Save apg/5b86abd86fcaefc8607f to your computer and use it in GitHub Desktop.
match thing

Many years ago, Marius Eriksen wrote asome code to do pattern matching in Python. I quickly forked the code and had envisioned expanding upon it by "fixing" the interface, and making it possible to dispatch functions with it like the Erlang example he provided.

Like most of my ambitions of this type, it never happened, and despite the fact that I had forked the repo it went completely untouched. In the mean time, though, I had played with with, on numerous occassions, experiments that were fueled by my inability to properly extend the language without diving into it's internals.

But, recently, I had a little bit of time to spare while waiting for a meeting, and so, I made an attempt at providing pattern matched function dispatch to Python.

With it, Marius's example looks like this:

@when("/", _)
def handle(ign):
    raise InvalidResource()

@when(C/0, "PUT")
def handle(path):
    create_new_resource(path)

@when(C/0, "POST")
def handle(path):
    update_resource(path)

@when(C/0, "GET")
def handle(path):
    retrieve_resource(path)

@when(_, _)
def handle(ign, ign):
    raise InvalidRequest()

We could definitely get closer, and avoid capturing the wildcards, as in the last clause, but I do that now for a particular purpose:

@when([])
def listlen():
    return 0

@when([C/0])
def listlen(x):
    return 1

@when([C/0, _])
def listlen(xs):
    return 1 + listlen(xs[1])

Here, we destructure a list into it's head C/0 and it's tail _. Since there isn't a way to say "capture the rest of this list," I simply utilize the fact that a _ can capture it all, but then save it off. A better solution would simply be to create another capturing parameter, say R or something which does this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment