Re: a macro
as a follow up with further clarifications, I would like to mention that Variables is already a predefined macro and I don't want have to execute it at run-time since it uses mathematica and we cannot distribute mathematica to the end user. and also please read my last sentence as I know f is a function and will not be evaluated before the macro expands.. may be there is a way to wrap it in a macro (since f is already defined which I would like to use) and have the macro Variables apply on the result of evaluation of f it was a typo in my earlier email. On Wed, Oct 13, 2010 at 11:25 AM, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Hello Everybody, I think I was not clear about things in my previous email.. I am reposting simplifying things... Variables is a macro which works in the following way.. (Variables (+ x (* 2 y)) returns [x y] now let us say we have a function (defn f [] '(+ x (* 2 y))) now I would like to do something like (Variables (f)) which would return [x y] I know if is a function and will not be evaluated before the macro expands.. may be there is a way to wrap it in a macro (since f is already defined which I would like to use) and have the macro Variables apply on the result of evaluation of f any help is greatly appreciated. Thanks, Sunil. -- 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: a macro
I'm still a little confused as to what you're trying to do, but is this what you're looking for? (defmacro zzz [form] (first form)) (defmacro eval-zzz [form] `(zzz ~(eval form))) rlm.play-all (zzz (range 1 2)) #core$range clojure.core$ra...@61e066 rlm.play-all (macroexpand-1 '(eval-zzz (range 5))) (rlm.play-all/zzz (0 1 2 3 4)) rlm.play-all (eval-zzz (range 5)) 0 --Robert On Wed, Oct 13, 2010 at 1:55 AM, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Hello Everybody, I think I was not clear about things in my previous email.. I am reposting simplifying things... Variables is a macro which works in the following way.. (Variables (+ x (* 2 y)) returns [x y] now let us say we have a function (defn f [] '(+ x (* 2 y))) now I would like to do something like (Variables (f)) which would return [x y] I know if is a function and will not be evaluated before the macro expands.. may be there is a way to wrap it in a macro (since f is already defined which I would like to use) and have the macro Variables apply on the result of evaluation of f any help is greatly appreciated. Thanks, Sunil. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: a macro
Hi, On 13 Okt., 07:55, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: I know if is a function and will not be evaluated before the macro expands.. may be there is a way to wrap it in a macro (since f is already defined which I would like to use) and have the macro Variables apply on the result of evaluation of f This is not possible. Macros cannot use information which is not available at compile time. You should investigate whether it is possible to split the Variables macro in two parts. A function doing the work and a convenience macro. (defn Variables* [form] ...) (defmacro Variables [form] `(Variables* (quote ~form))) Then you can call (Variables (+ x (* 2 y))) without quoting and (Variables* (f)) at runtime with your function result. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: a macro
2010/10/13 Sunil S Nandihalli sunil.nandiha...@gmail.com as a follow up with further clarifications, I would like to mention that Variables is already a predefined macro and I don't want have to execute it at run-time since it uses mathematica and we cannot distribute mathematica to the end user. and also please read my last sentence as I know f is a function Here lies the problem. The f that is passed as an argument to the call to the macro Variable is not a function. It's the plain symbol f , within a plain list . If you want the macro to interpret the symbol f as a function (or rather the datastructure '(f) as a function call, then you'll have to evaluate it from the macro (which is probably possible and justified in you case because you do not want to distribute the mathematica stuff for the runtime, but it will be available when evaluating from inside the macro at compile time = I assume you will AOT compile things, of course). So in short: calling eval from the macro, on its argument. HTH, -- Laurent and will not be evaluated before the macro expands.. may be there is a way to wrap it in a macro (since f is already defined which I would like to use) and have the macro Variables apply on the result of evaluation of f it was a typo in my earlier email. On Wed, Oct 13, 2010 at 11:25 AM, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Hello Everybody, I think I was not clear about things in my previous email.. I am reposting simplifying things... Variables is a macro which works in the following way.. (Variables (+ x (* 2 y)) returns [x y] now let us say we have a function (defn f [] '(+ x (* 2 y))) now I would like to do something like (Variables (f)) which would return [x y] I know if is a function and will not be evaluated before the macro expands.. may be there is a way to wrap it in a macro (since f is already defined which I would like to use) and have the macro Variables apply on the result of evaluation of f any help is greatly appreciated. Thanks, Sunil. -- 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: a macro
Hi, On 13 Okt., 08:56, Laurent PETIT laurent.pe...@gmail.com wrote: So in short: calling eval from the macro, on its argument. Beware the leopard! user= (defn f [constant] `(+ x# (* ~constant y#))) #'user/f user= (defn variables* [form] (if (seq? form) (reduce into [] (map variables* form)) (when (and (symbol? form) (nil? (resolve form))) [form]))) #'user/variables* user= (defmacro variables [form] `(variables* (quote ~form))) #'user/variables user= (defmacro dynamic?-variables [form] `(variables ~(eval form))) #user/dynamic?-variables user= (dynamic?-variables '(+ x (* 2 y))) [x y] user= (dynamic?-variables (+ x (* 2 y))) java.lang.Exception: Unable to resolve symbol: x in this context (NO_SOURCE_FILE:18) user= (dynamic?-variables (f 2)) [x__12__auto__ y__13__auto__] user= (let [x 2] (dynamic?-variables (f x))) java.lang.InstantiationException: user$eval48$eval49__50 (NO_SOURCE_FILE:52) One has to be aware of the limitations of such an approach. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: a macro
basically the following is the macro that creates a function from the expression calculated using mathematica.. it seems to be doing something still not the whole thing.. hopefully some of you may be able to help me. (defmacro sexp2fn [sexp] (let [sym (eval sexp) vars (eval (math (Variables sexp)))] (println [sym vars]) `(fn ~vars ~sym))) ;; when I macro expand the following (sexp2fn (mathematica-eval D[x*x+x*y,x])) ;; I get the error whose stack trace is Unable to resolve symbol: sexp in this context [Thrown class java.lang.Exception] Restarts: 0: [QUIT] Quit to the SLIME top level Backtrace: 0: clojure.lang.Compiler.resolveIn(Compiler.java:5677) ;; however if I replace the above macro with the following (defmacro sexp2fn [sexp] (let [sym (eval sexp) vars []] ;(eval (math (Variables sexp)))] (println [sym vars]) `(fn ~vars ~sym))) ;and I macro expand the same expression i get (clojure.core/fn [] (+ (* 2 x) y)) ; as you can see the arguments list is empty .. i would have liked to have [x y] over there and (math (Variables (+ (* 2 x) )y) would return [x y] but for some reason sexp is not visible .. can anybody help? does eval have any lexical scope in which it will run or does it run in the null-lexical scope? Sunil. On Wed, Oct 13, 2010 at 2:27 PM, Meikel Brandmeyer m...@kotka.de wrote: Hi, On 13 Okt., 08:56, Laurent PETIT laurent.pe...@gmail.com wrote: So in short: calling eval from the macro, on its argument. Beware the leopard! user= (defn f [constant] `(+ x# (* ~constant y#))) #'user/f user= (defn variables* [form] (if (seq? form) (reduce into [] (map variables* form)) (when (and (symbol? form) (nil? (resolve form))) [form]))) #'user/variables* user= (defmacro variables [form] `(variables* (quote ~form))) #'user/variables user= (defmacro dynamic?-variables [form] `(variables ~(eval form))) #user/dynamic?-variables user= (dynamic?-variables '(+ x (* 2 y))) [x y] user= (dynamic?-variables (+ x (* 2 y))) java.lang.Exception: Unable to resolve symbol: x in this context (NO_SOURCE_FILE:18) user= (dynamic?-variables (f 2)) [x__12__auto__ y__13__auto__] user= (let [x 2] (dynamic?-variables (f x))) java.lang.InstantiationException: user$eval48$eval49__50 (NO_SOURCE_FILE:52) One has to be aware of the limitations of such an approach. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: a macro
Hi, On 13 Okt., 11:19, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: (defmacro sexp2fn [sexp] (let [sym (eval sexp) vars (eval (math (Variables sexp)))] (println [sym vars]) `(fn ~vars ~sym))) Try the following: (defn evaled-variables [form] (eval `(math (Variables ~form (defmacro sexp2fn [string] (let [form (mathematica-eval string) vars (evaled-variables form)] `(fn ~vars ~form))) Using my previous stubs I get: user= (macroexpand-1 '(sexp2fn 2)) (clojure.core/fn [x__1__auto__ y__2__auto__] (clojure.core/+ x__1__auto__ (clojure.core/* 2 y__2__auto__))) You would call it (sexp2fn D[x*x+x*y,x]). Hope that helps. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Problems with clojure couchdb
On Wed, Oct 13, 2010 at 4:00 AM, Mark Engelberg mark.engelb...@gmail.com wrote: On Tue, Oct 12, 2010 at 6:41 AM, Moritz Ulrich ulrich.mor...@googlemail.com wrote: Regarding your error: Maybe you open too many sockets which don't get closed and your process runs out of file descriptors. Yes, I think that's the problem. I found a blurb on the net about how to expand the range of usable ports for sockets, but instead I went the route of writing my documents in batches of 50 as both of you suggested. This didn't entirely solve the problem, but it definitely helped and I was able to get much further. But after entering about 2,000,000 small documents, the database size was nearing 4GB and couch seemed to really crawl to add new documents. I like couch's ease-of-use alongside Clojure, but I think I need something that isn't quite so space-hungry and remains fast for largish collections. So I'm thinking I'm going to have to punt on couch db. Any other tips on what I might be doing wrong, or does this sound typical? Thanks, Mark Do you update your documents often? CouchDB keeps old versions of documents in the database. To remove them, do a compact on the database. If you don't update your documents often, you could have a look at the config parameters. However, I'm not sure if that will bring you the desired results. -- Moritz Ulrich Programmer, Student, Almost normal Guy http://www.google.com/profiles/ulrich.moritz BB5F086F-C798-41D5-B742-494C1E9677E8 -- 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: Creating a new library
Good to know... is this written somewhere ? I looked at Clojars yesterday but did not find anything... Luc P. Saul Hazledine shaz...@gmail.com wrote .. On Oct 13, 5:31 am, lprefonta...@softaddicts.ca wrote: As far a publishing to Clojars, I do not know the policy. Uploading various jars maintained by other teams not involved in Clojure may pollute the repo along the way. As I understand it, its fine to put jars from other projects on Clojars. If you do this, it is recommended to use your own groupid or org.clojars.your-userid as the groupid. That way people know that the jar files aren't from the originating team. If the originating team ever puts their package on the central maven repository the clojars package won't be picked up by mistake by people who want the official package. Saul -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Help to optimize palindrome search from input file
On Oct 12, 2010, at 3:02 PM, tonyl wrote: (defn palindrome? [s] (= s (reduce str (reverse s One opportunity to micro-optimize is to replace reduce str with apply str. str uses a StringBuilder object to build a string from its arguments. When you use reduce, the code walks down s appending the result so far with the next string, creating a new StringBuilder object each time. When you use apply, str creates one StringBuilder object and passes all the remaining elements of s to it. The amount of improvement depends on the length of s. In a micro-benchmark I did just now, using apply reduced the overall runtime of the benchmark by a factor of 4.8. (pun acknowledged). --Steve -- 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: Creating a new library
On Oct 13, 1:21 pm, lprefonta...@softaddicts.ca wrote: Good to know... is this written somewhere ? I looked at Clojars yesterday but did not find anything... Its mentioned near the end of the tutorial: http://github.com/ato/clojars-web/wiki/tutorial Saul -- 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: Creating a new library
Hi, On 13 Okt., 07:59, Saul Hazledine shaz...@gmail.com wrote: As I understand it, its fine to put jars from other projects on Clojars. If you do this, it is recommended to use your own groupid or org.clojars.your-userid as the groupid. That way people know that the jar files aren't from the originating team. If the originating team ever puts their package on the central maven repository the clojars package won't be picked up by mistake by people who want the official package. I find this to be greatly abused by the people. Sometimes you have to scroll through several pages of search results only to find the original project jar by accident. There is no documentation whatsoever what is changed in the different variants. Sometimes they are even uploaded under non-org.clojars groups giving even a little official touch. I had one user having trouble to set up vimclojure who said that he downloaded random vimclojure jars because he couldn't tell which is the official one. All-in-all I think that an easy accessible repository is a big Good Thing(tm). But the org.clojars groups where a bad idea, IMHO. If a dependency doesn't have artifacts on clojars, there is always the possibility of approaching the original project team on the issue. If you really need jars which are modified in some way (eg. a bugfix which hasn't made it upstream, yet), they should be put into a local repo, be it .m2 or something like archiva (BTW: Thanks for this tip, Luc) Sincerely Meikel PS: all that said, I'm guilty myself of putting stuff in org.clojars.kotarak... -- 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: New Release of the Clojure Debugging Toolkit
I suppose it could be a way to unify both versions using (System/ getProperty path.separator) and (System/getProperty file.separator) I try to fix it like Leo but i get a regexp exception using (reval) with \ -- 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: New Release of the Clojure Debugging Toolkit
I suppose it could be a way to unify both versions using (System/ getProperty path.separator) and (System/getProperty file.separator) I add the leo changes (to master vesion -lesses changes-) and it works for me thanks!! On Oct 12, 2:53 pm, leo leonardo.lsilves...@gmail.com wrote: This works for me under Windows 7. I set all forward slashes paths in my .emacs file like this: (progn (setq cdt-dir c:/msysgit/cdt) (setq cdt-source-path c:/clj/clojure-1.2.0/src/jvm;c:/clj/ clojure-1.2.0/src/clj;c:/clj/clojure-contrib-1.2.0/src/main/clojure/ clojure/contrib;) (load-file (format %s/ide/emacs/cdt.el cdt-dir))) And these are the diffs from George's current windows version (hopefully George will be able to make them available in a more convenient way) - and note the file:/// with 3 slashes under Windows: - diff --git a/.gitignore b/.gitignore diff --git a/README b/README diff --git a/docs/cdt.muse b/docs/cdt.muse diff --git a/docs/emacs-cdt.muse b/docs/emacs-cdt.muse diff --git a/ide/emacs/cdt.el b/ide/emacs/cdt.el index 0560ab2..42e3e1a 100644 --- a/ide/emacs/cdt.el +++ b/ide/emacs/cdt.el @@ -25,13 +25,13 @@ (gud-call (format (reval-display '%s) (thing-at-point 'sexp (defun strip-trail (path) - (if (= (elt path (- (length path) 1)) ?\\) + (if (= (elt path (- (length path) 1)) ?/) (substring path 0 (- (length path) 1)) path)) (defun cdt-query-cmdline () (let ((path (strip-trail cdt-dir))) - (format java -classpath%s\\lib\\clojure-1.2.0.jar;%s\\lib\ \clojure-contrib-1.2.0.jar;%s\\lib\\debug- repl-0.3.0-20091229.021828-3.jar;%s\\src clojure.main --repl + (format java -classpath%s/lib/clojure-1.2.0.jar;%s/lib/clojure- contrib-1.2.0.jar;%s/lib/debug-repl-0.3.0-20091229.021828-3.jar;%s/src clojure.main --repl path path path path))) (defun cdt (port) diff --git a/project.clj b/project.clj diff --git a/src/com/georgejahad/cdt.clj b/src/com/georgejahad/cdt.clj index d479877..d2d570f 100644 --- a/src/com/georgejahad/cdt.clj +++ b/src/com/georgejahad/cdt.clj @@ -21,10 +21,11 @@ ;; add-classpath is ugly, but handles the fact that tools.jar and ;; sa-jdi.jar are platform dependencies that I can't easily put in a ;; repo: -(with-out-str (add-classpath (format file://%s/../lib/tools.jar +(with-out-str (add-classpath (format file:///%s/../lib/tools.jar (System/getProperty java.home -(with-out-str (add-classpath (format file://%s/../lib/sa-jdi.jar +(with-out-str (add-classpath (format file:///%s/../lib/sa-jdi.jar (System/getProperty java.home + (import com.sun.jdi.Bootstrap com.sun.jdi.request.EventRequest com.sun.jdi.event.BreakpointEvent @@ -90,7 +91,7 @@ (defonce source-path (atom )) (defn remove-trailing-slashes [s] - (str/replace s \\; ;)) + (str/replace s /: :)) (defn set-source-path [path] (reset! source-path (remove-trailing-slashes path))) @@ -98,10 +99,10 @@ (defn get-source [] (let [file (.sourcePath (.location (.frame (ct) (cf paths (.split @source-path ;)] - (if (= (first file) \\) + (if (= (first file) \/) file (first (filter #(.exists (java.io.File. %)) - (for [p paths] (str p \\ file))) + (for [p paths] (str p / file))) (defmacro check-unexpected-exception [ body] `(try @@ -325,11 +326,11 @@ (re-pattern (str s \\$ (defn fix-class [c] - (str/replace c / .)) + (str/replace c \\ .)) (defn get-class* [fname] (- (.split @source-path ;) - (map #(re-find (re-pattern (str % \\(.*)(.clj|.java))) fname)) + (map #(re-find (re-pattern (str % /(.*)(.clj|.java))) fname)) (remove nil?) first second @@ -426,7 +427,7 @@ (defn get-file-name [frame] (let [sp (try (.sourcePath (.location frame)) (catch Exception e source not found))] - (last (.split sp \\ + (last (.split sp / (defn clojure-frame? [frame fields] (let [names (map #(.name %) fields)] On Oct 11, 6:48 pm, atreyu atreyu@gmail.com wrote: Hi folks and congrats to George Jahad for this great work. Hoewer the cdt dont work on my windows vista. After some changes on my own i get the same error of Greg Willams: java.lang.ClassNotFoundException: com.sun.jdi.Bootstrap (cdt.clj:28) i've tried add-classpath of tool.jar (where is the class in my jdk) with various formats, after testing the urls in browser with success but i get the ClassNotFound all the time Current directory is c:/Users/atreyu/AppData/Roaming/.emacs.d/ Clojure 1.2.0 user= java.lang.ClassNotFoundException: com.sun.jdi.Bootstrap (cdt.clj:28) user= java.lang.Exception: Unable to resolve symbol: set-source-path in this context (NO_SOURCE_FILE:2) user= java.lang.Exception: Unable to resolve symbol: cdt-attach in this
Override print-method of struct
How can I override print-method for a map, defined with defstruct? I have to create object hierarchy: one map is a parent for another, i.e. it holds link to a child, and another is a child for the first one, i.e. holds link to a parent. When I try to print it, I get StackOverflowError since printer tries recursively print objects: parent - child - parent - child - The best solution I see is to override print-method or str, so the printing will go normally. I found this topic: http://groups.google.com/group/clojure/browse_thread/thread/4a675222f208899d which shows how to override print-method for objects defined by deftype, but is there a way to do same trick for maps? Maybe it is possible to add some special tag to object's meta? Or to redefine print-method in the only namespace? Or maybe I'm just looking at the wrong direction? -- 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: precise numbers
On Tue, Oct 12, 2010 at 8:35 PM, cej38 junkerme...@gmail.com wrote: The more that I think about it, the more I would rather have a set of equalities that always work. float= was a good try. The only way to do so is to have numbers with infinite precision. For example as lazy-seq of their digits. But: - it is slow - equality is semi-decidable only. -- 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: strange bug in range or lazy-seq?
After thinking about it some more, I don't understand it either. I have created a ticket for this: https://www.assembla.com/spaces/clojure/tickets/457-lazy-recursive-definition-giving-incorrect-results. As a workaround, eliminate the lazy intermediary nums sequence, e.g. (def primes (concat [2] (lazy-seq (let [primes-from (fn primes-from [n] (if (some #(zero? (rem n %)) (take-while #(= (* % %) n) primes)) (recur (+ n 2)) (lazy-seq (cons n (primes-from (+ n 2))] (primes-from 3) Stu Thank you all for explaining this to me but I still don't understand clojures behavior in this case, Try running this code: (def nums (drop 2 (range))) (def primes (cons (first nums) (lazy-seq (- (rest nums) (remove (fn [x] (let [dividors (take-while #(= (* % %) x) primes)] (println (str primes = primes)) (some #(= 0 (rem x %)) dividors (take 5 primes) It prints out: (primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) primes = (2) 2 3 5 7 9) How can (println primes) ever print out (2) ? That means that primes must have length 1 and that should be impossible no matter how chunked it is. It's hard to believe that that is intended behavior. I don't insist that a recursive lazy definition needs to work. It could also throw an error. But simply giving incorrect and unpredictable results can't be a good solution in my opinion. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: precise numbers
Nice rant, I learned something here :) I somehow thought BigDecimal wouldn't have any precision issues, but I probably never noticed because I can only think in base-10 arithmetic. Has been good enough for my humble precision problems so far though, never had a notable performance issue with it either. On 12/10/10 23:44, Brian Hurt wrote: On Tue, Oct 12, 2010 at 3:35 PM, cej38 junkerme...@gmail.com mailto:junkerme...@gmail.com wrote: The more that I think about it, the more I would rather have a set of equalities that always work. float= was a good try. RANT Every fucking language I've ever worked on has had this problem- floats are broken! And every single one, people keep coming up with the same wrong answers to this. C, Java, Ocaml, Haskell, SQL, now Clojure. Makes me wonder what language you are coming from where floats *aren't* broken. Some languages patch their print methods to hide the errors in the simple cases, but I've yet to see one where 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 = 1.0. Try it in the language of your choice. First of all, the base of the floating point number just changes what fractions break. For example, in base 10, 1/3 * 3 = 0.9... So no, going to base-10 doesn't save you. IEEE 754 floats are base-2, so 1/10th is impossible to represent precisely, the same way 1/3 is impossible to represent precisely in base-10. Oh, and Clojure has, from it's Java roots, a BigDecimal class which does do base-10 arithmetic. And no, going to rationals doesn't save you either. Take the vector [1, 0, 1], and normalize it so it's euclidean length is 1, without error. Have a nice day. *Any* finite precision representation is going to have round off error. Oh, and Clojure does have a rational class. And once you have round-off, you're going to have numeric errors. At which point, how you deal with those errors is important. Numeric algorithms fall into two broad categories- stable and unstable. With stable algorithms, errors tend to cancel each other, so your final answer is going to be pretty close to correct. With unstable algorithms, errors tend to accumulate (I'm simplifying here for the newbies, for those who know what I'm talking about). No, throwing more bits at the problem won't save an unstable algorithm, it'll just take longer for the unstable algorithm to finally destroy any and all accuracy. Double precision numbers give you enough precision to measure the distance from here to the moon- in multiples of the wavelength of red light. Precisely. Also note there is a difference between precision and accuracy- if I say pi is equal to 3.179830482027405068272948472, that's very precise- but not very accurate. Unstable algorithms destroy accuracy, not precision. And no, ranged floats don't help either- as they grossly overestimate the error of stable algorithms. A classic example of a super-stable algorithm is Newton's method- generally, the number of bits of precision is doubled (or more) every iteration, as the algorithm converges to the answer. But ranged floats have the error increasing every iteration. Oh, and double precision floating point numbers (especially if they're unboxed) are between 10x and 1000x as fast as other representations- thanks to hardware acceleration. Your CPU can execute one floating point operation a clock cycle, two if it's vectorized code. Floating point is not broken. /RANT Brian -- 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 signature.asc Description: OpenPGP digital signature
Seen in #clojure – October 7th w/ maybe-m monad
Hi, I was reading the blog entry Seen in #clojure – October 7th [1] and couldn't stop thinking it might be easier with monads. Since I'm new to monads, Clojure and functional programming in general I'd appreciate any comments on my solution, esp. with regards to maybe-m monad's use. I guess there should be a way to ease weeks, days, hours and minutes functions since they all share the same structure. Any tips on doing it in a Clojure idiomatic way *with* monads are greatly appreciated. Thanks. (defn weeks [v] (let [divider (* 60 24 7)] [(int (/ v divider))(rem v divider)])) (defn days [v] (let [divider (* 60 24)] [(int (/ v divider))(rem v divider)])) (defn hours [v] (let [divider 60] [(int (/ v divider))(rem v divider)])) (defn minutes [v] (second (hours v))) (defn expand-minutes [i] (domonad maybe-m [[ms remaining] (weeks i) [ds remaining] (days remaining) [hs remaining] (hours remaining)] (println ms weeks ds days hs hours remaining minutes))) [1] http://matthewm.net/blog/2010/10/13/seen-in-clojure-october-7th Jacek -- Jacek Laskowski Notatnik Projektanta Java EE - http://jaceklaskowski.pl -- 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: precise numbers
On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. Of course, the problem arises when we truncate the string of 9's, which we must invariably do in a computer-based representation. Have all good days, David Sletten -- 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: Test-driven development in Clojure
I see. So instead of using interfaces and implementations of these, I would simply use closures, one for mock and one for production? That was actually my first attempt, but I didn't like it back then. Take this code for example - passing a function just to have it called feels weird: (defn load-page [provider name] (provider name)) (load-page (make-mock-provider) home) In Java, this would probably look like this: class PageLoader { Provider provider; PageLoader(Provider p) { provider = p; } Page loadPage(String name) { provider.loadPage(name); } } PageLoader l = new PageLoader(new MockProvider()); l.loadPage(home); Then again, it might just feel weird because I've gotten very used to OOP. In my Java code, loading pages is a responsibility of the PageLoader and it delegates it to the Provider. Objects have responsibilities and send messages to each other to fulfill these, that's OOP. In functional programming, there's simply a function that has a certain functionality, and everything it needs to fulfill it has to be provided by the caller. That's at least how I understand it by now. Maybe I should just call the function returned by (make-mock-provider) directly? The interface in Java has the great benefit of ensuring type safety (plus there's no closures yet, so it's the only way), but does this make sense in a dynamic language? I mean, if I passed an implementation of the wrong interface or a closure with the wrong number of arguments, wouldn't both situations result in weird runtime errors? On 12/10/10 22:34, Armando Blancas wrote: Back to my question: Am I trying to do Java in Clojure? Is there a more Lisp-y way to do this? You can hide the types so your client code is more lispy: (defn load-page [prov] (.loadPage prov)) ;;test (def mp (make-mock-provider)) ... (load-page mp) ;;production (def prov (make-provider)) ... (load-page prov) Depending on your app the provider could be a singleton and need not be passed to each function. Another option is multimethods, in which case you'd be using mock functions with an argument that would indicate which version to dispatch to. As for the repl, I think it works just as well for bottom-up and top- down development. I use it for both all the time and to avoid throw- away tests I write them top-down, black-box for only what's visible to client/interop code first, then move down the layers as the code is more mature and stable. I'm not really into TDD but I depend on a test suite as complete as I can get it. signature.asc Description: OpenPGP digital signature
Re: precise numbers
A slight tangent, is there anyway to represent exact square roots? I'd like to have an exact closed form fibonacci function. On Oct 13, 1:28 pm, David Sletten da...@bosatsu.net wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. Of course, the problem arises when we truncate the string of 9's, which we must invariably do in a computer-based representation. Have all good days, David Sletten -- 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: precise numbers
Um, not if you're going to try and turn them into numbers first. But if you store them as ['sqrt 5] or some similar operator/operand pair, then you can manipulate them symbolically and wait for them to cancel out, instead of evaluating them. This requires implementing some kind of symbolic-algebra system, but it's certainly possible: when I was in college my TI-89 could compute the closed form for arbitrarily large N without losing precision (or accuracy). On Oct 13, 2:02 pm, Jarl Haggerty fictivela...@gmail.com wrote: A slight tangent, is there anyway to represent exact square roots? I'd like to have an exact closed form fibonacci function. On Oct 13, 1:28 pm, David Sletten da...@bosatsu.net wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. Of course, the problem arises when we truncate the string of 9's, which we must invariably do in a computer-based representation. Have all good days, David Sletten -- 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: Override print-method of struct
You can add a :type metadata to your maps, and this can be catched by the (type) method of multimethods. But if you have parent - child - parent - child ... relationships, I guess that you're building a tree made of mixins of maps and refs to maps ... and indeed this should bell some rings in your head if you haven't already carefully balanced alternative choices ... 2010/10/13 andrei andrei.zhabin...@gmail.com How can I override print-method for a map, defined with defstruct? I have to create object hierarchy: one map is a parent for another, i.e. it holds link to a child, and another is a child for the first one, i.e. holds link to a parent. When I try to print it, I get StackOverflowError since printer tries recursively print objects: parent - child - parent - child - The best solution I see is to override print-method or str, so the printing will go normally. I found this topic: http://groups.google.com/group/clojure/browse_thread/thread/4a675222f208899d which shows how to override print-method for objects defined by deftype, but is there a way to do same trick for maps? Maybe it is possible to add some special tag to object's meta? Or to redefine print-method in the only namespace? Or maybe I'm just looking at the wrong direction? -- 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Creating a new library
Thank you guys about all the valuable answers. I've pushed the jars to Clojars on my group [1] and updated the wiki with a simple tutorial on how to create a POM to non-clojure jars [2]. All the best. [1] http://clojars.org/groups/org.clojars.automata [2] http://github.com/ato/clojars-web/wiki/POM 2010/10/13 lprefonta...@softaddicts.ca I need a new pair of eyes... Saul Hazledine shaz...@gmail.com wrote .. On Oct 13, 1:21 pm, lprefonta...@softaddicts.ca wrote: Good to know... is this written somewhere ? I looked at Clojars yesterday but did not find anything... Its mentioned near the end of the tutorial: http://github.com/ato/clojars-web/wiki/tutorial Saul -- 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- Vilson Vieira vil...@void.cc ((( http://automata.cc ))) ((( http://musa.cc ))) -- 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: Is ClojureCLR converging toward a release?
Thank you for all the work you've put into this! On Oct 11, 5:39 pm, dmiller dmiller2...@gmail.com wrote: Check out the downloads area onhttp://github.com/richhickey/clojure-clr. Grabclojure-clr-1.2.0.zip. Unzip, start up Clojure.Main.exe and you should be running. The zip also contains Clojure.Compile.exe, which you can invoke with command line arguments indicating files to compile. The support DLLs for the DLR are included. These are debug builds for .Net 3.5 only. Within the next day or so, the master branch will updated with a new build process that will create debug and release builds for 3.5 and 4.0. Futurebinarydistributions will be available in all four flavors. The new build process and extension to .Net 4.0 requires theClojureCLRproject to move to Visual Studio 2010. It will simplify getting started for developers, too. It's ready to go. I just have to get the wiki pages updated. -David On Oct 4, 11:13 pm, Mike K mbk.li...@gmail.com wrote: David, Rich: any further updates on this? Mike On Sep 24, 8:24 am, dmiller dmiller2...@gmail.com wrote: Just waiting for that person's CA to be processed by Rich. -- 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: precise numbers
On 13/10/10 22:28, David Sletten wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. I'm clearly not a mathematician, but doesn't 0.9... asymptotically approach 1, i.e. never reaching it? How is that the same as 1? signature.asc Description: OpenPGP digital signature
Re: precise numbers
Felix~ You are correct that the sequence of numbers 0.9 0.99 0.999 ... asymptotically approaches 1; however, the number 0.... (with an infinite number of 9s) is equal to 1. The formal proof of this is fairly tricky as the definition of the real number is usually done as an equivalence class of Cauchy sequences; a simplified version of the proof can be thought of as follows: For any two real numbers *a* and *b* there exists an infinite number of real numbers *c *such that *a c b*. However, there do not exist any numbers between 0.9... and 1, thus they must be same number. As it turns out, it took mathematicians a long time to nail down formally exactly what we naively think of as numbers. Matt On Wed, Oct 13, 2010 at 6:27 PM, Felix H. Dahlke f...@ubercode.de wrote: On 13/10/10 22:28, David Sletten wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. I'm clearly not a mathematician, but doesn't 0.9... asymptotically approach 1, i.e. never reaching it? How is that the same as 1? -- 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: precise numbers
Here's a slightly more informal argument. Suppose you challenge me that 1 is not equal to 0.... What you are saying is that 1 - 0.... is not equal to 0, i.e., the difference is more than 0. But for any positive value arbitrarily close to 0 I can show that 0.999... is closer to 1 than that. If you were to say that the difference is 0.1, I could show that 0.999... 0.9 so the difference is smaller. For every 0 you added to your challenge: 0.1, 0.01, 0.001 I could provide a counterexample with another 9: 0.9, 0.99, 0.999, ... In other words, there is no positive number that satisfies your claim, so equality must hold. Have all good days, David Sletten On Oct 13, 2010, at 6:36 PM, Matt Fowles wrote: Felix~ You are correct that the sequence of numbers 0.9 0.99 0.999 ... asymptotically approaches 1; however, the number 0.... (with an infinite number of 9s) is equal to 1. The formal proof of this is fairly tricky as the definition of the real number is usually done as an equivalence class of Cauchy sequences; a simplified version of the proof can be thought of as follows: For any two real numbers a and b there exists an infinite number of real numbers c such that a c b. However, there do not exist any numbers between 0.9... and 1, thus they must be same number. As it turns out, it took mathematicians a long time to nail down formally exactly what we naively think of as numbers. Matt On Wed, Oct 13, 2010 at 6:27 PM, Felix H. Dahlke f...@ubercode.de wrote: On 13/10/10 22:28, David Sletten wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. I'm clearly not a mathematician, but doesn't 0.9... asymptotically approach 1, i.e. never reaching it? How is that the same as 1? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: precise numbers
On Thu, 14 Oct 2010 00:27:39 +0200 Felix H. Dahlke f...@ubercode.de wrote: On 13/10/10 22:28, David Sletten wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. I'm clearly not a mathematician, but doesn't 0.9... asymptotically approach 1, i.e. never reaching it? How is that the same as 1? This representation implies the sum of the series (iterate #(/ % 10) 9/10), and that sum behaves as you say. However, since the series is infinite, you can prove that the number it represents is actually equal to one, like so: 1) a = 0.999... # define a as 0.999... 2) 10a = 9.999... # multiply both sides by 10 3) 10a - a = 9.999... - 0.999...# subtract equation 1 from equation 2 4) 9a = 9 # simplify 5) a = 1# divide both sides by 9. The subtraction step doesn't work unless the sequence is infinite, if a is any finite sequence of 9s, you'll get a number whose decimal representation is matches the re 8\.(9)*1. This relies on the property that adding 1 to an infinite number gives you back the same infinite number, so that: (= (rest (map #(* % 10) (iterate #(/ % 10) 9/10))) (iterate #(/ % 10) 9/10)) is true, but I don't recommend typing that into a repl to check it! Hmm. I wonder if you could represent irrationals as lazy sequences, and do arithmetic on those? mike -- Mike Meyer m...@mired.org http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O ascii ribbon campaign - stop html mail - www.asciiribbon.org -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: precise numbers
The quick and dirty proof (not formal proof) for 1 = .... 1/3 = .33... 2/3 = .66... 3/3 = .99... Think of 3/3 as 1/3 (that is .3...) times 3. -Terrance Davis www.terrancedavis.com Felix H. Dahlke wrote: On 13/10/10 22:28, David Sletten wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. I'm clearly not a mathematician, but doesn't 0.9... asymptotically approach 1, i.e. never reaching it? How is that the same as 1? -- 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: Override print-method of struct
That works, thanks! Yeah, I understand that it is not the best data structure to use. The task is to create a tree, and it is needed to get all children and all parents of specified node in this tree in a constant time. So, I cannot see another way to do it except storing refs both from parents to children and from children to parents. On Oct 14, 12:40 am, Laurent PETIT laurent.pe...@gmail.com wrote: You can add a :type metadata to your maps, and this can be catched by the (type) method of multimethods. But if you have parent - child - parent - child ... relationships, I guess that you're building a tree made of mixins of maps and refs to maps ... and indeed this should bell some rings in your head if you haven't already carefully balanced alternative choices ... 2010/10/13 andrei andrei.zhabin...@gmail.com How can I override print-method for a map, defined with defstruct? I have to create object hierarchy: one map is a parent for another, i.e. it holds link to a child, and another is a child for the first one, i.e. holds link to a parent. When I try to print it, I get StackOverflowError since printer tries recursively print objects: parent - child - parent - child - The best solution I see is to override print-method or str, so the printing will go normally. I found this topic: http://groups.google.com/group/clojure/browse_thread/thread/4a675222f... which shows how to override print-method for objects defined by deftype, but is there a way to do same trick for maps? Maybe it is possible to add some special tag to object's meta? Or to redefine print-method in the only namespace? Or maybe I'm just looking at the wrong direction? -- 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Override print-method of struct
Instead of using a ref, you might consider using a closure, which seems a little more functional. So every child would simply store a function that when called would return the map of the parent, map you capture using a closure. This would also reduce your printing problems because functions just print their classname, and you would know that the function brings you back to the parent. I did this for a Neo4j wrapper I wrote to idiomatically represent traversing webs and trees. Would that help anyway? Then you wouldn't have to worry about messing with redefining prints or using alters. The thunk would be created as part of the process. Mark On Oct 13, 4:21 pm, andrei andrei.zhabin...@gmail.com wrote: That works, thanks! Yeah, I understand that it is not the best data structure to use. The task is to create a tree, and it is needed to get all children and all parents of specified node in this tree in a constant time. So, I cannot see another way to do it except storing refs both from parents to children and from children to parents. On Oct 14, 12:40 am, Laurent PETIT laurent.pe...@gmail.com wrote: You can add a :type metadata to your maps, and this can be catched by the (type) method of multimethods. But if you have parent - child - parent - child ... relationships, I guess that you're building a tree made of mixins of maps and refs to maps ... and indeed this should bell some rings in your head if you haven't already carefully balanced alternative choices ... 2010/10/13 andrei andrei.zhabin...@gmail.com How can I override print-method for a map, defined with defstruct? I have to create object hierarchy: one map is a parent for another, i.e. it holds link to a child, and another is a child for the first one, i.e. holds link to a parent. When I try to print it, I get StackOverflowError since printer tries recursively print objects: parent - child - parent - child - The best solution I see is to override print-method or str, so the printing will go normally. I found this topic: http://groups.google.com/group/clojure/browse_thread/thread/4a675222f... which shows how to override print-method for objects defined by deftype, but is there a way to do same trick for maps? Maybe it is possible to add some special tag to object's meta? Or to redefine print-method in the only namespace? Or maybe I'm just looking at the wrong direction? -- 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Help to optimize palindrome search from input file
I think the indexing in all-combs may be off, causing it to miss certain combinations/substrings. user= (all-combs abc) (a ab) I used this instead: (defn substrings [s] (let [length (count s)] (for [i (range length) j (range (inc i) (inc length))] (subs s i j user= (substrings abc) (a ab abc b bc c) On Oct 12, 1:02 pm, tonyl celtich...@gmail.com wrote: Hi, I just started to learn clojure in a more serious way and I am doing the first level of the greplin challenge. I made it to work with a short palindrome like the example they give me, but when it comes to work with the input file, it takes for ever and I have to stop it. $ time clj level1.clj ^C real 11m35.477s user 1m44.431s sys 9m3.878s This is my code: (defn palindrome? [s] (= s (reduce str (reverse s (defn all-combs [in] (let [len (count in)] (for [i (range 0 (- len 2)), j (range (+ i 1) len)] (subs in i j (defn max-comp [x y] (let [lenx (count x), leny (count y)] (cond ( lenx leny) 1 (= lenx leny) 0 ( lenx leny) -1))) ;;(let [input I like racecars that go fast] (let [input (slurp ../_input/level1.in)] (println (nth (sort max-comp (filter palindrome? (all-combs input))) 0))) The input file is thishttp://challenge.greplin.com/static/gettysburg.txt It looks a bit procedural. It is long, but I don't think is the biggest bottleneck, I think it is my approach to create all the combinations possible for substrings. Maybe I should be using a lazy seq? How would I go to do that? -- 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: Test-driven development in Clojure
One thing that OOP and FP can have in common is the use of polymorphism. With protocols and types you can implement your Java design efficiently because you'll get basically the same interfaces and classes. The thing about hiding the calls to instances of a data type is only to make the client code not reply on the interop notation, even if it is only to call a method on them, just like Clojure core functions do. With multimethods you can have different versions of the same function. You're right, you call it with the necessary data, one of which will be the one that controls the dispatch. Both data types and multimethods provide late-binding; the difference is that multi- methods are objects turned inside-out, as if you keep a reference to this (as a record with fields) and use in function calls. And each method is a particular responsibility. That's how I think about it, anyway. Either choice should be fine. I write Java interfaces for implementations in Clojure when I want interop with Java, otherwise I use multimethods and do it all in Clojure. On Oct 13, 1:37 pm, Felix H. Dahlke f...@ubercode.de wrote: I see. So instead of using interfaces and implementations of these, I would simply use closures, one for mock and one for production? That was actually my first attempt, but I didn't like it back then. Take this code for example - passing a function just to have it called feels weird: (defn load-page [provider name] (provider name)) (load-page (make-mock-provider) home) In Java, this would probably look like this: class PageLoader { Provider provider; PageLoader(Provider p) { provider = p; } Page loadPage(String name) { provider.loadPage(name); } } PageLoader l = new PageLoader(new MockProvider()); l.loadPage(home); Then again, it might just feel weird because I've gotten very used to OOP. In my Java code, loading pages is a responsibility of the PageLoader and it delegates it to the Provider. Objects have responsibilities and send messages to each other to fulfill these, that's OOP. In functional programming, there's simply a function that has a certain functionality, and everything it needs to fulfill it has to be provided by the caller. That's at least how I understand it by now. Maybe I should just call the function returned by (make-mock-provider) directly? The interface in Java has the great benefit of ensuring type safety (plus there's no closures yet, so it's the only way), but does this make sense in a dynamic language? I mean, if I passed an implementation of the wrong interface or a closure with the wrong number of arguments, wouldn't both situations result in weird runtime errors? On 12/10/10 22:34, Armando Blancas wrote: Back to my question: Am I trying to do Java in Clojure? Is there a more Lisp-y way to do this? You can hide the types so your client code is more lispy: (defn load-page [prov] (.loadPage prov)) ;;test (def mp (make-mock-provider)) ... (load-page mp) ;;production (def prov (make-provider)) ... (load-page prov) Depending on your app the provider could be a singleton and need not be passed to each function. Another option is multimethods, in which case you'd be using mock functions with an argument that would indicate which version to dispatch to. As for the repl, I think it works just as well for bottom-up and top- down development. I use it for both all the time and to avoid throw- away tests I write them top-down, black-box for only what's visible to client/interop code first, then move down the layers as the code is more mature and stable. I'm not really into TDD but I depend on a test suite as complete as I can get it. signature.asc 1KViewDownload -- 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