[dmd-concurrency] Pattern matching on message receives, error handling
Fawzi Mohamed
fawzi at gmx.ch
Wed Jan 13 08:16:48 PST 2010
On 13-gen-10, at 16:44, Mark Kegel wrote:
> The reason I'm scared is fairly simple, I've seen this exact design
> (well maybe not exact, but the similarities are too great to ignore)
> used before. I worked for a couple of years on a large Telco system.
> Message handling was its bread and butter. We had lots of independent
> process with probably thousands of different messages flying through
> the system.
>
> One thing that got beat into my head was that you really, really want
> to be able to easily trace the sequence of messages in a system. What
> pattern matching gives you is a more concise notation for telling
> outside users what is handled and what is not. That is the protocols
> that actors use to communicate are made explicit, not left implicit
> and thus recalcuated everytime you want to know how it works. In
> essence you can segment your code more cleanly along logical
> communication lines rather than function signature, since one function
> signature might be the entry point for fifteen different completely
> orthogonal messages.
>
> It really all comes down to how easily the syntax of the language
> scales to large designs. Sure, taking anonymous functions and then
> testing for all messages that matching that signature is exactly as
> powerful as pattern matching, but I would contend that its a lot less
> readable.
>
> So lets assume that you let receive() take some kind of pattern
> object, what might this look like? To write it out in the worst
> possible way, here's one idea:
>
> receive( pattern("foo", _1) + (string a, string b) { ...},
> pattern("bar", _1) + (string a, string b) { ...},
> pattern(_1, _2) + (string a, string b) { ...},
> ...
> );
>
> I've used _* placeholders similar to the way boost lambda does.
>
> While I've intentionally made this as ugly (and self documenting) as
> possible, I really have no idea how'd you'd clean this syntax up,
> since I'm just not that familiar with D's introspection capabilites.
> Does any one more familiar with D have a better way to implement
> pattern matching?
maybe the place where you want to go looks like exposing an object
that has several methods, and thus a fixed interface, and have
execution on that object be sequential by default on the server (what
I do in blip.parallel.rpc).
Also to send a message in general you use a proxy tat has exactly the
same exposed interface and does the remote call.
Fawzi
>
> Mark
>
>
> On Tue, Jan 12, 2010 at 11:38 PM, Sean Kelly
> <sean at invisibleduck.org> wrote:
>> On Jan 12, 2010, at 7:54 PM, Andrei Alexandrescu wrote:
>>
>>> Mark Kegel wrote:
>>>> Call me silly, but how many of you have seen 1000 line switch
>>>> statements when polymorphism was called for? And what is
>>>> polymorphism but dispatch / pattern matching over argument type?
>>>> So when I see code like this:
>>>> auto msg = receiveOnly!(Tid, int)();
>>>> if (!msg[0]) return;
>>>> writeln("Secondary thread: ", msg[1]);
>>>> msg[0].send(thisTid);
>>>> ...where you the first thing you tell new readers about how to
>>>> test what message you just got is with an 'if' statement, I get
>>>> scared. Please give users a more elegant mechanism, and if you
>>>> need ideas about what it could look like I would suggest that
>>>> Scala offers a passable (and maybe even compatible) syntax.
>>>
>>> You have a point, but quite a weak one. First, the example above
>>> is not illustrative on the pattern matching capabilities of D;
>>> we'll get to those with the full-fledged receive() function. For
>>> now I just considered fine to send a null Tid to signal loop
>>> termination. With receive() you can dispatch to various functions
>>> depending on the types of the arguments. With introspection it's
>>> very easy to dispatch messages to an object depending on their
>>> types.
>>>
>>> I don't agree with the comparison with switch() vs. virtuals at
>>> all. The problem with switch() is that it breaks modularity by
>>> requiring all cases to be present in the same place. On the
>>> contrary, pattern matching _also_ requires all cases to be present
>>> together (which makes me believe it's much less powerful than it's
>>> cracked to be). So if I pattern match with
>>>
>>> patternmatch (receive()) {
>>> case int x: ...
>>> case (string a, int b): ...
>>> }
>>>
>>> versus
>>>
>>> receive(
>>> (int x) { ... },
>>> (string a, int b) { ... }
>>> );
>>>
>>> we're only talking about a difference in syntax, not power. So
>>> essentially you shouldn't be scared just because there's no built-
>>> in syntax for something that can be expressed within the existing
>>> language with the same power.
>>
>> It's worth adding that Erlang does provide pattern matching
>> capabilities that have to be a run time in D, but I'm not sure this
>> same capability is available in Scala, for example. In our case,
>> this will probably be handled manually by the user, with possibly
>> some fancier way to do it later (metaprogramming can do quite a lot
>> in D). For example:
>>
>> receive(
>> (int x) { ... },
>> (string a, int b) { if (a == "blah") return false; ...;
>> return true; }
>> );
>>
>> Here, the second function checks string a to see if it matches a
>> pattern, and returns true/false to indicate that there was a match.
>>
>> _______________________________________________
>> dmd-concurrency mailing list
>> dmd-concurrency at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
>>
> _______________________________________________
> dmd-concurrency mailing list
> dmd-concurrency at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-concurrency
More information about the dmd-concurrency
mailing list