georgek
georgek

Reputation: 877

why can't I call a println after a while in defn body in Clojure?

I have a function that looks like,

(defn app [server]
  (println "before while...."))
  (while test
    while-body)
  (println "...after while."))

However when I call the fn I just see the "before while" at the REPL, and then when the while fails its test, "nil".

If I write a test foo at the repl like

(defn foo [] 
  (println "testing before")
  (loop [i 100]
    (when (> i 10)
      (prn i)
      (recur (- i 2))))
  (println "after..."))

It works as I'd expect.

I've put the actual code up in a paste here, https://www.refheap.com/paste/12147 , if it helps.

What explains the difference in behavior here?

edit

Apologies for not trying this before, but this does work at the REPL:

(defn bar []
  (let [i (atom 100)]
    (println "before...")
    (while (> @i 10)
      (swap! i dec))
    (println "after...")))

So there's something else going on.

edit #2

Testing more at the repl, if I comment out the while loop, the println before and after will print. I was mistaken before about the 'nil', this is the return value of a different function called after the while was called. So it seems to have something to do with the while loop.

I noticed that if I change the while to this

(loop []
  (if test
    (do things and recur...)
    (println "test failed")))

The "test failed" never prints to the repl.

Upvotes: 1

Views: 185

Answers (3)

georgek
georgek

Reputation: 877

The problem wasn't what I thought it was. I was blocking on a select call (called in the while loop) and that was causing problems with my shutdown function which ended the while loop. Adding a timeout to the select fixes it.

Upvotes: 1

Joost Diepenmaat
Joost Diepenmaat

Reputation: 17773

You've got an extranious ) at the end of the first println.

(defn app [server]
  (println "before while....")
  (while test
    while-body)
  (println "...after while."))

But since this is obviously example code that you didn't run, I expect the problem to be in the code that you did run. Please copy & paste that code exactly as is if this doesn't fix the problem.

Upvotes: 1

Hendekagon
Hendekagon

Reputation: 4643

In Clojure function definitions, the last thing to be evaluated is what's returned, and (println ...) returns nil

Upvotes: 0

Related Questions