1

conj is used in (conj coll item), for example (conj #{} "Stu").

But, I found this example in 'Programming Clojure' book page16.

(alter visitors conj username)

I guess (conj visitors username) would be the correct usage. What's the secret?

2 Answers 2

5

The "secret" is that alter is a special function that is called in a transaction on a ref, and it has the effect of inserting the current value of the ref as the first parameter to whichever function is supplied as its second argument.

In fact the normal usage for conj with a ref would be:

(conj @visitors username)

So alter roughly translates as follows:

(alter vistors conj username)
=> (ref-set visitors (conj @visitors username))
Sign up to request clarification or add additional context in comments.

Comments

2

It is not uncommon in Clojure for macros and higher order functions to take a function followed by args and then execute it by inserting a context-dependent argument before the supplied args. This makes caller's life a bit easier. This way you can write:

(alter visitors conj username)

instead of:

(alter visitors #(conj %1 username))

Some other forms that do this are: send,doto,update-in,->,alter-meta!.

2 Comments

doto and -> are very different from the others in this list. They are macros that rewrite forms: (doto x println) expands to (roughly) (do (println x) x), which is very different from (send x println). The latter is a function wrapping up less-convenient syntax you describe.
@amalloy: Yes, they are different but I don't think that this difference matters in this context. The convention is syntactical and the syntax for macros and functions is basically the same (this is advertised as an advantage of Lisp :) ) so it works for both macros and functions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.