Writing conditions on geometric coordinates
I often write code that deals with geometric coordinates and similar ordered n-tuples on homogenous bases. Lots of times I face the situation where I want to write a condition that says, "if these two regions overlap, then do something," or "if this function is satisfied over an axis ax+by=c or over an axis bx+ay=c then do something." The issue is that the x and y (and z and z' ... ) coordinates are often interchangeable and the condition needs to be satisfied over any one of them or all of them. Here, for instance, is a check that two rectangles, rect-one and rect- two, with corners [:x0 :y0] and [:x1 :y1] overlap. This is vastly simplified, of course. I'm sure you can imagine that when the combinations of axes and desired conditions become more and more complex, the code gets more and more repetitive and awful. (and (>= (rect-one :x1) (rect-two :x0)) (>= (rect-two :x1) (rect-one :x0)) (>= (rect-one :y1) (rect-two :y0)) (>= (rect-two :y1) (rect-one :y0))) Problem is that code is awful and repetitive. I can shrink it in various one-off ways but I wonder if anyone has general advice or experience in writing a readable condition function. I think it should be reduced with multiple axes substituted into a function somehow but I don't know a good idiom to make it clear. Maybe an experienced lisper or wise code craftsman can help me 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
Re: Getting line numbers in stack traces
Okay, I can get that stack trace, but there's no line for clojure.core/ divide in your trace. How would I know which function threw the exception? "eval" isn't very useful. Ideally I'd like a line number, too. If I have a function, (defn process [sequence] (map some-function sequence)) And it gets called by another function, (defn higher-up [sequence] (concat (list 1 2 3 4 5) (process sequence))) And that gets called by (higher-up 12) ;; note: 12 is not a seq Then the stack trace for "don't know how to create ISeq from 12" doesn't mention anything about 'higher-up or 'process at all. It's lazy-seq evals and fn invokes. The error occurs in a closure that was created inside these functions being evaluated to print a lazy seq, but most of the work done by programs occurs in contexts like that. If the closure can't have a context and line numbers attached, is it just impossible to have meaningful debugging and stack traces? On May 13, 12:05 pm, MarkSwanson wrote: > On May 13, 6:11 am, Brian Watkins wrote: > > > What is the method that gets line numbers and function names into > > stack traces? I know I can't get them in the Repl (because there > > aren't any), but I tried loading my file with load-file and that > > doesn't help either. > > It's there; Clojure binds the last Exception to *e > > http://tech.puredanger.com/2010/02/17/clojure-stack-trace-repl/ > > user=> (use 'clojure.stacktrace) > nil > user=> (/ 5 0) > java.lang.ArithmeticException: Divide by zero (NO_SOURCE_FILE:0) > user=> (print-stack-trace *e) > clojure.lang.Compiler$CompilerException: > java.lang.ArithmeticException: Divide by zero (NO_SOURCE_FILE:0) > at clojure.lang.Compiler.eval (Compiler.java:5365) > clojure.lang.Compiler.eval (Compiler.java:5317) > clojure.core/eval (core.clj:2132) > ... > > I use vimclojure and in its repl embedded inside vim all I have to do > is ,st or ,ct > > -- > 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 > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Getting line numbers in stack traces
What is the method that gets line numbers and function names into stack traces? I know I can't get them in the Repl (because there aren't any), but I tried loading my file with load-file and that doesn't help either. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Primitive arithmetic and mod
Thank you for the pointer to unchecked-remainder. That runs much better. -B On May 3, 6:23 pm, kaukeb wrote: > Using unchecked-remainder and adding a type declaration to the last > constant keeps the primitives unboxed and improves performance by a > factor of 6 for me. I couldn't say whether there's a reason rem and > mod don't work like you'd expect here. > > (defn NF-mod-limit [p q limit] > (let [p (long p) q (long q) limit (long limit)] > (loop [n (long 0), nf (long 0), z (long 0), S (long 290797)] > (if (= n (inc q)) > nf > (recur > (inc n) > (unchecked-remainder > (+ nf (* (unchecked-remainder S p) z)) > limit) > (unchecked-remainder (inc (* p z)) limit) > (unchecked-remainder (* S S) (long 50515093))) > > On May 3, 1:21 pm, Brian Watkins wrote: > > > > > Any ideas about this? > > > On May 2, 1:44 am, Brian Watkins wrote: > > > > I'm trying to speed up computing terms of a simple recurrence where > > > the terms are computed modulo some value each iteration, > > > > (defn NF-mod-limit [p q limit] > > > (loop [n 0, nf 0, z 0, S 290797] > > > (if (= n (inc q)) nf > > > (recur (inc n) > > > (mod (+ nf (* (mod S p) z)) limit) > > > (mod (inc (* p z)) limit) > > > (mod (* S S) 50515093)) > > > > So I added in some type hinting, > > > > (defn NF-mod-limit [p q limit] > > > (let [p (long p) q (long q) limit (long limit)] > > > (loop [n (long 0), nf (long 0), z (long 0), S (long 290797)] > > > (if (= n (inc q)) nf > > > (recur (inc n) > > > (long (mod (+ nf (* (long (mod S p)) z)) limit)) > > > (long (mod (inc (* p z)) limit)) > > > (long (mod (* S S) 50515093))) > > > > But it doesn't run any faster. Also it doesn't work without casting > > > to long within the recur. Is that maybe a problem with mod and > > > primitive arithmetic or does this simply not speed up any more in > > > 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 > > > athttp://groups.google.com/group/clojure?hl=en > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clojure@googlegroups.com > > Note that posts from new members are moderated - please be patient with > > your first post. > > To unsubscribe from this group, send email to > > clojure+unsubscr...@googlegroups.com > > For more options, visit this group > > athttp://groups.google.com/group/clojure?hl=en > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Primitive arithmetic and mod
The main example is (NF-mod-limit 61 1000 (reduce * (repeat 10 61))) It runs in about 10 seconds but this is somewhat typical of other computations I want to be able to do that take longer. I'd just like to be able to make the integer math as fast as is reasonable in Clojure. I'll try rem for time but I see that I still have to cast to long; Clojure doesn't think (rem (long ) (long x)) is a long. The error is "recur arg for primitive local: nf must be matching primitive." On May 3, 6:53 pm, David Nolen wrote: > On Mon, May 3, 2010 at 4:21 PM, Brian Watkins wrote: > > Any ideas about this? > > > On May 2, 1:44 am, Brian Watkins wrote: > > > I'm trying to speed up computing terms of a simple recurrence where > > > the terms are computed modulo some value each iteration, > > > > (defn NF-mod-limit [p q limit] > > > (loop [n 0, nf 0, z 0, S 290797] > > > (if (= n (inc q)) nf > > > (recur (inc n) > > > (mod (+ nf (* (mod S p) z)) limit) > > > (mod (inc (* p z)) limit) > > > (mod (* S S) 50515093)) > > > > So I added in some type hinting, > > > > (defn NF-mod-limit [p q limit] > > > (let [p (long p) q (long q) limit (long limit)] > > > (loop [n (long 0), nf (long 0), z (long 0), S (long 290797)] > > > (if (= n (inc q)) nf > > > (recur (inc n) > > > (long (mod (+ nf (* (long (mod S p)) z)) limit)) > > > (long (mod (inc (* p z)) limit)) > > > (long (mod (* S S) 50515093))) > > > > But it doesn't run any faster. Also it doesn't work without casting > > > to long within the recur. Is that maybe a problem with mod and > > > primitive arithmetic or does this simply not speed up any more in > > > Clojure? > > mod is a bit more general than Java's % operator. If you just want the % > operator, then it looks like you need to use rem not mod. That seems to > speed things up ~2X for me. Do you have some sample values you're passing to > your function and the corresponding runtimes that you are seeing? > > David > > -- > 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 > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Primitive arithmetic and mod
Any ideas about this? On May 2, 1:44 am, Brian Watkins wrote: > I'm trying to speed up computing terms of a simple recurrence where > the terms are computed modulo some value each iteration, > > (defn NF-mod-limit [p q limit] > (loop [n 0, nf 0, z 0, S 290797] > (if (= n (inc q)) nf > (recur (inc n) > (mod (+ nf (* (mod S p) z)) limit) > (mod (inc (* p z)) limit) > (mod (* S S) 50515093)) > > So I added in some type hinting, > > (defn NF-mod-limit [p q limit] > (let [p (long p) q (long q) limit (long limit)] > (loop [n (long 0), nf (long 0), z (long 0), S (long 290797)] > (if (= n (inc q)) nf > (recur (inc n) > (long (mod (+ nf (* (long (mod S p)) z)) limit)) > (long (mod (inc (* p z)) limit)) > (long (mod (* S S) 50515093))) > > But it doesn't run any faster. Also it doesn't work without casting > to long within the recur. Is that maybe a problem with mod and > primitive arithmetic or does this simply not speed up any more in > 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 > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Primitive arithmetic and mod
I'm trying to speed up computing terms of a simple recurrence where the terms are computed modulo some value each iteration, (defn NF-mod-limit [p q limit] (loop [n 0, nf 0, z 0, S 290797] (if (= n (inc q)) nf (recur (inc n) (mod (+ nf (* (mod S p) z)) limit) (mod (inc (* p z)) limit) (mod (* S S) 50515093)) So I added in some type hinting, (defn NF-mod-limit [p q limit] (let [p (long p) q (long q) limit (long limit)] (loop [n (long 0), nf (long 0), z (long 0), S (long 290797)] (if (= n (inc q)) nf (recur (inc n) (long (mod (+ nf (* (long (mod S p)) z)) limit)) (long (mod (inc (* p z)) limit)) (long (mod (* S S) 50515093))) But it doesn't run any faster. Also it doesn't work without casting to long within the recur. Is that maybe a problem with mod and primitive arithmetic or does this simply not speed up any more in 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
Interrupting the Repl
Is there a way to interrupt the Repl when I've set to some kind of infinite loop without also shutting down the JVM entirely? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: regex literal syntax
Yes, dealing with multiple escaped escape sequences is a weak point of handling regexs. To really integrate them into the language, and that integration is essential to success, they must be typed straight into the code literally without baggage. As much as flexibility and simplicity, the easy application of powerful first class regular expressions to text processing was the killer app for Perl. No programmer wants to accept second best anymore. -Brian On Oct 8, 4:24 pm, Bob <[EMAIL PROTECTED]> wrote: > Yes, I like this. The double backslashing is really a pain and > confused me at first. Get off that road now while clojure is still > pretty new. > > Bob > > On Oct 8, 9:03 am, Chouser <[EMAIL PROTECTED]> wrote: > > > On Wed, Oct 8, 2008 at 8:08 AM, Rich Hickey <[EMAIL PROTECTED]> wrote: > > > > Will existing Clojure regex (consumer) code need to change, i.e. will > > > people need to modify their existing #"" literals and if so in what > > > way? > > > Yes, many existing #"" literals would have new meaning or become > > invalid under this proposal. > > > Some patterns wouldn't have to be changed. Here are a couple examples: > > #"foo" > > #"(one) *(two)" > > #"/this.*/that" > > > By far the most common change people would have to make would be to > > remove doubled back-slashes: > > old: #"\\w" new: #"\w" > > old: #"\\(" new: #"\(" > > old: #"\\bword\\b" new: #"\bword\b" > > > Reading through Clojures string reader and Java's Pattern docs, the > > only other anomaly I've spotted is if someone was using \b to mean > > \backspace. With the proposed change, #"\b" means word boundary, so: > > old: #"\b" new: #"\x08" > > > Most of the time, failing to update your regex literal will result in > > a valid regex that means something different. Put another way, things > > that used to match like you wanted will just stop matching. In a few > > cases (such as #"\\(") what used to be a valid regex will throw an > > exception at read time, with a detailed error message pointing out the > > position of the illegal paren. > > > Of course if this change is unacceptable, these proposed rules could > > be applied to a new dispatch macro. One option would be something > > like #r/foo/ that would allow your choice of delimiters to further > > reduce the need for back-slash quoting within the regex. > > > --Chouser --~--~-~--~~~---~--~~ 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 To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---