Re: about the repl
I have submitted a patch for pprint's tendency to mess up when exceeding *print-length*. I assume that Stuart will apply it to the 1.3 (master) branch RSN, unless he sees a problem with it. Sorry for the inconvenience. Tom On Dec 21, 12:30 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Hmm, looks like I broke some logic when I hand unrolled the original cl-format based dispatch to get better performance for lists, vectors, and maps. (Really I shouldn't have to do this, but I need to make cl-format itself generate code rather than threaded functions which are slow and tend to blow your stack. Haven't gotten around to that yet, though so the hand-coded versions are stop-gaps.) I'm not digging the patch too much, though, for 3 reasons: 1) It breaks sets and arrays, which work in master. 2) It pushes the logic for *print-length* printing into the dispatch functions (redundantly since there's still logic in write-out). Since these are customizable, it places that load on whoever customizes it. 3) It adds redundant logic in write-out which is the called for every object that the pretty printer deals with. I'll try to take a stab at a patch that fits a little better with what I'm trying to do in the next couple of days. Tom On Sat, Dec 18, 2010 at 1:18 PM, Stuart Halloway stuart.hallo...@gmail.comwrote: The latter is easy to fix: provide a version of println that wraps an implicit (take n ...) around seq arguments (including when it calls itself on seqs nested within other structures). (*print-length* doesn't seem to work, just causes an infinite seq to print the first n items and then a never-ending string of ...s.) Hi Ken, In my tests *print-length* works fine with the regular REPL printer, but has the defect you describe when using pprint. Can you confirm that you are also seeing the problem with pprint, not print? Do some REPLs automatically replace print with pprint? Tom: I have created a ticket with a partial fix and would appreciate your input:http://dev.clojure.org/jira/browse/CLJ-695. Thanks, Stu -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
Well even if you don't like emacs it still serves as a decent repl :) Also if you don't like emacs you might try the eclipse counterclockwise plugin --- it has a nice repl too. good luck, --Robert McIntyre On Sat, Dec 18, 2010 at 2:56 AM, tor torgau...@gmail.com wrote: Thanks for the quick reply! I tried to get used to emacs a few years ago with little success. But I'm going to give it another try. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
Hi, Am 18.12.2010 um 09:00 schrieb Robert McIntyre: Also if you don't like emacs you might try the eclipse counterclockwise plugin --- it has a nice repl too. I think all of the major environments have decent repls. Emacs/swank, Eclipse/ccw, Netbeans/enclojure, Vim/VimClojure. What you are familiar with is probably the best choice. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
While this not what tor explicitly asked about, it is worth mentioning that the only way to kill an infinite loop in a Clojure repl is to kill the JVM. I too recommend experimenting with other environments (I use Emacs) -- just don't expect them to deal better with infinite loops than the REPL you are already using. Bill Smith -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Dec 18, 2010, at 8:23 AM, .Bill Smith wrote: While this not what tor explicitly asked about, it is worth mentioning that the only way to kill an infinite loop in a Clojure repl is to kill the JVM. Is this architecturally necessary, or might someone be able to provide a more flexible interrupt system some day? Having spent decades in other lisps one of the things I miss most in Clojure is the ability to interrupt a process from the keyboard, land in a break loop REPL, and be able to examine the local state in which the interrupt occurred, evaluate forms, possibly reset variables, and possibly restart the process. This is really handy when debugging, not only for infinite loops but for all sorts of long-running processes. I understand that in a multi-threaded application there might be choices about which thread(s) to interrupt, but it would be great to have anything along these lines. I also understand that allowing for this may have a runtime cost, but perhaps it could be turned on/off for development/deployment? -Lee -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Sat, Dec 18, 2010 at 10:34 AM, Lee Spector lspec...@hampshire.edu wrote: On Dec 18, 2010, at 8:23 AM, .Bill Smith wrote: While this not what tor explicitly asked about, it is worth mentioning that the only way to kill an infinite loop in a Clojure repl is to kill the JVM. Is this architecturally necessary, or might someone be able to provide a more flexible interrupt system some day? Having spent decades in other lisps one of the things I miss most in Clojure is the ability to interrupt a process from the keyboard, land in a break loop REPL, and be able to examine the local state in which the interrupt occurred, evaluate forms, possibly reset variables, and possibly restart the process. This is really handy when debugging, not only for infinite loops but for all sorts of long-running processes. I understand that in a multi-threaded application there might be choices about which thread(s) to interrupt, but it would be great to have anything along these lines. I also understand that allowing for this may have a runtime cost, but perhaps it could be turned on/off for development/deployment? There already exists clojure.contrib.repl-utils/add-break-thread! which attempts to address this. (http://clojure.github.com/clojure-contrib/repl-utils-api.html#clojure.contrib.repl-utils/add-break-thread!). I'm not sure there's any way to resume the broken-into threads though. Note that it's impossible in the JVM to cause threads to cancel in some cases (for instance are looping and never execute an interruptible function within the loop). -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
You don't necessarily need to kill the whole JVM. If your REPL implementation runs each command in a new Threadhttp://download.oracle.com/javase/6/docs/api/java/lang/Thread.html(as most of them do, I think) it can just stophttp://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop()the thread. That won't work in every situation (for example, a thread blocked waiting for I/O) but it will get you out of an infinite sequence. -Stuart Sierra clojure.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Dec 18, 2010, at 11:25 AM, Aaron Cohen wrote: There already exists clojure.contrib.repl-utils/add-break-thread! which attempts to address this. (http://clojure.github.com/clojure-contrib/repl-utils-api.html#clojure.contrib.repl-utils/add-break-thread!). I'm not sure there's any way to resume the broken-into threads though. It's not just resumption that's missing (at least in my experience -- see details below), but also the REPL in the context of the break (which is really the most useful thing for me anyway, to be able to look at the values of variables, including locals, at the point of the interruption). I'd love to know if I should be getting a break REPL and if I'm just doing something wrong. When I use add-break-thread! under Eclipse/CCW on a mac it seems to make no difference at all -- Cntrl-C doesn't do anything. But maybe that's Eclipse or Mac OS X getting in the way? When I run the same code from a java command line under linux it does change the behavior of Cntrl-C, but the only apparent difference is that I get a stack dump before termination. But I still end up back in the shell, with no REPL. Here's the code I was using to test this: (ns breaker (:require [clojure.contrib.repl-utils :as ru])) (ru/add-break-thread!) (loop [x 0] (println x) (recur (inc x))) And here's my java command line: java -cp $PWD:* clojure.main -i breaker.clj FWIW the 3 methods I've been using to run Clojure code are Eclipse/CCW, a java command line like the above, and recently cake (with or without TextMate). I suspect that someone may say that the way to do what I'm describing is with emacs... and my reply would be that that would be useful, and I'd like to know about it, but that I would also be (more) interested in a way to do it outside of an emacs-based development environment. I use emacs and have it set up for clojure but the setup issues and usability issues are a real pain for me, especially in a teaching context. -Lee -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Sat, Dec 18, 2010 at 11:43 AM, Stuart Sierra the.stuart.sie...@gmail.com wrote: You don't necessarily need to kill the whole JVM. If your REPL implementation runs each command in a new Thread (as most of them do, I think) it can just stop the thread. That won't work in every situation (for example, a thread blocked waiting for I/O) but it will get you out of an infinite sequence. The two commonest causes of repl hangs are * Buggy (loop ... recur) that does not terminate * Repl tries to print an infinite lazy seq The latter is easy to fix: provide a version of println that wraps an implicit (take n ...) around seq arguments (including when it calls itself on seqs nested within other structures). (*print-length* doesn't seem to work, just causes an infinite seq to print the first n items and then a never-ending string of ...s.) The former is a bit trickier, but with a debugging flag it could be done. When the flag is set, every (recur ...) form would compile into a check for an interrupted flag FOLLOWED by whatever the (recur ...) would normally produce. If the interrupted flag was set an exception would be thrown. This could be as simple as checking Thread/interrupted and throwing InterruptedException, the existing Java mechanism for this sort of thing. With the flag not set, (recur ...) forms compile as they do now. Then the repl only needs a way to interrupt the thread with a keystroke like control-C. The debug flag could also add interrupted checks to println, doseq, and doall to provide the ability to escape from most situations attempting to realize an infinite seq. This could be implemented by adding one new special form, (debuginterrupt), that does the interruption-check-and-throw and is omitted in non-debug compiles, inserting it in key places in functions like doseq and doall, and making recur a macro instead of a special form; it would call a recur* special form that was the old recur, so (defmacro recur [ stuff] `(do (debuginterrupt) (recur* ~...@stuff))) or similar. The repl would need to be implemented appropriately, though. Instead of the interaction and repl-issued commands running on the same thread the repl would have to spawn a separate thread for a submitted expression and then not accept inputs other than control-C until that thread returned. A GUI repl can handle this easily enough, using SwingWorker to launch the expression and letting the EDT catch both the SwingWorker being done and a control-C keystroke. A command line repl will have to roll its own EDT analogue for this. Control-C sends interrupt to the thread, and the usual result is probably an InterruptedException stack trace printing out and then a new repl prompt. The stack trace might be useful. Letting the user debug state and the like is trickier but (debuginterrupt) provides a suitable hook. Who says the only thing it can do on interrupt is throw an exception? It could also capture env and launch a GUI inspector or whatever. A mechanism could be provided for hooking on-interrupt behavior into this special form, with the default being (throw InterruptedException). In fact if there is a debug-vs.-production flag known at macroexpansion time, (debuginterrupt) can be a mere macro, something like (def interrupt-handler (atom (fn [_] (throw InterruptedException (defmacro debuginterrupt [] (if not-debug `(if (Thread/interrupted) (@interrupt-handler env (defmacro set-interrupt-handler [env body] `(reset! interrupt-handler (fn [~env] ~...@body))) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Dec 18, 2010, at 12:14 PM, Ken Wesson wrote: The two commonest causes of repl hangs are * Buggy (loop ... recur) that does not terminate * Repl tries to print an infinite lazy seq Not sure what the OP's interest is but FWIW the cases in which I most often want to break (and look around, e.g. using a REPL -- see previous message) are neither of these. Often I'm deep inside of some long-running computation that's not buggy in any of these straightforward senses but in which I want to see what's going on -- e.g. maybe because some structure got bigger than I expected and this is leading to an exponential slowdown somewhere, etc. Perhaps some of the suggestions later in your message provide a path towards a general interrupt and look around solution? That would be great. If I may be permitted (another) curmudgeonly wisecrack, this seems to be another area in which modern software development environments are slowly being dragged forward to where good lisp environments were a quarter of a century (!) ago. :-) -Lee -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Fri, 17 Dec 2010 22:45:01 -0800 (PST) tor torgau...@gmail.com wrote: Is there a way to activate word completion in the repl? I find myself hitting tab all the time... Since nobody else mentioned it (or even offered a solution other than Try my environment), you can use rlwrap (should be available in your systems package manager) to run your repl, and get word completion - among other goodies one wants on a command line. The appropriate rlwrap invocation is: rlwrap --command clojure --complete-filenames --quote-characters='' --prompt-colour=Red followed by whatever command you use to start the repl. You'll also want to past this code into a repl running in your home directory: (def completions (reduce concat (map (fn [ns] (keys (ns-publics ns))) (all-ns (defn save-completions-to [filename] (with-open [f (java.io.BufferedWriter. (java.io.FileWriter. filename))] (.write f (apply str (interleave completions (repeat \n)) (save-completions-to .clojure_completions) to create the list of completions for rlwrap. mike -- Mike Meyer m...@mired.org http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O ascii ribbon campaign - stop html mail - www.asciiribbon.org -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
The rlwrap method is very cool, but I can't seem to get ctrl-C to work (it still quits to the terminal) any advice? --Robert McIntyre On Sat, Dec 18, 2010 at 3:01 PM, Mike Meyer mwm-keyword-googlegroups.620...@mired.org wrote: On Fri, 17 Dec 2010 22:45:01 -0800 (PST) tor torgau...@gmail.com wrote: Is there a way to activate word completion in the repl? I find myself hitting tab all the time... Since nobody else mentioned it (or even offered a solution other than Try my environment), you can use rlwrap (should be available in your systems package manager) to run your repl, and get word completion - among other goodies one wants on a command line. The appropriate rlwrap invocation is: rlwrap --command clojure --complete-filenames --quote-characters='' --prompt-colour=Red followed by whatever command you use to start the repl. You'll also want to past this code into a repl running in your home directory: (def completions (reduce concat (map (fn [ns] (keys (ns-publics ns))) (all-ns (defn save-completions-to [filename] (with-open [f (java.io.BufferedWriter. (java.io.FileWriter. filename))] (.write f (apply str (interleave completions (repeat \n)) (save-completions-to .clojure_completions) to create the list of completions for rlwrap. mike -- Mike Meyer m...@mired.org http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O ascii ribbon campaign - stop html mail - www.asciiribbon.org -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
The latter is easy to fix: provide a version of println that wraps an implicit (take n ...) around seq arguments (including when it calls itself on seqs nested within other structures). (*print-length* doesn't seem to work, just causes an infinite seq to print the first n items and then a never-ending string of ...s.) Hi Ken, In my tests *print-length* works fine with the regular REPL printer, but has the defect you describe when using pprint. Can you confirm that you are also seeing the problem with pprint, not print? Do some REPLs automatically replace print with pprint? Tom: I have created a ticket with a partial fix and would appreciate your input: http://dev.clojure.org/jira/browse/CLJ-695. Thanks, Stu -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
On Sat, Dec 18, 2010 at 4:18 PM, Stuart Halloway stuart.hallo...@gmail.com wrote: The latter is easy to fix: provide a version of println that wraps an implicit (take n ...) around seq arguments (including when it calls itself on seqs nested within other structures). (*print-length* doesn't seem to work, just causes an infinite seq to print the first n items and then a never-ending string of ...s.) Hi Ken, In my tests *print-length* works fine with the regular REPL printer, but has the defect you describe when using pprint. Can you confirm that you are also seeing the problem with pprint, not print? Do some REPLs automatically replace print with pprint? The one built into Enclojure, for one. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
Stuart Sierra the.stuart.sie...@gmail.com writes: If your REPL implementation runs each command in a new Thread (as most of them do, I think) it can just stop the thread. That won't work in every situation (for example, a thread blocked waiting for I/O) but it will get you out of an infinite sequence. For just a plain command-line REPL on unix you can try running this before going into your infinite loop. Of course if something captures the ThreadDeath exception then it's not going to work. (sun.misc.Signal/handle (sun.misc.Signal. INT) (let [t (Thread/currentThread)] (proxy [sun.misc.SignalHandler] [] (handle [sig] (.stop t) Here's what it looks like when you hit Ctrl+C: user= (while true) ^Cjava.lang.ThreadDeath (NO_SOURCE_FILE:0) user= Under Emacs/Slime you can achieve the same thing by hitting C-c C-b (or M-x slime-interrupt). -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
That's really cool and has been added to my standard system stuff :) --Robert McIntyre On Sat, Dec 18, 2010 at 6:46 PM, Alex Osborne a...@meshy.org wrote: Stuart Sierra the.stuart.sie...@gmail.com writes: If your REPL implementation runs each command in a new Thread (as most of them do, I think) it can just stop the thread. That won't work in every situation (for example, a thread blocked waiting for I/O) but it will get you out of an infinite sequence. For just a plain command-line REPL on unix you can try running this before going into your infinite loop. Of course if something captures the ThreadDeath exception then it's not going to work. (sun.misc.Signal/handle (sun.misc.Signal. INT) (let [t (Thread/currentThread)] (proxy [sun.misc.SignalHandler] [] (handle [sig] (.stop t) Here's what it looks like when you hit Ctrl+C: user= (while true) ^Cjava.lang.ThreadDeath (NO_SOURCE_FILE:0) user= Under Emacs/Slime you can achieve the same thing by hitting C-c C-b (or M-x slime-interrupt). -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
You can execute (set! *print-length* 20) to avoid traps with printing infinite data structures. I'd also highly recommend the emacs/swank combo for your repl. It's got tab completion and a lot more. try http://riddell.us/ClojureSwankLeiningenWithEmacsOnLinux.html to learn how to get started with emacs and clojure. Hope that helps, --Robert McIntyre On Sat, Dec 18, 2010 at 1:45 AM, tor torgau...@gmail.com wrote: Hi, I have a couple of questions. If I start listing an infinite sequence in the repl and the press ctrl-c, I always exit to bash. Is there a way to interrupt without exiting the repl? Is there a way to activate word completion in the repl? I find myself hitting tab all the time... I use the linux repl.sh if case that makes a difference thanks in advance -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: about the repl
Thanks for the quick reply! I tried to get used to emacs a few years ago with little success. But I'm going to give it another try. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en