Mysterious errors w/ protocols and types
The following code contains an error, and I cannot figure out what it is at all. When I run StateMeta's test once, the statement marked with a comment above fails. When I run it again, it succeeds. This has been causing very weird bugs in my code. I've replicated the behavior in both a script and the REPL. Here's the bugged code: (ns name.choi.joshua.fnparse [:use clojure.test]) (defprotocol ABankable (get-bank [o]) (vary-bank [o f & args])) (with-test (deftype StateMeta [bank index rule-stack] [clojure.lang.IPersistentMap]) (let [bank {:a 3} state-meta (StateMeta bank nil nil)] (is (= (get-bank state-meta) bank)) (is (= (get-bank (vary-bank state-meta identity)) bank)) ; This is the statement throwing an exception (is (= (get-bank (vary-bank state-meta assoc :b 2)) (assoc bank :b 2) (extend ::StateMeta ABankable {:get-bank :bank :vary-bank (fn vary-state-meta-bank [this f & args] (println ">" this f args) (apply update-in this [:bank] f args))}) --- Here is the behavior in a REPL by pasting in that code: Clojure 1.1.0-alpha-SNAPSHOT user=> (ns name.choi.joshua.fnparse [:use clojure.test]) (defprotocol ABankable (get-bank [o]) (vary-bank [o f & args])) (with-test (deftype StateMeta [bank index rule-stack] [clojure.lang.IPersistentMap]) (let [bank {:a 3} state-meta (StateMeta bank nil nil)] (is (= (get-bank state-meta) bank)) (is (= (get-bank (vary-bank state-meta identity)) bank)) (is (= (get-bank (vary-bank state-meta assoc :b 2)) (assoc bank :b 2) (extend ::StateMeta ABankable {:get-bank :bank :vary-bank (fn vary-state-meta-bank [this f & args] (println ">" this f args) (apply update-in this [:bank] f args))}) nil name.choi.joshua.fnparse=> name.choi.joshua.fnparse=> ABankable name.choi.joshua.fnparse=> name.choi.joshua.fnparse=> #'name.choi.joshua.fnparse/StateMeta name.choi.joshua.fnparse=> name.choi.joshua.fnparse=> name.choi.joshua.fnparse=> nil name.choi.joshua.fnparse=> name.choi.joshua.fnparse=> (test #'StateMeta) ERROR in clojure.lang.persistentlist$emptyl...@1 (NO_SOURCE_FILE:13) expected: (= (get-bank (vary-bank state-meta identity)) bank) actual: java.lang.IllegalArgumentException: Wrong number of args passed to: fnparse$eval--21$fn--33$G--9 at clojure.lang.AFn.throwArity (AFn.java:449) clojure.lang.AFn.invoke (AFn.java:56) name.choi.joshua.fnparse$eval__54$fn__84$fn__91.invoke (NO_SOURCE_FILE:13) name.choi.joshua.fnparse$eval__54$fn__84.invoke (NO_SOURCE_FILE: 13) clojure.core/test (core.clj:3125) name.choi.joshua.fnparse/eval (NO_SOURCE_FILE:24) clojure.lang.Compiler.eval (Compiler.java:4939) clojure.lang.Compiler.eval (Compiler.java:4907) clojure.core/eval (core.clj:1975) clojure.main$repl__7993$read_eval_print__8005.invoke (main.clj: 180) clojure.main$repl__7993.doInvoke (main.clj:197) clojure.lang.RestFn.invoke (RestFn.java:422) clojure.main/repl_opt (main.clj:251) clojure.main/legacy_repl (main.clj:292) clojure.lang.Var.invoke (Var.java:365) clojure.main.legacy_repl (main.java:27) clojure.lang.Repl.main (Repl.java:20) > #:StateMeta{:bank {:a 3}, :index nil, :rule-stack nil} > # (:b 2) :ok name.choi.joshua.fnparse=> (test #'StateMeta) > #:StateMeta{:bank {:a 3}, :index nil, :rule-stack nil} > # nil > #:StateMeta{:bank {:a 3}, :index nil, :rule-stack nil} > # (:b 2) :ok --- This is absolutely stupefying. What in the world could it be? -- 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
AOT'd namespaces lose their metadata
I noticed an odd bug when working on the help command for leiningen. It uses docstrings on metadata for help output, but when AOTing the project, the docstrings (as well as all other metadata) would be lost. Note that this doesn't happen when metadata is added to the namespace after the fact as is the case with clojure.core and alter-meta!. Any idea what might be causing this? I'd like to dig deeper but am unsure where to look. thanks, Phil -- 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
Improving Clojure startup time with -Xbootclasspath
We were discussing Clojure startup time (in the context of Leiningen) and Phil Hagelberg asked some JRuby people about startup time. They suggested using -Xbootclasspath. Check this out: % time (echo | java -client -cp clojure.jar clojure.main) 0.84s user 0.04s system 96% cpu 0.908 total % time (echo | java -client -Xbootclasspath/a:clojure.jar clojure.main) 0.42s user 0.04s system 106% cpu 0.431 total For the server VM: % time (echo | java -server -cp clojure.jar clojure.main) 1.07s user 0.06s system 113% cpu 0.995 total % time (echo | java -server -Xbootclasspath/a:clojure.jar clojure.main) 0.56s user 0.06s system 109% cpu 0.562 total For reference: % java -version java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode) Apparently on Dan Larkin's PC startup time went from a terrible 5.5s to a more bearable 1.9s. Looks like it's problematic to put Clojure libs in the bootclasspath though. I get an NPE: Caused by: java.lang.NullPointerException at clojure.lang.RT.load(RT.java:377) at clojure.lang.RT.load(RT.java:371) Which is this line from RT.java: URL classURL = baseLoader().getResource(classfile); (clojure.lang.RT/baseLoader) isn't null, so I'm not sure what the deal is with that unless the class loading runs in a different thread where it is null or something. But if you just put the Clojure jar itself in -Xbootclasspath and the rest of your libs as normal -cp you still get a nice fast start. :-) Charles Nutter has a nice list of JVM flags here: http://blog.headius.com/2009/01/my-favorite-hotspot-jvm-flags.html I don't get much of a benefit out of -XShare on my system but it might be worth trying as well. -- 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: Clojure Scoping Rules
> Richard, do you know where one can read about Rich Hickey's > speculative work on scoping constructs? I did find a good description > by him of what Clojure currently does, from 2007: http://clojure.org/todo http://www.assembla.com/spaces/clojure/tickets/2-Scopes Better off asking Rich, I think :) I believe "Scopes" as written is related to things like with-open more than bindings, but I'm sure there's interplay. -- 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: String to Decimal Conversion
> Awesome Kevin. That solution is sexy. I don't even need the java > library anymore. Note, however, that this can return (or do!) near anything, because it accepts any Clojure syntax. user=> (read-string "\"foo\"") "foo" ; a string user=> (read-string "(1.1)") (1.1) ; a list containing a float user=> (read-string "foo") user/foo; an interned symbol including executing arbitrary code, unless you bind *read-eval*: user=> (read-string "#=(println \"Oof\")") Oof; this gets printed. It could do much worse. nil In short... use the reader when you want to handle Clojure syntax. If you want to convert a string to a decimal, do it properly. You'll get useful exceptions, prevent bad input, and avoid inadvertent attack vectors. There's no "needing the Java library" -- you always have the core Java classes available, including Double and BigDecimal. HTH, -R -- 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: Clojure Scoping Rules
Richard, do you know where one can read about Rich Hickey's speculative work on scoping constructs? I did find a good description by him of what Clojure currently does, from 2007: http://markmail.org/message/kpuq4dvcavek26sp#query:+page:1+mid:mgfsubipgaqdmzru+state:results -- 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: String to Decimal Conversion
Awesome Kevin. That solution is sexy. I don't even need the java library anymore. On Nov 22, 5:02 pm, Kevin Downey wrote: > user=> (read-string "1.1") > 1.1 > user=> > > > > > > On Sun, Nov 22, 2009 at 4:48 PM, Don wrote: > > Thanks a bunch Richard. > > > On Nov 22, 4:47 pm, Richard Newman wrote: > >> > I am having a problem converting a string to decimal. I want to > >> > convert "1.0" to decimal 1.0. > > >> For a double (not decimal): > > >> (Double/parseDouble "1.1") > >> => > >> 1.1 > > >> for a decimal: > > >> (BigDecimal. "1.1") > >> 1.1M > > >> Note that Clojure has reader support for BigDecimal (the "M"). > > > -- > > 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 > > -- > And what is good, Phaedrus, > And what is not good— > Need we ask anyone to tell us these things? -- 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: String to Decimal Conversion
Awesome Kevin. That solution is sexy. I don't even need the libraries anymore. On Nov 22, 5:02 pm, Kevin Downey wrote: > user=> (read-string "1.1") > 1.1 > user=> > > > > > > On Sun, Nov 22, 2009 at 4:48 PM, Don wrote: > > Thanks a bunch Richard. > > > On Nov 22, 4:47 pm, Richard Newman wrote: > >> > I am having a problem converting a string to decimal. I want to > >> > convert "1.0" to decimal 1.0. > > >> For a double (not decimal): > > >> (Double/parseDouble "1.1") > >> => > >> 1.1 > > >> for a decimal: > > >> (BigDecimal. "1.1") > >> 1.1M > > >> Note that Clojure has reader support for BigDecimal (the "M"). > > > -- > > 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 > > -- > And what is good, Phaedrus, > And what is not good— > Need we ask anyone to tell us these things? -- 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: String to Decimal Conversion
user=> (read-string "1.1") 1.1 user=> On Sun, Nov 22, 2009 at 4:48 PM, Don wrote: > Thanks a bunch Richard. > > On Nov 22, 4:47 pm, Richard Newman wrote: >> > I am having a problem converting a string to decimal. I want to >> > convert "1.0" to decimal 1.0. >> >> For a double (not decimal): >> >> (Double/parseDouble "1.1") >> => >> 1.1 >> >> for a decimal: >> >> (BigDecimal. "1.1") >> 1.1M >> >> Note that Clojure has reader support for BigDecimal (the "M"). > > -- > 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 -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- 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: String to Decimal Conversion
Thanks a bunch Richard. On Nov 22, 4:47 pm, Richard Newman wrote: > > I am having a problem converting a string to decimal. I want to > > convert "1.0" to decimal 1.0. > > For a double (not decimal): > > (Double/parseDouble "1.1") > => > 1.1 > > for a decimal: > > (BigDecimal. "1.1") > 1.1M > > Note that Clojure has reader support for BigDecimal (the "M"). -- 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: String to Decimal Conversion
> I am having a problem converting a string to decimal. I want to > convert "1.0" to decimal 1.0. For a double (not decimal): (Double/parseDouble "1.1") => 1.1 for a decimal: (BigDecimal. "1.1") 1.1M Note that Clojure has reader support for BigDecimal (the "M"). -- 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: String to Decimal Conversion
Yes you are right. Hence the error message I posted. But it was the only idea that came to mind. I'm new to clojure and not a java programmer. On Nov 22, 4:20 pm, Kevin Downey wrote: > 1.1 is not representable as an Integer(Java class, or primitive int) > and is not an integer (mathematical sense) so expecting to be > representable as one, is kind of... odd. > > > > > > On Sun, Nov 22, 2009 at 4:14 PM, Don wrote: > > I am having a problem converting a string to decimal. I want to > > convert "1.0" to decimal 1.0. I have tried the java.lang.Integer > > class > > > use=> (Integer/parseInt "1.1") > > java.lang.NumberFormatException: For input string: > > "1.1" (NO_SOURCE_FILE:0) > > > But it won't give. It does however work when I run it with "1". > > > Any suggestions would be greatly appreciated. Thank you. > > > -- > > 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 > > -- > And what is good, Phaedrus, > And what is not good— > Need we ask anyone to tell us these things? -- 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: String to Decimal Conversion
1.1 is not representable as an Integer(Java class, or primitive int) and is not an integer (mathematical sense) so expecting to be representable as one, is kind of... odd. On Sun, Nov 22, 2009 at 4:14 PM, Don wrote: > I am having a problem converting a string to decimal. I want to > convert "1.0" to decimal 1.0. I have tried the java.lang.Integer > class > > use=> (Integer/parseInt "1.1") > java.lang.NumberFormatException: For input string: > "1.1" (NO_SOURCE_FILE:0) > > But it won't give. It does however work when I run it with "1". > > Any suggestions would be greatly appreciated. Thank you. > > -- > 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 -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- 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
String to Decimal Conversion
I am having a problem converting a string to decimal. I want to convert "1.0" to decimal 1.0. I have tried the java.lang.Integer class use=> (Integer/parseInt "1.1") java.lang.NumberFormatException: For input string: "1.1" (NO_SOURCE_FILE:0) But it won't give. It does however work when I run it with "1". Any suggestions would be greatly appreciated. Thank you. -- 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
Holding onto your head & step functions -- confusion
Hi All, I'll confused about the hold-onto-your-head business when building lazy seqs using lazy-seq. The "lazier" documentation on the web site doesn't really clear things up for me, though I've read it a few times. Under what circumstances must one use a "step" function, and under what circumstances it it acceptable not to? If this is covered in depth somewhere other than the "lazier" page please feel free just to send a link. As a point of discussion, does the following function have the potential to cause memory problems? Some notes: *kernel* and *options* are dynamic vars I want the lazy-seq to close over. parse-simple-atom is a function for parsing each element ("atom," **unrelated to Clojure atoms**) of the coll. type is an arg that is used in the parsing of each element of the coll. (defn parse-expr-coll-to-lazy-seq [coll type] (let [kernel *kernel* options *options*] (lazy-seq (binding [*kernel* kernel *options* options] (when-let [s (seq coll)] (cons (parse-simple-atom (first s) type) (parse-expr-coll-to-lazy-seq (rest s) type))) Thanks, Garth -- 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: Monad problems: finding an m-zero
I wrote one specifically for monads in Clojure. http://intensivesystems.net/tutorials/monads_101.html There's also a second part. Also, Konrad Hinson wrote one: http://onclojure.com/2009/03/06/a-monad-tutorial-for-clojure-programmers-part-1 it's in 4 parts, I believe. John Harrop wrote: > On Sun, Nov 22, 2009 at 4:25 PM, Martin DeMello > wrote: > > > On Mon, Nov 23, 2009 at 2:40 AM, John Harrop wrote: > > > Is there an explanation of monads out there that doesn't require the > > reader > > > to know Haskell to understand it? One that's generic to any FP-capable > > > language? > > > > Most of them use the concrete syntax of *some* language. But this is a > > good non-haskell one: > > > > > > http://www.ccs.neu.edu/home/dherman/research/tutorials/monads-for-schemers.txt > > > Thanks. -- 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: Clojure Scoping Rules
> True, that's a problem. But couldn't the library protect itself by > putting a (binding [*strict* false] ...) in front of its code? > (Having a namespace-level binding construct would be helpful.) That's exactly what I meant when I wrote "it would introduce a problem that library authors have to think about". I don't support any solution that requires libraries to "protect themselves" from decisions made in user code, particularly when it's so easy to externally control the evaluation of lazy sequences -- just visit them within the correct bindings! > This raises a more general thought about binding in general (while > we're talking about new language constructs). Right now you have > basically two choices for influencing code: Parameter passing, which > is, "nothing happens to my code without my permission", and dynamic > binding, which is "You might have the rug yanked from under you, and > there's nothing you can do about it!" (Exclamation point here is an > indicator of mutation, not exclamation.) An interesting point that I don't think anyone's addressed: it's not so much that the rug might be yanked from under you, but that you might find yourself on a different rug when asked to do the work. That can actually be advantageous; you can create lazy sequences and hand them somewhere else, where the appropriate bindings will be enforced during evaluation. (Maybe selecting an output stream or queue dynamically while processing a lazy stream of values, for example). Perhaps I'm just an optimist, or think a little differently. > I'm not really sure what this construct would look like. Somebody > else might have a better idea I believe that Rich has done some speculative work on scoping constructs. > Maybe the problem with binding is not that it's inherently evil, it's > just not democratic enough. Heh, I would say it's too democratic — there's something you want to do, but the broader 'society' (the existing configuration of lazy constructs and bindings) wants to do something else, so you must suffer! I'd venture a different opinion: most programmers are not used to thinking of evaluation outside the lexical order (much the same as the switch to concurrent programming). Once you get that, it ceases to be a big deal, and you use appropriate techniques (thunks, controlling evaluation yourself, taking care to choose your scopes, etc.) without much conscious thought. This switch causes a divide in discussions, where one side sees a huge problem to be fixed, and the other side sees an interesting language feature which both requires care and offers power, but arises naturally from the semantics of the language. -- 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: Does a standard function exist that acts like assoc except it applies fns to vals
Ah, update-in is exactly what I need. Excellent, thank you. On Nov 22, 2:38 pm, John Harrop wrote: > On Sun, Nov 22, 2009 at 4:32 PM, samppi wrote: > > Does a function that does this: > > (vary coll :x fn-x, :y fn-y) > > ; Equivalent to (assoc coll :x (fn-x (:x coll)), :y (fn-y (:y > > coll))) > > exist in the core or contrib APIs? > > > I'm surprised that I can't find any. It's a very natural extension of > > assoc. > > There's update-in, which is like what you want but for assoc-in, but oddly > no plain update analogously to plain assoc. I'd use update-in. -- 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: Monad problems: finding an m-zero
On Sun, Nov 22, 2009 at 4:25 PM, Martin DeMello wrote: > On Mon, Nov 23, 2009 at 2:40 AM, John Harrop wrote: > > Is there an explanation of monads out there that doesn't require the > reader > > to know Haskell to understand it? One that's generic to any FP-capable > > language? > > Most of them use the concrete syntax of *some* language. But this is a > good non-haskell one: > > > http://www.ccs.neu.edu/home/dherman/research/tutorials/monads-for-schemers.txt Thanks. -- 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: Does a standard function exist that acts like assoc except it applies fns to vals
On Sun, Nov 22, 2009 at 4:32 PM, samppi wrote: > Does a function that does this: > (vary coll :x fn-x, :y fn-y) > ; Equivalent to (assoc coll :x (fn-x (:x coll)), :y (fn-y (:y > coll))) > exist in the core or contrib APIs? > > I'm surprised that I can't find any. It's a very natural extension of > assoc. There's update-in, which is like what you want but for assoc-in, but oddly no plain update analogously to plain assoc. I'd use update-in. -- 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
Does a standard function exist that acts like assoc except it applies fns to vals
Does a function that does this: (vary coll :x fn-x, :y fn-y) ; Equivalent to (assoc coll :x (fn-x (:x coll)), :y (fn-y (:y coll))) exist in the core or contrib APIs? I'm surprised that I can't find any. It's a very natural extension of assoc. But if there really isn't any, is the code below the best/most- idiomatic/most-efficient way to implement such a function? (defn vary [coll & keys-and-fns] (let [fn-map (apply arrray-map keys-and-fns) keys-and-vals (mapcat #((val %) (get coll (key %))) fn-map)] (apply assoc-args coll keys-and-vals))) -- 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: Clojure Scoping Rules
Richard--- > What if you accidentally cause a library to realize an infinite > lazy sequence? True, that's a problem. But couldn't the library protect itself by putting a (binding [*strict* false] ...) in front of its code? (Having a namespace-level binding construct would be helpful.) This raises a more general thought about binding in general (while we're talking about new language constructs). Right now you have basically two choices for influencing code: Parameter passing, which is, "nothing happens to my code without my permission", and dynamic binding, which is "You might have the rug yanked from under you, and there's nothing you can do about it!" (Exclamation point here is an indicator of mutation, not exclamation.) Well, this might be wildly speculative, but couldn't there be a middle way? I.E. a scope or a function body (if we are trying to unify these concepts then Scope and Function Body is really the same thing), instead of exporting variables of things that can be substituted, basically sets up a negotiation over what can and should be bound. It might state things like "binding this such-and-such a way is a \really \bad idea, but if you do X first, it would be OK; and of course if you \insist" The actual binding (if such a guard has been put up) then doesn't happen until the conditions have been run through. I'm not really sure what this construct would look like. Somebody else might have a better idea Maybe the problem with binding is not that it's inherently evil, it's just not democratic enough. -- 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: Monad problems: finding an m-zero
On Mon, Nov 23, 2009 at 2:40 AM, John Harrop wrote: > Is there an explanation of monads out there that doesn't require the reader > to know Haskell to understand it? One that's generic to any FP-capable > language? Most of them use the concrete syntax of *some* language. But this is a good non-haskell one: http://www.ccs.neu.edu/home/dherman/research/tutorials/monads-for-schemers.txt martin -- 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: Monad problems: finding an m-zero
Is there an explanation of monads out there that doesn't require the reader to know Haskell to understand it? One that's generic to any FP-capable language? -- 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: Monad problems: finding an m-zero
Yes, I see. I'm going to guess that the parser-m that I give above has no possible m-zero, so I think I'll have to rethink how I'm going to approach this problem. I probably am going to just define failure in another way. (The reason why I can't use nil is because I need to store metadata on the object representing failure. I'm sure I'll figure something out.) Thanks for your help. On Nov 22, 1:31 pm, jim wrote: > Samppi, > > Good work on figuring that out. It's by working through those kinds of > problems that you really learn about monads. It is indeed the case > that not all monads have m-zero and m-plus defined for them. The state- > m monad is one of those. Not only that, but if you take a look at the > state-t monad transformer, you'll see m-zero defined like this: > > m-zero (with-monad m > (if (= ::undefined m-zero) > ::undefined > (fn [s] > m-zero))) > > Notice that when you combine the state-m monad with another monad > using state-t, an m-zero for the resulting monad is only defined if > the original monad had an m-zero. Also notice that when an m-zero is > defined for the original monad, the new m-zero is a function that > accepts a state and returns the original m-zero without regard to the > state that was passed in. And that's where your original monad ran > into problems, you tried to make the new m-zero's return value > dependent on the state that was passed in. > > Furthermore, it's hard to see it, but :when clauses in domonad require > that m-zero exists, and obeys the monad laws for zero and plus. So if > you're m-zero is incorrect, :when clauses won't work either. > > At this point, you need to drop back and understand exactly what > you're trying to accomplish and make sure you really understand monads > as fully as possible. I just spent almost 2 weeks working on my own > monad for writing web applications. I finally gave up and sat down to > really learn how the continuation monad works. After that, I > discovered I could use it instead of writing my own and it turned out > to be very easy. Very often, you can come up with something that > almost works and think that it just needs one more tweak to get it > right. That's what happened to me and I wasted a lot of effort before > I finally tossed it out and really focused on understanding. > > If you'd like to post details of what you're doing, I'd guess some > folks would lend some assistance. > > Jim > > On Nov 22, 11:04 am, samppi wrote: > > > > > Thanks for the help. > > > After working it out, I just figured out that the reason why the > > second axiom isn't fulfilled by the m-zero above is this part in m- > > bind: > > ((product-fn product) new-state)) > > > product-fn, which in the second axiom's case is (fn [x] m-zero), gets > > called and becomes m-zero, which is in turn called on new-state, not > > the old state. > > > I cannot figure out at all, though, what m-zero *is* valid under both > > axioms. Now I don't see how it's simply possible at all—are there > > monads for which there is no value of m-zero, and is this one of them? > > > On Nov 21, 9:02 pm, jim wrote: > > > > Glad you found that tutorial useful. I had to run this morning, so I > > > couldn't really reply. I'll try to read your post more closely > > > tomorrow and see if I can offer any useful insight. > > > > Jim -- 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: leiningen - a Clojure build tool
bOR_ wrote: > What is the normal way to let Leiningen know about local jars? I am > using brics automaton in one of my projects, and that jar is only > downloadable after confirming the bsd licence (http://www.brics.dk/ > automaton/), so I have it locally on my disk, but it isn't in clojars > or mvnrepositiory.com. > > It being a BSD licence, it allows redistribution. Can I just upload it > to Clojars? Sure, go for it. > Having to agree with a BSD license is a bit strange. Yeah, you see that a lot with university projects for some reason. Even worse they sometimes force you to join a mailing list or fill in a "what are you going to use this for?" form. -- 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: Monad problems: finding an m-zero
Samppi, Good work on figuring that out. It's by working through those kinds of problems that you really learn about monads. It is indeed the case that not all monads have m-zero and m-plus defined for them. The state- m monad is one of those. Not only that, but if you take a look at the state-t monad transformer, you'll see m-zero defined like this: m-zero (with-monad m (if (= ::undefined m-zero) ::undefined (fn [s] m-zero))) Notice that when you combine the state-m monad with another monad using state-t, an m-zero for the resulting monad is only defined if the original monad had an m-zero. Also notice that when an m-zero is defined for the original monad, the new m-zero is a function that accepts a state and returns the original m-zero without regard to the state that was passed in. And that's where your original monad ran into problems, you tried to make the new m-zero's return value dependent on the state that was passed in. Furthermore, it's hard to see it, but :when clauses in domonad require that m-zero exists, and obeys the monad laws for zero and plus. So if you're m-zero is incorrect, :when clauses won't work either. At this point, you need to drop back and understand exactly what you're trying to accomplish and make sure you really understand monads as fully as possible. I just spent almost 2 weeks working on my own monad for writing web applications. I finally gave up and sat down to really learn how the continuation monad works. After that, I discovered I could use it instead of writing my own and it turned out to be very easy. Very often, you can come up with something that almost works and think that it just needs one more tweak to get it right. That's what happened to me and I wasted a lot of effort before I finally tossed it out and really focused on understanding. If you'd like to post details of what you're doing, I'd guess some folks would lend some assistance. Jim On Nov 22, 11:04 am, samppi wrote: > Thanks for the help. > > After working it out, I just figured out that the reason why the > second axiom isn't fulfilled by the m-zero above is this part in m- > bind: > ((product-fn product) new-state)) > > product-fn, which in the second axiom's case is (fn [x] m-zero), gets > called and becomes m-zero, which is in turn called on new-state, not > the old state. > > I cannot figure out at all, though, what m-zero *is* valid under both > axioms. Now I don't see how it's simply possible at all—are there > monads for which there is no value of m-zero, and is this one of them? > > On Nov 21, 9:02 pm, jim wrote: > > > Glad you found that tutorial useful. I had to run this morning, so I > > couldn't really reply. I'll try to read your post more closely > > tomorrow and see if I can offer any useful insight. > > > Jim -- 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: How to make this a non-reflecting call?
On Sun, Nov 22, 2009 at 08:40:42PM +0100, Christophe Grand wrote: >(defn foo [#^FileChannel chan, bufs] >(.write chan #^"[Ljava.nio.ByteBuffer;" (to-array bufs))) Excellent, it was the quotes I was missing. Nice to know I can hint any type. Thanks, 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 at http://groups.google.com/group/clojure?hl=en
Re: Clojure Scoping Rules
> Richard--- > It's not the same thing: > > (class (doall (map (fn [x] x) [1 2 3]))) > -> clojure.lang.LazySeq > > whereas > > (class (binding [*strict* true] > (map (fn[x] x) [1 2 3]))) > -> clojure.lang.LazilyPersistentVector From Clojure's perspective those *are* the same thing: user=> (= (map identity [1 2 3]) [1 2 3]) true Also, just because it's lazy doesn't mean it hasn't already done the work, and user=> (def *x* 1) #'user/*x* user=> (doseq [y (map (fn [x] (* *x* x)) [1 2 3])] (println y)) 1 2 3 nil user=> (doseq [y (binding [*x* 2] (map (fn [x] (* *x* x)) [1 2 3]))] (println y)) 1 2 3 nil user=> (doseq [y (binding [*x* 2] (doall (map (fn [x] (* *x* x)) [1 2 3])))] (println y)) 2 4 6 nil The result of doall is a sequence that has already been evaluated. If you want a concrete sequence, you can get one: simply call seq on the output, or use vec or into. user=> (type (binding [*x* 2] (doall (map (fn [x] (* *x* x)) [1 2 3] clojure.lang.LazySeq user=> (type (seq (binding [*x* 2] (doall (map (fn [x] (* *x* x)) [1 2 3]) clojure.lang.ChunkedCons user=> (type (vec (binding [*x* 2] (doall (map (fn [x] (* *x* x)) [1 2 3]) clojure.lang.PersistentVector user=> (vec (binding [*x* 2] (doall (map (fn [x] (* *x* x)) [1 2 3] [2 4 6] > Also, having a dynamic var that turns laziness on and off would allow > you to do it once for any given scope, without having to add the extra > 'ceremony' of doalls. Sure, but it would either require complicating the core, or making functions that use lazy-seq pay attention to the binding of that var. Not fun -- it would introduce a problem that library authors have to think about. > I would add to that that casting your types back to what they were is > also unrealistic. I get the impression that programming with *abstractions* is the Clojure way. Dependence on particular sequence types is usually bad. If you need to, though, it's only a vec call away. If you call vec inside a binding form, you don't even need to realize the lazy sequence yourself. > If there were a *strict* dynamic var, then you \could choose code > simplification over laziness with a single line. What would be wrong > with that? To play devil's advocate: it complicates the implementation (and the implementation of libraries); the strictness would be undesirably viral (what if you accidentally cause a library to realize an infinite lazy sequence?); and for all I know it would screw up JIT optimization. My opinion is that an easier way to realize nested lazy sequences would be a more elegant solution to your problem; doall*, say. This could almost be implemented as (defmulti doall* class) (defmethod doall* clojure.lang.LazySeq [x] (seq (doall (map doall* x (defmethod doall* :default [x] x) ... ;; Make some nested LazySeqs. user=> (type (map (fn [x] (repeat x :foo)) [1 2 3])) clojure.lang.LazySeq user=> (map type (map (fn [x] (repeat x :foo)) [1 2 3])) (clojure.lang.LazySeq clojure.lang.LazySeq clojure.lang.LazySeq) ;; Recursively eager evaluation. user=> (type (doall* (map (fn [x] (repeat x :foo)) [1 2 3]))) clojure.lang.ChunkedCons user=> (map type (doall* (map (fn [x] (repeat x :foo)) [1 2 3]))) (clojure.lang.Cons clojure.lang.Cons clojure.lang.Cons) You can omit the seq call in doall* if all you want is bindings capture/eager evaluation, and don't actually mind that it's LazySeq implementing ISeq rather than a 'concrete' sequence. -- 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: positions
Thanks Emeka, I took a look at it. I still say it would be nice to organize the sequence functions (somehow). -- 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: How to make this a non-reflecting call?
Hi David, On Sun, Nov 22, 2009 at 6:55 PM, David Brown wrote: > java.nio.channels.FileChannel contains some .write methods: > > [27] write : int (ByteBuffer) > [28] write : int (ByteBuffer,long) > [29] write : long (ByteBuffer[]) > [30] write : long (ByteBuffer[],int,int) > > I have an array of ByteBufers, but I can't figure out how to call #29 > without it being a reflecting call. Giving a type of #^objects > doesn't seem to help. > > (defn foo [#^FileChannel chan, bufs] > (.write chan (to-array bufs))) > > gives a reflection warning. > > Any ideas? Yup: (defn foo [#^FileChannel chan, bufs] (.write chan #^"[Ljava.nio.ByteBuffer;" (to-array bufs))) #^objects is a shortcut for hinting Object[] instances. When you want to hint an instance of some.Class[], the hint is #^"[Lsome.Class;" So #^objects is short for #^"[Ljava.lang.Object;". If you can't remember the syntax, you can try this at the repl: user=> (class (into-array ByteBuffer nil)) [Ljava.nio.ByteBuffer; hth, Christophe -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (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: Clojure Scoping Rules
Richard--- It's not the same thing: (class (doall (map (fn [x] x) [1 2 3]))) -> clojure.lang.LazySeq whereas (class (binding [*strict* true] (map (fn[x] x) [1 2 3]))) -> clojure.lang.LazilyPersistentVector Also, having a dynamic var that turns laziness on and off would allow you to do it once for any given scope, without having to add the extra 'ceremony' of doalls. To quote Mark Engleberg: "If you want to choose code simplification over laziness, it's not always even clear how to do that safely. For example, it's not uncommon to end up with lazy sequences of lazy sequences [...], and then a single doall isn't going to the trick. Wrapping doall around every single call in your code is unrealistic. " I would add to that that casting your types back to what they were is also unrealistic. If there were a *strict* dynamic var, then you \could choose code simplification over laziness with a single line. What would be wrong with 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: How to make this a non-reflecting call?
On Sun, Nov 22, 2009 at 01:00:51PM -0500, John Harrop wrote: >On Sun, Nov 22, 2009 at 12:55 PM, David Brown wrote: > >> java.nio.channels.FileChannel contains some .write methods: >> >> [27] write : int (ByteBuffer) >> [28] write : int (ByteBuffer,long) >> [29] write : long (ByteBuffer[]) >> [30] write : long (ByteBuffer[],int,int) >> >> I have an array of ByteBufers, but I can't figure out how to call #29 >> without it being a reflecting call. Giving a type of #^objects >> doesn't seem to help. >> >> (defn foo [#^FileChannel chan, bufs] >> (.write chan (to-array bufs))) >> >> gives a reflection warning. >> >> Any ideas? >Try #^[LByteBuffer; That doesn't parse. I did get it to work with reflection, by using (into-array ByteBuffer bufs) instead of to-array. That way I at least get the right array type, even if the compiler can't figure it out. Any idea what kind of performance hit this actually ends up being? 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 at http://groups.google.com/group/clojure?hl=en
Re: leiningen - a Clojure build tool
2009/11/22 John Harrop : > How is it pronounced anyway, at the start? LINE... or LANE...? If it's German-ish, it would be the former. If it's more like Afrikaans (or maybe Dutch?) it would be the latter, although it would be a very strange sort of Afrikaans word, so I'd go with the German pronunciation. -- Michael Wood -- 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: How to make this a non-reflecting call?
On Sun, Nov 22, 2009 at 12:55 PM, David Brown wrote: > java.nio.channels.FileChannel contains some .write methods: > > [27] write : int (ByteBuffer) > [28] write : int (ByteBuffer,long) > [29] write : long (ByteBuffer[]) > [30] write : long (ByteBuffer[],int,int) > > I have an array of ByteBufers, but I can't figure out how to call #29 > without it being a reflecting call. Giving a type of #^objects > doesn't seem to help. > > (defn foo [#^FileChannel chan, bufs] > (.write chan (to-array bufs))) > > gives a reflection warning. > > Any ideas? Try #^[LByteBuffer; -- 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: leiningen - a Clojure build tool
How is it pronounced anyway, at the start? LINE... or LANE...? -- 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
How to make this a non-reflecting call?
java.nio.channels.FileChannel contains some .write methods: [27] write : int (ByteBuffer) [28] write : int (ByteBuffer,long) [29] write : long (ByteBuffer[]) [30] write : long (ByteBuffer[],int,int) I have an array of ByteBufers, but I can't figure out how to call #29 without it being a reflecting call. Giving a type of #^objects doesn't seem to help. (defn foo [#^FileChannel chan, bufs] (.write chan (to-array bufs))) gives a reflection warning. Any ideas? -- 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: "Oh, yeah, transients are fast!"
On Sun, Nov 22, 2009 at 11:45:46AM -0500, John Harrop wrote: >Nothing so serious as a hang, though, and at least I can do basic things in >my IDE without reaching for the frelling manual every two minutes to look up >some key-combination :) I suspect both models are going to be important. I feel the same way you do when I'm running an IDE rather than vim. Oddly enough, I've found myself most productive with a repl in it's own window, and a short script (below) in user.clj to let me specify a namespace to test. I put this in a 'repl' directory that I only add to my classpath for the repl script. David (println "Running user startup") (use 'clojure.contrib.repl-utils) (use 'clojure.contrib.str-utils) (use 'clojure.contrib.java-utils) (use 'clojure.contrib.def) (use 'clojure.contrib.ns-utils) (use 'clojure.contrib.test-is) (use 'clojure.contrib.sql) (use 'clojure.stacktrace) (set! *warn-on-reflection* true) ;;; The NS that we are testing/working on. ;;; This can be given through the java property work-ns, e.g. ;;; ./run.sh -Dwork-ns=org.davidb.chunk-file (def *work-ns* (symbol (or (System/getProperty "work-ns") 'org.davidb.foo))) ;;; A testing NS. (def *test-ns* (symbol (or (System/getProperty "test-ns") (symbol (re-sub #"[^\.]+$" #(str "test-" %) (name *work-ns*)) ; (use *work-ns*) (defn l [] (binding [*warn-on-reflection* true] (use *work-ns* :reload))) (defn t [] (binding [*warn-on-reflection* true] (require *test-ns* :reload) (run-tests *test-ns*))) (defn i [] (in-ns *work-ns*)) ; Load the User's test-user.clj if present. (try (load "/test-user") (catch java.io.FileNotFoundException e (println "No test-user.clj found in classpath."))) -- 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: leiningen - a Clojure build tool
On Sun, Nov 22, 2009 at 07:14:33AM -0800, bOR_ wrote: >What is the normal way to let Leiningen know about local jars? I am >using brics automaton in one of my projects, and that jar is only >downloadable after confirming the bsd licence (http://www.brics.dk/ >automaton/), so I have it locally on my disk, but it isn't in clojars >or mvnrepositiory.com. When the maven fails to find the package, it will spew out instructions on how to install it into your local maven cache. Something like: mvn install:install-file -DgroupId=org.domain -DartifactId=package -Dversion=1.2.3 -Dpackaging=jar -Dfile=path/to/file.jar But, on one line. Having to agree with a BSD license is a bit strange. 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 at http://groups.google.com/group/clojure?hl=en
Re: leiningen - a Clojure build tool
On Sun, Nov 22, 2009 at 01:05:43AM -0800, bOR_ wrote: >elif [ ${1: -4} = ".clj" ]; then ># Small hack to use lein to start clojure scripts >java -cp "$CLASSPATH" clojure.main "$1" How about elif [ ${1: -4} = ".clj" ]; then # Small hack to use lein to start clojure scripts java -cp "$CLASSPATH" clojure.main "$@" So you can even pass arguments to the script. BTW, the leiningen.core invocation at the end should also be "$@" so that arguments with spaces don't get expanded into multiple arguments. If you add arguments to the 'repl' case, then you can run scripts using that as well. 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 at http://groups.google.com/group/clojure?hl=en
Re: Monad problems: finding an m-zero
Thanks for the help. After working it out, I just figured out that the reason why the second axiom isn't fulfilled by the m-zero above is this part in m- bind: ((product-fn product) new-state)) product-fn, which in the second axiom's case is (fn [x] m-zero), gets called and becomes m-zero, which is in turn called on new-state, not the old state. I cannot figure out at all, though, what m-zero *is* valid under both axioms. Now I don't see how it's simply possible at all—are there monads for which there is no value of m-zero, and is this one of them? On Nov 21, 9:02 pm, jim wrote: > Glad you found that tutorial useful. I had to run this morning, so I > couldn't really reply. I'll try to read your post more closely > tomorrow and see if I can offer any useful insight. > > Jim -- 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: positions
On Sun, Nov 22, 2009 at 7:54 AM, Emeka wrote: > John, > > You should have added that you code came from Programming Clojure. > It didn't. If it's the same as, or closely similar to, code from there, it's entirely coincidental. In Clojure there's usually several ways to do something, but often only a few elegant ways to do something as short as that, so it's not very surprising. (I checked and my implementation of indexed is virtually identical to the one in clojure.contrib too, as it happens.) -- 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: "Oh, yeah, transients are fast!"
On Sun, Nov 22, 2009 at 6:05 AM, Michael Wood wrote: > > You've got some kind of system problem confounding your results, I'll > bet. > > It got slower? One test actually hung? > > My suspicion, of course, lies with the emacs environment you've just > > confessed to using. Half the traffic on this list at times is from people > > having problems with configuring either emacs or vi to work well with > > Clojure. > > Try it in a modern IDE, or from the command line, and see if the problem > > goes away. If it does, then you know the likely culprit and it isn't > > Clojure's transients. :) > > To be fair, John, you've had an issue or two with the REPL provided by > your modern IDE too :) > Nothing so serious as a hang, though, and at least I can do basic things in my IDE without reaching for the frelling manual every two minutes to look up some key-combination :) -- 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: leiningen - a Clojure build tool
What is the normal way to let Leiningen know about local jars? I am using brics automaton in one of my projects, and that jar is only downloadable after confirming the bsd licence (http://www.brics.dk/ automaton/), so I have it locally on my disk, but it isn't in clojars or mvnrepositiory.com. It being a BSD licence, it allows redistribution. Can I just upload it to Clojars? On Nov 22, 10:54 am, bOR_ wrote: > I'm currently modeling the spread and prevalence of chlamydia over a > dynamic sexual contact network. Hence the name :-). > > Plotting the graphs etc is done with Incanter, and I'm looking into > processing to draw parts of the network. Its my second science project > in Clojure (the first one was called Eden, on evolution of the human > immune system in response to pathogens), and there will be a third one > starting in january on disease spread percolating through a network of > gerbil burrows in Kazachstan (unnamed as of yet). > > On Nov 22, 10:18 am, ajuc wrote: > > > > > On 22 Lis, 13:09, bOR_ wrote: > > > > Ontopic: I might be missing something, but is there an obvious way to > > > do something like "lein src/chlamydia.clj" when I'm in the projects' > > > directory ("chlamydia"), to run a script as in "java -server > > > clojure.main chlamydia.clj"? I didn't see anything in the file "lein" > > > itself that seemed to point to that, so I added the below bit after > > > the "if repl" bit. > > > Offtopic: I'm very curious, what are the reasons to call the project > > "chlamydia" :) -- 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: Transforming a Seq to a Map
(apply has-map (apply concat (map (fn [b] [(apply hash-map (apply concat (butlast b))) (val (last b))]) (list {9 5 9 9 7 8} {3 4 5 6 7 0} {{3 4, 5 6} 0, {8 9, 9 5} 8} I just added some noise! On Wed, Nov 18, 2009 at 2:05 PM, Sean Devlin wrote: > user=>(def your-data [{:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6} {:a 7 :b 8 :c > 9}]) > > user=>(into {} (map (juxt #(dissoc % :c) :c) your-data)) > > {{:a 1, :b 2} 3, {:a 4, :b 5} 6, {:a 7, :b 8} 9} > > On Nov 18, 8:36 am, Rich Hickey wrote: > > On Wed, Nov 18, 2009 at 8:19 AM, Robert Campbell > wrote: > > > Hey guys, > > > > > I'm having some trouble finding a nice way to perform a map > > > transformation I need. I need to transform this: > > > > > [ {:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6} {:a 7 :b 8 :c 9} ] > > > > > into this: > > > > > { {:a 1 :b 2} 3 {:a 4 :b 5} 6 {:a 7 :b 8} 9 } > > > > > I wanted to use map, but each f in map only returns one value, so I > > > couldn't figure it out. Here is what I have now: > > > > > (def result (ref {})) > > > (for [item coll] > > >(dosync (alter result assoc (dissoc item :c) (item :c > > > ; result should now have correct value > > > > > I also wrote a recursive version to build the map without using a ref, > > > but I feel like I'm missing a simpler way.. > > > > (into {} > > (map (fn [m] [(dissoc m :c) (:c m)]) > > [{:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6} {:a 7 :b 8 :c 9}])) > > > > -> {{:a 1, :b 2} 3, {:a 4, :b 5} 6, {:a 7, :b 8} 9} > > > > 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 > -- 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: positions
John, You should have added that you code came from Programming Clojure. Regards, Emeka On Thu, Nov 19, 2009 at 8:05 PM, John Harrop wrote: > On Thu, Nov 19, 2009 at 1:23 PM, Sean Devlin wrote: > >> Try clojure.contrib.seq-utils :) >> >> As a learning exercise, I'd recommend re-writing it to be lazy. Your >> version is eager because it uses loop. In order to make it lazy, >> you'd want to construct a lazy-seq. See the macro w/ the same name. >> >> Another choice is to use built-in functions, like this: >> >> (defn positions [pred coll] >> (map second >>(filter (comp pred first) >> (map vector coll (iterate inc 0) > > > (defn indexed [coll] > (map vector (iterate inc 0) coll)) > > (defn positions [pred coll] > (for [[i e] (indexed coll) :when (pred e)] i)) > > Seems to work: > > user=> (positions even? [1 1 2 9 3 4 8 7 6]) > (2 5 6 8) > > (yes, I know there's already an "indexed" with similar semantics in > clojure.contrib.) > > -- > 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: positions
Nick, Remember to re-visit indexed and index-filter functions of programming Clojure. Regard, Emeka On Thu, Nov 19, 2009 at 7:13 PM, nchubrich wrote: > Thanks Sean, I'll do the exercise. I don't know how I missed it in > seq-utils. > After months of programming Clojure, I realize how much I still > have to learn. > (Knowledge is power; knowledge of lack of knowledge is power to > power.) > > Nick. > > -- > 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: "Oh, yeah, transients are fast!"
2009/11/21 John Harrop : > On Fri, Nov 20, 2009 at 5:16 PM, Raoul Duke wrote: >> >> > Try with a 1.6 JVM... >> >> wow. it actually got worse than when i was using 1.5. ... so much for >> hallowed write-once-run-the-same-anywhere-ish of the jvm, d'oh. >> >> Clojure 1.1.0-alpha-SNAPSHOT >> user=> (load-file "/tmp/test.clj") >> #'user/vrange2 >> user=> (. System getProperty "java.version") >> "1.6.0_15" >> user=> (time (def v2 (vrange2 100))) >> "Elapsed time: 329.906 msecs" >> #'user/v2 >> user=> (time (def v2 (vrange2 100))) >> "Elapsed time: 888.734 msecs" >> #'user/v2 >> user=> (time (def v2 (vrange2 100))) >> "Elapsed time: 546.982 msecs" >> #'user/v2 >> user=> (time (def v2 (vrange2 100))) >> "Elapsed time: 517.969 msecs" >> #'user/v2 >> user=> (time (def v (vrange 100))) >> "Elapsed time: 1649.449 msecs" >> #'user/v >> user=> (time (def v (vrange 100))) >> --- never came back, i had to ^C^C (in emacs buffer)!! > > You've got some kind of system problem confounding your results, I'll bet. > It got slower? One test actually hung? > My suspicion, of course, lies with the emacs environment you've just > confessed to using. Half the traffic on this list at times is from people > having problems with configuring either emacs or vi to work well with > Clojure. > Try it in a modern IDE, or from the command line, and see if the problem > goes away. If it does, then you know the likely culprit and it isn't > Clojure's transients. :) To be fair, John, you've had an issue or two with the REPL provided by your modern IDE too :) Raoul, are you using the server VM? Not sure how much of a difference it makes, and I haven't benchmarked this myself. -- Michael Wood -- 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: leiningen - a Clojure build tool
I'm currently modeling the spread and prevalence of chlamydia over a dynamic sexual contact network. Hence the name :-). Plotting the graphs etc is done with Incanter, and I'm looking into processing to draw parts of the network. Its my second science project in Clojure (the first one was called Eden, on evolution of the human immune system in response to pathogens), and there will be a third one starting in january on disease spread percolating through a network of gerbil burrows in Kazachstan (unnamed as of yet). On Nov 22, 10:18 am, ajuc wrote: > On 22 Lis, 13:09, bOR_ wrote: > > > Ontopic: I might be missing something, but is there an obvious way to > > do something like "lein src/chlamydia.clj" when I'm in the projects' > > directory ("chlamydia"), to run a script as in "java -server > > clojure.main chlamydia.clj"? I didn't see anything in the file "lein" > > itself that seemed to point to that, so I added the below bit after > > the "if repl" bit. > > Offtopic: I'm very curious, what are the reasons to call the project > "chlamydia" :) -- 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: leiningen - a Clojure build tool
On 22 Lis, 13:09, bOR_ wrote: > Ontopic: I might be missing something, but is there an obvious way to > do something like "lein src/chlamydia.clj" when I'm in the projects' > directory ("chlamydia"), to run a script as in "java -server > clojure.main chlamydia.clj"? I didn't see anything in the file "lein" > itself that seemed to point to that, so I added the below bit after > the "if repl" bit. Offtopic: I'm very curious, what are the reasons to call the project "chlamydia" :) -- 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: leiningen - a Clojure build tool
Leiningen is very easy to pronounce for the dutch :). We've the word "Leningen" anyway ("Loans"), and ei is a common vowel combination in dutch as well (I actually grew up in Leiden). Ontopic: I might be missing something, but is there an obvious way to do something like "lein src/chlamydia.clj" when I'm in the projects' directory ("chlamydia"), to run a script as in "java -server clojure.main chlamydia.clj"? I didn't see anything in the file "lein" itself that seemed to point to that, so I added the below bit after the "if repl" bit. elif [ ${1: -4} = ".clj" ]; then # Small hack to use lein to start clojure scripts java -cp "$CLASSPATH" clojure.main "$1" which seems to work fine, but as I'm unfamiliar with the whole building practice of having a project directory, with a src and a project.clj, I'm not sure if there is a better workflow than using the above and a few different variants of chlamydia.clj (next to the main one) in the src directory. On Nov 20, 7:40 pm, Phil Hagelberg wrote: > Sean Devlin writes: > > Something tells me we'll just be calling it 'lein'. Is that okay > > Phil? > > Yeah, there's a reason the bin script is called "lein"... I was > misspelling it myself for the first few days of working on it. =) > > -Phil -- 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: leiningen - a Clojure build tool
Leiningen is very easy to pronounce for the dutch :). We've the word "Leningen" anyway ("Loans"), and ei is a common vowel combination in dutch as well (I actually grew up in Leiden). Ontopic: I might be missing something, but is there an obvious way to do something like "lein src/chlamydia.clj" when I'm in the projects' directory ("chlamydia"), to run a script as in "java -server clojure.main chlamydia.clj"? I didn't see anything in the file "lein" itself that seemed to point to that, so I added the below bit after the if elif [ ${1: -4} = ".clj" ]; then # Small hack to use lein to start clojure scripts java -cp "$CLASSPATH" clojure.main "$1" Exception in thread "main" java.io.FileNotFoundException: Could not locate chlamydia/clj__init.class or chlamydia/clj.clj on classpath: On Nov 20, 7:40 pm, Phil Hagelberg wrote: > Sean Devlin writes: > > Something tells me we'll just be calling it 'lein'. Is that okay > > Phil? > > Yeah, there's a reason the bin script is called "lein"... I was > misspelling it myself for the first few days of working on it. =) > > -Phil -- 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