Reputation: 32524
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?
Upvotes: 2
Views: 331
Reputation: 106401
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)
Upvotes: 6
Reputation: 1237
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
Upvotes: 5