

Clojure on the Google App Engine - coglethorpe
http://www.fatvat.co.uk/2009/05/clojure-on-google-app-engine.html

======
jefffoster
There is one big limitation. The GAE doesn't allow you to spawn threads, which
stops one big selling point of Clojure (concurrency).

~~~
swannodette
Only _one_, you still get macros, robust data structures (for example hash-
maps that take anything as a key), multimethods (dispatch on anything, not
just type), lazy data structures, dynamic variables, metadata, etc. macros
alone would be worth it in IMHO, the rest is just icing on the cake.

~~~
mahmud
> multimethods (dispatch on anything, not just type)

Care to elaborate? I know Common Lisp's multimethods dispatch on class and
object identity

    
    
      (defmethod foo ((obj class-name)) ..)
    
      (defmethod foo ((obj (eql object)) ..)
    

The first one dispatches if obj is of class "class-name", and the second
dispatches if obj and object are EQL (i.e. strictly equal by value or
pointer.) and this second one allows you to do very clean switch/case style
dispatching on actual values.

How does clojure do it?

~~~
jefffoster
You can write a function that determines the dispatch action.

In the example below we dispatch my-add based on a function of the two
arguments. This function returns a bool that determines the function to call,
but it could return anything that you could then use to define the method upon
(e.g. a symbol).

    
    
      (defmulti my-add (fn [x y] (and (string? x) (string? y))))
    
      (defmethod my-add true [x y]
        (str x y))
    
      (defmethod my-add false [x y]
        (+ x y))
    
      (my-add 3 4) ==> 7
      (my-add "3" "4") ==> "34"

~~~
mahmud
I don't understand the need for defmulti.

    
    
      (defmethod my-add ((x integer) (y integer))
        (+ x y))
    
      (defmethod my-add ((x string) (y string))
        (concatenate 'string x y))
    
      CL-USER(8): (my-add 2 3)
      5
      CL-USER(9): (my-add "foo" "bar")
      "foobar"
    

Keep in mind you're dispatching on both arguments; the MY-ADD generic function
is created for you and it's lurking in memory. You can add :before, :after and
:around methods, which will allow you to get a hold of both arguments BEFORE
the dispatch method is applied and after in a serial fashion, or AROUND the
method dispatch altogether. This allows for stuff like logging, debugging,
tracing, method wrapping and augmentation for moving-target type protocols and
designs, etc.

~~~
swannodette
No criticism of CLOS generic functions, but they accomplish something very
different from Clojure multimethods. generic functions are intended to support
objects. Clojure doesn't have objects, so Clojure does not limit multimethods
to the kinds of use cases that generic methods are intended to solve.

Again you can dispatch on anything. Your dispatch function can return any
value (a set, a hash-map, a vector, a list, a string, a number, etc.).

(defn new-dispatch [x y z] (meta y))

(defmulti my-multi new-dispatch)

(defmethod my-multi {:meta-key1 meta-val1} [x y z] ...)

(defmethod my-multi {:meta-key2 meta-val2} [x y z] ...)

This one dispatches on the metadata attached to the second argument.

------
marcusbooster
For the interested, here's an example of using Clojure with Compojure on the
GAE: [http://elhumidor.blogspot.com/2009/04/clojure-on-google-
appe...](http://elhumidor.blogspot.com/2009/04/clojure-on-google-
appengine.html)

------
themanual
thanks for the post. I was waiting for this to be setup by someone. We also
have php working on the app engine [http://www.webdigi.co.uk/blog/2009/run-
php-on-the-google-app...](http://www.webdigi.co.uk/blog/2009/run-php-on-the-
google-app-engine/)

