Multiple dispatch 
Tags: perl6, elixir, functional, dispatching
Published: 2017-12-28 09:35:52

---
title: Multiple dispatch 
published: True
description: How multiple dispatch works in Perl6 and how it can help us to get stuff done
tags: perl6, elixir, functional, dispatching.
---
![Multiple versions of "hilos"](https://thepracticaldev.s3.amazonaws.com/i/by1rl1xd2k4mfqpkod3b.jpg)
Sometimes you want to get things done to a piece of data, but you don't know in advance what that piece of data is made of. It can be an array, it can be a string, it can be a more complicated arrangement of data. Happens all the time in [dynamically typed languages](https://en.wikipedia.org/wiki/Type_system#Dynamic_typing): you want to do something to a list of things, such as printing it or simply converting it to a string. You can jump to hoops and do a `switch` clause and check type and dispatch the corresponding operation. Or you can use multiple dispatch.

## Many languages use multiple dispatch 

And they use it to bind a function to a type. For instance, [Elixir](http://elixir-lang.github.io/), a Rubyfication of Erlang that turns it into something that can be understood by mere humans:
```Elixir
defprotocol Stringifier do
  @doc "Can convert to string using tostring"
  def tostring( whatever)
end

defmodule Span do
  @doc "A few words"
  defstruct words: []
end

defimpl Stringifier, for: Span do
  def tostring(span), do: Enum.join(span.words," ")
end

defmodule Quoted do
  @doc "A few words and a quote"
  defstruct words: [], quote: "em"

  def i(string, quote) do
    "<#{quote}> #{string} </#{quote}>"
  end
end

defimpl Stringifier, for: Quoted do
  def tostring(quoted), do: Quoted.i(Enum.join(quoted.words," "),quoted.quote)
end
```
Some languages require the programmer to declare, in advance, the function we intend to use for multiple dispatch; in elixir parlance, they are called [protocos](http://elixir-lang.github.io/getting-started/protocols.html). We need to declare a `protocol` with the name of the function and the function signature. In this case, it takes a single artument, which we are going to be calling `whatever`. We will call the protocol `Stringifier`. 
We will use the marked text model here as we have done [so far](https://dev.to/jj/assuming-roles-2dog). We have a `Span` which is a simple list of words, and a `Quoted` which adds some kind of quoting construct around it. [Modules in Elixir](http://elixir-lang.github.io/getting-started/modules-and-functions.html) are packaging constructs, but are in no way objects: they are structs and stuff you can do to them, but don't get instantiated or anything like that. But they at least define a structure we can use later on to define the multiple dispatching:

```Elixir
defimpl Stringifier, for: Span do
  def tostring(span), do: Enum.join(span.words," ")
end
```
Since a protocol is kind of an abstract interface, we define a function that follows that interface by declaring an implementation using `defimpl`; `defimpl Stringifier` defines an implementation of that protocol. Applied to what? `for: Span` says this is going to be applied to that specific data `struct`. The actual implementation of the function follows, and it wraps around the `join`ed words the quote we have defined. The other implementation follows the same, but when we want to use it:
```Elixir
defmodule Main do
  def main do
    words = %Span{words: ["A","few","words"]}
    IO.puts(Stringifier.tostring(words))
    quoted = %Quoted{words: ["More","words"], quote: "em"}
    IO.puts(Stringifier.tostring(quoted))
  end
end

Main.main
```
No matter what we use, `IO.puts(Stringifier.tostring(quoted))` will detect the data type and will dispatch to the corresponding code the *message* so that it gets printed alright.

And we know that Perl6 throws everything and the kitchen sink in. Let's see

## Multiple dispatch in Perl6

We have seen a bit of that [already](https://dev.to/jj/role-ing-on-the-grammars-1bd5). Grammars use multiple dispatch to deal with symbols that have pretty much the same function, as in quoting constructs. Since grammars are classes, multiple-dispatching rules which are methods make sense. But let's go back to the actual data structures that would represent paragraphs with enrichment:
```Perl6
role stringifiable {
    method to-string( Str $ligature ) { ... }
}

# Thanks to https://perl6advent.wordpress.com/2009/12/18/day-18-roles/
role Span does stringifiable {
    has @.words;
    method to-string( Str $ligature ) {
	return @!words.join( $ligature );
    }
}

class Quoted does Span {
    has $.quote;

    method to-string( Str $ligature ) {
	return self.þ ~  self.Span::to-string( $ligature ) ~ self.ø;
    }

    method þ () {
	return "<" ~ $!quote ~ ">";
    }

    method ø () {
	return "</" ~ $!quote ~ ">";
    }

}

class Heading does Span {

    submethod BUILD( :@!words ) {
    }
    
    method to-string() {
	return "\n<h1>" ~ self.Span::to-string( " " ) ~ "</h1>\n";
    }
}
```
It's rather longish because we are throwing a bit of everything we have done so far in. We define a lightweight [role](https://dev.to/jj/assuming-roles-2dog) which is just a function, with no implementation. The `{ ... } ` takes care of that. We defer the implementation to the role users, and we actually force them to do so. We have another role, `Span`, which is consumed by two classes, `Quoted` for enriched words and `Heading` for header class. This is a more full-fledged class with its `BUILD` function and all, but it needs that since it's got to tie the object instantiation function (`new`) to the instance variables. [Been there, done that](https://dev.to/jj/assuming-roles-2dog). No big deal. But now we might need to convert to string some object whose class we do not know in advance. Multiple dispatch to the rescue:
```Perl6
# Stringifier for stuff above
proto stringify-chunk( | )                          {*}
multi stringify-chunk( $chunk where Quoted | Span ) {
    return $chunk.to-string( " " );
}
multi stringify-chunk( Heading $heading )           {
    return $heading.to-string();
}
```
We use exactly the same syntax [we used before in grammars](https://dev.to/jj/role-ing-on-the-grammars-1bd5). A `proto` says "Hey, this is the way the multiply dispatched functions are going to look". Proto as in `protocol`, or maybe prototype, but protocol suits me just fine since it's how they are called in Elixir and we have seen before. However, Elixir used a placeholder to say that the implementations were going to use a single word. Perl6 is more flexible: [| is a `Capture`](https://docs.perl6.org/type/Signature#index-entry-parameter_%7C-Capture_Parameters) which says "I don't care what you throw in here, I'll take care of it". 
The instantiations of the proto(type|col) use `multi`, as in `multi`ple dispatch. They do not need to declare that they are part of that protocol, just the general shape of it takes care of that. But the first one use again `|` in a different way. We got `Span` and `Quoted`, but they are pretty much the same, so they can use the same implementation. `$chunk where Quoted | Span` uses two features in Perl6. `Quoted | Span` is a [Junction](https://docs.perl6.org/type/Junction) whose value is one or the other. And Perl6 allows to add constrains to type declarations via `where`. `$chunk` can be either a `Quoted` or a `Span`, and we declare it in a very compact fashion.
> Another proof that Perl6 gets stuff done. We have here a `multi` function that deals with multiple types too. 

We will use this function from here:
```Perl6
class Paragraph {
    has stringifiable @!chunks;

    method new( *@chunks ) {
	return self.bless(:@chunks);
    }
    
    submethod BUILD( :@!chunks ) {}
    
    method to-string() {
	return "\n" ~ (@!chunks.map: { stringify-chunk( $^þ ) }).join(" " );
    }
}
```
Which is a class with `new` and all. This kind of function is a method (can be inherited) and not a submethod (which can't) and allows us to make a more compact definition that does not use named parameters. `*@chunks` is a *slurpy* parameters (uses *) which takes everything and puts it into an array `@chunks`, which we then bless and turn into the instance variable. But `@chunks` does `stringifiable`. We don't know what every piece of the text will be in advance, but we do know we can `string` it. That is why we call `{ stringify-chunk( $^þ ) }` on it later on.

How can we use it? 
> As usual, the full code is [in GitHub](https://github.com/JJ/dev.to-code) 

```Perl6
my $heading  = Heading.new( words => "Here we are".comb(/\w+/) );
my $span     = Span.new( words => "This goes first");
my $quoted   = Quoted.new( words => "This is last",
			  quote => "em" );


my $sentence = Paragraph.new( $heading, $span, $quoted );

say $sentence.to-string();
```
We define three different kinds of objects, which get slurped when defining a `Paragraph`, and eventually are printed by calling the multi `stringify-chunk` on them using `map`.  The result is a not incredibly beautiful but serviceable
```
<h1>Here we are</h1>
 This goes first <em>This is last</em>
```

## To be continued

Grammars are kind of the nexus of everything that is new and beautiful about Perl6. We will continue expanding the grammar with new features to make it almost, but not quite, a Markdown grammar.