<?xml version="1.0"?>
<paste-with-annotations>
  <paste>
    <number>
      <integer>53591</integer>
    </number>
    <user>
      <string>gabor</string>
    </user>
    <title>
      <string>some multi-dispatch opportunities</string>
    </title>
    <contents>
      <string>I have many examples from my day job. (Optical Crossconnect Business, Alcatel-Lucent, probably
sounds familiar :-)

Here is one where multi-methods would be ideal:

(I am using the dylan syntax for the sketch)

//-----------------------------

define class &lt;synchronous&gt;(&lt;object&gt;)
end;

/*
define class &lt;plesio&gt;(&lt;object&gt;)
end;

... other transmission methodologies
*/

define class &lt;tributary&gt;(&lt;object&gt;)
  slot matrix-ref :: &lt;integer&gt;;
end;

define class &lt;wrapped-ethernet&gt;(&lt;tributary&gt;)
end;

define class &lt;synchronous-tributary&gt;(&lt;tributary&gt;, &lt;synchronous&gt;)
end;

define class &lt;SDH-tributary&gt;(&lt;synchronous-tributary&gt;)
end;

define class &lt;SONET-tributary&gt;(&lt;synchronous-tributary&gt;)
end;


define generic crossconnect(from :: &lt;tributary&gt;, to :: &lt;tributary&gt;) =&gt; ();

// (1)
define method crossconnect(from :: &lt;tributary&gt;, to :: &lt;tributary&gt;) =&gt; ();
  matrix-connect(from.matrix-ref, to.matrix-ref);
end;

// (2)
define method crossconnect(from :: &lt;synchronous-tributary&gt;, to :: &lt;tributary&gt;) =&gt; ();
  next-method();
  enable-external-fault-monitor(from);
end;

// (3)
define method crossconnect(from :: &lt;synchronous-tributary&gt;, to :: &lt;wrapped-ethernet&gt;) =&gt; ();
  next-method();
  enable-extra-bandwidth(to);
end;

//-----------------------------

In our system we have a dozen of transmission types, so the combination
of input-&gt;output becomes huge. Currently all processing is done in
various huge functions with many &quot;if&quot; clauses that check for the various
specializations. It is a mess. Using multi-methods would be a big leap
in maintainability.

What I have shown above is the binary dispatch case, but usually there are
some more arguments which also guide the behaviour and are best included in
the dispatch scheme. Dispatching over 3-4 arguments is not uncommon, and such
a situation would definitely break any visitor-like pattern.

The only thing one has to be careful with is the ambiguity of the method resolution
(Dylan resolves in a symmetric way (for arguments) but respects the left-to-right
order of class inheritance (when multiply-inherited).) A good compiler warns the
user if ambiguities can lead to surprising method selection.

Another nice example to multimethods is when a state machine is triggered in different
situations. For example a circuit can be completed by the local segment or by a
remote segment, and whether this segment is the dropping segment of the circuit:

//-----------------------------

define generic completed-by (state :: &lt;state&gt;, situation :: &lt;segment&gt;);

//-----------------------------

here we typically have 6-8 states and 8 situations ({local, remote} x {add, thru-out, thru-in, drop}).

</string>
    </contents>
    <universal-time>
      <integer>3408458017</integer>
    </universal-time>
    <channel>
      <string>#dylan</string>
    </channel>
    <colorization-mode>
      <string>None</string>
    </colorization-mode>
    <maybe-spam>
      <null/>
    </maybe-spam>
    <is-unicode>
      <null/>
    </is-unicode>
  </paste>
</paste-with-annotations>