It’s just data

Pattern Matching

Simon Johnston: The difference I see is that stackless is an enabling feature of the VM, that we will still need the language-level primitives for message send/receieve I see in Erlang and then library support for managing local and remote distribution.

The “secret sauce” is pattern matching.  Things like “if these conditions are met, this code fires, with the following variables set”.  With Erlang, this metaphor is everywhere.  Function calls are an exercise in pattern matching.  Database queries are an exercise in pattern matching.  Message passing is... oh, you get the idea.

You see things like this in Django’s url.py.  As indicated by that link, regular expressions are used for this purpose in Django.  Powerful, albeit a bit user unfriendly.  Furthermore, I will state that Python’s choice to relegate regular expressions to being a library function is a the reason why a good amount of my personal scripts were previously written in Perl, and now mostly are in Ruby.  The other reason is XPath.

But meanwhile, if you are interested in message passing along these lines in Python, I’d suggest PyLinda.


I will state that Python’s choice to relegate regular expressions to being a library function is a the reason why a good amount of my personal scripts were previously written in Perl.

I like how regular expressions are built right into Perl’s syntax, but I don’t see how using regexes from Python’s standard lib makes it that much more difficult or verbose.

------------
Python:

import re
if re.search('foo', 'foobar'):
    print 'match'

------------
Perl:

if ('foobar' =~ /foo/) {
    print 'match';
}
Posted by Corey Goldberg at

Corey, try porting this from Ruby to Python:

puts $1 if foo =~ /xyz (\d+)/
Posted by Sam Ruby at

Corey, try porting this from Ruby to Python:

ahh.. I see your point.  The syntax (especially the $1) for matching groups is terse and handy.. vs. Python’s matching groups syntax.  Porting that example from python would take your one-liner and turn it into several lines of code.

thanks for the clarification.

Posted by Corey Goldberg at

I like the fact that, in Ruby, regexes are Objects. Too bad the implementation sucks.

Posted by Jacques Distler at

Pattern matching is probably 1/3 of the secret sauce. The other two thirds of the mixture are:

I’ll probably have to write those up better on my blog.

Posted by Patrick Logan at

Um, some formatting I did not know about. I had a list of two items up there...

1. Mailbox per process with pattern-matched reception rather than solely chronological reception.
2. Fail fast with implicit failure, no code required to say “else fail”.

Anyway.

Posted by Patrick Logan at

Secret Sauce

Sam Ruby writes ... The “secret sauce” is pattern matching. Things like “if these conditions are met, this code fires, with the following variables set”. With Erlang, this metaphor is everywhere. Function calls are an exercise in pattern matching....

Excerpt from Making it stick. at

[from pauldwaite] Sam Ruby: Pattern Matching

[link]...

Excerpt from del.icio.us/network/anselm at

A fuller pattern matching in Python can be done with RuleDispatch, now being reimplemented as Rules: http://peak.telecommunity.com/DevCenter/RulesReadme

It looks like in the reimplementation he’s just reimplementing type-based dispatch, whereas in RuleDispatch you could dispatch on arbitrary predicates.  With arbitrary predicates you could potentially dispatch on, say, an XPath expression or a regex.  Of course an XPath expression might be rather inefficient (depending on how exactly you are using it)... but perhaps the idea behind Rules with the extensible dispatching is that you could build in something more like native XPath support, so that the dispatching mechanism could do an efficient search to find a matching implementation for a given set of data.

For some particular kind of dispatch, decorators are quite capable of expressing it, in a style that’s not unlike Erlang.  I particularly like the RuleDispatch technique where the abstract implementation becomes the decorator and hub for specific implementations; but it’s easy enough to do it otherwise too.

