Clojure infinite loop

472 views
Skip to first unread message

mike.f...@gmail.com

unread,
Mar 6, 2009, 12:24:22 AM3/6/09
to Clojure
Hi,

Having attend Stu Halloway's talk on Clojure, at NFJS, I decided to
download it and check it out. The language seems like a perfect fit
for some database set manipulation that I do, and may need to do in
the future.

So, I downloaded clojure and started it up with the command:
java -cp clojure.jar clojure.lang.Repl

The docs indicate: "This will bring up a simple read-eval-print loop
(REPL)."

Is this truly an infinite loop?

I tried a number of commands to exit.
So, I just hit ctrl-C. (This is on Windows).

Anyhow, one other question, since clojure can access Java classes,
I should be able to open a database connection and do all of the good
DB things, right?

Thanks for your patience,
Mike

Paul Stadig

unread,
Mar 6, 2009, 9:27:00 AM3/6/09
to clo...@googlegroups.com
On Fri, Mar 6, 2009 at 12:24 AM, mike.f...@gmail.com
<mike.f...@gmail.com> wrote:
>
> Hi,
>
> Having attend Stu Halloway's talk on Clojure, at NFJS, I decided to
> download it and check it out. The language seems like a perfect fit
> for some database set manipulation that I do, and may need to do in
> the future.

Hi, Mike, and welcome!

> So, I downloaded clojure and started it up with the command:
> java -cp clojure.jar clojure.lang.Repl
>
> The docs indicate: "This will bring up a simple read-eval-print loop
> (REPL)."
>
> Is this truly an infinite loop?
>
> I tried a number of commands to exit.
> So, I just hit ctrl-C. (This is on Windows).

I had the same question in getting started. Someone told me to type
"(System/exit 0)" which will call the java.lang.System.exit method and
terminate the program. This seems to work for me.

> Anyhow, one other question, since clojure can access Java classes,
> I should be able to open a database connection and do all of the good
> DB things, right?

You can find the details here:
http://clojure.org/java_interop

Shawn Hoover

unread,
Mar 6, 2009, 9:31:07 AM3/6/09
to clo...@googlegroups.com
On Fri, Mar 6, 2009 at 12:24 AM, mike.f...@gmail.com <mike.f...@gmail.com> wrote:

So, I downloaded clojure and started it up with the command:
java -cp clojure.jar clojure.lang.Repl

The docs indicate: "This will bring up a simple read-eval-print loop
(REPL)."

Is this truly an infinite loop?

I tried a number of commands to exit.
So, I just hit ctrl-C. (This is on Windows).

You can also stop it by typing (System/exit 0).

Anyhow, one other question, since clojure can access Java classes,
I should be able to open a database connection and do all of the good
DB things, right?

Sure. Here's an example of some Java interop: http://clojure.org/jvm_hosted. There's a Clojure interface to jdbc in the clojure-contrib project: http://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/sql.clj.

Shawn

Mark Volkmann

unread,
Mar 6, 2009, 9:44:16 AM3/6/09
to clo...@googlegroups.com
On Thu, Mar 5, 2009 at 11:24 PM, mike.f...@gmail.com
<mike.f...@gmail.com> wrote:
>
> Hi,
>
> Having attend Stu Halloway's talk on Clojure, at NFJS, I decided to
> download it and check it out. The language seems like a perfect fit
> for some database set manipulation that I do, and may need to do in
> the future.
>
> So, I downloaded clojure and started it up with the command:
> java -cp clojure.jar clojure.lang.Repl
>
> The docs indicate: "This will bring up a simple read-eval-print loop
> (REPL)."
>
> Is this truly an infinite loop?
>
> I tried a number of commands to exit.
> So, I just hit ctrl-C. (This is on Windows).

ctrl-c is the right way to exit under Windows.
Under UNIX, Linux and Mac OS X, I think ctrl-d is preferred.

> Anyhow, one other question, since clojure can access Java classes,
> I should be able to open a database connection and do all of the good
> DB things, right?

Right. See http://www.ociweb.com/mark/clojure/article.html#Databases.

--
R. Mark Volkmann
Object Computing, Inc.

Chouser

unread,
Mar 6, 2009, 9:55:10 AM3/6/09
to clo...@googlegroups.com
On Fri, Mar 6, 2009 at 9:27 AM, Paul Stadig <pa...@stadig.name> wrote:
>
> On Fri, Mar 6, 2009 at 12:24 AM, mike.f...@gmail.com
>>
>> I tried a number of commands to exit.
>> So, I just hit ctrl-C. (This is on Windows).
>
> I had the same question in getting started. Someone told me to type
> "(System/exit 0)" which will call the java.lang.System.exit method and
> terminate the program. This seems to work for me.

