zellio
zellio

Reputation: 32524

How to translate this code from common lisp to clojure

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

Answers (2)

mikera
mikera

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

ChrisR
ChrisR

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

Related Questions