2

In common lisp I can place multiple defun in the same closure and have them all set functions.

(let ((number 0)) (defun get-number () number) (defun set-number ( arg ) (setq number arg))) 

How ever if I use the same syntax in clojure only the last function ends up getting defined.

(let [ number 0 ] (defn get-number [] number) (defn set-number [ arg ] (def number arg))) 

Is there a way to translate this code into clojure so that you have access to both functions?

1
  • 1
    You can use DEFUN inside a LET in Common Lisp, but I won't generally recommend it. DEFUN is no longer a top-level form inside the LET, which has slight drawbacks for compilation. Commented Jul 22, 2012 at 2:11

2 Answers 2

6

user593508 gives a good answer in terms of a literal translation.

But it's a bit unidiomatic in Clojure, where the use of data encapsulated behind side-effectful setters and getter functions is discouraged. Clojure tends to emphasize pure functions, and explicit control of state though managed references (see this excellent video by Rich Hickey on data structures and managed references)

An alternative would be to use an atom directly to store the mutable number:

(def number (atom 0)) @number => 0 (swap! number + 5) => 5 @number => 5 

Apart from being more concise and more idiomatic Clojure, you get the extra advantage that swap! can execute aribtrary functions on the atom's value, not just getting and setting (see the example with +5 above)

Sign up to request clarification or add additional context in comments.

Comments

5

Here is one possible translation of your code - the get-number function is accessible.

(let [number (atom 0)] (defn get-number [] @number) (defn set-number [arg] (reset! number arg))) (get-number) => 0 (set-number 5) (get-number) => 5 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.