Re: Step by step debugging
Hi Ryan, Ryan Spangler ryan.spang...@gmail.com writes: I'll have an official announcement once it is ready to be released, but until then I welcome any feedback. I don't have time to test experimental stuff right now but I'm very much looking forward to reading your announcement! Thanks to tacking this. Best, -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Hi Marshall, Sure. Clojure implements locals clearing, which means that the compiler will set local variables to null when it knows that the value of those variables won't be used any more. This allows the garbage collector to reclaim any values that those variables were pointing to, which is particularly important in the case of large lazy sequences, which cache the values they return to ensure that the same sequence always returns the same values. What you'll see if this option is not set is that the majority of local variables (and of course, always the one you actually want to look at), especially further up the stack frames, will be set to null even if your code doesn't do so. This can be very confusing and/or frustrating when debugging. *compiler-options* is a dynamic var that controls various compiler options, although I believe disabling locals clearing is the only one at present. You control locals clearing by setting the value of :disable-locals-clearing in this map to true. There are various ways to do this - you could set it explicitly in the REPL, or you can set the system property clojure.compiler.disable-locals-clearing to the value you would like it to be set to. You can see the code that does this herehttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compile.java#L58, and if you're really interested the whole change is herehttps://github.com/clojure/clojure/commit/4036c7720949cb21ccf53c5c7c54ed1daaff2fda. You would set this system property in your JVM args, so if you're running an app from the command line using java ... then just add -Dclojure.compiler.disable-locals-clearing=true to your command line, or you can add it to your jvm-opts in leiningen as shown elsewhere in this thread. However note that the code I linked to above is actually in the main function of the compiler (I was wrong in my previous message, it's not clojure.main) so this system property will only apply when AOTing your code, not running it normally. In that case you'll have to do something like: (set! *compiler-options* {:disable-locals-clearing true}) or (binding [*compiler-options* (assoc *compiler-options* :disable-locals-clearing true)] ... your code here ...) somewhere right near the start of your code (I'm not on a dev machine so I haven't tested those, but that's the idea). The problem here is that you'll have to ensure that this variable is set before the code you're interested in is compiled! i.e. before its namespace is require'd, in the majority of cases. This is not too much of a problem in the REPL when you can always re-evaluate a namespace to recompile it, but it's a PITA in an application. In Cursive I actually do it in Java before I bootstrap Clojure. IMO this whole process is a fairly confusing which is unfortunate - I think a few changes would have made it much easier to work with, but that's how it currently works. Let me know if you have any more questions! Cheers, Colin On 13 November 2013 18:52, Mars0i marsh...@logical.net wrote: Sorry to keep replying to my own posts with corrections: Rereading previous posts, I think I understand now that Colin's comments about retaining locals were intended to be relevant only to possible future facilities (which would go beyond my current knowledge). But I'm still curious about where the -Dblahblah goes, etc. Thanks. On Tuesday, November 12, 2013 11:15:11 PM UTC-6, Mars0i wrote: Colin (or anyone), for a Clojure newbie, could you spell out what you're saying about *compiler-options* and -Dblahblah a little bit further? I think you're saying that if *compiler-options* is set to :disable-locals-clearing , then values of local variables are available, somehow. Can I see them from the lein REPL, somehow? If not, what do I get from :disable-locals-clearing ? It also sounds as if the only way to set *compiler-options* to :disable-locals-clearing is to use -Dclojure.compile.disable-locals-clearing=true . Where would I put that in a Leiningen project file? After :jvm-opts or :javac-options? Somewhere else? (I experimented with both, and with trying to set *command-options* in various ways, but I'm not what effect I should see.) Thanks- Marshall (Also, another big +1 for Lee's original comments, and thanks for all of the debugger suggestions from others. Locals are especially important when there's no state. I just recently started rewriting a Common Lisp application. The code had gotten too convoluted; parts of it are very old, with many layers of accretions. I've been doing the rewrite in Clojure as my first Clojure project. I'm seriously wondering at this moment, though, whether I should stop and do the rewrite in CL instead, despite several advantages of Clojure for me. Being able to easily look at any data structure at any time in the CL version of this application has been absolutely crucial in the past.) On Friday, November 8, 2013 11:13:01 PM UTC-6, Colin Fleming wrote:
Re: Step by step debugging
Thanks Colin! Wow--that's extremely helpful. The concepts are very clear now, and I now understand that it's a map *compiler-options* is supposed to be set to. What I was trying before wasn't right. No matter what I do, I am not seeing an effect on the value of *compiler-options* from the command line option. Tried :jvm-opts [-Dclojure.compiler.disable-locals-clearing=true] in a Leiningen project.clj, both with and without compiling to class files ahead of time. Tried it starting Clojure with a java command line from the prompt. I can't set the value of *compiler-options* with set!, but I'm able to set *compiler-options* with binding, and see that it's bound to {:disable-locals-clearing true} inside the binding form (of course). I'm still not clear on what effect this should have. I can refer to a local variable inside its scope, but that's nothing special. Is :disable-locals-clearing = true supposed to allow me to be able to reference a local outside of its scope? (A bad thing in general, but good, sometimes, for debugging?) For example, if I compile this: (defn yo [n] (if (= n 15) (throw (Exception. (format Yow!))) (if (= n 0) Done! (yo (dec n) with *compiler-options* set to {:disable-locals-clearing true}, is there a way to see, after the exception is thrown, that n had the value 15? Thanks- Marshall On Wednesday, November 13, 2013 3:45:27 AM UTC-6, Colin Fleming wrote: Hi Marshall, Sure. Clojure implements locals clearing, which means that the compiler will set local variables to null when it knows that the value of those variables won't be used any more. This allows the garbage collector to reclaim any values that those variables were pointing to, which is particularly important in the case of large lazy sequences, which cache the values they return to ensure that the same sequence always returns the same values. What you'll see if this option is not set is that the majority of local variables (and of course, always the one you actually want to look at), especially further up the stack frames, will be set to null even if your code doesn't do so. This can be very confusing and/or frustrating when debugging. *compiler-options* is a dynamic var that controls various compiler options, although I believe disabling locals clearing is the only one at present. You control locals clearing by setting the value of :disable-locals-clearing in this map to true. There are various ways to do this - you could set it explicitly in the REPL, or you can set the system property clojure.compiler.disable-locals-clearing to the value you would like it to be set to. You can see the code that does this herehttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compile.java#L58, and if you're really interested the whole change is herehttps://github.com/clojure/clojure/commit/4036c7720949cb21ccf53c5c7c54ed1daaff2fda. You would set this system property in your JVM args, so if you're running an app from the command line using java ... then just add -Dclojure.compiler.disable-locals-clearing=true to your command line, or you can add it to your jvm-opts in leiningen as shown elsewhere in this thread. However note that the code I linked to above is actually in the main function of the compiler (I was wrong in my previous message, it's not clojure.main) so this system property will only apply when AOTing your code, not running it normally. In that case you'll have to do something like: (set! *compiler-options* {:disable-locals-clearing true}) or (binding [*compiler-options* (assoc *compiler-options* :disable-locals-clearing true)] ... your code here ...) somewhere right near the start of your code (I'm not on a dev machine so I haven't tested those, but that's the idea). The problem here is that you'll have to ensure that this variable is set before the code you're interested in is compiled! i.e. before its namespace is require'd, in the majority of cases. This is not too much of a problem in the REPL when you can always re-evaluate a namespace to recompile it, but it's a PITA in an application. In Cursive I actually do it in Java before I bootstrap Clojure. IMO this whole process is a fairly confusing which is unfortunate - I think a few changes would have made it much easier to work with, but that's how it currently works. Let me know if you have any more questions! Cheers, Colin -- -- 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
Re: Step by step debugging
Hi Marshall, You'll only see a difference due to locals clearing if you're stepping with a debugger and looking at locals in your local stack frame or in the frames above it. In your example, the ability to pause when an exception is thrown is a capability your debugger provides. Cursive does provide this (although I need to test it thoroughly, most of the functionality is provided by IntelliJ and I haven't tested it all with Clojure yet), I'm not sure about other debuggers. So if your debugger provides that capability, when you pause on the thrown exception, if you didn't have locals clearing disabled when that code was compiled you'll see the value of n as null since the compiler has inferred that the value is never used in the branch you took (the branch throwing the exception) and has nulled it out. If you had locals clearing disabled when that code was compiled, then you will correctly see the value of n as 15, yes. Cheers, Colin On 14 November 2013 08:53, Mars0i marsh...@logical.net wrote: Thanks Colin! Wow--that's extremely helpful. The concepts are very clear now, and I now understand that it's a map *compiler-options* is supposed to be set to. What I was trying before wasn't right. No matter what I do, I am not seeing an effect on the value of *compiler-options* from the command line option. Tried :jvm-opts [-Dclojure.compiler.disable-locals-clearing=true] in a Leiningen project.clj, both with and without compiling to class files ahead of time. Tried it starting Clojure with a java command line from the prompt. I can't set the value of *compiler-options* with set!, but I'm able to set *compiler-options* with binding, and see that it's bound to {:disable-locals-clearing true} inside the binding form (of course). I'm still not clear on what effect this should have. I can refer to a local variable inside its scope, but that's nothing special. Is :disable-locals-clearing = true supposed to allow me to be able to reference a local outside of its scope? (A bad thing in general, but good, sometimes, for debugging?) For example, if I compile this: (defn yo [n] (if (= n 15) (throw (Exception. (format Yow!))) (if (= n 0) Done! (yo (dec n) with *compiler-options* set to {:disable-locals-clearing true}, is there a way to see, after the exception is thrown, that n had the value 15? Thanks- Marshall On Wednesday, November 13, 2013 3:45:27 AM UTC-6, Colin Fleming wrote: Hi Marshall, Sure. Clojure implements locals clearing, which means that the compiler will set local variables to null when it knows that the value of those variables won't be used any more. This allows the garbage collector to reclaim any values that those variables were pointing to, which is particularly important in the case of large lazy sequences, which cache the values they return to ensure that the same sequence always returns the same values. What you'll see if this option is not set is that the majority of local variables (and of course, always the one you actually want to look at), especially further up the stack frames, will be set to null even if your code doesn't do so. This can be very confusing and/or frustrating when debugging. *compiler-options* is a dynamic var that controls various compiler options, although I believe disabling locals clearing is the only one at present. You control locals clearing by setting the value of :disable-locals-clearing in this map to true. There are various ways to do this - you could set it explicitly in the REPL, or you can set the system property clojure.compiler.disable-locals-clearing to the value you would like it to be set to. You can see the code that does this herehttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compile.java#L58, and if you're really interested the whole change is herehttps://github.com/clojure/clojure/commit/4036c7720949cb21ccf53c5c7c54ed1daaff2fda. You would set this system property in your JVM args, so if you're running an app from the command line using java ... then just add -Dclojure.compiler.disable-locals-clearing=true to your command line, or you can add it to your jvm-opts in leiningen as shown elsewhere in this thread. However note that the code I linked to above is actually in the main function of the compiler (I was wrong in my previous message, it's not clojure.main) so this system property will only apply when AOTing your code, not running it normally. In that case you'll have to do something like: (set! *compiler-options* {:disable-locals-clearing true}) or (binding [*compiler-options* (assoc *compiler-options* :disable-locals-clearing true)] ... your code here ...) somewhere right near the start of your code (I'm not on a dev machine so I haven't tested those, but that's the idea). The problem here is that you'll have to ensure that this variable is set before the code you're interested in is compiled! i.e.
Re: Step by step debugging
Colin, Got it--this setting is relevant to use of a debugger. I was trying to see something from vanilla and Leiningen repls. Thank you for taking so much time to explain. (My current debugger is (print (format ...)). Have to upgrade.) -Marshall On Wednesday, November 13, 2013 5:16:27 PM UTC-6, Colin Fleming wrote: Hi Marshall, You'll only see a difference due to locals clearing if you're stepping with a debugger and looking at locals in your local stack frame or in the frames above it. In your example, the ability to pause when an exception is thrown is a capability your debugger provides. Cursive does provide this (although I need to test it thoroughly, most of the functionality is provided by IntelliJ and I haven't tested it all with Clojure yet), I'm not sure about other debuggers. So if your debugger provides that capability, when you pause on the thrown exception, if you didn't have locals clearing disabled when that code was compiled you'll see the value of n as null since the compiler has inferred that the value is never used in the branch you took (the branch throwing the exception) and has nulled it out. If you had locals clearing disabled when that code was compiled, then you will correctly see the value of n as 15, yes. Cheers, Colin -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
I would imagine that cinc could side-step any jvm-imposed limitations on developing a reference debugger for clojure. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-) I have started a project that does this: a browser based debugger that breaks on exceptions (it attaches to a dt_socket port): https://github.com/prismofeverything/schmetterling I should have locals displaying this week sometime (you can currently get their value, it just doesn't show them to you by default yet). I am planning on adding breakpoints, stepping and source viewing. Just started this... looking for feedback! On Thursday, November 7, 2013 1:16:17 AM UTC-8, Bastien Guerry wrote: I'm a big fan of edebug, the Emacs debugger, which allows step through debugging (and breakpoints, and some more fun.) Is there anything similar for Clojure? For example, from an Emacs (cider) REPL, I'd evaluate some Clojure expression, then a window would let me go through a buffer containing a copy of the function being evaluated, while allowing me to stop at any step, and to show the result of each step in the minibuffer. (I'm aware of LightTable live REPL, but this is not exactly what I describe above.) Thanks for any hints/pointers, -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Very excited by this. Thanks also to Justin for the pointer. From my perspective a particularly nice additional would be to provide minimal instructions on how to get this running for people who don't know (or necessarily want to have to know) what a dt_socket is. On Nov 12, 2013, at 7:11 PM, Ryan Spangler wrote: Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-) I have started a project that does this: a browser based debugger that breaks on exceptions (it attaches to a dt_socket port): https://github.com/prismofeverything/schmetterling I should have locals displaying this week sometime (you can currently get their value, it just doesn't show them to you by default yet). I am planning on adding breakpoints, stepping and source viewing. Just started this... looking for feedback! -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Colin (or anyone), for a Clojure newbie, could you spell out what you're saying about *compiler-options* and -Dblahblah a little bit further? I think you're saying that if *compiler-options* is set to :disable-locals-clearing , then values of local variables are available, somehow. Can I see them from the lein REPL, somehow? If not, what do I get from :disable-locals-clearing ? It also sounds as if the only way to set *compiler-options* to :disable-locals-clearing is to use -Dclojure.compile.disable-locals-clearing=true . Where would I put that in a Leiningen project file? After :jvm-opts or :javac-options? Somewhere else? (I experimented with both, and with trying to set *command-options* in various ways, but I'm not what effect I should see.) Thanks- Marshall (Also, another big +1 for Lee's original comments, and thanks for all of the debugger suggestions from others. Locals are especially important when there's no state. I just recently started rewriting a Common Lisp application. The code had gotten too convoluted; parts of it are very old, with many layers of accretions. I've been doing the rewrite in Clojure as my first Clojure project. I'm seriously wondering at this moment, though, whether I should stop and do the rewrite in CL instead, despite several advantages of Clojure for me. Being able to easily look at any data structure at any time in the CL version of this application has been absolutely crucial in the past.) On Friday, November 8, 2013 11:13:01 PM UTC-6, Colin Fleming wrote: One quick clarification about -Dclojure.compile.disable-locals-clearing=true which bit me - this is actually read in clojure.main, which uses it to initialise the *compiler-options* var. This means that if you start your app in any other way (I'm not sure if lein duplicates the clojure.main functionality) setting this system property doesn't do anything. On 8 November 2013 10:22, Alex Miller al...@puredanger.com javascript:wrote: I believe the locals are actually *not* available because they are proactively cleared to help GC. Setting the *compiler-options* var with :disable-locals-clearing can turn that off. Which is probably what you often want in dev, but is not the default. You can also set this via command line with -Dclojure.compile.disable-locals-clearing=true On Thursday, November 7, 2013 11:32:29 AM UTC-6, Lee wrote: I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or from Eclipse/CCW (or I think from any other way that I might run it) I get (or can easily get) a backtrace that shows the function call stack at the time of the error... which is good, but surely (?) the locals are also available when the backtrace is produced and I really also want to see those. The ability to browse and navigate this information dynamically, as in a Common Lisp break loop, is cool but I
Re: Step by step debugging
On Tuesday, November 12, 2013 11:15:11 PM UTC-6, Mars0i wrote: ... I'm seriously wondering at this moment, though, whether I should stop and do the rewrite in CL instead, despite several advantages of Clojure for me. Being able to easily look at any data structure at any time in the CL version of this application has been absolutely crucial in the past.) Sorry, that didn't make sense. The right thing to say was I guess I'd better go investigate the debugger options that have been mentioned. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Sorry to keep replying to my own posts with corrections: Rereading previous posts, I think I understand now that Colin's comments about retaining locals were intended to be relevant only to possible future facilities (which would go beyond my current knowledge). But I'm still curious about where the -Dblahblah goes, etc. Thanks. On Tuesday, November 12, 2013 11:15:11 PM UTC-6, Mars0i wrote: Colin (or anyone), for a Clojure newbie, could you spell out what you're saying about *compiler-options* and -Dblahblah a little bit further? I think you're saying that if *compiler-options* is set to :disable-locals-clearing , then values of local variables are available, somehow. Can I see them from the lein REPL, somehow? If not, what do I get from :disable-locals-clearing ? It also sounds as if the only way to set *compiler-options* to :disable-locals-clearing is to use -Dclojure.compile.disable-locals-clearing=true . Where would I put that in a Leiningen project file? After :jvm-opts or :javac-options? Somewhere else? (I experimented with both, and with trying to set *command-options* in various ways, but I'm not what effect I should see.) Thanks- Marshall (Also, another big +1 for Lee's original comments, and thanks for all of the debugger suggestions from others. Locals are especially important when there's no state. I just recently started rewriting a Common Lisp application. The code had gotten too convoluted; parts of it are very old, with many layers of accretions. I've been doing the rewrite in Clojure as my first Clojure project. I'm seriously wondering at this moment, though, whether I should stop and do the rewrite in CL instead, despite several advantages of Clojure for me. Being able to easily look at any data structure at any time in the CL version of this application has been absolutely crucial in the past.) On Friday, November 8, 2013 11:13:01 PM UTC-6, Colin Fleming wrote: One quick clarification about -Dclojure.compile.disable-locals-clearing=true which bit me - this is actually read in clojure.main, which uses it to initialise the *compiler-options* var. This means that if you start your app in any other way (I'm not sure if lein duplicates the clojure.main functionality) setting this system property doesn't do anything. On 8 November 2013 10:22, Alex Miller al...@puredanger.com wrote: I believe the locals are actually *not* available because they are proactively cleared to help GC. Setting the *compiler-options* var with :disable-locals-clearing can turn that off. Which is probably what you often want in dev, but is not the default. You can also set this via command line with -Dclojure.compile.disable-locals-clearing=true On Thursday, November 7, 2013 11:32:29 AM UTC-6, Lee wrote: I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or
Re: Step by step debugging
Lee, Thank you for pointing that out! The README has been updated with more explicit instructions. For those who don't know, to open a dt_socket from your project.clj simply add this line: :jvm-opts [-agentlib:jdwp=transport=dt_socket,server=y,suspend=n] Schmetterling is still very new (I just started it last week!) and not really meant to be released yet, but it is still useful. And actually the earlier people start using it the earlier I can start improving it in ways that are relevant to people. I'll have an official announcement once it is ready to be released, but until then I welcome any feedback. On Tuesday, November 12, 2013 8:33:57 PM UTC-8, Lee wrote: Very excited by this. Thanks also to Justin for the pointer. From my perspective a particularly nice additional would be to provide minimal instructions on how to get this running for people who don't know (or necessarily want to have to know) what a dt_socket is. On Nov 12, 2013, at 7:11 PM, Ryan Spangler wrote: Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-) I have started a project that does this: a browser based debugger that breaks on exceptions (it attaches to a dt_socket port): https://github.com/prismofeverything/schmetterling I should have locals displaying this week sometime (you can currently get their value, it just doesn't show them to you by default yet). I am planning on adding breakpoints, stepping and source viewing. Just started this... looking for feedback! -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
On Thursday, November 7, 2013 6:32:29 PM UTC+1, Lee wrote: In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. inc -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
As far as I can see, though ritz is not Emacs specific per se. It's a set of middleware for nrepl. So you should be able to build clients against it for different environments, including a textual one. There's no reason that a debugger shouldn't be part of lein. I think making it work with java -jar clojure.jar would be harder because you need two JVMs (one running the clojure process, and one the debugger). Phil Lee Spector lspec...@hampshire.edu writes: Not as good as having it work everywhere with whatever you're already using, of course, but certainly better than (for example) requiring that you figure out how to install and use an Emacs-based environment just to figure out what values your locals have when you crash. Would what you have in mind work from lein run as well as lein repl? FWIW I (and my students) do a lot via lein run. -Lee On Nov 7, 2013, at 2:47 PM, Andy Fingerhut wrote: Lee, I am curious whether you would consider it too tied to a particular dev environment if the kind of minimal debugging features you wish for worked from Leiningen's REPL? i.e. 'lein repl' I do not know if Ritz can work in such an environment or not, but I am guessing it might be easier to get a subset of it working there than from a REPL started via 'java -cp clojure.jar clojure.main' Andy -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
One quick clarification about -Dclojure.compile.disable-locals-clearing=true which bit me - this is actually read in clojure.main, which uses it to initialise the *compiler-options* var. This means that if you start your app in any other way (I'm not sure if lein duplicates the clojure.main functionality) setting this system property doesn't do anything. On 8 November 2013 10:22, Alex Miller a...@puredanger.com wrote: I believe the locals are actually *not* available because they are proactively cleared to help GC. Setting the *compiler-options* var with :disable-locals-clearing can turn that off. Which is probably what you often want in dev, but is not the default. You can also set this via command line with -Dclojure.compile.disable-locals-clearing=true On Thursday, November 7, 2013 11:32:29 AM UTC-6, Lee wrote: I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or from Eclipse/CCW (or I think from any other way that I might run it) I get (or can easily get) a backtrace that shows the function call stack at the time of the error... which is good, but surely (?) the locals are also available when the backtrace is produced and I really also want to see those. The ability to browse and navigate this information dynamically, as in a Common Lisp break loop, is cool but I can understand that something about the Clojure/JVM execution architecture might make that difficult -- maybe that really would have to be tied to a particular IDE? However, if it would just dump all of the values of the locals to standard output, just like it does already with the trace, then I'd be plenty happy since I could dig through that output to find what I need but can't currently get. (Yes, dumping the values of all of the locals might produce a lot of output and yes, one might want to make this an option that could be turned off or on, maybe including options re: limits on how much of sequences to print, etc.) I guess the bottom line of this long message (sorry) is that I hope that some of the great tool developers in this community will continue to consider providing things like debugging tools that are as untethered as possible from particular IDEs. My impression is that nrepl (and maybe other projects) are intended to help untether things in this way, but it still seems like a lot of people assume that something like access to locals should naturally be tied to a specific IDE. From my perspective that seems like a really unfortunate assumption. I realize that debugging tools are unlikely to become part of the language in Clojure as they are in Common Lisp, but I think there's an important middle ground between that and being available only within some specific IDE. Thanks, -Lee philli...@newcastle.ac.uk (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any
Re: Step by step debugging
Cedric, you're right in both your assessment of the potential solution (this could definitely be done) and also the problems. You'd need an additional line number mapping of original source line to expanded-lines source line to be able to make any sense of stack traces, thread dumps etc, and of course your debugger would need to use it to correctly highlight the current line. It's a nice idea but I fear it's not very practical. I'll think about it a bit, though, and see if I can take advantage of it in some way. I thought there was an additional line limit per class that might have been problematic but I was wrong, it's a bytecode size limit per method. On 8 November 2013 19:24, Cedric Greevey cgree...@gmail.com wrote: This JVMTI doesn't know Clojure source code from parsnip soup, I expect, so can't it be fooled into thinking that the bytecode it's interpreting came from a source with many more, shorter lines? So (defn x [y z] (a (b (c)) ((d) e (f g could be passed off to it as if it were (defn x [y z] (a (b (c)) ((d) e (f g with breakpoints on (defn ...), (a ...), a, (b (c)), or b being passed to JVMTI as breakpoints on the first line of the latter formatting of the code; breakpoints on (c) or c the second line; breakpoints on (d) or d the third line; and breakpoints on e, (f g), f, or g the fourth line. Execution would halt at the breakpoint with the correct amount of evaluation done. (The bare letters are presumed to be self-evaluating literals or var lookups here, and the operators, other than defn, to be functions.) Breakpoints on a macro sexp would need to halt on the first evaluation of any of the expansion, and breakpoints on a macro argument would need to be carried through into the expansion. The special forms are mostly fairly obvious -- break on an if or its condition, for example, breaks before evaluating the condition; break on the then clause breaks after evaluating the condition, before evaluating the then clause, only if the condition was true; etc. Combined, those rules mean a breakpoint on a particular (cond ...) condition X would only trip if all the previous conditions were false, before evaluating condition X, and a breakpoint on the corresponding then clause only if all the preceding conditions were false but condition X was true, after evaluating X but before evaluating X's then clause, because it would end up attached to X's corresponding conditional or then clause (respectively) in the macro-expanded if-tree ((sexp) indicates breakpoint target): (cond (thing1) (dothis) (thing2) (dothat) (thing3) (dosomethingelse) :else (default)) should macroexpand to (if (thing1) (dothis) (if (thing2) (dothat) (if (thing3) (dosomethingelse) (if :else (default) (throw ( ... no matching clause blah blah ... [never actually executes in this case])) so the (if (thing3) line would be what JVMTI thinks is the breakpointed line in this case. The real issue I can foresee here would be if there's no way to make the lines seen by the breakpoint/debugging stuff be different from the lines used for error reporting (e.g. in stacktraces), as then *either* the line granularity for breakpoints is whole lines of your actual source code *or* stacktrace line numbers won't always correspond to what your editor shows for the problem line in your source code, for example if (default) threw a ClassCastException because default did not implement IFn in the above the stacktrace might point to line 8 when it was really line 5 of your (cond ...) expression (but line 8 of the (if ...) it macroexpanded to, and which was vertically spread out to put each distinct (as to what nontrivial evaluation has happened yet) sexp-based breakpoint position on its own line to please JVMTI). On Fri, Nov 8, 2013 at 12:53 AM, Colin Fleming colin.mailingl...@gmail.com wrote: Right, sadly I believe this is impossible using JVMTI, although I'm far from an expert. On 8 November 2013 18:51, Cedric Greevey cgree...@gmail.com wrote: Ideally, in a Lisp I'd think the unit of breakpoints would not be a line but instead an s-expression, tripping before evaluating the body of the expression. On Fri, Nov 8, 2013 at 12:24 AM, Colin Fleming colin.mailingl...@gmail.com wrote: I'm slightly late to the discussion, sorry - currently moving cities. Cursive does indeed have a stepping debugger which works well with Clojure, although it's quite slow (I haven't been able to figure out why, yet - I suspect Clojure adds a lot of line information to the bytecode). There have also been some fairly annoying bugs with it which will be fixed in the next drop. Here's more or less what it can do: 1. Standard stepping - step into, step over. Step out is flaky for non-Java languages for some reason, I believe this is fixed in the
Re: Step by step debugging
Hi Bastien, I think Ritz https://github.com/pallet/ritz [1] might be what you are looking for. Although I haven't tried it myself yet, I recently saw the presentation Ritz, The Missing Clojure Tooling and really liked what I saw. HTH, J [1]: https://github.com/pallet/ritz [2]: http://www.infoq.com/presentations/ritz-clojure On Thursday, November 7, 2013 5:16:17 PM UTC+8, Bastien Guerry wrote: I'm a big fan of edebug, the Emacs debugger, which allows step through debugging (and breakpoints, and some more fun.) Is there anything similar for Clojure? For example, from an Emacs (cider) REPL, I'd evaluate some Clojure expression, then a window would let me go through a buffer containing a copy of the function being evaluated, while allowing me to stop at any step, and to show the result of each step in the minibuffer. (I'm aware of LightTable live REPL, but this is not exactly what I describe above.) Thanks for any hints/pointers, -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Hi Juan, juan.facorro juan.faco...@gmail.com writes: I think Ritz [1] might be what you are looking for. Although I haven't tried it myself yet, I recently saw the presentation Ritz, The Missing Clojure Tooling and really liked what I saw. This seems great indeed, I'll watch the presentation carefully. Thanks! -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. Phil Bastien bastiengue...@gmail.com writes: I'm a big fan of edebug, the Emacs debugger, which allows step through debugging (and breakpoints, and some more fun.) Is there anything similar for Clojure? For example, from an Emacs (cider) REPL, I'd evaluate some Clojure expression, then a window would let me go through a buffer containing a copy of the function being evaluated, while allowing me to stop at any step, and to show the result of each step in the minibuffer. (I'm aware of LightTable live REPL, but this is not exactly what I describe above.) Thanks for any hints/pointers, -- Bastien -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
phillip.l...@newcastle.ac.uk (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. Well, I suspect this -- but I'll see what comes close enough. Best, -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
If you're willing to look outside of Emacs *shock* *horror*, both Eclipse CCW and IntelliJ Cursive have debuggers that work to some degree with Clojure. On Thursday, November 7, 2013 3:16:17 AM UTC-6, Bastien Guerry wrote: I'm a big fan of edebug, the Emacs debugger, which allows step through debugging (and breakpoints, and some more fun.) Is there anything similar for Clojure? For example, from an Emacs (cider) REPL, I'd evaluate some Clojure expression, then a window would let me go through a buffer containing a copy of the function being evaluated, while allowing me to stop at any step, and to show the result of each step in the minibuffer. (I'm aware of LightTable live REPL, but this is not exactly what I describe above.) Thanks for any hints/pointers, -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Hi Alex, Alex Miller a...@puredanger.com writes: If you're willing to look outside of Emacs *shock* *horror*, both Eclipse CCW and IntelliJ Cursive have debuggers that work to some degree with Clojure. I love testing new tools, I did not sign a life-time contract with any software ;) Is there a video somewhere where I can see this debugging tools in action? Thanks! -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Not to my knowledge. (if anyone wants to make one, that would be useful hint hint) I would try asking on the CCW list at https://groups.google.com/forum/#!msg/clojuredev-users/ for help on the CCW/Eclipse debugger. For Cursive, there is some info at http://cursiveclojure.com/userguide/repl.html on starting a debug REPL. On Thu, Nov 7, 2013 at 8:37 AM, Bastien bastiengue...@gmail.com wrote: Hi Alex, Alex Miller a...@puredanger.com writes: If you're willing to look outside of Emacs *shock* *horror*, both Eclipse CCW and IntelliJ Cursive have debuggers that work to some degree with Clojure. I love testing new tools, I did not sign a life-time contract with any software ;) Is there a video somewhere where I can see this debugging tools in action? Thanks! -- Bastien -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
There is redl which does some of this too, that's more for the vim workflow though On Thursday, November 7, 2013, Phillip Lord wrote: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. Phil Bastien bastiengue...@gmail.com javascript:; writes: I'm a big fan of edebug, the Emacs debugger, which allows step through debugging (and breakpoints, and some more fun.) Is there anything similar for Clojure? For example, from an Emacs (cider) REPL, I'd evaluate some Clojure expression, then a window would let me go through a buffer containing a copy of the function being evaluated, while allowing me to stop at any step, and to show the result of each step in the minibuffer. (I'm aware of LightTable live REPL, but this is not exactly what I describe above.) Thanks for any hints/pointers, -- Bastien -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk javascript:; School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.comjavascript:; 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 javascript:; 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com javascript:;. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or from Eclipse/CCW (or I think from any other way that I might run it) I get (or can easily get) a backtrace that shows the function call stack at the time of the error... which is good, but surely (?) the locals are also available when the backtrace is produced and I really also want to see those. The ability to browse and navigate this information dynamically, as in a Common Lisp break loop, is cool but I can understand that something about the Clojure/JVM execution architecture might make that difficult -- maybe that really would have to be tied to a particular IDE? However, if it would just dump all of the values of the locals to standard output, just like it does already with the trace, then I'd be plenty happy since I could dig through that output to find what I need but can't currently get. (Yes, dumping the values of all of the locals might produce a lot of output and yes, one might want to make this an option that could be turned off or on, maybe including options re: limits on how much of sequences to print, etc.) I guess the bottom line of this long message (sorry) is that I hope that some of the great tool developers in this community will continue to consider providing things like debugging tools that are as untethered as possible from particular IDEs. My impression is that nrepl (and maybe other projects) are intended to help untether things in this way, but it still seems like a lot of people assume that something like access to locals should naturally be tied to a specific IDE. From my perspective that seems like a really unfortunate assumption. I realize that debugging tools are unlikely to become part of the language in Clojure as they are in Common Lisp, but I think there's an important middle ground between that and being available only within some specific IDE. Thanks, -Lee phillip.l...@newcastle.ac.uk (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
There is redl which does some of this too, that's more for the vim workflow though On Thursday, November 7, 2013, Phillip Lord wrote: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. Phil Bastien bastiengue...@gmail.com javascript:; writes: I'm a big fan of edebug, the Emacs debugger, which allows step through debugging (and breakpoints, and some more fun.) Is there anything similar for Clojure? For example, from an Emacs (cider) REPL, I'd evaluate some Clojure expression, then a window would let me go through a buffer containing a copy of the function being evaluated, while allowing me to stop at any step, and to show the result of each step in the minibuffer. (I'm aware of LightTable live REPL, but this is not exactly what I describe above.) Thanks for any hints/pointers, -- Bastien -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk javascript:; School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.comjavascript:; 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 javascript:; 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com javascript:;. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Hi Lee, you made me cry (almost). I've been working in the eighties on Lisp Machine (both Symbolics and Texas Instruments) and I still have to see a programming environment comparable to the one I was using 30 years ago. At the moment we're still far way from those happy days. Well written! My Best Mimmo On Nov 7, 2013, at 6:32 PM, Lee Spector lspec...@hampshire.edu wrote: I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or from Eclipse/CCW (or I think from any other way that I might run it) I get (or can easily get) a backtrace that shows the function call stack at the time of the error... which is good, but surely (?) the locals are also available when the backtrace is produced and I really also want to see those. The ability to browse and navigate this information dynamically, as in a Common Lisp break loop, is cool but I can understand that something about the Clojure/JVM execution architecture might make that difficult -- maybe that really would have to be tied to a particular IDE? However, if it would just dump all of the values of the locals to standard output, just like it does already with the trace, then I'd be plenty happy since I could dig through that output to find what I need but can't currently get. (Yes, dumping the values of all of the locals might produce a lot of output and yes, one might want to make this an option that could be turned off or on, maybe including options re: limits on how much of sequences to print, etc.) I guess the bottom line of this long message (sorry) is that I hope that some of the great tool developers in this community will continue to consider providing things like debugging tools that are as untethered as possible from particular IDEs. My impression is that nrepl (and maybe other projects) are intended to help untether things in this way, but it still seems like a lot of people assume that something like access to locals should naturally be tied to a specific IDE. From my perspective that seems like a really unfortunate assumption. I realize that debugging tools are unlikely to become part of the language in Clojure as they are in Common Lisp, but I think there's an important middle ground between that and being available only within some specific IDE. Thanks, -Lee phillip.l...@newcastle.ac.uk (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. -- -- 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
Re: Step by step debugging
Lee, I am curious whether you would consider it too tied to a particular dev environment if the kind of minimal debugging features you wish for worked from Leiningen's REPL? i.e. 'lein repl' I do not know if Ritz can work in such an environment or not, but I am guessing it might be easier to get a subset of it working there than from a REPL started via 'java -cp clojure.jar clojure.main' Andy On Thu, Nov 7, 2013 at 9:32 AM, Lee Spector lspec...@hampshire.edu wrote: I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or from Eclipse/CCW (or I think from any other way that I might run it) I get (or can easily get) a backtrace that shows the function call stack at the time of the error... which is good, but surely (?) the locals are also available when the backtrace is produced and I really also want to see those. The ability to browse and navigate this information dynamically, as in a Common Lisp break loop, is cool but I can understand that something about the Clojure/JVM execution architecture might make that difficult -- maybe that really would have to be tied to a particular IDE? However, if it would just dump all of the values of the locals to standard output, just like it does already with the trace, then I'd be plenty happy since I could dig through that output to find what I need but can't currently get. (Yes, dumping the values of all of the locals might produce a lot of output and yes, one might want to make this an option that could be turned off or on, maybe including options re: limits on how much of sequences to print, etc.) I guess the bottom line of this long message (sorry) is that I hope that some of the great tool developers in this community will continue to consider providing things like debugging tools that are as untethered as possible from particular IDEs. My impression is that nrepl (and maybe other projects) are intended to help untether things in this way, but it still seems like a lot of people assume that something like access to locals should naturally be tied to a specific IDE. From my perspective that seems like a really unfortunate assumption. I realize that debugging tools are unlikely to become part of the language in Clojure as they are in Common Lisp, but I think there's an important middle ground between that and being available only within some specific IDE. Thanks, -Lee phillip.l...@newcastle.ac.uk (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. -- -- 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
Re: Step by step debugging
I believe the locals are actually *not* available because they are proactively cleared to help GC. Setting the *compiler-options* var with :disable-locals-clearing can turn that off. Which is probably what you often want in dev, but is not the default. You can also set this via command line with -Dclojure.compile.disable-locals-clearing=true On Thursday, November 7, 2013 11:32:29 AM UTC-6, Lee wrote: I'd like to chime in here from a background that involved a lot of Common Lisping back in the day. I have been continually dismayed, as I've moved further from Common Lisp, that debugging facilities that are so basic and ubiquitous and helpful in that world are considered exotic or specialized or necessarily tied to particular IDEs or tool chains in other language ecosystems. Even more basic (and useful, in my experience) than things like steppers or the ability to set break points is the ability just to see the values of locals when an error occurs. This is so obviously useful, and so obviously doable (for decades), that I'm really quite stunned that it's so complicated to do in Clojure and tied to a particular toolset if you can do it at all. In Common Lisp when you hit an error you're thrown into a break loop REPL in which you can view locals, move up and down the stack, and do lots of other fancier things (re-binding things, restarting...) that are probably useful in some situations, but just being able to see the locals is, in my experience, the really huge win. It doesn't matter what IDE you're using or if you're running it from a command line or whatever -- it's part of the language and easy to access no matter how you write and run your code. And my guess is that every Common Lisper takes advantage of this frequently. Different implementations/environments provide different modes of access to this information (e.g. some are GUI-based, and in emacs you can have interactive access to it using interaction conventions that seemed like a good idea in the 1970s :-), but there's always some way to get the information. By contrast in Clojure this information seems really hard to come by. I saw and was excited by a Ritz video -- and I note the enthusiastic applause from the crowd when it was shown that you could see locals (gasp!) -- but my understanding is that this functionality requires commitment to an Emacs-based tool set with all that that implies (which is a lot, IMHO). When I hit an error running my code from lein run or from Clooj or from Eclipse/CCW (or I think from any other way that I might run it) I get (or can easily get) a backtrace that shows the function call stack at the time of the error... which is good, but surely (?) the locals are also available when the backtrace is produced and I really also want to see those. The ability to browse and navigate this information dynamically, as in a Common Lisp break loop, is cool but I can understand that something about the Clojure/JVM execution architecture might make that difficult -- maybe that really would have to be tied to a particular IDE? However, if it would just dump all of the values of the locals to standard output, just like it does already with the trace, then I'd be plenty happy since I could dig through that output to find what I need but can't currently get. (Yes, dumping the values of all of the locals might produce a lot of output and yes, one might want to make this an option that could be turned off or on, maybe including options re: limits on how much of sequences to print, etc.) I guess the bottom line of this long message (sorry) is that I hope that some of the great tool developers in this community will continue to consider providing things like debugging tools that are as untethered as possible from particular IDEs. My impression is that nrepl (and maybe other projects) are intended to help untether things in this way, but it still seems like a lot of people assume that something like access to locals should naturally be tied to a specific IDE. From my perspective that seems like a really unfortunate assumption. I realize that debugging tools are unlikely to become part of the language in Clojure as they are in Common Lisp, but I think there's an important middle ground between that and being available only within some specific IDE. Thanks, -Lee philli...@newcastle.ac.uk javascript: (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. -- -- 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
Re: Step by step debugging
Andy, I do think that if a debugging feature has to be limited to a particular environment then Leiningen would be preferable to any other, since it's so simple to install and use (and maybe most people have it anyway?) that people who use other environments could, without too much trouble, do a new run from Leiningen when they know they need to do some debugging. Not as good as having it work everywhere with whatever you're already using, of course, but certainly better than (for example) requiring that you figure out how to install and use an Emacs-based environment just to figure out what values your locals have when you crash. Would what you have in mind work from lein run as well as lein repl? FWIW I (and my students) do a lot via lein run. -Lee On Nov 7, 2013, at 2:47 PM, Andy Fingerhut wrote: Lee, I am curious whether you would consider it too tied to a particular dev environment if the kind of minimal debugging features you wish for worked from Leiningen's REPL? i.e. 'lein repl' I do not know if Ritz can work in such an environment or not, but I am guessing it might be easier to get a subset of it working there than from a REPL started via 'java -cp clojure.jar clojure.main' Andy -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
What would I need to do to get it to not only retain locals but also show them to me when I hit an error? -Lee On Nov 7, 2013, at 4:22 PM, Alex Miller wrote: I believe the locals are actually *not* available because they are proactively cleared to help GC. Setting the *compiler-options* var with :disable-locals-clearing can turn that off. Which is probably what you often want in dev, but is not the default. You can also set this via command line with -Dclojure.compile.disable-locals-clearing=true -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
+1 Rudi Engelbrecht Mobile: +61 (0) 455 500 369 Voice: +61 (0) 2 8091 5554 Voice: +27 (0) 11 083 7774 Email: r...@engelbrecht.me On 8 Nov 2013, at 8:29, Lee Spector lspec...@hampshire.edu wrote: Andy, I do think that if a debugging feature has to be limited to a particular environment then Leiningen would be preferable to any other, since it's so simple to install and use (and maybe most people have it anyway?) that people who use other environments could, without too much trouble, do a new run from Leiningen when they know they need to do some debugging. Not as good as having it work everywhere with whatever you're already using, of course, but certainly better than (for example) requiring that you figure out how to install and use an Emacs-based environment just to figure out what values your locals have when you crash. Would what you have in mind work from lein run as well as lein repl? FWIW I (and my students) do a lot via lein run. -Lee On Nov 7, 2013, at 2:47 PM, Andy Fingerhut wrote: Lee, I am curious whether you would consider it too tied to a particular dev environment if the kind of minimal debugging features you wish for worked from Leiningen's REPL? i.e. 'lein repl' I do not know if Ritz can work in such an environment or not, but I am guessing it might be easier to get a subset of it working there than from a REPL started via 'java -cp clojure.jar clojure.main' Andy -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
When you say hit an error, I'm assuming you mean clojure throws an exception and not hit a breakpoint in a debugger or something else. I don't think there is one place where we could generically attach locals info to a thrown exception. The JVM debugging interface (JVMTI - http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html) can do an awful lot of things (including arbitrary class bytecode transformation) so I would guess it's possible to build a java agent that could do this (or to modify the Compiler to inject the right code at compile time). Sounds like a fun project, but probably non-trivial. On Thursday, November 7, 2013 3:34:23 PM UTC-6, Lee wrote: What would I need to do to get it to not only retain locals but also show them to me when I hit an error? -Lee On Nov 7, 2013, at 4:22 PM, Alex Miller wrote: I believe the locals are actually *not* available because they are proactively cleared to help GC. Setting the *compiler-options* var with :disable-locals-clearing can turn that off. Which is probably what you often want in dev, but is not the default. You can also set this via command line with -Dclojure.compile.disable-locals-clearing=true -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
I don't know yet, since what I have in mind at the moment is based on vague pattern matching of words rather than on knowledge of how Ritz works. :-) My basic idea was simply that the Ritz nrepl stuff only works in Emacs now, but it does work across an nREPL connection between a client and the JVM process containing the code you want to debug. If there is a subset of Ritz's debugging features that could be switched to work over a terminal/console connection like what you get with 'lein repl', then that might be a quicker path to the desired goal than lots of modifications to Clojure itself. CC'ing Hugo Duncan in case he has time and interest in adding his much-more-educated-than-mine comments (Hugo, please don't take this as a request to do any work you don't want to -- I'm mostly hoping for an off-the-top-of-your-head answer like debug features X and Y wouldn't be hard to do that way, but the rest would be much harder). Andy On Thu, Nov 7, 2013 at 1:29 PM, Lee Spector lspec...@hampshire.edu wrote: Andy, I do think that if a debugging feature has to be limited to a particular environment then Leiningen would be preferable to any other, since it's so simple to install and use (and maybe most people have it anyway?) that people who use other environments could, without too much trouble, do a new run from Leiningen when they know they need to do some debugging. Not as good as having it work everywhere with whatever you're already using, of course, but certainly better than (for example) requiring that you figure out how to install and use an Emacs-based environment just to figure out what values your locals have when you crash. Would what you have in mind work from lein run as well as lein repl? FWIW I (and my students) do a lot via lein run. -Lee On Nov 7, 2013, at 2:47 PM, Andy Fingerhut wrote: Lee, I am curious whether you would consider it too tied to a particular dev environment if the kind of minimal debugging features you wish for worked from Leiningen's REPL? i.e. 'lein repl' I do not know if Ritz can work in such an environment or not, but I am guessing it might be easier to get a subset of it working there than from a REPL started via 'java -cp clojure.jar clojure.main' Andy -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
On Nov 7, 2013, at 5:48 PM, Alex Miller wrote: When you say hit an error, I'm assuming you mean clojure throws an exception and not hit a breakpoint in a debugger or something else. Yes -- I mean clojure throws an exception. I don't think there is one place where we could generically attach locals info to a thrown exception. The JVM debugging interface (JVMTI - http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html) can do an awful lot of things (including arbitrary class bytecode transformation) so I would guess it's possible to build a java agent that could do this (or to modify the Compiler to inject the right code at compile time). Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-). It still strikes me as really odd that such basic and clearly desirable functionality, available forever in other environments, should be so hard to come by. -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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
+1 well said, Lee. philli...@newcastle.ac.uk javascript: (Phillip Lord) writes: Ritz does some things, but it doesn't do step through like edebug. I've never found anything as nice as edebug in any language; I guess, it's the big advantage of running your editor and whatever you are debugging in the environment. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Why would a break function in clojure the language not be considered, a-la common-lisp? On Friday, 8 November 2013 09:31:55 UTC+10, Lee wrote: On Nov 7, 2013, at 5:48 PM, Alex Miller wrote: When you say hit an error, I'm assuming you mean clojure throws an exception and not hit a breakpoint in a debugger or something else. Yes -- I mean clojure throws an exception. I don't think there is one place where we could generically attach locals info to a thrown exception. The JVM debugging interface (JVMTI - http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html) can do an awful lot of things (including arbitrary class bytecode transformation) so I would guess it's possible to build a java agent that could do this (or to modify the Compiler to inject the right code at compile time). Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-). It still strikes me as really odd that such basic and clearly desirable functionality, available forever in other environments, should be so hard to come by. -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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
I'm slightly late to the discussion, sorry - currently moving cities. Cursive does indeed have a stepping debugger which works well with Clojure, although it's quite slow (I haven't been able to figure out why, yet - I suspect Clojure adds a lot of line information to the bytecode). There have also been some fairly annoying bugs with it which will be fixed in the next drop. Here's more or less what it can do: 1. Standard stepping - step into, step over. Step out is flaky for non-Java languages for some reason, I believe this is fixed in the new version of IntelliJ (13, currently in beta, due to be released soon). 2. Place breakpoints on any line. This generally works well but is occasionally frustrating with Clojure since you can pack a lot on a line. I've found chained sequence operations to be particularly difficult to debug. This is really a JVM limitation since JVMTI is line-oriented. 3. Breakpoints can be configured in various ways. Instead of stopping you can configure them to print the value of an expression, or to stop only the current thread, or to stop all threads. 4. Drop frame to go back in time, as long as you're not mutating any global state. You're not, right? 5. Look at locals up and down the stack, as long as you have locals clearing disabled. 6. For the next drop I'm going to add the ability to toggle locals clearing in debug REPLs with a button in the REPL tool window. 7. You can evaluate arbitrary Clojure expressions at any point in the call stack. 8. You can set a breakpoint on an arbitrary exception, and it will pause *at the time the exception is thrown* and you can inspect locals etc. I'm pretty sure all of this works, and I use most of it regularly. Expression evaluation has been broken until the current dev build so I need to test that things that depend on it work before promising them, but I'm pretty sure they will. They include: 1. Watches. 2. Being able to configure breakpoints to only stop when a particular expression is true. For the next drop I'm planning to work a lot on the debugger and document it all properly including some pretty animations, so I'll post to the list when that is done. On 8 November 2013 13:14, intronic m...@pheasant.co.nz wrote: Why would a break function in clojure the language not be considered, a-la common-lisp? On Friday, 8 November 2013 09:31:55 UTC+10, Lee wrote: On Nov 7, 2013, at 5:48 PM, Alex Miller wrote: When you say hit an error, I'm assuming you mean clojure throws an exception and not hit a breakpoint in a debugger or something else. Yes -- I mean clojure throws an exception. I don't think there is one place where we could generically attach locals info to a thrown exception. The JVM debugging interface (JVMTI - http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html) can do an awful lot of things (including arbitrary class bytecode transformation) so I would guess it's possible to build a java agent that could do this (or to modify the Compiler to inject the right code at compile time). Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-). It still strikes me as really odd that such basic and clearly desirable functionality, available forever in other environments, should be so hard to come by. -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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Step by step debugging
Ideally, in a Lisp I'd think the unit of breakpoints would not be a line but instead an s-expression, tripping before evaluating the body of the expression. On Fri, Nov 8, 2013 at 12:24 AM, Colin Fleming colin.mailingl...@gmail.comwrote: I'm slightly late to the discussion, sorry - currently moving cities. Cursive does indeed have a stepping debugger which works well with Clojure, although it's quite slow (I haven't been able to figure out why, yet - I suspect Clojure adds a lot of line information to the bytecode). There have also been some fairly annoying bugs with it which will be fixed in the next drop. Here's more or less what it can do: 1. Standard stepping - step into, step over. Step out is flaky for non-Java languages for some reason, I believe this is fixed in the new version of IntelliJ (13, currently in beta, due to be released soon). 2. Place breakpoints on any line. This generally works well but is occasionally frustrating with Clojure since you can pack a lot on a line. I've found chained sequence operations to be particularly difficult to debug. This is really a JVM limitation since JVMTI is line-oriented. 3. Breakpoints can be configured in various ways. Instead of stopping you can configure them to print the value of an expression, or to stop only the current thread, or to stop all threads. 4. Drop frame to go back in time, as long as you're not mutating any global state. You're not, right? 5. Look at locals up and down the stack, as long as you have locals clearing disabled. 6. For the next drop I'm going to add the ability to toggle locals clearing in debug REPLs with a button in the REPL tool window. 7. You can evaluate arbitrary Clojure expressions at any point in the call stack. 8. You can set a breakpoint on an arbitrary exception, and it will pause *at the time the exception is thrown* and you can inspect locals etc. I'm pretty sure all of this works, and I use most of it regularly. Expression evaluation has been broken until the current dev build so I need to test that things that depend on it work before promising them, but I'm pretty sure they will. They include: 1. Watches. 2. Being able to configure breakpoints to only stop when a particular expression is true. For the next drop I'm planning to work a lot on the debugger and document it all properly including some pretty animations, so I'll post to the list when that is done. On 8 November 2013 13:14, intronic m...@pheasant.co.nz wrote: Why would a break function in clojure the language not be considered, a-la common-lisp? On Friday, 8 November 2013 09:31:55 UTC+10, Lee wrote: On Nov 7, 2013, at 5:48 PM, Alex Miller wrote: When you say hit an error, I'm assuming you mean clojure throws an exception and not hit a breakpoint in a debugger or something else. Yes -- I mean clojure throws an exception. I don't think there is one place where we could generically attach locals info to a thrown exception. The JVM debugging interface (JVMTI - http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html) can do an awful lot of things (including arbitrary class bytecode transformation) so I would guess it's possible to build a java agent that could do this (or to modify the Compiler to inject the right code at compile time). Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-). It still strikes me as really odd that such basic and clearly desirable functionality, available forever in other environments, should be so hard to come by. -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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop
Re: Step by step debugging
Right, sadly I believe this is impossible using JVMTI, although I'm far from an expert. On 8 November 2013 18:51, Cedric Greevey cgree...@gmail.com wrote: Ideally, in a Lisp I'd think the unit of breakpoints would not be a line but instead an s-expression, tripping before evaluating the body of the expression. On Fri, Nov 8, 2013 at 12:24 AM, Colin Fleming colin.mailingl...@gmail.com wrote: I'm slightly late to the discussion, sorry - currently moving cities. Cursive does indeed have a stepping debugger which works well with Clojure, although it's quite slow (I haven't been able to figure out why, yet - I suspect Clojure adds a lot of line information to the bytecode). There have also been some fairly annoying bugs with it which will be fixed in the next drop. Here's more or less what it can do: 1. Standard stepping - step into, step over. Step out is flaky for non-Java languages for some reason, I believe this is fixed in the new version of IntelliJ (13, currently in beta, due to be released soon). 2. Place breakpoints on any line. This generally works well but is occasionally frustrating with Clojure since you can pack a lot on a line. I've found chained sequence operations to be particularly difficult to debug. This is really a JVM limitation since JVMTI is line-oriented. 3. Breakpoints can be configured in various ways. Instead of stopping you can configure them to print the value of an expression, or to stop only the current thread, or to stop all threads. 4. Drop frame to go back in time, as long as you're not mutating any global state. You're not, right? 5. Look at locals up and down the stack, as long as you have locals clearing disabled. 6. For the next drop I'm going to add the ability to toggle locals clearing in debug REPLs with a button in the REPL tool window. 7. You can evaluate arbitrary Clojure expressions at any point in the call stack. 8. You can set a breakpoint on an arbitrary exception, and it will pause *at the time the exception is thrown* and you can inspect locals etc. I'm pretty sure all of this works, and I use most of it regularly. Expression evaluation has been broken until the current dev build so I need to test that things that depend on it work before promising them, but I'm pretty sure they will. They include: 1. Watches. 2. Being able to configure breakpoints to only stop when a particular expression is true. For the next drop I'm planning to work a lot on the debugger and document it all properly including some pretty animations, so I'll post to the list when that is done. On 8 November 2013 13:14, intronic m...@pheasant.co.nz wrote: Why would a break function in clojure the language not be considered, a-la common-lisp? On Friday, 8 November 2013 09:31:55 UTC+10, Lee wrote: On Nov 7, 2013, at 5:48 PM, Alex Miller wrote: When you say hit an error, I'm assuming you mean clojure throws an exception and not hit a breakpoint in a debugger or something else. Yes -- I mean clojure throws an exception. I don't think there is one place where we could generically attach locals info to a thrown exception. The JVM debugging interface (JVMTI - http://docs.oracle.com/javase/7/docs/technotes/guides/jvmti/index.html) can do an awful lot of things (including arbitrary class bytecode transformation) so I would guess it's possible to build a java agent that could do this (or to modify the Compiler to inject the right code at compile time). Sounds like a fun project, but probably non-trivial. Too bad... unless someone wants to have that fun and then share it with the rest of us :-). It still strikes me as really odd that such basic and clearly desirable functionality, available forever in other environments, should be so hard to come by. -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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: Step by step debugging
This JVMTI doesn't know Clojure source code from parsnip soup, I expect, so can't it be fooled into thinking that the bytecode it's interpreting came from a source with many more, shorter lines? So (defn x [y z] (a (b (c)) ((d) e (f g could be passed off to it as if it were (defn x [y z] (a (b (c)) ((d) e (f g with breakpoints on (defn ...), (a ...), a, (b (c)), or b being passed to JVMTI as breakpoints on the first line of the latter formatting of the code; breakpoints on (c) or c the second line; breakpoints on (d) or d the third line; and breakpoints on e, (f g), f, or g the fourth line. Execution would halt at the breakpoint with the correct amount of evaluation done. (The bare letters are presumed to be self-evaluating literals or var lookups here, and the operators, other than defn, to be functions.) Breakpoints on a macro sexp would need to halt on the first evaluation of any of the expansion, and breakpoints on a macro argument would need to be carried through into the expansion. The special forms are mostly fairly obvious -- break on an if or its condition, for example, breaks before evaluating the condition; break on the then clause breaks after evaluating the condition, before evaluating the then clause, only if the condition was true; etc. Combined, those rules mean a breakpoint on a particular (cond ...) condition X would only trip if all the previous conditions were false, before evaluating condition X, and a breakpoint on the corresponding then clause only if all the preceding conditions were false but condition X was true, after evaluating X but before evaluating X's then clause, because it would end up attached to X's corresponding conditional or then clause (respectively) in the macro-expanded if-tree ((sexp) indicates breakpoint target): (cond (thing1) (dothis) (thing2) (dothat) (thing3) (dosomethingelse) :else (default)) should macroexpand to (if (thing1) (dothis) (if (thing2) (dothat) (if (thing3) (dosomethingelse) (if :else (default) (throw ( ... no matching clause blah blah ... [never actually executes in this case])) so the (if (thing3) line would be what JVMTI thinks is the breakpointed line in this case. The real issue I can foresee here would be if there's no way to make the lines seen by the breakpoint/debugging stuff be different from the lines used for error reporting (e.g. in stacktraces), as then *either* the line granularity for breakpoints is whole lines of your actual source code *or* stacktrace line numbers won't always correspond to what your editor shows for the problem line in your source code, for example if (default) threw a ClassCastException because default did not implement IFn in the above the stacktrace might point to line 8 when it was really line 5 of your (cond ...) expression (but line 8 of the (if ...) it macroexpanded to, and which was vertically spread out to put each distinct (as to what nontrivial evaluation has happened yet) sexp-based breakpoint position on its own line to please JVMTI). On Fri, Nov 8, 2013 at 12:53 AM, Colin Fleming colin.mailingl...@gmail.comwrote: Right, sadly I believe this is impossible using JVMTI, although I'm far from an expert. On 8 November 2013 18:51, Cedric Greevey cgree...@gmail.com wrote: Ideally, in a Lisp I'd think the unit of breakpoints would not be a line but instead an s-expression, tripping before evaluating the body of the expression. On Fri, Nov 8, 2013 at 12:24 AM, Colin Fleming colin.mailingl...@gmail.com wrote: I'm slightly late to the discussion, sorry - currently moving cities. Cursive does indeed have a stepping debugger which works well with Clojure, although it's quite slow (I haven't been able to figure out why, yet - I suspect Clojure adds a lot of line information to the bytecode). There have also been some fairly annoying bugs with it which will be fixed in the next drop. Here's more or less what it can do: 1. Standard stepping - step into, step over. Step out is flaky for non-Java languages for some reason, I believe this is fixed in the new version of IntelliJ (13, currently in beta, due to be released soon). 2. Place breakpoints on any line. This generally works well but is occasionally frustrating with Clojure since you can pack a lot on a line. I've found chained sequence operations to be particularly difficult to debug. This is really a JVM limitation since JVMTI is line-oriented. 3. Breakpoints can be configured in various ways. Instead of stopping you can configure them to print the value of an expression, or to stop only the current thread, or to stop all threads. 4. Drop frame to go back in time, as long as you're not mutating any global state. You're not, right? 5. Look at locals up and down the stack, as long as you have locals clearing disabled. 6. For the