2011-03-11
| 00:32 | sorenmacbeth | hi all |
| 00:33 | sorenmacbeth | could someone help me? I'm trying to collapse a seq of seqs into a single seq like: (("a") ("b") ("a b")) -> ("a" "b" "a b") |
| 00:37 | tomoj | $findfn '(("a") ("b") ("a b")) '("a" "b" "a b") |
| 00:37 | sexpbot | [clojure.core/flatten] |
| 00:38 | sorenmacbeth | thank you! |
| 00:43 | tomoj | sexpbot: botsnack |
| 00:43 | sexpbot | tomoj: Thanks! Om nom nom!! |
| 00:43 | tomoj | though.. |
| 00:43 | tomoj | if yours are only nested one deep, maybe (apply concat) is better? |
| 01:36 | amalloy | tomoj, sorenmacbeth: http://stackoverflow.com/questions/5232350/clojure-semi-flattening-a-nested-sequence/5236194#5236194 |
| 01:47 | tomoj | "usually" because you're usually using map? |
| 01:48 | sorenmacbeth | amalloy: simple! thanks much |
| 01:48 | amalloy | tomoj: that often turns out to be the case, yes |
| 01:48 | amalloy | even if it's at level N-2 instead of level N-1 |
| 01:54 | sorenmacbeth | actually, my problem is slightly more complex. I need to go from (("a") ("b") ("a" "b")) to ("a" "b" "a b") |
| 01:54 | sorenmacbeth | basically a str-join on the inner seqs, then apply concat? |
| 01:55 | amalloy | oh, i see |
| 01:55 | amalloy | &(let [s [["a"] ["b"] ["a" "b"]]] (mapcat #(apply str %&) s)) |
| 01:55 | sexpbot | ⟹ (\[ \" \a \" \] \[ \" \b \" \] \[ \" \a \" \space \" \b \" \]) |
| 01:55 | amalloy | hm |
| 01:56 | amalloy | &(let [s [["a"] ["b"] ["a" "b"]]] (mapcat #(apply str %) s)) |
| 01:56 | sexpbot | ⟹ (\a \b \a \b) |
| 01:56 | amalloy | bah |
| 01:57 | tomoj | don't cat |
| 01:57 | amalloy | oh right |
| 01:57 | amalloy | thanks tomoj |
| 01:57 | amalloy | &(let [s [["a"] ["b"] ["a" "b"]]] (map #(apply str %) s)) |
| 01:57 | sexpbot | ⟹ ("a" "b" "ab") |
| 02:00 | sorenmacbeth | awesome |
| 02:03 | sorenmacbeth | just need to add a space between the last "ab", so result should be ("a" "b" "a b") |
| 02:03 | amalloy | sorenmacbeth: yeah, so use clojure.string/join instead of apply str |
| 02:04 | sorenmacbeth | amalloy: thanks again |
| 02:07 | sorenmacbeth | perfect, that works :) |
| 02:13 | amalloy | hey here's a neat little "macro-do" macro i just put together. anyone interested in either the code or a blog post about it? |
| 02:13 | amalloy | (macroexpand '(macro-do [[f & args]] `(def ~(symbol (str "basic-" f)) (partial ~f ~@args)) [f "test"] [y 1 2 3])) |
| 02:13 | amalloy | (do (do (def basic-f (clojure.core/partial f "test")) (def basic-y (clojure.core/partial y 1 2 3)))) |
| 02:16 | amalloy | basically it's c.c.macro-utils/macrolet wrapped up to make it easy to create an anonymous macro and call it once on an arglist |
| 03:22 | tsdh | If I have an instance of ITransientVector in Java, how can I remove one given Object o? |
| 03:23 | tsdh | Or, if that doesn't work, how can I remove the element at a given index? |
| 03:23 | amalloy | vectors don't like inserts and removes in the middle |
| 03:24 | amalloy | if you are doing that to vectors, there's usually a better solution that involves either not using vectors or not messing around with the middles |
| 03:26 | tsdh | amalloy: I use ninjudd's ordered-set lib. That has a class PersistentOrderedSet, that is backed by a PersistentSet and a PersistentVector for the ordering. Now I want to make that support `transient'. |
| 03:27 | amalloy | so look at his impl for POS and see how he's doing it? |
| 03:28 | tsdh | Oh, indeed. :-) |
| 03:29 | amalloy | anyway, good luck. i'm off to bed |
| 03:31 | tsdh | Bye |
| 04:05 | ejackson | Good Morning Clojuristas ! |
| 04:09 | tsdh | Hi ejackson. |
| 04:11 | tsdh | If I want to walk some nested structure (vec of vecs), and only pick out some parts, how do I do that? |
| 04:12 | tsdh | Oh, I got it. |
| 04:28 | Dranik | hi all! |
| 04:36 | clgv | good morning. what is the "default case" in a case statement? |
| 04:36 | brehaut | :else |
| 04:36 | brehaut | oh, case? |
| 04:37 | raek | clgv: (case :a 1, :b 2, "default here") |
| 04:37 | clgv | raek: th |
| 04:37 | clgv | thx |
| 04:37 | tsdh | How to I check if a Var foo is bound? Both (when @foo) and (when foo) error... |
| 04:37 | raek | tsdh: what problem is that the solution for? |
| 04:38 | raek | normally, when a fn knows about a var, it already exists |
| 04:38 | raek | or has to exist |
| 04:38 | clgv | $inc reak |
| 04:38 | sexpbot | ⟹ 1 |
| 04:38 | clgv | ;) |
| 04:39 | clgv | ups |
| 04:39 | clgv | $inc raek |
| 04:39 | sexpbot | ⟹ 6 |
| 04:39 | tsdh | raek: There is (def foo) with no root binding, but if it is bound (to a ref), then some of my fns should record some additional information. |
| 04:40 | raek | there's 'bound?' when you have an existing var |
| 04:40 | brehaut | tsdh: if you have declared a var (such as (def abc whatever) or (declare abc) ) then (bound? #'abc) |
| 04:41 | raek | tsdh: is this done as some initialization, or are those changes going to happen while the application runs? |
| 04:42 | tsdh | brehaut: Ouch, that was too obvious. My slime just didn't want to complete it... |
| 04:42 | tsdh | raek: There's an entry function that might establish a binding of that Var. |
| 04:43 | brehaut | tsdh: if you need to see if a symbol exists, then you can use (resolve (symbol "abc")) |
| 04:43 | brehaut | but i think if you have reached that stage, you have probably done something wrong |
| 04:44 | brehaut | actually, (resolve 'abc) would be smarter |
| 04:44 | tsdh | brehaut: Hm, (bound? foo) errors with ClassCastException: clojure.lang.Ref cannot be cast to clojure.lang.Var. |
| 04:44 | tsdh | Hm, I'll poste the code... |
| 04:44 | brehaut | tsdh: you have to var quote it |
| 04:44 | brehaut | #'foo |
| 04:45 | tsdh | brehaut: Ah, now that seems to do the trick! |
| 04:46 | brehaut | (defn exist-and-bound? [sym] (if-let [v (resolve sym)] (bound? v) false) |
| 04:46 | brehaut | i wouldnt advise using it though |
| 04:47 | brehaut | night |
| 04:47 | tsdh | brehaut: Well, it's globally def-ed without root binding, so it's existance is always true. |
| 04:48 | raek | tsdh: couldn't it be a solution to just define it as (def foo (ref ...))), and then let functions that want to change the ref do that |
| 04:48 | raek | maintaining state wihtout a ref/atom/agent feels non-clojure-y |
| 04:49 | clgv | raek: I'd skip the "e" -> clojury ;) |
| 04:49 | tsdh | raek: I do exactly that using a (binding [foo (ref {})] ...) in the entry function. |
| 04:50 | tsdh | raek: So the state is only dynamically inside the call stack of the entry fn, and it gets out of it as usual return value. |
| 04:52 | tsdh | raek: (p-apply v1 --> -->) ==> reachable vertices as set. (p-apply v1 --> --> :trace-path true) ==> [<reachable vertices> <shortest paths map>] |
| 04:53 | raek | ah, I see. |
| 05:02 | raek | hrm. what happens when you leave out a method in a proxy, and then call it? |
| 05:03 | raek | ah. java.lang.UnsupportedOperationException |
| 05:03 | clgv | is there a general comparison functions that can handle strings, keywords and numbers? |
| 05:04 | raek | clgv: compare. but it can only compare things of the same kind |
| 05:04 | clgv | raek: there is nothing for the mixed case? |
| 05:05 | raek | don't know |
| 05:06 | raek | hrm. java.lang.Class is not comparable |
| 05:06 | raek | although, (.getName some-class) is |
| 05:07 | raek | clgv: what should the order of "foo", :foo and 123 be? |
| 05:07 | clgv | raek: e.g. numbers could always be less than keyword which are less than strings |
| 05:08 | clgv | raek: I could use the string representation of the full classname ;) |
| 05:12 | raek | yeah, maybe something like (defn über-compare [x y] (try (compare x y) (catch ClassCastException _ (compare (.getName (class x)) (.getName (class y)))))) |
| 05:13 | clgv | I would skip the exception part. you could first try on equality of classes |
| 05:13 | raek | ,(compare (long 1) (int 1)) |
| 05:13 | clojurebot | 0 |
| 05:13 | clgv | lol ok ;) |
| 05:13 | clgv | maybe except for numbers |
| 05:14 | raek | I wouldn't be surpised if, for instance, clojure.lang.PersistentArrayMap and clojure.lang.PersistentHashMap can be compared to each other |
| 05:16 | clgv | hmok. the the exception version would be the most general and short one |
| 05:17 | raek | but still, I feel bad for using exceptions for control flow |
| 05:18 | clgv | yeah, that's why I wanted to remove them in that example |
| 05:19 | clgv | but I'll use it like that now. It's just for an inspection tree. |
| 05:21 | clgv | I hated it when my maps/structs... showed there entries in a random order ;) |
| 06:49 | tsdh | Wow, (apply (first args) (next args)) has some noticable overhead compared to ((first args)), so that it really pays of to do (let [n (next args)] (if n (apply ...) ((first args))))... |
| 06:55 | raek | (apply apply args) |
| 07:27 | clgv | can I use robert.hooke for protocol methods? |
| 07:27 | clgv | the straight-forward approach doesnt work |
| 07:28 | clgv | (add-hook ...) doesnt complain but the hook itself isnt called either |
| 07:42 | Fossi | shouldn't the stable clojure jars be in clojars? |
| 07:55 | raek | Fossi: it's in the clojure repo |
| 07:55 | raek | http://build.clojure.org/releases/ |
| 07:55 | raek | http://build.clojure.org/snapshots/ |
| 07:57 | tsdh | I started using clojure and functional programming end of last week, and now my notebook makes alarming noises. Is that the way it's got to be? ;-) |
| 08:20 | Fossi | hmm, leiningen has those configured, but i'm still getting 5 required artifacts are missing. |
| 08:20 | Fossi | from the specified remote repositories: |
| 08:20 | Fossi | clojure (http://build.clojure.org/releases), |
| 08:20 | Fossi | clojars (http://clojars.org/repo/), |
| 08:20 | Fossi | [...] |
| 08:26 | Fossi | ah, i had them as [clojure "1.2.0"] not [org.clojure/clojure "1.2.0"] |
| 08:28 | longfin | :) |
| 08:47 | tsdh | If I have something like (foo --> -->) where the arrows are functions, how can I achieve a numbering on them. I want to have a map from function to number, but now my problem is that the two arrows are identical, and so the latter --> entry overrides the former --> entry. |
| 08:50 | tsdh | So basically, I need a function that gets a function and returns a copy of that function... |
| 08:52 | longfin | intersting... |
| 08:54 | tsdh | Hm, maybe I can copy `complement' without the nots? |
| 08:59 | chouser | tsdh: 'identity'? |
| 08:59 | chouser | tsdh: honestly though, I don't really understand your question yet. |
| 09:01 | tsdh | chouser: --> is a function. Now I want to create another function that is totally equal with behavior and parameters, but which is that different that I can use both function as different key in a map. |
| 09:01 | chouser | heh, ok, I see. |
| 09:02 | Chousuke | hmm |
| 09:02 | Chousuke | (partial -->) ? |
| 09:02 | chouser | Chousuke: there you go. |
| 09:02 | chouser | actually, that fails I think |
| 09:02 | chouser | ,(partial +) |
| 09:02 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial |
| 09:02 | Chousuke | yeah :/ |
| 09:02 | chouser | ,#(+ %1 %2) |
| 09:02 | clojurebot | #<sandbox$eval3210$fn__3211 sandbox$eval3210$fn__3211@22d4f0> |
| 09:03 | chouser | tsdh: So there is that, but I'm suspicious of a design that requires such contortions. |
| 09:04 | tsdh | chouser, Chousuke: Oh, wait. Instead of using a map fun -> number, I can put the number as metadata on the function, and (with-meta) returns a new function then, right? |
| 09:04 | clgv | ,(leftfn [(f [& args] (map-indexed (fn [i t] (with-meta t {:index i})) args)) (g [x] (inc x))] (f g g g)) |
| 09:04 | clojurebot | java.lang.Exception: Unable to resolve symbol: leftfn in this context |
| 09:04 | clgv | ,(letfn [(f [& args] (map-indexed (fn [i t] (with-meta t {:index i})) args)) (g [x] (inc x))] (f g g g)) |
| 09:04 | clojurebot | (#<sandbox$eval3215$g__3220 sandbox$eval3215$g__3220@bd648a> #<sandbox$eval3215$g__3220 sandbox$eval3215$g__3220@13b905> #<sandbox$eval3215$g__3220 sandbox$eval3215$g__3220@d82990>) |
| 09:05 | tsdh | clgv: I guess I go with clojure.walk/prewalk, but thanks for that superb tip anyway. |
| 09:07 | clgv | tsdh: just an example. and I wanted to see what the bot does with it |
| 09:08 | tsdh | Was'n there some syntax shugar for accessing a maps value by key :foo? |
| 09:09 | tsdh | s/shugar/sugar/ |
| 09:09 | sexpbot | <tsdh> Was'n there some syntax sugar for accessing a maps value by key :foo? |
| 09:09 | tsdh | Wow, there's a bot for everything... |
| 09:11 | pjstadig | i like it spelled shugar, but that's just me |
| 09:13 | tsdh | :-) |
| 09:16 | choffstein | Hey all, I have a question. I come from a Ruby background where it is easy to create custom behavior of standard classes using monkey patching. I am new to clojure, and I would expect that monkey patching isn't possible (partially due to the fact that clojure isn't object focused and partially because it sits on the JVM). What I am really looking to do is come up with a way to have a method run anytime an Exception |
| 09:16 | choffstein | occurs (e.g. an Exception object is created). In Ruby I could just monkey-patch the Exception class and just require my library and have things taken care of. Any ideas in clojure? |
| 09:17 | choffstein | It seems like it may be possible with Extension methods in Java 7? |
| 09:17 | stuartsierra | choffstein: You can set a default "uncaught exception handler" on threads in Java. |
| 09:18 | choffstein | stuartsierra: Which works, but I even want to take action if the exception is caught |
| 09:18 | stuartsierra | Then you need to alter the code that does the catching. |
| 09:20 | choffstein | Yeah, that is what I figured. I'm assuming I need to drop to the Java level? |
| 09:20 | stuartsierra | Not at all. |
| 09:20 | stuartsierra | That is, unless you want to alter the behavior of compiled code that you didn't write. |
| 09:21 | stuartsierra | Which is a very risky idea. |
| 09:22 | choffstein | Yeah ... I think I might just have to acknowledge that I can't do what I want. Basically, I am trying to replicate ruby's exceptional plugin (getexceptional.com) for my clojure app. It's super easy in Ruby because of monkey patching. I think I need to step back from the 'ruby frame of mind' and tackle the problem with a clojure mind-set. |
| 09:23 | Fossi | somebody already used ring/jetty with the proxy servlet that ships with it? |
| 09:23 | clgv | choffstein: I would like the idea to be able to get a debug-repl run in the place where an exception is thrown^^ |
| 09:24 | Fossi | i've got a snipplet of web.xml config like http://docs.codehaus.org/display/JETTY/Asynchronous+Proxy+Servlet , but no idea how that get's set on the jetty classes |
| 09:25 | stuartsierra | choffstein: There are debugging and profiling tools that hook into the JVM that probably offer similar functionaliity. |
| 09:28 | choffstein | cigv: I was really just trying to catch all exceptions on creation, whether caught or not, and send them to either a log or an amazon s3 bucket (or both) |
| 09:28 | choffstein | but dropping to a debug-repl would be awesome too |
| 09:30 | stuartsierra | IDEs like Eclipse may also offer these features. |
| 09:32 | choffstein | Well, I am really looking to use it as a deployed tool. For example, when my web service is running, on my 'status' admin page that tells me which servers are up and spinning, I also want to see a log of all exceptions raised |
| 09:32 | choffstein | whether they were caught or not |
| 09:32 | stuartsierra | choffstein: Again, look at JVM-level stuff, or application containers like JBoss/Tomcat/Glassfish. I'm sure something like this exists. |
| 09:32 | choffstein | I'll check it out. Thanks. |
| 09:33 | stuartsierra | 'welcome |
| 10:20 | stuartsierra | gazhundheit |
| 10:27 | TimMc | stuartsierra: I came across your trick for unit testing private defns -- thanks! |
| 10:28 | stuartsierra | 'welcome |
| 10:29 | stuartsierra | I don't think I can claim credit for @#' though. |
| 10:29 | timvisher | hey all |
| 10:29 | timvisher | does anyone have anything they'd suggest for trying to learn to think recursively? |
| 10:30 | timvisher | recursion is a little like functional programming for me in that I often can understand a solution presented to me, but at the same time can't get to that solution on my own given the same problem |
| 10:31 | stuartsierra | Think back to Algorithms 101 — what are the loop invariants? |
| 10:31 | stuartsierra | What changes at each iteration of the loop? |
| 10:31 | stuartsierra | The stuff that changes will be arguments to the recursive function (or loop/recur in Clojure). |
| 10:32 | timvisher | stuartsierra: that revelation just hit me the other day |
| 10:32 | timvisher | that fp uses recursion not because it's inherently attracted to elegance but because it's a natural way to do iteration without side effects |
| 10:32 | timvisher | what I mean more is how to approach a problem recursively |
| 10:33 | timvisher | in other words, in the SICP course they say that the key to recursion is wishful thinking |
| 10:33 | timvisher | you try to think of how they problem would look if it was easy to solve |
| 10:33 | timvisher | and then you see if you can reduce the problem in steps towards that degenerative case and then solve the simpler problem |
| 10:33 | goodmike_mh | timvisher: Your requirements match the raison d'etre of The Little Schemer |
| 10:33 | timvisher | it's that series of decompositions that I struggle to see |
| 10:34 | timvisher | goodmike_mh: i.e. learning to think recursively? |
| 10:34 | goodmike_mh | yes |
| 10:34 | dnolen | timvisher: Little Schemer, Seasoned Schemer are great for getting comfortable w/ recursive thinking. There's more to recursion than looping. mutual recursion, continuation passing style are useful bits to understand as well. |
| 10:34 | timvisher | mmm |
| 10:35 | timvisher | they've been on my reading backlog for forever. Perhaps it's finally time to pick them up... |
| 10:35 | TimMc | timvisher: HtDP teaches recursive thinking via recursive data structures. (Free to read online.) |
| 10:36 | timvisher | TimMc: nice |
| 10:36 | timvisher | thanks for that pointer |
| 10:36 | timvisher | i'm wondering if I'm not just coming up upon my own inadequacies. SICP seems to do a pretty good job of trying to slowly encourage the recursive decomposition of problems. |
| 10:36 | TimMc | It's the textbook for my school's Fundamentals of Computer Programming course. |
| 10:36 | timvisher | it may just be that I need to study recursive solutions over and over again |
| 10:37 | TimMc | timvisher: Do you have a lot of imperative programming background? |
| 10:37 | timvisher | all i've ever done is Algol based languages (Java, Groovy, PHP, etc.) |
| 10:37 | timvisher | Dabbled in ELisp but Clojure's my chosen tool for teaching myself FP |
| 10:38 | timvisher | going through SICP right now (the text) and I'm running into a lot of trouble as they go into recursion. |
| 10:38 | timvisher | again, not so much the understanding of the solution when presented but being able to get there on my own. |
| 10:38 | TimMc | Yeah, so you're just having difficulty with the unlearning. :-) |
| 10:38 | timvisher | figures |
| 10:38 | timvisher | i always want the answer to be 'read this paragrah and it'll all click!'. :) |
| 10:39 | timvisher | alright, well on I will forge |
| 10:39 | TimMc | It's pretty common, from what I hear. |
| 10:39 | TimMc | You can teach (e.g.) middle school kids either functional or imperative programming with pretty much equal ease. |
| 10:40 | paraseba | is there anything done to help declaring macros similar to defn? I mean to get the different parts of the passed forms: metadata, declarations for each arity, etc.? |
| 10:40 | TimMc | It's harder to switch styles the first time you do it. Later, you'll be able to think in both. |
| 10:40 | paraseba | name-with-attributes in c.c. is the closer I can find, but it doesn't help much |
| 10:42 | paraseba | ideally, given defn like arguments I would want a name with all corresponding metadata, and a list of declarations with one element for each arity |
| 10:43 | paraseba | It's pretty easy to write, but I can't believe it's not done already in clojure or c.c. |
| 10:45 | dnolen | paraseba: ? |
| 10:45 | dnolen | (defmacro foo ([a b] nil) ([a b c] nil)) |
| 10:45 | dnolen | (meta #'foo) |
| 10:45 | dnolen | {:macro true, :ns #<Namespace user>, :name foo, :file "NO_SOURCE_PATH", :line 9, :arglists ([a b] [a b c])} |
| 10:47 | paraseba | sorry, I'm not explaining it right. I want to declare a macro that will define a new function, with given name, metadata and declarations. The macro will take the same arguments as defn |
| 10:48 | paraseba | the macro will define the function, using the declarations passed but adding some extra stuff |
| 10:49 | paraseba | imagine something like (my-defn f "my doc" {:my :meta} ([a] nil) ([a b] nil) {:more :meta}) |
| 10:49 | paraseba | I have to handle all possible forms of defn declarations (single arity, multiple arity, no doc, no meta, two meta maps, etc.) |
| 10:51 | clgv | is there a command like partition that includes the remaining elements as last smaller list? |
| 10:51 | TimMc | clgv: partition-all |
| 10:51 | clgv | ,(partition 5 (range 23)) |
| 10:51 | clojurebot | ((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14) (15 16 17 18 19)) |
| 10:51 | clgv | oh thx :D |
| 10:51 | paraseba | clgv: you almost always want to use partition-all |
| 10:52 | TimMc | amalloy_: Early bird gets the worm. |
| 10:53 | fbru02_ | paraseba: i haven't seen it anywhere in core/or contrib all the times i have seen it is like this (defmacro generatefn [args & body] ~args ~@body)) |
| 10:53 | fbru02_ | paraseba: welcome to irc btw ! :) |
| 10:54 | fbru02_ | defmacro `(defn generatefn [args & body] ~args ~@body)) |
| 10:55 | paraseba | fbru02_: thanks for the welcome .. I'm trying new forms of not getting work done |
| 10:56 | paraseba | fbru02_: yes, the problem is that it doesn't handle defn like arguments correctly. In my case I need to wrap function body with some stuff, that's why I need to get every arity declaration |
| 10:56 | paraseba | fbru02_: and also, I don't want to loose doc and metadata information |
| 10:57 | fbru02_ | paraseba: i kind of agree it would be nice to have that in core/contrib, maybe you should open a enhancement and see if people like it provided you can find a goodname for the macro |
| 10:58 | fbru02_ | paraseba: which i cannot think of , at least now |
| 10:59 | paraseba | fbru02_: it would be a nice addition to c.c.macro-utils or c.c.def if it's not there already |
| 11:02 | ev4l | according to the standard clojure code conventions when should i give a function a bang sign at the end of its name? (judging by the code i've read so far, only when the function performs some side effect on a var) |
| 11:02 | ev4l | . Are there any more cases? |
| 11:03 | paraseba | by the way, any idea of why defn supports two attribute maps? why the first one is not enough? |
| 11:04 | stuarthalloway | official word on bang: for fns that are not safe in an STM transaction |
| 11:05 | TimMc | stuarthalloway: Unless the name clearly implies side effects? |
| 11:05 | stuarthalloway | TimMc: honestly I don't think the bang idiom is that important |
| 11:06 | stuarthalloway | but the STM interaction was the original motivation for the bang fns in core |
| 11:06 | tsdh | Why does (clojure.inspector/inspect foo) throw a ClassNotFoundException, but (clojure.set/difference s1 s2) can be called? The clojure.inspector classes are contained in the clojure 1.2.0 jar that leiningen fetched me... |
| 11:07 | ev4l | stuarthalloway: thanks! it's funny to have the question answered to the guy who wrote the book i have opened here along with the irc client :D |
| 11:07 | stuarthalloway | all the best stuarts hang out here and answer book questions, right stuartsierra? |
| 11:08 | TimMc | stuarthalloway: Ah, interesting. |
| 11:08 | ev4l | s/to/by |
| 11:08 | sexpbot | <ev4l> stuarthalloway: thanks! it's funny by have the question answered by the guy who wrote the book i have opened here along with the irc client :D |
| 11:09 | ev4l | (haha faster than you bot... suck it xD) |
| 11:10 | wooby | tsdh: (require 'clojure.inspector) first |
| 11:14 | tsdh | wooby: But why do I have to require clojure.inspector, but I can access clojure.set functions qualified without doing so? |
| 11:16 | raek | tsdh: they are loaded automatically in versions up to 1.2, iirc |
| 11:16 | tsdh | Ok, thanks. |
| 11:17 | raek | an old detail that you should not rely upon |
| 11:17 | raek | I think that was from the times before require and firends |
| 11:18 | abedra | where did the other stuart dissapear to? |
| 11:19 | wooby | tsdh: Because Clojure requires set for you when you start it up. |
| 11:20 | goodmike_mh | tsdh: wooby and I are not sure exactly why. sets are a major seq collection type, even though they are defined outside core |
| 11:21 | goodmike_mh | Not all libraries are quite created equal |
| 11:22 | raek | https://github.com/clojure/clojure/commit/d6bc47ae952255c5b45f449e73db2439ba2a80f5 |
| 11:23 | TimMc | abedra: Quit about 50 minutes ago. |
| 11:23 | raek | since this commit clojure.(zip|xml|set) are not loaded automatically anymore |
| 11:24 | TimMc | tsdh: If it isn't in clojure.core or java.lang, you need to explicitly require, use, or import it. |
| 11:25 | Dantas | Hi everyone !!! One , newbie, question !!! - The commute form is executed in two phases. is the last phase , commit phase, will be executed in atomic way ? |
| 11:25 | tsdh | TimMc: Yes, except it's in clojure.set, in what case I can call it qualified. |
| 11:25 | tsdh | Ok, gotta run. |
| 11:49 | choffstein | anyone know a good write-up on working macros in with special forms? I am trying to create a macro around try/catch but am having some trouble. Basically, I want to inject code to be executed when I use 'my-try' instead of just 'try'. |
| 11:52 | rmarianski | with-open might be a good candidate to look at for that sort of thing |
| 11:53 | rmarianski | choffstein: https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L2911 |
| 11:53 | rmarianski | not really a write up, but you might be able to do the same sort of thing |
| 11:54 | choffstein | thanks guys |
| 11:54 | choffstein | err...guy |
| 12:03 | Fossi | how do you inspect java objects again? |
| 12:04 | Fossi | i want to see the methods |
| 12:04 | Dantas | The COMMUTE form is executed in two phases , right ? . is the last phase , called commit phase, synchronized ? "LOCK commute fn UNLOCK" |
| 12:11 | choffstein | Can someone show me an example of a macro that takes a list of functions and executes each function? Is it possible? Basically ... I am looking for the 'do' special form as a macro... |
| 12:13 | amalloy | choffstein: doseq? |
| 12:13 | amalloy | or dorun? |
| 12:13 | amalloy | Fossi: clojure.contrib.repl-utils/show |
| 12:14 | amalloy | or clojure.java.javadoc, i think? |
| 12:15 | choffstein | I'll check those out. Thanks amalloy. |
| 12:16 | Chousuke | choffstein: you mean like (run foo bar whatever) expanding to (do (foo) (bar) (whatever))? |
| 12:17 | choffstein | chousuke: yeah, exactly. I'm trying to figure out how to do that. |
| 12:18 | choffstein | Basically, I am trying to create a wrapper around 'try' to inject some code ... but it isn't going well :D |
| 12:18 | amalloy | (defmacro run [& fs] (cons 'do (map list fs))) :P |
| 12:19 | amalloy | would bring Chousuke's example to life |
| 12:19 | Chousuke | amalloy: you were just a few keypresses faster than me :P |
| 12:20 | Chousuke | I was counting my parens :( damn irc for not having paredit |
| 12:20 | amalloy | Chousuke: i'm working on a sexp-balancer for sexpbot |
| 12:20 | choffstein | awesome. thanks! |
| 12:20 | amalloy | by which i mean, complaining about not having one and getting brehaut to write the parser for me |
| 12:26 | choffstein | Okay, I definitely don't know enough clojure to do what I am trying to do :D |
| 12:27 | Fossi | amalloy: thanks |
| 12:28 | choffstein | Any thoughts on how to intercept a 'catch' clause and add some code to it? |
| 12:32 | amalloy | choffstein: let's say the user calls your macro with the & arglist '(/ 1 0) 'x '(catch Exception _ nil) |
| 12:32 | amalloy | you can find all the catches in that list with (filter (comp first #{'catch}) arglist) |
| 12:33 | amalloy | er, that's backwards. (comp #{'catch} first) |
| 12:33 | amalloy | then you can mess around with them however you want and put them back in |
| 12:33 | choffstein | wow. That ... that might be perfect. |
| 12:34 | Fossi | any ring'ers herre? |
| 12:34 | Fossi | i just wanna add a second servlet to a jetty |
| 12:35 | Fossi | and i miss add-servlet! from compojure |
| 12:38 | amalloy | TimMc: what worm did i not get? i couldn't tell |
| 12:38 | amalloy | or, i suppose, did i get |
| 12:38 | TimMc | amalloy: I got to tell someone about partition-all! |
| 12:38 | TimMc | And you were probably still asleep. |
| 12:39 | amalloy | you bet i was |
| 12:44 | TimMc | Damn, I forgot to ask clgv why s/he wanted partition-all. I still haven't had a need for it |
| 12:44 | TimMc | I suppose it could be useful for layout logic. |
| 12:44 | jkkramer | is http://dev.clojure.org/display/doc/Getting+Started the current, official link to give to a clojure newbie? |
| 12:48 | stuarthalloway | jkkramer: no one person probably knows if that is all up to date |
| 12:48 | Dantas | The COMMUTE form is executed in two phases , right ? . is the last phase , called commit phase, synchronized ? "LOCK commute fn UNLOCK" |
| 12:49 | jkkramer | stuarthalloway: at the very least, the assembla one is no longer official, right? |
| 12:49 | stuarthalloway | right |
| 12:49 | stuarthalloway | and please suggest (or make) edits in Confluence if you see something wrong |
| 12:50 | TimMc | Dantas: I don't know if locks are involved, per se. |
| 12:50 | stuarthalloway | Dantas: that is implementation detail |
| 12:51 | jkkramer | will do. getting a friend setup this weekend |
| 12:51 | stuarthalloway | what you can count on is that readers require no locks |
| 12:51 | stuarthalloway | er, should say that readers can *never* block |
| 12:52 | stuarthalloway | any locks down in the STM, if they exists, are about STM resources, not about your refs |
| 12:52 | Dantas | stuarthalloway: yes, but semantically, could i think that the commit phase is atomic ? ( sorry for my english ) |
| 12:53 | TimMc | Dantas: Here is an excellent article on STM in Clojure: http://java.ociweb.com/mark/stm/article.html |
| 12:53 | stuarthalloway | transactions are always atomic, across the set of refs transacted upon |
| 12:53 | TimMc | The latter part is all implementation details, but there is a good high-level description as well. |
| 12:54 | Dantas | TimMc: Thanks, stm is really cool. a easy way to create concurrent applications |
| 12:54 | Dantas | an* |
| 12:55 | TimMc | Dantas: Just watch out for write skew, that's the only thing that isn't obvious from most of the descriptions I've seen. |
| 12:55 | TimMc | Dantas: http://java.ociweb.com/mark/stm/article.html#write-skew |
| 12:56 | Dantas | stuarthalloway: thank you |
| 12:56 | Dantas | TimMc: Thanks |
| 12:57 | TimMc | If you're not sure about commute yet, you can avoid it easily. |
| 12:58 | Dantas | TimMc: according the clojure documentation, commute is performed in two phases. the second phase is where the ref value will be changed |
| 12:59 | Dantas | so, i dont want to understand the implementation detail, only if this operation is atomic ! this way avoid race conditions |
| 12:59 | TimMc | I don't understand that aspect of commute yet myself. |
| 13:00 | Dantas | if i understand right, stuarthalloway said that they are atomic |
| 13:00 | TimMc | My understanding is that commute allows some more interleaving of transactions by rescheduling commutes. |
| 13:00 | stuarthalloway | commute is for when you don't care when the change happens |
| 13:00 | TimMc | ...but I'm really not sure. |
| 13:00 | stuarthalloway | e.g. commute is for "add 100 to account" |
| 13:02 | TimMc | stuarthalloway: I assume commute should not be used when you want to keep consistency constraints between refs? |
| 13:02 | stuarthalloway | probably right |
| 13:03 | Dantas | i asked about that cause i came from shared state way. so commute is really new from my background ! |
| 13:07 | stuarthalloway | commute is still atomic, but you might not know its result |
| 13:08 | Fossi | ring/jetty is driving me crazy :/ |
| 13:10 | Dantas | stuarthalloway: but, after commit phase, the commute result is the same located in the memory |
| 13:10 | Dantas | ?? |
| 13:10 | stuarthalloway | Dantas: the return value of your call to commute is not necessarily the final result |
| 13:11 | stuarthalloway | because commute says "feel free to retry this independently of everything else" |
| 13:16 | Dantas | stuarthalloway: TimMc thank |
| 13:16 | Dantas | cya |
| 13:17 | Fossi | anybody know if it's even possible to use another servlet with ring? |
| 13:17 | Fossi | the leiningen task seems to have only one of them as well |
| 13:17 | Fossi | and everything i try resets the original servlet |
| 13:19 | ndimiduk | Fossi, another servlet, or another web container? |
| 13:20 | Fossi | ndimiduk: just another servlet |
| 13:20 | Fossi | one jetty is fine |
| 13:30 | choffstein | is there a way to add an element to the back of a list? |
| 13:31 | choffstein | this seems like an easy google ... but I just can't find it... |
| 13:33 | ataggart | not without rebuilding the list |
| 13:34 | spewn | choffstein: If you were using a vector, conj would append to the end. Is there are reason you're using a list instead? |
| 13:34 | stuarthalloway | hugod: what is testbuild1-SNAPSHOT? |
| 13:34 | choffstein | spewn -- it's in a macro. Basically, I have something like (1 2 3) and (4 5 6), and want to create (1 2 3 (4 5 6)). It just seemed easier to add (4 5 6) to the back of (1 2 3) rather than three cons. |
| 13:35 | TimMc | choffstein: concat? |
| 13:35 | spewn | TimMc: Wouldn't that make (1 2 3 4 5 6)? |
| 13:35 | Chousuke | choffstein: are you doing that in a macro? |
| 13:35 | choffstein | Chousuke: Yes. |
| 13:35 | Chousuke | then you might be able to use splicing |
| 13:35 | amalloy | choffstein: it's awkward for a reason: adding to the back of an immutable linked-list is not cheap |
| 13:35 | TimMc | spewn: Yes, I suppose so. |
| 13:36 | amalloy | but Chousuke is probably right |
| 13:36 | choffstein | amalloy: I know ... you have to iterate the list. |
| 13:36 | Chousuke | ,(let [a '(1 2 3)] `(1 2 3 ~a ~@a)) |
| 13:36 | TimMc | spewn: Unless you wrap it first. :-) |
| 13:36 | clojurebot | (1 2 3 (1 2 3) 1 2 3) |
| 13:36 | hugod | stuarthalloway: org.clojure:clojure:jar:1.3.0-testbuild1-SNAPSHOT |
| 13:36 | hugod | on oss snapshots |
| 13:36 | choffstein | hmm ... that might work. |
| 13:36 | amalloy | Chousuke: fwiw that's just concat under the covers |
| 13:37 | stuarthalloway | hugod: do you have projects that are resolving dependencies to that |
| 13:37 | Chousuke | amalloy: yeah, but it's a bit simpler to use |
| 13:37 | amalloy | it's totally reasonable to use inside a macro though, cause the lists are going to be short (the user actually typed them in!) |
| 13:37 | choffstein | Yeah, the list is only 3 elements long... |
| 13:37 | stuarthalloway | hugod: the goal of releasing alphas is for you to have non-snapshot targets. |
| 13:37 | hugod | I depend on enlive, which uses a dependency range for clojure, which pulls it in |
| 13:37 | stuarthalloway | If that isn't working for you, but something could be fixed to make it better, would like to do it |
| 13:38 | choffstein | Okay, maybe I can get some help then ... because I can't figure out how to splice this in. Basically, it comes down to: (->> catch-clause# (list 'println `(. ~exception-name# toString)) (list 'do) (list ~@catch-phrase#))). It's the last part I am having trouble with... |
| 13:38 | TimMc | jkkramer: Any stable releases of loom? |
| 13:38 | hugod | my dependencies are all clojure-1.2.0 |
| 13:39 | amalloy | you can't splice a gensym# |
| 13:39 | jkkramer | TimMc: not yet. i may still rewrite a bunch of the underlying code. e.g., using deftype instead of defrecord |
| 13:39 | __name__ | jo, mc tim, wassup? |
| 13:39 | hugod | stuarthalloway: is it possible to remove the testbuilds? |
| 13:39 | choffstein | amalloy: oh...didn't know that. Hmm ... (new to clojure, if you couldn't tell :)) |
| 13:39 | amalloy | unless you have two levels of backticks in there somewhere, and only showed one? |
| 13:39 | stuarthalloway | hugod: just pinged stuartsierra and cemerick to ask that very question |
| 13:39 | jkkramer | TimMc: I don't plan on changing the API much, though |
| 13:39 | choffstein | Nope. Just one amalloy. |
| 13:39 | hugod | thanks |
| 13:40 | amalloy | choffstein: gensyms# only exist inside the expanded scope - you can't do things like splice them while expanding, because you don't know what they are |
| 13:40 | choffstein | amalloy: ah, that makes sense. |
| 13:41 | choffstein | Gotta get better at really understanding what exactly is going on with macros. Practice, practice, practice i guess... |
| 13:41 | TimMc | wassup, __name__? |
| 13:41 | amalloy | actually i don't understand why you have a gensym# outside of any backtick-scopes. that can't be working ro you |
| 13:41 | amalloy | for |
| 13:42 | hugod | stuarthalloway: btw, I would use a 1.2.1 for pallet - users have been hit before with the stackoverflow keyword issue |
| 13:42 | __name__ | TimMc: Weekend :-) |
| 13:42 | stuarthalloway | hugod: working on the patch for it now |
| 13:42 | hugod | :) |
| 13:42 | stuarthalloway | but would also love to know what we need to do to get people using 1.3 branch :-) |
| 13:43 | stuarthalloway | hugod: maven exclusions should be viable as a workaround |
| 13:43 | choffstein | amalloy: https://gist.github.com/866348 |
| 13:43 | hugod | stuarthalloway: exclusions don't seem to work |
| 13:43 | stuarthalloway | yikes |
| 13:44 | technomancy | exclusions in maven must be specified for every single dep that pulls clojure in |
| 13:44 | choffstein | amalloy: warning -- I am very green on macros. This is my first macro ever. |
| 13:44 | technomancy | (but global exclusions were just added to Leiningen this morning.) |
| 13:44 | amalloy | choffstein: yeah, that's never going to work. try replacing it with (defmacro my-try [& args] (let [thing# args] thing#)) |
| 13:44 | choffstein | amalloy: but basically, I am trying to deconstruct a catch clause, inject some code using a do, and reconstruct it. |
| 13:44 | choffstein | amalloy: it works now... |
| 13:44 | TimMc | jkkramer: Leiningen is going to yell at me if I try to make a non-SNAPSHOT release. :-P |
| 13:44 | amalloy | oh hm |
| 13:44 | amalloy | &(let [x# 1] x#) |
| 13:44 | sexpbot | ⟹ 1 |
| 13:45 | amalloy | hah, i guess # is legal in symbol names |
| 13:45 | hugod | technomancy: does that work when you dependencies are themselves using dependency ranges? |
| 13:45 | TimMc | &x# |
| 13:45 | sexpbot | java.lang.Exception: Unable to resolve symbol: x# in this context |
| 13:45 | choffstein | oh, does it work for all the wrong reasons? |
| 13:45 | amalloy | but don't do it outside of backtick scopes - they're usually used for gensumming |
| 13:45 | amalloy | symming |
| 13:45 | choffstein | yeah...I was trying to gensym |
| 13:45 | TimMc | &(quote x#) |
| 13:45 | sexpbot | ⟹ x# |
| 13:45 | technomancy | hugod: that's orthogonal, I think. |
| 13:45 | TimMc | &`x# |
| 13:45 | sexpbot | ⟹ x__17725__auto__ |
| 13:45 | technomancy | exclusions don't involve versions |
| 13:46 | choffstein | Lot's to learn here... |
| 13:46 | hugod | stuarthalloway: I shalln't switch pallet to 1.3 until it is released - I don't need the 1.3 features, and can wait for stability |
| 13:47 | hugod | technomancy: is that in lein HEAD? |
| 13:47 | pjstadig | people really need to respond to the ML thread instead of coming out of the woodwork after a decision has been made :) |
| 13:47 | hugod | I can't post on the dev list |
| 13:47 | amalloy | &(let [[_ e-class e-name & e-ret :as catch-clause] '(catch Exception _ x)] `(catch ~e-class ~e-name (do (println ~e-name) ~e-ret))) |
| 13:47 | technomancy | hugod: yeah |
| 13:47 | sexpbot | java.lang.SecurityException: You tripped the alarm! catch is bad! |
| 13:47 | stuarthalloway | pjstadig: working on your 1.2.1 patch now |
| 13:48 | danlarkin | yay |
| 13:48 | amalloy | choffstein: https://gist.github.com/866354 ? |
| 13:49 | pjstadig | stuarthalloway: thx :) |
| 13:49 | amalloy | oops, i missed a @ in there. gist updated |
| 13:50 | amalloy | and i guess i don't need the :as at all since i'm not using it, but you might want it for some reason |
| 13:50 | choffstein | amalloy: thanks, I'll take a look at that guy |
| 13:52 | choffstein | amalloy: basically, I am trying to iterate through all given catch clauses in a try/catch/finally and inject some code. So I was trying to use gensym to make sure I didn't get any symbol clashing |
| 13:52 | choffstein | but I guess I don't need to, since the let's make everything local, huh? |
| 13:55 | amalloy | right, as long as you put them in the *macro* scope and not the expansion scope |
| 13:55 | choffstein | expansion scope being `? |
| 13:55 | choffstein | I think I am getting this. Come on enlightenment, hit me! |
| 13:56 | amalloy | choffstein: the difference is between (let [x 1] `(+ ~x ~user-arg)) and `(let [x# 1] (+ x# ~user-arg)) |
| 13:57 | amalloy | in the former, x belongs to your macro, and no trace of it will ever show up in the expansion |
| 13:57 | amalloy | in the latter, you want to create a new binding in the expansion scope, which will be used in the user's code - there, you have to avoid clashing with one of their names |
| 13:58 | choffstein | amalloy: Awesome. That makes perfect sense. |
| 13:58 | jkkramer | TimMc: hmm, I guess I could cut a 0.1 release. I was also going to take out the ubigraph stuff, which adds a dependency on apache xml-rpc. I'll see about doing that this weekend |
| 13:58 | TimMc | jkkramer: That would be awesome. |
| 13:59 | choffstein | amalloy: one quick last question, if you don't mind. In my macro, I am trying to map over all the catch-clauses ... how can I use splicing in my anonymous function? e.g. line 6 @ https://gist.github.com/866348 -- which obviously doesn't work, but I don't know how to make it work. |
| 13:59 | TimMc | No rush on my end -- my project is very new, and the only known dependent is a homework assignment I haven't really started on. :-P |
| 14:01 | choffstein | Ah, whoops, didn't see those ~ on arglist |
| 14:01 | amalloy | choffstein: it obviously doesn't work? looks reasonable to me |
| 14:01 | amalloy | ah |
| 14:01 | amalloy | nor did i :P |
| 14:02 | choffstein | Well, it was obvious it didn't work to me because I thought I understood what the hell I am talking about, but I obviously don't :P |
| 14:02 | choffstein | Thanks for all the help. I'll keep studying this bad boy. |
| 14:02 | amalloy | you can avoid the (first arglist) with some destructuring: (defmacro my-try [execute-clause & more] ...) |
| 14:03 | stuarthalloway | hugod, pjstadig, danlarkin, technomancy, + anyone else wanting 1.2.1: please make sure http://dev.clojure.org/jira/browse/CLJ-754 looks right |
| 14:03 | choffstein | haha. love some good old refactoring :) |
| 14:03 | amalloy | refactoring is my favorite vice. improve old code instead of writing new |
| 14:08 | tsdh | Is there something like a this pointer for functions? |
| 14:08 | choffstein | If I am writing a library that would have global configuration, what is the clojure way of doing it? For example, in ruby, we would use a yaml file, or something like that. How do you do it in clojure? |
| 14:09 | tsdh | choffstein: Why not a possibly nested map? |
| 14:09 | spewn | stuarthalloway: Could we get https://github.com/clojure/clojure/commit/6d300332f810a68869c11ddfcc55f4439b70fdb3 ? Especially since http://clojure.org/special_forms assumes def can take a docstring. |
| 14:09 | technomancy | stuarthalloway: excellent; thanks. giving it a go. |
| 14:10 | technomancy | choffstein: just use load-file. |
| 14:10 | amalloy | choffstein: yeah, just a hashmap |
| 14:10 | amalloy | write it to a file, read it in, you're good to go |
| 14:10 | choffstein | And just have the library user pass it in? |
| 14:10 | stuarthalloway | spewn: probably not. If we start doing enhancements on a past branch I don't know where to stop |
| 14:11 | stuarthalloway | also makes the documentation more confusing, not less |
| 14:11 | amalloy | i don't think that's necessary. have your library read from "myconfig.clj", and if they want it to behave differently they can write the file before calling you |
| 14:11 | amalloy | just like a yaml |
| 14:11 | pjstadig | stuarthalloway: you stop when you don't have a bug that has no user workaround |
| 14:12 | stuarthalloway | pjstadig: works for me, and excludes the suggested enhancement by definition |
| 14:12 | pjstadig | stuarthalloway: which enhancement? |
| 14:12 | stuarthalloway | https://github.com/clojure/clojure/commit/6d300332f810a68869c11ddfcc55f4439b70fdb3 |
| 14:13 | stuarthalloway | proposed by spewn a few minutes ago |
| 14:13 | pjstadig | stuarthalloway: agreed probably not bugfix worthy |
| 14:20 | tsdh | How can I access the currently running function's metadata in its own body in the presence of more than one instances of that function, which hinders referring to it by its name? |
| 14:23 | amalloy | tsdh: that has no particular meaning, because anything nontrivial is nested within many layers of functions |
| 14:24 | raek | ,((fn f [] (meta f))) |
| 14:24 | clojurebot | nil |
| 14:24 | raek | ,(^{:a 1} (fn f [] (meta f))) |
| 14:24 | clojurebot | {:a 1} |
| 14:25 | raek | tsdh: note that metadata on a function object and metadata on a var holding it is not the same thing |
| 14:26 | tsdh | I think, I can solve my problem in a better way. :-) |
| 14:49 | simard | is there a unique? predicate in clojure ? I would do: (defn unique? [coll x] (= nil (second (filter #(= % x) coll)))) |
| 14:49 | ieure | What’s the recommended way to produce XML in Clojure? It seems that clojure.xml/emit is semi-deprecated. |
| 14:49 | ieure | clojure.contrib.lazy-xml/emit |
| 14:49 | ieure | Perhaps? |
| 14:49 | amalloy | ieure: prxml? |
| 14:50 | ieure | amalloy, Seems reasonable, I’ll check it out. |
| 14:50 | amalloy | it's pretty convenient and flexible. it's what i used the one time i needed to make xml |
| 14:50 | ieure | I guess I have to rebind *out* to capture it as a string. |
| 14:50 | amalloy | ieure: i think so, yeah. but you have with-out-str, so... |
| 14:56 | brehaut | simard: my best effort so far is (defn unique? [s x] (-> (get (group-by identity s) x) next nil?)) |
| 14:58 | amalloy | (= 1 ((frequencies s) x)) |
| 14:58 | brehaut | bah :P |
| 14:59 | amalloy | meh. my version is wasting a lot of computational effort on data you don't care about |
| 15:01 | simard | yup |
| 15:01 | simard | what about mine ? |
| 15:01 | simard | anything wrong with it ? |
| 15:01 | simard | it's lazy, right ? |
| 15:02 | choffstein | Any thoughts on what I am doing wrong here? (def l '(#(+ 1 %) #(+ 2 %))) / (apply (first l) 3)? I am getting a "clojure.lang.Cons cannot be cast to clojure.lang.IFn" ... which makes me think I am not actually creating a list of anonymous functions like I thought I was... |
| 15:03 | amalloy | choffstein: use [x y] instead of '(x y) |
| 15:03 | choffstein | *slaps face* |
| 15:03 | choffstein | really? |
| 15:04 | amalloy | simard: yes, it will stop early if it finds any duplicates, but it can't really be lazy because it will have to search the whole list to confirm that there are no duplicates |
| 15:04 | TimMc | So, fail-fast. |
| 15:04 | simard | amalloy: well, yes that's as good as I can do I guess |
| 15:04 | amalloy | choffstein: only old common-lisp codgers use '(anything) :). when you want to bundle up some data objects into a list, vectors are usually the way to go |
| 15:04 | TimMc | But all solutions have a best worst-case of O(n) |
| 15:05 | choffstein | amalloy: i'll remember that. thanks. |
| 15:05 | TimMc | Er... "Best solution will be O(n)." |
| 15:07 | choffstein | Okay ... now i'm just getting stupid here. How can I pass a function if I don't create a function object? Pass the symbol? I wouldn't expect apply to work on that... |
| 15:07 | raek | simard: I would write (= nil (second ...)) as (not (next ...)) |
| 15:07 | brehaut | ,(let [myinc (fn [x] (+ 1 x))] (map myinc [1 2 3])) |
| 15:07 | clojurebot | (2 3 4) |
| 15:08 | brehaut | choffstein: does that make sense? |
| 15:08 | raek | then it also works for checking the uniqieness of nil |
| 15:08 | choffstein | brehaut: yeah, that makes perfect sense...but you are creating a function object. |
| 15:08 | simard | raek: nice, I'll change that |
| 15:08 | choffstein | brehaut: basically, I am trying to construct a list of dispatch functions |
| 15:08 | choffstein | brehaut: so I construct the list, and on a certain event, call all the functions |
| 15:09 | brehaut | so for instnace you have [inc dec], and then later you want (map #(% arg) my-fns) ? |
| 15:10 | choffstein | yeah |
| 15:10 | TimMc | JUXT |
| 15:11 | brehaut | TimMc: probably :) |
| 15:11 | brehaut | choffstein: ##(let [fs (juxt inc dec)] (fs 1)) |
| 15:11 | sexpbot | ⟹ [2 0] |
| 15:11 | TimMc | ,((juxt [* + - /]) 4 6) |
| 15:11 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (2) passed to: PersistentVector |
| 15:12 | choffstein | brehaut: but let's say I have a ref to an empty vector -- how do I add 'inc' and 'dec' to that vector? |
| 15:12 | TimMc | bah |
| 15:12 | TimMc | ,((juxt * + - /) 4 6) |
| 15:12 | clojurebot | [24 10 -2 2/3] |
| 15:12 | brehaut | choffstein: (def fs (ref [])) (dosync (alter rs conj inc dec)) |
| 15:13 | ieure | Next question… Is there a simple way to create a WAR file from a Leiningen/Compojure project? |
| 15:13 | TimMc | ieure: I think there's a lein-war plugin. |
| 15:15 | brehaut | choffstein: (def ref-juxt [r] (fn [& args] (dosync (map #(apply % args) @r)))) ; the dosync is kind of optional there |
| 15:15 | choffstein | brehaut: yeah, I have that. But I am trying to pass in a variable function. So something like: (defn add-dispatch [fn] (dosync (alter *dispatchers* conj fn))). ... or something like that |
| 15:16 | jcromartie | how does dosync work in the context of a lazy seq (map) |
| 15:16 | brehaut | choffstein: what do you mean 'variable function'? |
| 15:16 | choffstein | brehaut, so I could call (add-dispatch 'inc) or (add-dispatch #(+ 3 %)) |
| 15:17 | brehaut | you dont need to quote in there |
| 15:17 | brehaut | err |
| 15:17 | brehaut | inc |
| 15:17 | ieure | TimMc, Beautiful, thanks. |
| 15:17 | brehaut | (add-dispatch inc) would work just fine |
| 15:17 | amalloy | brehaut: in happened to work in context |
| 15:17 | brehaut | amalloy: wait what? |
| 15:17 | amalloy | as in, "in that instance/function-call" |
| 15:17 | choffstein | brehaut: Really? Herm. Okay ... thanks. |
| 15:18 | amalloy | even if you meant inc, in was a viable substitute, is what i meant |
| 15:18 | brehaut | choffstein: you want to pass the fn not the smybol right? |
| 15:18 | choffstein | right |
| 15:18 | stuartsierra | stuartsierra has returned! |
| 15:19 | stuarthalloway | stuartsierra: so glad you are back, I have work for you :-) |
| 15:20 | stuartsierra | stuarthalloway: the correct response is "And there was much rejoicing." |
| 15:20 | stuartsierra | "And grousing about Maven." |
| 15:21 | hiredman | and snicker about pictures where people grab their chins |
| 15:21 | hiredman | snickering |
| 15:22 | stuarthalloway | stuartsierra: specifically, could you look at http://dev.clojure.org/jira/browse/CLJ-755 |
| 15:22 | stuarthalloway | which is, in fact, about maven :-) |
| 15:23 | choffstein | holy crap, my code works. |
| 15:24 | brehaut | choffstein: well done |
| 15:24 | choffstein | brehaut: thanks for the help |
| 15:24 | stuartsierra | stuarthalloway: mvn -Pdistribution package |
| 15:24 | choffstein | clojure is blowing my mind. |
| 15:25 | choffstein | I thought meta-programming in ruby was cool. But damn ... I think I am starting to understand what all the hub-bub about macros is... |
| 15:25 | gregh | macros are "hey! I can write bits of a compiler." |
| 15:26 | stuarthalloway | stuartsierra: did that run on Hudson? where do I grab the artifact? |
| 15:26 | jweiss | anyone here use clojure.contrib.logging? i have a potential fix where stack inspection seems to work at least for java.util.logging. More informative than just printing the name of the logger. i'd like to submit it but havne't signed the CI yet. |
| 15:27 | stuartsierra | stuarthalloway: It doesn't run on Hudson by default. I can change that. |
| 15:27 | stuarthalloway | stuartsierra: that would be great, if not a lot of trouble |
| 15:27 | stuartsierra | no problem |
| 15:27 | stuarthalloway | otherwise people have to get the release build built from my laptop, which is gross |
| 15:27 | jweiss | is this the current CA? https://github.com/weissjeffm/webui-framework/blob/unify/src/com/redhat/qe/logging.clj |
| 15:27 | jweiss | doh |
| 15:27 | jweiss | i meant http://clojure.org/file/view/ca.pdf |
| 15:28 | stuarthalloway | jweiss: logging became its own top-level project this morning; https://github.com/clojure/tools.logging |
| 15:28 | stuartsierra | stuarthalloway: Just for release builds, right? Not snapshots. |
| 15:28 | stuarthalloway | stuartsierra: right. and with instructions for where I go to grab the bits |
| 15:30 | stuarthalloway | stuartsierra: is inclusion of the file "clojure.iml" by design? |
| 15:31 | stuartsierra | yes. I think I tried to include everything that was included in previous releases. |
| 15:31 | jweiss | stuarthalloway: good timing then :) so do i still need to sign the CA to submit a patch (I see the new project could still use it) |
| 15:31 | stuarthalloway | jweiss: yes |
| 15:31 | jweiss | was that the right url for it? |
| 15:31 | stuartsierra | FYI, the definition of what goes in the ZIP is in src/assembly/distribution.xml |
| 15:32 | stuarthalloway | jweiss: yes |
| 15:33 | jweiss | great, thx |
| 15:38 | jweiss | i am kinda surprised no one else has wanted to see ns and fn name in their logs. you can get it by (-> (Thread/currentThread) .getStackTrace second .getClassName (split #"\$")) |
| 15:39 | jweiss | (from within clojure.contrib.logging or clojure.tools.logging |
| 15:39 | ataggart | stuarthalloway: regarding the chars bug with case, the issue is that character literals are ConstantExprs, thus cannot emit as primitives. I'm going to remove support for the all-chars case, and we can revisit if we ever add support for literal character primitives. |
| 15:39 | ataggart | jweiss: it's slow, that's why it's not used |
| 15:39 | xkb | any of you going to dyncon2011? |
| 15:39 | stuarthalloway | ataggart: thanks |
| 15:39 | jweiss | ataggart: isn't that exactly what the loggers themselves do? |
| 15:39 | stuarthalloway | ataggart: did you see you have a logging repo now? |
| 15:39 | jweiss | (if you use the location in your log config) |
| 15:40 | ataggart | stuarthalloway: what does "have" mean, and where would I see that? |
| 15:40 | stuarthalloway | :-) |
| 15:40 | stuarthalloway | Aaron sent you a direct email |
| 15:40 | stuarthalloway | and copied the dev list |
| 15:40 | stuarthalloway | and it got mentioned here a few minutes ago: logging became its own top-level project this morning; https://github.com/clojure/tools.logging |
| 15:40 | ataggart | jweiss: if you configure it to do so, but it's rarely used due t the performance hit. Class:linenum usually suffices |
| 15:41 | stuarthalloway | and I just told you directly :-) |
| 15:41 | ataggart | heh |
| 15:41 | jweiss | ataggart: java.util.logging does not support line numbers - that was my patch - to add the ability to do stack inspection for j.u.l because it allows you to pass in the location if you calculate it yourself. |
| 15:43 | ataggart | jweiss: ok, open an enhancement once you're able. Aside: j.u.l sucks. |
| 15:43 | jweiss | but I do see your point ataggart that using that patch will mean slowness all the time, not just when the formatter uses it |
| 15:43 | jweiss | ataggart: yeah i know, we've been using it just because it made one less dep |
| 15:44 | jweiss | with java code it worked fine. w clojure not so much. |
| 15:44 | mlimotte | I'm confused by the conj implementtaion. The source from RT.java is: static public IPersistentCollection conj(IPersistentCollection coll, Object x){ if(coll == null) return new PersistentList(x); return coll.cons(x); } So, it looks like conj is equal to cons. So how does it achieve different behavior? In a PersistentVector, for example, conj adds to the end, and cons adds to the front. |
| 15:44 | amalloy | mlimotte: coll.cons is polymorphic |
| 15:45 | amalloy | List implements it by adding to the front, Vector by adding at the end |
| 15:46 | jweiss | ataggart: afaik log4k does not support any metadata (aka params) in logs. j.u.l does |
| 15:46 | jweiss | s/log4k/log4j |
| 15:46 | sexpbot | <jweiss> ataggart: afaik log4j does not support any metadata (aka params) in logs. j.u.l does |
| 15:46 | mlimotte | amalloy: thanks for the response. not sure i get it, though. i thought cons was always supposed to ad to the front. |
| 15:47 | amalloy | mlimotte: (cons foo bar) doesn't call the collection's cons method |
| 15:47 | amalloy | it creates a new Cons object |
| 15:47 | amalloy | $source cons |
| 15:47 | sexpbot | cons is http://is.gd/yyphKM |
| 15:49 | mlimotte | amalloy: ahh, i see. "cons" on the collection class is really a "conj" implementation; and the cons fn is imlpemented in RT. |
| 15:49 | mlimotte | thankks for the explanation. |
| 15:50 | amalloy | yeah. not an ideal state of affairs imo, but not *too* confusing once you realize |
| 15:51 | mlimotte | Yea. Fine once you know it. I jumped to some conclusions based on names without reading all the code. |
| 15:52 | ataggart | stuarthalloway: CLJ-426 updated |
| 15:58 | ataggart | stuarthalloway: could you please provide an example to reproduce the errors with CLJ-445 |
| 16:00 | stuarthalloway | ataggart: not quickly or simply, but I will get to it |
| 16:19 | TimMc | Someone please write a program prover (like ACL-2) in Clojure and call it "Conjecture". :-P |
| 16:20 | companion_cube | :D |
| 16:20 | stuartsierra | stuarthalloway: so it seems that including the distribution ZIP in the release build will include it in the build artifacts that get pushed to Central |
| 16:21 | stuarthalloway | stuartsierra: awesome |
| 16:21 | stuarthalloway | is that just a config change, or will you be sending me a patch |
| 16:21 | stuartsierra | Just Hudson config. |
| 16:21 | stuartsierra | We won't really know if that works until the next release. |
| 16:30 | abedra | stuartsierra, can you give tools.logging a once over |
| 16:30 | stuartsierra | yes |
| 16:30 | stuartsierra | Deleting stuff in the -testbuild-SNAPSHOT chain on oss.sonatype.org. |
| 16:30 | abedra | ok cool |
| 16:40 | edbond | how to execute raw sql in clojureql? |
| 16:41 | fliebel | thanks for the alpha. are these fn meta changes in there? |
| 16:45 | ataggart | stuarthalloway: given how many of the numeric functions can be inlined, removing certain overloads from Numbers might cause problems with extant compiled code. That might be what you're seeing as well. |
| 16:45 | stuarthalloway | ataggart: ruling that out was my next todo item |
| 16:47 | ataggart | stuarthalloway: having nothing better to do, I'll make a patch with those overloads put back in place. |
| 16:48 | fliebel | dnolen: ping |
| 16:48 | dnolen | fliebel: hullo |
| 16:49 | fliebel | dnolen: How is logos coming along? I noticed you made some commits, but the delay branch gives me IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Delay clojure.lang.RT.seqFrom |
| 16:49 | fliebel | (just randomly trying that) |
| 16:50 | stuartsierra | abedra: There's more in the pom.xml than you need. |
| 16:50 | dnolen | fliebel: heh, I wouldn't mess w/ anything in the delay branch :) I thought about it a LOT more. I have some serious thinking to do. delay branch won't work. |
| 16:50 | stuarthalloway | stuartsierra, abedra: make sure what's needed is documented somehere, I will be trying to promote jmx over the weekend |
| 16:50 | fliebel | dnolen: Totally cool, I was just checking out :) |
| 16:52 | stuartsierra | stuarthalloway: should all be on the wiki, which just stopped responding again |
| 16:53 | dnolen | fliebel: Yeah, delays and lazy-seqs can't really mix in the current design. Trying to figure out how to accomplish it with just lazy-seqs. Tricky. |
| 16:55 | fliebel | dnolen: Interesting, I love lasy seqs :) What was the name of the paper you mentioned again? I might want to read it tomorrow. |
| 16:56 | dnolen | fliebel: http://pqdtopen.proquest.com/#abstract?dispub=3380156 |
| 16:56 | stuartsierra | Wow. Old Contrib managed to crash the JVM. http://build.clojure.org/job/clojure-contrib/339/org.clojure.contrib$condition/console |
| 16:57 | fliebel | dnolen: Thanks… Whoa! that is a lot of dead tree to read. |
| 16:58 | stuartsierra | stuarthalloway: http://dev.clojure.org/display/design/How+to+Create+New+Contrib+Projects |
| 16:58 | dnolen | fliebel: the current design uses lazy-seqs, that's how I simulate Scheme's TCO. Original Scheme version used pairs (a . fn) to represent streams. Problem is in Clojure (first infinite-lazy-seq) which doesn't have any results is going to drill down forever. You can avoid that with (a . fn) representation. |
| 16:58 | dnolen | fliebel: you only need to read Part I to understand how it works. |
| 16:59 | stuarthalloway | stuartsierra: do you remember if there was a maven config thing one needed to do, to use the maven-ant-tasks stuff to release a 1.2 build? |
| 17:00 | stuartsierra | stuarthalloway: We never had 1.2.* builds releasing directly to a public Maven repository. |
| 17:00 | stuarthalloway | no, the hudson stuff |
| 17:00 | stuartsierra | I don't think there was anything special in Hudson. |
| 17:00 | stuarthalloway | it is calling mvn:deploy under the covers in ant |
| 17:01 | stuarthalloway | I was thinking some sort of ssh config thing |
| 17:01 | stuartsierra | Yes... |
| 17:01 | stuartsierra | It deployed to build.clojure.org |
| 17:01 | stuartsierra | Via SCP. |
| 17:01 | stuarthalloway | not working on my box atm. Gotta go, will try again tonight |
| 17:01 | stuartsierra | 'k |
| 17:03 | fliebel | dnolen: Ah, that helps :) The trees thank you. In other news, it irks me that Logos is so heavy on recursion. While this suits Scheme, it seems unnatural to do in Clojure. (no TCO and all, maybe also somewhat related to the blogpost by fogus) I was also wondering why you are writing Logos. Is it because of work, study, hobby, or other? |
| 17:04 | dnolen | fliebel: ? Clojure relies just as heavily on recursion, it does so itself with lazy-sequences. |
| 17:04 | fliebel | dnolen: I know, I know... |
| 17:05 | fliebel | Hm, not recursion maybe then, but something… Oh, well, nvm. |
| 17:08 | dnolen | fliebel: as far as why? it's an interesting opening into a lot of topics that are harder to deal w/ outside of logic programming. In Clojure it's also possible to write a logic engine that's not a toy. In Python, JS, Ruby it'll just be too slow to be generally useful. |
| 17:27 | TimMc | dnolen: Then why not one of the Schemes? |
| 17:27 | dnolen | TimMc: lack of persistent datastructures, lack of good concurrency story. |
| 17:28 | TimMc | *nod* |
| 17:28 | dnolen | both of these things contribute to how fast Logos is and can be. |
| 17:38 | puredanger | &(.equals Double/NaN Double/NaN) |
| 17:38 | sexpbot | ⟹ true |
| 17:38 | puredanger | &(= Double/NaN Double/NaN) |
| 17:38 | sexpbot | ⟹ false |
| 17:38 | puredanger | anyone know what's up with that? |
| 17:39 | dnolen | &(== Double/NaN Double/NaN) |
| 17:39 | sexpbot | ⟹ false |
| 17:39 | dnolen | &(identical? Double/NaN Double/NaN) |
| 17:39 | sexpbot | ⟹ false |
| 17:41 | dnolen | puredanger: that's Java, NAN is not equal to itself. |
| 17:41 | dnolen | puredanger: http://www.concentric.net/~ttwang/tech/javafloat.htm |
| 17:41 | puredanger | dnolen: shame on me :) |
| 17:42 | puredanger | and Java can suck it |
| 17:42 | stuartsierra | I think that's part of the floating-point spec. |
| 17:43 | stuartsierra | Java .equals is object-identity, Clojure's = on a Number dispatches to clojure.lang.Numbers, which eventually uses the Java == operator. |
| 17:44 | tsdh | Is there a function that finds the first item matching some predicate in a possibly nested seq? |
| 17:44 | puredanger | floating-point also can suck it :) |
| 17:45 | stuartsierra | heh |
| 17:45 | stuartsierra | tsdh: try 'some' and 'flatten' |
| 17:45 | puredanger | sorry...long Friday afternoon implementing inadequately specified specs has made me grumpy :) |
| 17:45 | tsdh | stuartsierra: thanks |
| 18:02 | Tomsik_ | Hi |
| 18:02 | Tomsik_ | I'm new to both clojure and java, how do I .add this createHorizontalStrut thing? |
| 18:03 | Tomsik_ | http://download.oracle.com/javase/1.3/docs/api/javax/swing/Box.html#createHorizontalStrut(int) this thing |
| 18:04 | brehaut | (javax.swing.Box/createHorizontalStrut 1) |
| 18:05 | longfin | (Class/static-method args) |
| 18:05 | Tomsik_ | Oh, I see. |
| 18:06 | Tomsik_ | Thanks :) |
| 18:06 | Tomsik_ | Is there a shorter way to write it? |
| 18:07 | brehaut | (import javax.swing.Box) (Box/createHorizontalStrut 1) |
| 18:07 | Tomsik_ | Ah, like with these constants |
| 18:09 | brehaut | Tomsik_: http://clojure.org/java_interop |
| 18:13 | longfin | is there suitable java lib for simple clojure interop demo? |
| 18:14 | stuartsierra | longfin: String and Math aren't bad. |
| 18:15 | longfin | hm.. thanks. |
| 18:15 | stuartsierra | Even Swing leads to some nice examples |
| 18:16 | stuartsierra | http://stuartsierra.com/tag/swing |
| 18:16 | longfin | It's cool. |
| 18:20 | raek | anyone know why clojure-mode highlights some symbols in (for me) green? it happens for: "deftest", "join" and "list-model" |
| 18:22 | hiredman | list-model is most likely because list* is in some list without the * being escaped |
| 18:22 | hiredman | (some list of symbols in clojure-mode) |
| 18:23 | mattmitchell | i'm going to attempt using jparsec in clojure, using this tutorial: http://docs.codehaus.org/display/JPARSEC/jparsec2+Tutorial |
| 18:24 | mattmitchell | i just don't know how to do "implements" in clojure! |
| 18:25 | amalloy | mattmitchell: reify |
| 18:26 | mattmitchell | amalloy: ok i'll check it out |
| 18:26 | amalloy | &(doc reify) |
| 18:26 | sexpbot | ⟹ "Macro ([& opts+specs]); reify is a macro with the following structure: (reify options* specs*) Currently there are no options. Each spec consists of the protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [a... http://gist.github.com/866794 |
| 18:26 | amalloy | blech. formatting is terrible for that; use your repl |
| 18:27 | mattmitchell | amalloy: ha ok np |
| 18:27 | mattmitchell | amalloy: so something like this: |
| 18:27 | mattmitchell | enum BinaryOperator implements Binary<Double> {} |
| 18:27 | mattmitchell | is possible? |
| 18:27 | amalloy | i don't think clojure has a way to declare enum types |
| 18:27 | mattmitchell | ok |
| 18:27 | amalloy | and certainly not to do this Generics stuff which doesn't really exist at the bytecode level |
| 18:28 | mattmitchell | amalloy: ok. you think maybe a bad fit for clojure? |
| 18:28 | amalloy | so you'd really be writing class BinaryOperator implements Binary { public Double perform(Double, Double) {...}} |
| 18:28 | amalloy | mattmitchell: it's not the sweet spot for sure, but it's not impossible either |
| 18:28 | clojurebot | Pardon? |
| 18:29 | mattmitchell | ok cool. good to know. |
| 18:29 | hiredman | you should look at how clojure.lang.Numbers does it |
| 18:31 | hiredman | (some list of symbols in clojure-mode) |
| 18:31 | hiredman | whoops |
| 18:38 | KirinDave | Does anyone have any references to talks/slides/videos on how to use protocols/datatypes? Not from an API standpoint, but from a design standpoint |
| 18:38 | KirinDave | I have a friend who's curious and I don't have time to go over it with him this weekend. |
| 18:38 | brehaut | KirinDave: Stuart Halloway's clj conj presentation about 'Simple' might cover some of it? |
| 18:40 | KirinDave | brehaut: got a link? Google is being unhelpful to me |
| 18:40 | brehaut | let me dig |
| 18:42 | brehaut | KirinDave: heres the slides https://github.com/downloads/stuarthalloway/clojure-presentations/Clojure-Simplicity.pdf http://clojure.blip.tv/file/4824610/ |
| 18:42 | KirinDave | ty |
| 18:45 | amalloy | KirinDave: just google for "clojure simple". how many people can there be who think clojure is simple? :) |
| 18:45 | KirinDave | amalloy: Ha. |
| 18:45 | KirinDave | amalloy: The boolean opeartors; they do nothing! |
| 18:46 | amalloy | &(= 1) |
| 18:46 | sexpbot | ⟹ true |
| 19:28 | TimMc | ,((juxt #(.equals %1 %2) identical? = ==) Double/NaN Double/NaN) |
| 19:28 | clojurebot | [true false false false] |
| 19:28 | TimMc | What I don't understand about that is why identical? gives a different result than .equals |
| 19:32 | TimMc | Both c.l.Util/equiv and c.l.Util/identical use Java's == as a first check. |
| 19:33 | TimMc | and Clojure's = uses Util/equiv |
| 19:40 | tomoj | "If d1 and d2 both represent Double.NaN, then the equals method returns true, even though Double.NaN==Double.NaN has the value false." |
| 19:40 | tomoj | http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html#equals(java.lang.Object) |
| 19:44 | TimMc | Oh.... Double.NaN is a primitive? |
| 19:44 | TimMc | Yes, it is. |
| 19:44 | TimMc | That's what I was missing. |
| 19:45 | TimMc | ,(#(identical? % %) (Double. Double/NaN)) |
| 19:45 | clojurebot | true |
| 19:46 | tomoj | wait, wat? |
| 19:47 | tomoj | so in java `Double.NaN == Double.NaN` is false, but `new Double(Double.NaN) == new Double(Double.NaN)` is true? |
| 19:49 | amalloy | tomoj: certainly it won't be true if you use == instead of .equals :P |
| 19:50 | TimMc | tomoj: ##(identical? (Double. Double/NaN) (Double. Double/NaN)) |
| 19:50 | sexpbot | ⟹ false |
| 19:50 | tomoj | oh, missed that it was the same Double up there |
| 19:51 | TimMc | ,(#(.equals % %) (Double. Double/NaN)) |
| 19:51 | clojurebot | true |
| 19:51 | TimMc | ,(#(= % %) (Double. Double/NaN)) |
| 19:51 | clojurebot | true |
| 19:51 | TimMc | ,(#(== % %) (Double. Double/NaN)) |
| 19:51 | clojurebot | false |
| 19:51 | tomoj | crazy |
| 19:59 | chouser | hm, that == might be a bug. |
| 20:11 | ataggart | NaNs are not well supported |
| 20:13 | ataggart | http://dev.clojure.org/jira/browse/CLJ-738 |
| 20:15 | TimMc | chouser: Java doesn't think so. |
| 20:29 | chouser | TimMc: == is not Java .equals, though. |
| 20:30 | chouser | & (.equals 5 5.0) |
| 20:30 | sexpbot | ⟹ false |
| 20:30 | chouser | & (= 5 5.0) |
| 20:30 | sexpbot | ⟹ true |
| 20:30 | chouser | & (== 5 5.0) |
| 20:30 | sexpbot | ⟹ true |
| 20:55 | ataggart | & (= (Long. 5) (Double. 5.0)) |
| 20:55 | sexpbot | java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Long |
| 21:22 | sritchie_ | hey all -- if I have a series of nested maps, like this -- (def test-map {:first {:ffirst true} :second {:fsecond false}}) |
| 21:23 | sritchie_ | is there a function like (nested-replace {:ffirst false}), or something, that would recursively find and replace some map entry, or return nil? |
| 21:23 | sritchie_ | I don't ever need to add anything new, here |
| 21:24 | brehaut | &(assoc-in {:a {:b 1} :c 2} [:a :b] 3) |
| 21:24 | sexpbot | ⟹ {:a {:b 3}, :c 2} |
| 21:24 | brehaut | its not quite what you want |
| 21:26 | sritchie_ | brehaut: I like assoc-in, but let me explain what I'm trying to do -- |
| 21:26 | sritchie_ | I've got three configuration files, with options split between each |
| 21:27 | sritchie_ | I want the user to be able to specify configuration options, without specifying which file they live in, and replace defaults |
| 21:27 | brehaut | i think you want a recursive merge-with |
| 21:27 | sritchie_ | yes |
| 21:27 | brehaut | details are left as an exercise for the reader :P |
| 21:28 | sritchie_ | you would have written it in the margins of the IRC chat, but there wasn't enough space |
| 21:28 | sritchie_ | anddd dead. |
| 21:28 | sritchie_ | sorry, not predicting your demise, there |
| 21:28 | brehaut | haha |
| 21:28 | ieure | Is there some way to get at the contents of my project.clj from inside my app? |
| 21:36 | stuartsierra | ieure: not unless you open the file |
| 21:36 | stuartsierra | and read it like any other file. |
| 22:14 | tufflax | Is there a better way to do (assoc a-vector an-index (inc (the-same-vector the-same-index)))? |
| 22:16 | tufflax | Hm, (update-in the-vector [the-index] inc) maybe |
| 22:17 | danlarkin | update-in is the greatest |
| 22:19 | tufflax | hehe |
| 22:26 | tufflax | What's the best way to create a vector of only zeros of length n? (vec (take n (cycle [0])))? |
| 22:37 | mlimotte | Hi. I'm having an issue with some simple floating point math. The numbers are small, so I don't think I should be running into rounding problems. With Clojure 1.2.0. In my repl: (+ 7.9 -4.0) => 3.9000000000000004 . Same result for (+ (double 7.9) (double -4.0)) |
| 22:43 | sattvik | mlimotte: I think that is the 'correct' result given floating point mathematics. |
| 22:44 | sattvik | tufflax: You can try (vec (repeat n 0)) |
| 22:45 | tufflax | mlimotte such errors are usually the result of the fact that not every number can be represented precisely in a float or double, but I'm a little bit confused because (def a 3.9) and then asking for the value of a gives 3.9 and not 3.9000000000000004. Anyway you sould never rely on floats being accurate. |
| 22:45 | tufflax | sattvik thanks |
| 22:49 | mlimotte | Still, 3.9 should work. And this example does work: (/ (math/round (* 10 (+ 7.9 -4.0))) 10.0) |
| 22:51 | tufflax | What is the result of (/ (math/round (* 10 (+ 7.9 -4.0))) 10.0)? |
| 22:52 | sattvik | mlimotte: No, I'm afraid not. 7.9 cannot be accurately represented. You can check out http://www.ecs.umass.edu/ece/koren/arith/simulator/FPAdd/ to see the details of what's going on. |
| 22:53 | tufflax | sattvik how come (def a 3.9) and then asking for a gives 3.9 then? :P |
| 22:54 | tufflax | oh, you said 7.9, but same thing |
| 22:56 | sattvik | Well, there's a number of things going on. Mainly, it's that the value you get for 3.9 is not the same as the result of (- 7.9 4.0). |
| 22:58 | sattvik | The two numbers are off by the smallest possible difference between those two numbers in double precision floating point arithmetic. |
| 22:58 | mlimotte | i see. so what's best practice? The multiply-round-divide trick? Or Use BigMath? Or is there something else? |
| 22:59 | tufflax | mlimotte try to use integers if you can, that's the best thing you can do |
| 22:59 | sattvik | Well, that depends on your application. For something like money, don't use floating point, stick to integers. |
| 22:59 | tufflax | Otherwise when comparing doubles, allow for some small error |
| 23:00 | mlimotte | alright. thanks for the insights. |
| 23:01 | tufflax | or maybe ratios :) |
| 23:04 | sattvik | ,(+ 79/10 -4) |
| 23:04 | clojurebot | 39/10 |
| 23:04 | sattvik | ,(+ 7.9M -4) |
| 23:04 | clojurebot | 3.9M |
| 23:09 | pdk | ,3.9 |
| 23:09 | clojurebot | 3.9 |
| 23:09 | pdk | ,7.9 |
| 23:09 | clojurebot | 7.9 |
| 23:11 | tufflax | finally after some staring at that page you linked to sattvik i understand what's going on :P |
| 23:11 | pdk | do tell, link it up |
| 23:12 | tufflax | http://www.ecs.umass.edu/ece/koren/arith/simulator/FPAdd/ was the page |
| 23:13 | tufflax | 3 is 11 in binary, and 7 is 111, so there is one less digit for the part "after the decimal point" available in 7.9 compared to 3.9, and that last digit is what gives the error |
| 23:16 | tufflax | not the best explaination, but look at the page :P |
| 23:25 | tufflax | or I should say, the last "digit" of 3.9 is necessary for it to be 3.9, but that last digit is not avaiblable in 7.9 because 7 uses one more digit than 3 for the integer part, so when computing 7.9 - 4, that last digit is not there to make it 3.9 |