On windows, Ctrl-Z <Enter> works as well. This is the normal
end-of-file pattern on Windows. That's Ctrl and Z together, then
released, then the <Enter> key.

--Chouser

Stephen C. Gilardi

unread,
Mar 6, 2009, 10:00:28 AM3/6/09
to clo...@googlegroups.com

On Mar 6, 2009, at 9:44 AM, Mark Volkmann wrote:

> ctrl-c is the right way to exit under Windows.
> Under UNIX, Linux and Mac OS X, I think ctrl-d is preferred.


I agree.

Here's some more info:

On the Unixes, ctl-d represents "end-of-file" (end of input stream).
Usually terminals and terminal-like interfaces will send ctl-d
immediately to the process waiting for input even in cases where input
would normally be line-buffered before being sent. ctl-d works to quit
the repl immediately on Linux and Mac OS X.

On Windows the corresponding end-of-file marker is ctl-z. However in a
default "cmd" window ctl-z doesn't act immediately. Instead, it's
interpreted after pressing return. Both "ctl-z return" and "ctl-c"
work to quit the clojure Repl on Windows. As the latter is more
succinct, I think it's reasonable for it to be preferred.

(System/exit 0) also works on all platforms.

Having something like:

(defn quit [] (System/exit 0))

in your user.clj would also allow you to quit with (user/quit) or just
(quit) if the current namespace is user.

--Steve

Michael Wood

unread,
Mar 6, 2009, 4:31:55 PM3/6/09
to clo...@googlegroups.com
On Fri, Mar 6, 2009 at 7:24 AM, mike.f...@gmail.com
<mike.f...@gmail.com> wrote:
>
> Hi,
>
> Having attend Stu Halloway's talk on Clojure, at NFJS, I decided to
> download it and check it out. The language seems like a perfect fit
> for some database set manipulation that I do, and may need to do in
> the future.
>
> So, I downloaded clojure and started it up with the command:
> java -cp clojure.jar clojure.lang.Repl
>
> The docs indicate: "This will bring up a simple read-eval-print loop
> (REPL)."
>
> Is this truly an infinite loop?

Yes. Unless you break out of it in some way :)

--
Michael Wood <esio...@gmail.com>

Michael Wood

unread,
Mar 6, 2009, 4:41:06 PM3/6/09
to clo...@googlegroups.com
On Fri, Mar 6, 2009 at 5:00 PM, Stephen C. Gilardi <sque...@mac.com> wrote:
>
> On Mar 6, 2009, at 9:44 AM, Mark Volkmann wrote:
>
>> ctrl-c is the right way to exit under Windows.
>> Under UNIX, Linux and Mac OS X, I think ctrl-d is preferred.
>
>
> I agree.
>
> Here's some more info:
>
> On the Unixes, ctl-d represents "end-of-file" (end of input stream). Usually
> terminals and terminal-like interfaces will send ctl-d immediately to the
> process waiting for input even in cases where input would normally be
> line-buffered before being sent. ctl-d works to quit the repl immediately on
> Linux and Mac OS X.
>
> On Windows the corresponding end-of-file marker is ctl-z. However in a
> default "cmd" window ctl-z doesn't act immediately. Instead, it's
> interpreted after pressing return. Both "ctl-z return" and "ctl-c" work to
> quit the clojure Repl on Windows. As the latter is more succinct, I think
> it's reasonable for it to be preferred.

I tend to use Ctrl-D on Linux/Mac and Ctrl-Z on Windows. The same
goes for Python (and sbcl, and psql, and mysql, and bash etc.)

This is partly because Ctrl-C doesn't work for exiting the Python
"REPL", but actually, I think the Python behaviour is more useful:

With Python you can use Ctrl-C to break out of long-running
functions/infinite loops. Basically you get a KeyboardInterrupt
exception thrown:

>>> while True:
... pass
...
(Ctrl-C pressed here)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>>

PostgreSQL's command line client, psql, behaves similarly. If you
accidentally issue an SQL statement that takes far longer than you
meant it to, you can press Ctrl-C and be back where you were before
you ran it. With MySQL the mysql client gets killed and you're back
at your shell prompt. I feel psql's behaviour is much more friendly.

--
Michael Wood <esio...@gmail.com>

Jason Wolfe

unread,
Mar 6, 2009, 5:05:58 PM3/6/09
to Clojure

> (Ctrl-C pressed here)
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> KeyboardInterrupt