I don’t exactly understand your XPath comment.  Unless you mean minidom isn’t very nice basis for that (minidom isn’t a good basis for anything at all).  XPath is pretty easy in lxml (http://codespeak.net/lxml/xpathxslt.html); you can do stuff like el.xpath('.//[@href=$href]', href=some_value) to search for every element with href=some_value.  I think that’s a pretty reasonable way to use XPath (though there’s a compilation overhead, which to avoid requires precompiling an xpath expression into a callable a little like re.compile).

Posted by Ian Bicking at

Though I’m sure Rules and RuleDispatch is better, this got me in the mind to whip up pattern matching that maybe looks a bit more like Erlang.  But still probably more like RuleDispatch.

Anyway, I threw it up here as an example: [link]

I can now understand PJE’s noting that it would be convenient to have generic functions while implementing generic functions.

I think it’s a point of syntactic convenience that symbols in Erlang are unquoted, which combined with pattern matching give something akin to methods.  If there was a routing system for an entire process, I’d be inclined to organize  to call a method or module member as the first (and often only needed) form of dispatch.  Or, in a specific example like Python, perhaps use the function name as the first match argument.  How many messages don’t have some preamble to indicate what the basic intention of the message is?  You might want to do further ad hoc pattern matching, but it’s awkward to phrase as one big pattern match in most languages.

Posted by Ian Bicking at

I don’t exactly understand your XPath comment.  Unless you mean minidom isn’t very nice basis for that (minidom isn’t a good basis for anything at all).  XPath is pretty easy in lxml

I try to stick with the batteries that happen to be included, and often specifically to the batteries which were included a few Python releases back.

When I stray, to date I’ve gone for libxml2 — which is both fast and full XPath support.

It looks like 2.5 has etree, which has a findall, but no XPath.

With Ruby, XPath is included, and has been for some time.  I have my other issues with REXML, but this is something I do appreciate.

Posted by Sam Ruby at

re.match(r"xyz (\d+)", foo).groups()[0]

trivial!

(And yes, you’d have to catch the exception, but that’s SEP :)

Posted by dbt at

If you’re interested in Python, pattern matching, generative communication, and coordination languages then you absolutely MUST check out NetWorkSpaces.  One of the authors, Nick Carriero, is one of the original implementers of the Linda system and a researcher at Scientific Computing Associates, the original commercial vendor of Linda.  NetWorkSpaces is a cross-language cross-platform generative communication framework with excellent bindings for both Python and R, and is an open source project of the aforementioned SCA.  It isn’t precisely Linda, but provides most of the benefits with less complexity, a number of new bells and whistles, and a more modern implementation.

Check out:

  lindaspaces.com

  the NetWorkSpaces SourceForge project

  <a hfref="http://www.ddj.com/web-development/200001971">this DDJ article</a>

Posted by Jeff Bone at

links for 2007-08-18

For Sale By Publisher- Non Ad Network Sales By creating a directory of websites that offer direct advertising opportunities, ForSaleByPublisher hopes to attract large numbers of advertisers who will use the directory, solving problems for...

Excerpt from All in a days work... at

dbt: tricky, but I guess

>>> foo = "xyz 123"
>>> print [i.groups()[0] for i in re.finditer(r"xyz (\d+)", foo) if i ]
['123']
>>> foo = "xyzk 123"
>>> print [i.groups()[0] for i in re.finditer(r"xyz (\d+)", foo) if i ]
[]
>>>

is closer to what Sam was asking for. I see how Ruby’s syntax can be cleaner. :)

Posted by Santiago Gala at

Small tweak on Santiago’s solution:

import re,sys
[sys.stdout.write("%s\n" % i.groups()[0]) for i in re.finditer(r"zyz (\d+)", foo) if i]

But, realistically, I do still write a fair amount of Python code, and regularly use regular expressions, and the way I would (and do) do this in Python would be to do this as three statements (not counting the import) and an additional local variable.

Sometimes terseness inhibits readability and maintainability.  Sometimes verbosity inhibits readability and maintainability.  In my experience, Ruby finds a better balance in the case of regular expressions.

Posted by Sam Ruby at

Have you checked out the pattern matching features in Scala yet?

Posted by Aaron Farr at

Pattern Matching - The “secret sauce” is pattern matching.

another plug for Erlang - I swear I need more time......

Excerpt from del.icio.us/billyg/django at

Erlang Days

... [more]

Trackback from Eighty-Twenty

at

Add your comment