views:

125

answers:

2
+3  Q: 

Dispatch functions

What exactly are dispatch functions? I've googled them and all is vague. They seem to just be nested blocks/closures inside of other functions? Speaking from a scala/lift point..but i assume it's universal, i've seen them mentioned in ruby as well.

+3  A: 

The goal of dispatching is to dynamically decide what to do in your function.

When you have a (dynamic) dispatch function it's main (or only, if you don't need casting or other conversions) responsibility is to decide which other function to call. The decision is often based on the type of the instance the method is called on, or the type of some of the parameters, but it can also depend e.g. on the value of the parameter(s), or some config values.

The dispatching rule can be hardcoded (using e.g. pattern matching in scala), or may come from a dispatch table.

As you mentioned there are several variations, like single dispatch (concrete method depends on the instance the original method is called on, which is a basic OO mechanism), double dispatch (dispatches a function call to different concrete functions depending on the runtime types of multiple objects involved in the call).

A related design pattern is the Visitor, which allows you to add a set of functions dynamically to existing classes and which also has dynamic dispatch at its core.

The nested blocks/closures appear when you define the concrete method inside of the dispatch method, or in some initialization code (e.f. for the dispatch table).

A simple example for the case when dispatching is based on the value of the parameter, with hardcoded decision and with dispatch table:

   class Dispatch {

     def helloJohn(): String = "Hello John"

     def helloJoe(): String = "Hello Joe"

     def helloOthers(): String = "Hello"

     def sayHello(msg: String): String = msg match {
       case "John" => helloJohn()
       case "Joe" => helloJoe()
       case _ => helloOthers()
     }


     val fs = Map("John" -> helloJohn _, "Joe" -> helloJoe _)

     def sayHelloDispatchTable(msg: String): String = fs.get(msg) match {
         case Some(f) => f()
         case _ => helloOthers()
     }
   }
Sandor Murakozi
+2  A: 

Dispatch is the term Lift uses for dispatching web services requests.

The easiest way to define the dispatch function using RestHelper (see http://www.assembla.com/wiki/show/liftweb/REST_Web_Services )

For example:

object MyRestService extends RestHelper {
  serve {
    case "api" :: "user" :: AsLong(id) :: _ XmlGet _ => <b>ID: {id}</b>
    case "api" :: "user" :: AsLong(id) :: _ JsonGet _ => JInt(id)
  }
}

Then in Boot.scala:

LiftRules.dispatch.append(MyRestService)

Hope this helps.

David Pollak