That is something I miss from SBCL. In SLIME-SBCL, you can just Ctrl-
C Ctrl-C to interrupt your code. I think it's not possible (or at
least easy) in Clojure without adding debugging cruft to your compiled
code, since in general once your code gets going there's no safe way
to stop it. (In the future, this might be a nice option to add to the
compiler ...). Killing threads is depracated in Java since it can
cause all sorts of nastiness.

This was one of my motivations for writing these timing utils:

http://groups.google.com/group/clojure/browse_frm/thread/231cc06b4b13744c?hl=en#

If you wrap your code in "time-limit", and make sure to call (timeout)
periodically within it, it will automatically be killed if it runs too
long. And, even if you don't run your code in a "time-limit", you can
call (interrupt-all-threads) to kill it. This also screws with the
REPL and other threads in the ecosystem, but I've found that in SLIME
I can usually just start up a new REPL and pick up where I left off
without losing any state. I'm sure this could be improved upon
greatly, but it's worked for me so far.

Cheers,
Jason

Chouser

unread,
Mar 6, 2009, 5:58:23 PM3/6/09
to clo...@googlegroups.com
On Fri, Mar 6, 2009 at 5:05 PM, Jason Wolfe <jaw...@berkeley.edu> wrote:
>
>> (Ctrl-C pressed here)
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>> KeyboardInterrupt
>
> That is something I miss from SBCL.  In SLIME-SBCL, you can just Ctrl-
> C Ctrl-C to interrupt your code.

I just added a couple functions to clojure.contrib.repl-utils in an
attempt to support Ctrl-C:

user=> (use 'clojure.contrib.repl-utils)
nil
user=> (add-break-thread!)
{1 #<WeakReference java.lang.ref.WeakReference@e29820>}

This registers the current thread to be stopped next time an INT
signal is recieved, which happens when the user presses Ctrl-C. Try
this:

user=> (Thread/sleep 10000)

Then press Ctrl-C before the 10 seconds are up, and you'll see:

java.lang.Exception: SIGINT (NO_SOURCE_FILE:0)
user=>

...and you're back at the repl so you can try something else. This
works for busy loops and should work for IO and other blocking
behavior.

It does use Thread.stop(), which is deprecated and has all
kinds of important warnings. But are the risks of using Thread.stop()
really worse than the consequences of shutting down the entire JVM?
I'll leave that for you to decide.

Please let me know if this fails in some case, or even more
importantly if it causes any kind of breakage.

--Chouser

Jason Wolfe

unread,
Mar 6, 2009, 6:29:57 PM3/6/09
to clo...@googlegroups.com
> I just added a couple functions to clojure.contrib.repl-utils in an
> attempt to support Ctrl-C:
>
> user=> (use 'clojure.contrib.repl-utils)
> nil
> user=> (add-break-thread!)
> {1 #<WeakReference java.lang.ref.WeakReference@e29820>}
>
> This registers the current thread to be stopped next time an INT
> signal is recieved, which happens when the user presses Ctrl-C. Try
> this:
>
> user=> (Thread/sleep 10000)
>
> Then press Ctrl-C before the 10 seconds are up, and you'll see:
>
> java.lang.Exception: SIGINT (NO_SOURCE_FILE:0)
> user=>
>
> ...and you're back at the repl so you can try something else. This
> works for busy loops and should work for IO and other blocking
> behavior.

Sweet, that is slicker than my solution. It works for me seamlessly
in SLIME at the inferior-lisp REPL. For expressions typed at the
slime-repl I have to switch to the inferior-lisp buffer to send the C-
C C-C signal, which also kills the slime-repl in the process. Anyway,
the Lisp process seems to survive, and I can easily start a new REPL,
so this isn't the end of the world.

Thanks!
Jason

Raffael Cavallaro

unread,
Mar 7, 2009, 2:17:16 AM3/7/09
to Clojure


On Mar 6, 5:58 pm, Chouser <chou...@gmail.com> wrote:

> This registers the current thread to be stopped next time an INT
> signal is recieved, which happens when the user presses Ctrl-C.  Try
> this:
>
>   user=> (Thread/sleep 10000)
>
> Then press Ctrl-C before the 10 seconds are up, and you'll see:
>
>   java.lang.Exception: SIGINT (NO_SOURCE_FILE:0)
>   user=>
>
> ...and you're back at the repl so you can try something else.  This
> works for busy loops and should work for IO and other blocking
> behavior.

Thanks for this - I just added it to my user.clj and now my reflexive
Ctrl-C Ctrl-C in slime to break runaway functions no longer kills the
clojure repl. Very nice.
Reply all
Reply to author
Forward
0 new messages