proj-plbook-plChClojureLang

Table of Contents for Programming Languages: a survey

Lisp and Clojure

Because it is so well-liked, Clojure gets its own chapter.

Cons

In clojure, the 'apply' function can't take a macro as the function to apply (functions and macros can't always be composed together).

Cheat Sheet

Tutorials and books

Respected exemplar code

Gotchas

Opinions

Library highlights

Comparisons

Best Practices

Features

Clojure.spec

An example is at the end of http://swannodette.github.io/2016/06/03/tools-for-thought .

Multimethods

Examples:

" A Clojure multimethods is a combination of a dispatch function and one or more methods, each defining its own dispatch value. The dispatching function is called first, and returns a dispatch value. This value is then matched to the correct method. Lets take a look at our previous example refactored into a multimethod.

    (defmulti convert class)
    (defmethod convert clojure.lang.Keyword [data]
    (convert (name data)))
    (defmethod convert java.lang.String [data]
    (str “\”" data “\”"))
    (defmethod convert nil [data]
    “null”)
    (defmethod convert :default [data]
    (str data))
    Awesome! We have our first polymorphic solution. Now we can add more data types without altering the existing functions. Let’s add a method for vectors as well.
    (defmethod convert clojure.lang.PersistentVector [data]
    (str “[" (join ", " (map convert data)) "]“))
    Now we can also convert vectors into JSON. 

In the above example, they are using “class” as the dispatch function (which returns the class of the parameter), so it works just like traditional OOP, and it even falls back on the underlying Java OOP. But we can use any function for dispatch in a multimethod.

Bozhidar Batsov offers an example using an anonymous function:

    Object oriented programming in most programming languages is based on a single dispatch message passing. The object on which we invoke a method (poor choice of words, but easier to comprehend) is the receiver, the method name and it’s arguments are the message. The method’s invoked solely on the base of the type of the receiver object.
    Lisps have traditionally implemented OOP with generic methods, that don’t have a receiver and are dispatched on the basis of the types of all of their arguments. In the world of multiple dispatch the more traditional single dispatch is just a special case in which only the type of the first method argument matters. Here’s a taste of multimethods in Clojure:
    (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))
    user=> (my-add 3 4) ; => 7
    user=> (my-add “3″ “4″) ; => “34″
    Here we defined a multi-method that behaves differently for string and numeric arguments — strings args are concatenated and numeric args are added together." -- [39]

Variants

Clojerl

Clojurescript

Jaunt