#clojure logs

2011-03-11

00:32sorenmacbethhi all
00:33sorenmacbethcould 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:37tomoj$findfn '(("a") ("b") ("a b")) '("a" "b" "a b")
00:37sexpbot[clojure.core/flatten]
00:38sorenmacbeththank you!
00:43tomojsexpbot: botsnack
00:43sexpbottomoj: Thanks! Om nom nom!!
00:43tomojthough..
00:43tomojif yours are only nested one deep, maybe (apply concat) is better?
01:36amalloytomoj, sorenmacbeth: http://stackoverflow.com/questions/5232350/clojure-semi-flattening-a-nested-sequence/5236194#5236194
01:47tomoj"usually" because you're usually using map?
01:48sorenmacbethamalloy: simple! thanks much
01:48amalloytomoj: that often turns out to be the case, yes
01:48amalloyeven if it's at level N-2 instead of level N-1
01:54sorenmacbethactually, my problem is slightly more complex. I need to go from (("a") ("b") ("a" "b")) to ("a" "b" "a b")
01:54sorenmacbethbasically a str-join on the inner seqs, then apply concat?
01:55amalloyoh, i see
01:55amalloy&(let [s [["a"] ["b"] ["a" "b"]]] (mapcat #(apply str %&) s))
01:55sexpbot⟹ (\[ \" \a \" \] \[ \" \b \" \] \[ \" \a \" \space \" \b \" \])
01:55amalloyhm
01:56amalloy&(let [s [["a"] ["b"] ["a" "b"]]] (mapcat #(apply str %) s))
01:56sexpbot⟹ (\a \b \a \b)
01:56amalloybah
01:57tomojdon't cat
01:57amalloyoh right
01:57amalloythanks tomoj
01:57amalloy&(let [s [["a"] ["b"] ["a" "b"]]] (map #(apply str %) s))
01:57sexpbot⟹ ("a" "b" "ab")
02:00sorenmacbethawesome
02:03sorenmacbethjust need to add a space between the last "ab", so result should be ("a" "b" "a b")
02:03amalloysorenmacbeth: yeah, so use clojure.string/join instead of apply str
02:04sorenmacbethamalloy: thanks again
02:07sorenmacbethperfect, that works :)
02:13amalloyhey 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:13amalloy(macroexpand '(macro-do [[f & args]] `(def ~(symbol (str "basic-" f)) (partial ~f ~@args)) [f "test"] [y 1 2 3]))
02:13amalloy(do (do (def basic-f (clojure.core/partial f "test")) (def basic-y (clojure.core/partial y 1 2 3))))
02:16amalloybasically 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:22tsdhIf I have an instance of ITransientVector in Java, how can I remove one given Object o?
03:23tsdhOr, if that doesn't work, how can I remove the element at a given index?
03:23amalloyvectors don't like inserts and removes in the middle
03:24amalloyif 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:26tsdhamalloy: 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:27amalloyso look at his impl for POS and see how he's doing it?
03:28tsdhOh, indeed. :-)
03:29amalloyanyway, good luck. i'm off to bed
03:31tsdhBye
04:05ejacksonGood Morning Clojuristas !
04:09tsdhHi ejackson.
04:11tsdhIf I want to walk some nested structure (vec of vecs), and only pick out some parts, how do I do that?
04:12tsdhOh, I got it.
04:28Dranikhi all!
04:36clgvgood morning. what is the "default case" in a case statement?
04:36brehaut:else
04:36brehautoh, case?
04:37raekclgv: (case :a 1, :b 2, "default here")
04:37clgvraek: th
04:37clgvthx
04:37tsdhHow to I check if a Var foo is bound? Both (when @foo) and (when foo) error...
04:37raektsdh: what problem is that the solution for?
04:38raeknormally, when a fn knows about a var, it already exists
04:38raekor has to exist
04:38clgv$inc reak
04:38sexpbot⟹ 1
04:38clgv;)
04:39clgvups
04:39clgv$inc raek
04:39sexpbot⟹ 6
04:39tsdhraek: 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:40raekthere's 'bound?' when you have an existing var
04:40brehauttsdh: if you have declared a var (such as (def abc whatever) or (declare abc) ) then (bound? #'abc)
04:41raektsdh: is this done as some initialization, or are those changes going to happen while the application runs?
04:42tsdhbrehaut: Ouch, that was too obvious. My slime just didn't want to complete it...
04:42tsdhraek: There's an entry function that might establish a binding of that Var.
04:43brehauttsdh: if you need to see if a symbol exists, then you can use (resolve (symbol "abc"))
04:43brehautbut i think if you have reached that stage, you have probably done something wrong
04:44brehautactually, (resolve 'abc) would be smarter
04:44tsdhbrehaut: Hm, (bound? foo) errors with ClassCastException: clojure.lang.Ref cannot be cast to clojure.lang.Var.
04:44tsdhHm, I'll poste the code...
04:44brehauttsdh: you have to var quote it
04:44brehaut#'foo
04:45tsdhbrehaut: Ah, now that seems to do the trick!
04:46brehaut(defn exist-and-bound? [sym] (if-let [v (resolve sym)] (bound? v) false)
04:46brehauti wouldnt advise using it though
04:47brehautnight
04:47tsdhbrehaut: Well, it's globally def-ed without root binding, so it's existance is always true.
04:48raektsdh: 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:48raekmaintaining state wihtout a ref/atom/agent feels non-clojure-y
04:49clgvraek: I'd skip the "e" -> clojury ;)
04:49tsdhraek: I do exactly that using a (binding [foo (ref {})] ...) in the entry function.
04:50tsdhraek: 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:52tsdhraek: (p-apply v1 --> -->) ==> reachable vertices as set. (p-apply v1 --> --> :trace-path true) ==> [<reachable vertices> <shortest paths map>]
04:53raekah, I see.
05:02raekhrm. what happens when you leave out a method in a proxy, and then call it?
05:03raekah. java.lang.UnsupportedOperationException
05:03clgvis there a general comparison functions that can handle strings, keywords and numbers?
05:04raekclgv: compare. but it can only compare things of the same kind
05:04clgvraek: there is nothing for the mixed case?
05:05raekdon't know
05:06raekhrm. java.lang.Class is not comparable
05:06raekalthough, (.getName some-class) is
05:07raekclgv: what should the order of "foo", :foo and 123 be?
05:07clgvraek: e.g. numbers could always be less than keyword which are less than strings
05:08clgvraek: I could use the string representation of the full classname ;)
05:12raekyeah, maybe something like (defn über-compare [x y] (try (compare x y) (catch ClassCastException _ (compare (.getName (class x)) (.getName (class y))))))
05:13clgvI would skip the exception part. you could first try on equality of classes
05:13raek,(compare (long 1) (int 1))
05:13clojurebot0
05:13clgvlol ok ;)
05:13clgvmaybe except for numbers
05:14raekI wouldn't be surpised if, for instance, clojure.lang.PersistentArrayMap and clojure.lang.PersistentHashMap can be compared to each other
05:16clgvhmok. the the exception version would be the most general and short one
05:17raekbut still, I feel bad for using exceptions for control flow
05:18clgvyeah, that's why I wanted to remove them in that example
05:19clgvbut I'll use it like that now. It's just for an inspection tree.
05:21clgvI hated it when my maps/structs... showed there entries in a random order ;)
06:49tsdhWow, (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:55raek(apply apply args)
07:27clgvcan I use robert.hooke for protocol methods?
07:27clgvthe straight-forward approach doesnt work
07:28clgv(add-hook ...) doesnt complain but the hook itself isnt called either
07:42Fossishouldn't the stable clojure jars be in clojars?
07:55raekFossi: it's in the clojure repo
07:55raekhttp://build.clojure.org/releases/
07:55raekhttp://build.clojure.org/snapshots/
07:57tsdhI 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:20Fossihmm, leiningen has those configured, but i'm still getting 5 required artifacts are missing.
08:20Fossifrom the specified remote repositories:
08:20Fossi clojure (http://build.clojure.org/releases),
08:20Fossi clojars (http://clojars.org/repo/),
08:20Fossi[...]
08:26Fossiah, i had them as [clojure "1.2.0"] not [org.clojure/clojure "1.2.0"]
08:28longfin:)
08:47tsdhIf 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:50tsdhSo basically, I need a function that gets a function and returns a copy of that function...
08:52longfinintersting...
08:54tsdhHm, maybe I can copy `complement' without the nots?
08:59chousertsdh: 'identity'?
08:59chousertsdh: honestly though, I don't really understand your question yet.
09:01tsdhchouser: --> 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:01chouserheh, ok, I see.
09:02Chousukehmm
09:02Chousuke(partial -->) ?
09:02chouserChousuke: there you go.
09:02chouseractually, that fails I think
09:02chouser,(partial +)
09:02clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$partial
09:02Chousukeyeah :/
09:02chouser,#(+ %1 %2)
09:02clojurebot#<sandbox$eval3210$fn__3211 sandbox$eval3210$fn__3211@22d4f0>
09:03chousertsdh: So there is that, but I'm suspicious of a design that requires such contortions.
09:04tsdhchouser, 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:04clgv,(leftfn [(f [& args] (map-indexed (fn [i t] (with-meta t {:index i})) args)) (g [x] (inc x))] (f g g g))
09:04clojurebotjava.lang.Exception: Unable to resolve symbol: leftfn in this context
09:04clgv,(letfn [(f [& args] (map-indexed (fn [i t] (with-meta t {:index i})) args)) (g [x] (inc x))] (f g g g))
09:04clojurebot(#<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:05tsdhclgv: I guess I go with clojure.walk/prewalk, but thanks for that superb tip anyway.
09:07clgvtsdh: just an example. and I wanted to see what the bot does with it
09:08tsdhWas'n there some syntax shugar for accessing a maps value by key :foo?
09:09tsdhs/shugar/sugar/
09:09sexpbot<tsdh> Was'n there some syntax sugar for accessing a maps value by key :foo?
09:09tsdhWow, there's a bot for everything...
09:11pjstadigi like it spelled shugar, but that's just me
09:13tsdh:-)
09:16choffsteinHey 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:16choffsteinoccurs (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:17choffsteinIt seems like it may be possible with Extension methods in Java 7?
09:17stuartsierrachoffstein: You can set a default "uncaught exception handler" on threads in Java.
09:18choffsteinstuartsierra: Which works, but I even want to take action if the exception is caught
09:18stuartsierraThen you need to alter the code that does the catching.
09:20choffsteinYeah, that is what I figured. I'm assuming I need to drop to the Java level?
09:20stuartsierraNot at all.
09:20stuartsierraThat is, unless you want to alter the behavior of compiled code that you didn't write.
09:21stuartsierraWhich is a very risky idea.
09:22choffsteinYeah ... 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:23Fossisomebody already used ring/jetty with the proxy servlet that ships with it?
09:23clgvchoffstein: I would like the idea to be able to get a debug-repl run in the place where an exception is thrown^^
09:24Fossii'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:25stuartsierrachoffstein: There are debugging and profiling tools that hook into the JVM that probably offer similar functionaliity.
09:28choffsteincigv: 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:28choffsteinbut dropping to a debug-repl would be awesome too
09:30stuartsierraIDEs like Eclipse may also offer these features.
09:32choffsteinWell, 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:32choffsteinwhether they were caught or not
09:32stuartsierrachoffstein: Again, look at JVM-level stuff, or application containers like JBoss/Tomcat/Glassfish. I'm sure something like this exists.
09:32choffsteinI'll check it out. Thanks.
09:33stuartsierra'welcome
10:20stuartsierragazhundheit
10:27TimMcstuartsierra: I came across your trick for unit testing private defns -- thanks!
10:28stuartsierra'welcome
10:29stuartsierraI don't think I can claim credit for @#' though.
10:29timvisherhey all
10:29timvisherdoes anyone have anything they'd suggest for trying to learn to think recursively?
10:30timvisherrecursion 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:31stuartsierraThink back to Algorithms 101 — what are the loop invariants?
10:31stuartsierraWhat changes at each iteration of the loop?
10:31stuartsierraThe stuff that changes will be arguments to the recursive function (or loop/recur in Clojure).
10:32timvisherstuartsierra: that revelation just hit me the other day
10:32timvisherthat 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:32timvisherwhat I mean more is how to approach a problem recursively
10:33timvisherin other words, in the SICP course they say that the key to recursion is wishful thinking
10:33timvisheryou try to think of how they problem would look if it was easy to solve
10:33timvisherand then you see if you can reduce the problem in steps towards that degenerative case and then solve the simpler problem
10:33goodmike_mhtimvisher: Your requirements match the raison d'etre of The Little Schemer
10:33timvisherit's that series of decompositions that I struggle to see
10:34timvishergoodmike_mh: i.e. learning to think recursively?
10:34goodmike_mhyes
10:34dnolentimvisher: 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:34timvishermmm
10:35timvisherthey've been on my reading backlog for forever. Perhaps it's finally time to pick them up...
10:35TimMctimvisher: HtDP teaches recursive thinking via recursive data structures. (Free to read online.)
10:36timvisherTimMc: nice
10:36timvisherthanks for that pointer
10:36timvisheri'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:36TimMcIt's the textbook for my school's Fundamentals of Computer Programming course.
10:36timvisherit may just be that I need to study recursive solutions over and over again
10:37TimMctimvisher: Do you have a lot of imperative programming background?
10:37timvisherall i've ever done is Algol based languages (Java, Groovy, PHP, etc.)
10:37timvisherDabbled in ELisp but Clojure's my chosen tool for teaching myself FP
10:38timvishergoing through SICP right now (the text) and I'm running into a lot of trouble as they go into recursion.
10:38timvisheragain, not so much the understanding of the solution when presented but being able to get there on my own.
10:38TimMcYeah, so you're just having difficulty with the unlearning. :-)
10:38timvisherfigures
10:38timvisheri always want the answer to be 'read this paragrah and it'll all click!'. :)
10:39timvisheralright, well on I will forge
10:39TimMcIt's pretty common, from what I hear.
10:39TimMcYou can teach (e.g.) middle school kids either functional or imperative programming with pretty much equal ease.
10:40parasebais 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:40TimMcIt's harder to switch styles the first time you do it. Later, you'll be able to think in both.
10:40parasebaname-with-attributes in c.c. is the closer I can find, but it doesn't help much
10:42parasebaideally, 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:43parasebaIt's pretty easy to write, but I can't believe it's not done already in clojure or c.c.
10:45dnolenparaseba: ?
10:45dnolen(defmacro foo ([a b] nil) ([a b c] nil))
10:45dnolen(meta #'foo)
10:45dnolen{:macro true, :ns #<Namespace user>, :name foo, :file "NO_SOURCE_PATH", :line 9, :arglists ([a b] [a b c])}
10:47parasebasorry, 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:48parasebathe macro will define the function, using the declarations passed but adding some extra stuff
10:49parasebaimagine something like (my-defn f "my doc" {:my :meta} ([a] nil) ([a b] nil) {:more :meta})
10:49parasebaI have to handle all possible forms of defn declarations (single arity, multiple arity, no doc, no meta, two meta maps, etc.)
10:51clgvis there a command like partition that includes the remaining elements as last smaller list?
10:51TimMcclgv: partition-all
10:51clgv,(partition 5 (range 23))
10:51clojurebot((0 1 2 3 4) (5 6 7 8 9) (10 11 12 13 14) (15 16 17 18 19))
10:51clgvoh thx :D
10:51parasebaclgv: you almost always want to use partition-all
10:52TimMcamalloy_: Early bird gets the worm.
10:53fbru02_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:53fbru02_paraseba: welcome to irc btw ! :)
10:54fbru02_defmacro `(defn generatefn [args & body] ~args ~@body))
10:55parasebafbru02_: thanks for the welcome .. I'm trying new forms of not getting work done
10:56parasebafbru02_: 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:56parasebafbru02_: and also, I don't want to loose doc and metadata information
10:57fbru02_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:58fbru02_paraseba: which i cannot think of , at least now
10:59parasebafbru02_: it would be a nice addition to c.c.macro-utils or c.c.def if it's not there already
11:02ev4laccording 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:02ev4l. Are there any more cases?
11:03parasebaby the way, any idea of why defn supports two attribute maps? why the first one is not enough?
11:04stuarthallowayofficial word on bang: for fns that are not safe in an STM transaction
11:05TimMcstuarthalloway: Unless the name clearly implies side effects?
11:05stuarthallowayTimMc: honestly I don't think the bang idiom is that important
11:06stuarthallowaybut the STM interaction was the original motivation for the bang fns in core
11:06tsdhWhy 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:07ev4lstuarthalloway: 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:07stuarthallowayall the best stuarts hang out here and answer book questions, right stuartsierra?
11:08TimMcstuarthalloway: Ah, interesting.
11:08ev4ls/to/by
11:08sexpbot<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:09ev4l(haha faster than you bot... suck it xD)
11:10woobytsdh: (require 'clojure.inspector) first
11:14tsdhwooby: But why do I have to require clojure.inspector, but I can access clojure.set functions qualified without doing so?
11:16raektsdh: they are loaded automatically in versions up to 1.2, iirc
11:16tsdhOk, thanks.
11:17raekan old detail that you should not rely upon
11:17raekI think that was from the times before require and firends
11:18abedrawhere did the other stuart dissapear to?
11:19woobytsdh: Because Clojure requires set for you when you start it up.
11:20goodmike_mhtsdh: wooby and I are not sure exactly why. sets are a major seq collection type, even though they are defined outside core
11:21goodmike_mhNot all libraries are quite created equal
11:22raekhttps://github.com/clojure/clojure/commit/d6bc47ae952255c5b45f449e73db2439ba2a80f5
11:23TimMcabedra: Quit about 50 minutes ago.
11:23raeksince this commit clojure.(zip|xml|set) are not loaded automatically anymore
11:24TimMctsdh: If it isn't in clojure.core or java.lang, you need to explicitly require, use, or import it.
11:25DantasHi 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:25tsdhTimMc: Yes, except it's in clojure.set, in what case I can call it qualified.
11:25tsdhOk, gotta run.
11:49choffsteinanyone 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:52rmarianskiwith-open might be a good candidate to look at for that sort of thing
11:53rmarianskichoffstein: https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L2911
11:53rmarianskinot really a write up, but you might be able to do the same sort of thing
11:54choffsteinthanks guys
11:54choffsteinerr...guy
12:03Fossihow do you inspect java objects again?
12:04Fossii want to see the methods
12:04DantasThe COMMUTE form is executed in two phases , right ? . is the last phase , called commit phase, synchronized ? "LOCK commute fn UNLOCK"
12:11choffsteinCan 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:13amalloychoffstein: doseq?
12:13amalloyor dorun?
12:13amalloyFossi: clojure.contrib.repl-utils/show
12:14amalloyor clojure.java.javadoc, i think?
12:15choffsteinI'll check those out. Thanks amalloy.
12:16Chousukechoffstein: you mean like (run foo bar whatever) expanding to (do (foo) (bar) (whatever))?
12:17choffsteinchousuke: yeah, exactly. I'm trying to figure out how to do that.
12:18choffsteinBasically, I am trying to create a wrapper around 'try' to inject some code ... but it isn't going well :D
12:18amalloy(defmacro run [& fs] (cons 'do (map list fs))) :P
12:19amalloywould bring Chousuke's example to life
12:19Chousukeamalloy: you were just a few keypresses faster than me :P
12:20ChousukeI was counting my parens :( damn irc for not having paredit
12:20amalloyChousuke: i'm working on a sexp-balancer for sexpbot
12:20choffsteinawesome. thanks!
12:20amalloyby which i mean, complaining about not having one and getting brehaut to write the parser for me
12:26choffsteinOkay, I definitely don't know enough clojure to do what I am trying to do :D
12:27Fossiamalloy: thanks
12:28choffsteinAny thoughts on how to intercept a 'catch' clause and add some code to it?
12:32amalloychoffstein: let's say the user calls your macro with the & arglist '(/ 1 0) 'x '(catch Exception _ nil)
12:32amalloyyou can find all the catches in that list with (filter (comp first #{'catch}) arglist)
12:33amalloyer, that's backwards. (comp #{'catch} first)
12:33amalloythen you can mess around with them however you want and put them back in
12:33choffsteinwow. That ... that might be perfect.
12:34Fossiany ring'ers herre?
12:34Fossii just wanna add a second servlet to a jetty
12:35Fossiand i miss add-servlet! from compojure
12:38amalloyTimMc: what worm did i not get? i couldn't tell
12:38amalloyor, i suppose, did i get
12:38TimMcamalloy: I got to tell someone about partition-all!
12:38TimMcAnd you were probably still asleep.
12:39amalloyyou bet i was
12:44TimMcDamn, I forgot to ask clgv why s/he wanted partition-all. I still haven't had a need for it
12:44TimMcI suppose it could be useful for layout logic.
12:44jkkrameris http://dev.clojure.org/display/doc/Getting+Started the current, official link to give to a clojure newbie?
12:48stuarthallowayjkkramer: no one person probably knows if that is all up to date
12:48DantasThe COMMUTE form is executed in two phases , right ? . is the last phase , called commit phase, synchronized ? "LOCK commute fn UNLOCK"
12:49jkkramerstuarthalloway: at the very least, the assembla one is no longer official, right?
12:49stuarthallowayright
12:49stuarthallowayand please suggest (or make) edits in Confluence if you see something wrong
12:50TimMcDantas: I don't know if locks are involved, per se.
12:50stuarthallowayDantas: that is implementation detail
12:51jkkramerwill do. getting a friend setup this weekend
12:51stuarthallowaywhat you can count on is that readers require no locks
12:51stuarthallowayer, should say that readers can *never* block
12:52stuarthallowayany locks down in the STM, if they exists, are about STM resources, not about your refs
12:52Dantasstuarthalloway: yes, but semantically, could i think that the commit phase is atomic ? ( sorry for my english )
12:53TimMcDantas: Here is an excellent article on STM in Clojure: http://java.ociweb.com/mark/stm/article.html
12:53stuarthallowaytransactions are always atomic, across the set of refs transacted upon
12:53TimMcThe latter part is all implementation details, but there is a good high-level description as well.
12:54DantasTimMc: Thanks, stm is really cool. a easy way to create concurrent applications
12:54Dantasan*
12:55TimMcDantas: Just watch out for write skew, that's the only thing that isn't obvious from most of the descriptions I've seen.
12:55TimMcDantas: http://java.ociweb.com/mark/stm/article.html#write-skew
12:56Dantasstuarthalloway: thank you
12:56DantasTimMc: Thanks
12:57TimMcIf you're not sure about commute yet, you can avoid it easily.
12:58DantasTimMc: according the clojure documentation, commute is performed in two phases. the second phase is where the ref value will be changed
12:59Dantasso, i dont want to understand the implementation detail, only if this operation is atomic ! this way avoid race conditions
12:59TimMcI don't understand that aspect of commute yet myself.
13:00Dantasif i understand right, stuarthalloway said that they are atomic
13:00TimMcMy understanding is that commute allows some more interleaving of transactions by rescheduling commutes.
13:00stuarthallowaycommute is for when you don't care when the change happens
13:00TimMc...but I'm really not sure.
13:00stuarthallowaye.g. commute is for "add 100 to account"
13:02TimMcstuarthalloway: I assume commute should not be used when you want to keep consistency constraints between refs?
13:02stuarthallowayprobably right
13:03Dantasi asked about that cause i came from shared state way. so commute is really new from my background !
13:07stuarthallowaycommute is still atomic, but you might not know its result
13:08Fossiring/jetty is driving me crazy :/
13:10Dantasstuarthalloway: but, after commit phase, the commute result is the same located in the memory
13:10Dantas??
13:10stuarthallowayDantas: the return value of your call to commute is not necessarily the final result
13:11stuarthallowaybecause commute says "feel free to retry this independently of everything else"
13:16Dantasstuarthalloway: TimMc thank
13:16Dantascya
13:17Fossianybody know if it's even possible to use another servlet with ring?
13:17Fossithe leiningen task seems to have only one of them as well
13:17Fossiand everything i try resets the original servlet
13:19ndimidukFossi, another servlet, or another web container?
13:20Fossindimiduk: just another servlet
13:20Fossione jetty is fine
13:30choffsteinis there a way to add an element to the back of a list?
13:31choffsteinthis seems like an easy google ... but I just can't find it...
13:33ataggartnot without rebuilding the list
13:34spewnchoffstein: If you were using a vector, conj would append to the end. Is there are reason you're using a list instead?
13:34stuarthallowayhugod: what is testbuild1-SNAPSHOT?
13:34choffsteinspewn -- 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:35TimMcchoffstein: concat?
13:35spewnTimMc: Wouldn't that make (1 2 3 4 5 6)?
13:35Chousukechoffstein: are you doing that in a macro?
13:35choffsteinChousuke: Yes.
13:35Chousukethen you might be able to use splicing
13:35amalloychoffstein: it's awkward for a reason: adding to the back of an immutable linked-list is not cheap
13:35TimMcspewn: Yes, I suppose so.
13:36amalloybut Chousuke is probably right
13:36choffsteinamalloy: I know ... you have to iterate the list.
13:36Chousuke,(let [a '(1 2 3)] `(1 2 3 ~a ~@a))
13:36TimMcspewn: Unless you wrap it first. :-)
13:36clojurebot(1 2 3 (1 2 3) 1 2 3)
13:36hugodstuarthalloway: org.clojure:clojure:jar:1.3.0-testbuild1-SNAPSHOT
13:36hugodon oss snapshots
13:36choffsteinhmm ... that might work.
13:36amalloyChousuke: fwiw that's just concat under the covers
13:37stuarthallowayhugod: do you have projects that are resolving dependencies to that
13:37Chousukeamalloy: yeah, but it's a bit simpler to use
13:37amalloyit's totally reasonable to use inside a macro though, cause the lists are going to be short (the user actually typed them in!)
13:37choffsteinYeah, the list is only 3 elements long...
13:37stuarthallowayhugod: the goal of releasing alphas is for you to have non-snapshot targets.
13:37hugodI depend on enlive, which uses a dependency range for clojure, which pulls it in
13:37stuarthallowayIf that isn't working for you, but something could be fixed to make it better, would like to do it
13:38choffsteinOkay, 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:38TimMcjkkramer: Any stable releases of loom?
13:38hugodmy dependencies are all clojure-1.2.0
13:39amalloyyou can't splice a gensym#
13:39jkkramerTimMc: 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:39hugodstuarthalloway: is it possible to remove the testbuilds?
13:39choffsteinamalloy: oh...didn't know that. Hmm ... (new to clojure, if you couldn't tell :))
13:39amalloyunless you have two levels of backticks in there somewhere, and only showed one?
13:39stuarthallowayhugod: just pinged stuartsierra and cemerick to ask that very question
13:39jkkramerTimMc: I don't plan on changing the API much, though
13:39choffsteinNope. Just one amalloy.
13:39hugodthanks
13:40amalloychoffstein: 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:40choffsteinamalloy: ah, that makes sense.
13:41choffsteinGotta get better at really understanding what exactly is going on with macros. Practice, practice, practice i guess...
13:41TimMcwassup, __name__?
13:41amalloyactually i don't understand why you have a gensym# outside of any backtick-scopes. that can't be working ro you
13:41amalloyfor
13:42hugodstuarthalloway: 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:42stuarthallowayhugod: working on the patch for it now
13:42hugod:)
13:42stuarthallowaybut would also love to know what we need to do to get people using 1.3 branch :-)
13:43stuarthallowayhugod: maven exclusions should be viable as a workaround
13:43choffsteinamalloy: https://gist.github.com/866348
13:43hugodstuarthalloway: exclusions don't seem to work
13:43stuarthallowayyikes
13:44technomancyexclusions in maven must be specified for every single dep that pulls clojure in
13:44choffsteinamalloy: warning -- I am very green on macros. This is my first macro ever.
13:44technomancy(but global exclusions were just added to Leiningen this morning.)
13:44amalloychoffstein: yeah, that's never going to work. try replacing it with (defmacro my-try [& args] (let [thing# args] thing#))
13:44choffsteinamalloy: but basically, I am trying to deconstruct a catch clause, inject some code using a do, and reconstruct it.
13:44choffsteinamalloy: it works now...
13:44TimMcjkkramer: Leiningen is going to yell at me if I try to make a non-SNAPSHOT release. :-P
13:44amalloyoh hm
13:44amalloy&(let [x# 1] x#)
13:44sexpbot⟹ 1
13:45amalloyhah, i guess # is legal in symbol names
13:45hugodtechnomancy: does that work when you dependencies are themselves using dependency ranges?
13:45TimMc&x#
13:45sexpbotjava.lang.Exception: Unable to resolve symbol: x# in this context
13:45choffsteinoh, does it work for all the wrong reasons?
13:45amalloybut don't do it outside of backtick scopes - they're usually used for gensumming
13:45amalloysymming
13:45choffsteinyeah...I was trying to gensym
13:45TimMc&(quote x#)
13:45sexpbot⟹ x#
13:45technomancyhugod: that's orthogonal, I think.
13:45TimMc&`x#
13:45sexpbot⟹ x__17725__auto__
13:45technomancyexclusions don't involve versions
13:46choffsteinLot's to learn here...
13:46hugodstuarthalloway: 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:47hugodtechnomancy: is that in lein HEAD?
13:47pjstadigpeople really need to respond to the ML thread instead of coming out of the woodwork after a decision has been made :)
13:47hugodI can't post on the dev list
13:47amalloy&(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:47technomancyhugod: yeah
13:47sexpbotjava.lang.SecurityException: You tripped the alarm! catch is bad!
13:47stuarthallowaypjstadig: working on your 1.2.1 patch now
13:48danlarkinyay
13:48amalloychoffstein: https://gist.github.com/866354 ?
13:49pjstadigstuarthalloway: thx :)
13:49amalloyoops, i missed a @ in there. gist updated
13:50amalloyand 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:50choffsteinamalloy: thanks, I'll take a look at that guy
13:52choffsteinamalloy: 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:52choffsteinbut I guess I don't need to, since the let's make everything local, huh?
13:55amalloyright, as long as you put them in the *macro* scope and not the expansion scope
13:55choffsteinexpansion scope being `?
13:55choffsteinI think I am getting this. Come on enlightenment, hit me!
13:56amalloychoffstein: the difference is between (let [x 1] `(+ ~x ~user-arg)) and `(let [x# 1] (+ x# ~user-arg))
13:57amalloyin the former, x belongs to your macro, and no trace of it will ever show up in the expansion
13:57amalloyin 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:58choffsteinamalloy: Awesome. That makes perfect sense.
13:58jkkramerTimMc: 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:58TimMcjkkramer: That would be awesome.
13:59choffsteinamalloy: 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:59TimMcNo 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:01choffsteinAh, whoops, didn't see those ~ on arglist
14:01amalloychoffstein: it obviously doesn't work? looks reasonable to me
14:01amalloyah
14:01amalloynor did i :P
14:02choffsteinWell, 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:02choffsteinThanks for all the help. I'll keep studying this bad boy.
14:02amalloyyou can avoid the (first arglist) with some destructuring: (defmacro my-try [execute-clause & more] ...)
14:03stuarthallowayhugod, pjstadig, danlarkin, technomancy, + anyone else wanting 1.2.1: please make sure http://dev.clojure.org/jira/browse/CLJ-754 looks right
14:03choffsteinhaha. love some good old refactoring :)
14:03amalloyrefactoring is my favorite vice. improve old code instead of writing new
14:08tsdhIs there something like a this pointer for functions?
14:08choffsteinIf 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:09tsdhchoffstein: Why not a possibly nested map?
14:09spewnstuarthalloway: Could we get https://github.com/clojure/clojure/commit/6d300332f810a68869c11ddfcc55f4439b70fdb3 ? Especially since http://clojure.org/special_forms assumes def can take a docstring.
14:09technomancystuarthalloway: excellent; thanks. giving it a go.
14:10technomancychoffstein: just use load-file.
14:10amalloychoffstein: yeah, just a hashmap
14:10amalloywrite it to a file, read it in, you're good to go
14:10choffsteinAnd just have the library user pass it in?
14:10stuarthallowayspewn: probably not. If we start doing enhancements on a past branch I don't know where to stop
14:11stuarthallowayalso makes the documentation more confusing, not less
14:11amalloyi 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:11amalloyjust like a yaml
14:11pjstadigstuarthalloway: you stop when you don't have a bug that has no user workaround
14:12stuarthallowaypjstadig: works for me, and excludes the suggested enhancement by definition
14:12pjstadigstuarthalloway: which enhancement?
14:12stuarthallowayhttps://github.com/clojure/clojure/commit/6d300332f810a68869c11ddfcc55f4439b70fdb3
14:13stuarthallowayproposed by spewn a few minutes ago
14:13pjstadigstuarthalloway: agreed probably not bugfix worthy
14:20tsdhHow 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:23amalloytsdh: that has no particular meaning, because anything nontrivial is nested within many layers of functions
14:24raek,((fn f [] (meta f)))
14:24clojurebotnil
14:24raek,(^{:a 1} (fn f [] (meta f)))
14:24clojurebot{:a 1}
14:25raektsdh: note that metadata on a function object and metadata on a var holding it is not the same thing
14:26tsdhI think, I can solve my problem in a better way. :-)
14:49simardis there a unique? predicate in clojure ? I would do: (defn unique? [coll x] (= nil (second (filter #(= % x) coll))))
14:49ieureWhat’s the recommended way to produce XML in Clojure? It seems that clojure.xml/emit is semi-deprecated.
14:49ieureclojure.contrib.lazy-xml/emit
14:49ieurePerhaps?
14:49amalloyieure: prxml?
14:50ieureamalloy, Seems reasonable, I’ll check it out.
14:50amalloyit's pretty convenient and flexible. it's what i used the one time i needed to make xml
14:50ieureI guess I have to rebind *out* to capture it as a string.
14:50amalloyieure: i think so, yeah. but you have with-out-str, so...
14:56brehautsimard: my best effort so far is (defn unique? [s x] (-> (get (group-by identity s) x) next nil?))
14:58amalloy(= 1 ((frequencies s) x))
14:58brehautbah :P
14:59amalloymeh. my version is wasting a lot of computational effort on data you don't care about
15:01simardyup
15:01simardwhat about mine ?
15:01simardanything wrong with it ?
15:01simardit's lazy, right ?
15:02choffsteinAny 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:03amalloychoffstein: use [x y] instead of '(x y)
15:03choffstein*slaps face*
15:03choffsteinreally?
15:04amalloysimard: 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:04TimMcSo, fail-fast.
15:04simardamalloy: well, yes that's as good as I can do I guess
15:04amalloychoffstein: 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:04TimMcBut all solutions have a best worst-case of O(n)
15:05choffsteinamalloy: i'll remember that. thanks.
15:05TimMcEr... "Best solution will be O(n)."
15:07choffsteinOkay ... 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:07raeksimard: I would write (= nil (second ...)) as (not (next ...))
15:07brehaut,(let [myinc (fn [x] (+ 1 x))] (map myinc [1 2 3]))
15:07clojurebot(2 3 4)
15:08brehautchoffstein: does that make sense?
15:08raekthen it also works for checking the uniqieness of nil
15:08choffsteinbrehaut: yeah, that makes perfect sense...but you are creating a function object.
15:08simardraek: nice, I'll change that
15:08choffsteinbrehaut: basically, I am trying to construct a list of dispatch functions
15:08choffsteinbrehaut: so I construct the list, and on a certain event, call all the functions
15:09brehautso for instnace you have [inc dec], and then later you want (map #(% arg) my-fns) ?
15:10choffsteinyeah
15:10TimMcJUXT
15:11brehautTimMc: probably :)
15:11brehautchoffstein: ##(let [fs (juxt inc dec)] (fs 1))
15:11sexpbot⟹ [2 0]
15:11TimMc,((juxt [* + - /]) 4 6)
15:11clojurebotjava.lang.IllegalArgumentException: Wrong number of args (2) passed to: PersistentVector
15:12choffsteinbrehaut: but let's say I have a ref to an empty vector -- how do I add 'inc' and 'dec' to that vector?
15:12TimMcbah
15:12TimMc,((juxt * + - /) 4 6)
15:12clojurebot[24 10 -2 2/3]
15:12brehautchoffstein: (def fs (ref [])) (dosync (alter rs conj inc dec))
15:13ieureNext question… Is there a simple way to create a WAR file from a Leiningen/Compojure project?
15:13TimMcieure: I think there's a lein-war plugin.
15:15brehautchoffstein: (def ref-juxt [r] (fn [& args] (dosync (map #(apply % args) @r)))) ; the dosync is kind of optional there
15:15choffsteinbrehaut: 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:16jcromartiehow does dosync work in the context of a lazy seq (map)
15:16brehautchoffstein: what do you mean 'variable function'?
15:16choffsteinbrehaut, so I could call (add-dispatch 'inc) or (add-dispatch #(+ 3 %))
15:17brehautyou dont need to quote in there
15:17brehauterr
15:17brehautinc
15:17ieureTimMc, Beautiful, thanks.
15:17brehaut(add-dispatch inc) would work just fine
15:17amalloybrehaut: in happened to work in context
15:17brehautamalloy: wait what?
15:17amalloyas in, "in that instance/function-call"
15:17choffsteinbrehaut: Really? Herm. Okay ... thanks.
15:18amalloyeven if you meant inc, in was a viable substitute, is what i meant
15:18brehautchoffstein: you want to pass the fn not the smybol right?
15:18choffsteinright
15:18stuartsierrastuartsierra has returned!
15:19stuarthallowaystuartsierra: so glad you are back, I have work for you :-)
15:20stuartsierrastuarthalloway: the correct response is "And there was much rejoicing."
15:20stuartsierra"And grousing about Maven."
15:21hiredmanand snicker about pictures where people grab their chins
15:21hiredmansnickering
15:22stuarthallowaystuartsierra: specifically, could you look at http://dev.clojure.org/jira/browse/CLJ-755
15:22stuarthallowaywhich is, in fact, about maven :-)
15:23choffsteinholy crap, my code works.
15:24brehautchoffstein: well done
15:24choffsteinbrehaut: thanks for the help
15:24stuartsierrastuarthalloway: mvn -Pdistribution package
15:24choffsteinclojure is blowing my mind.
15:25choffsteinI 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:25greghmacros are "hey! I can write bits of a compiler."
15:26stuarthallowaystuartsierra: did that run on Hudson? where do I grab the artifact?
15:26jweissanyone 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:27stuartsierrastuarthalloway: It doesn't run on Hudson by default. I can change that.
15:27stuarthallowaystuartsierra: that would be great, if not a lot of trouble
15:27stuartsierrano problem
15:27stuarthallowayotherwise people have to get the release build built from my laptop, which is gross
15:27jweissis this the current CA? https://github.com/weissjeffm/webui-framework/blob/unify/src/com/redhat/qe/logging.clj
15:27jweissdoh
15:27jweissi meant http://clojure.org/file/view/ca.pdf
15:28stuarthallowayjweiss: logging became its own top-level project this morning; https://github.com/clojure/tools.logging
15:28stuartsierrastuarthalloway: Just for release builds, right? Not snapshots.
15:28stuarthallowaystuartsierra: right. and with instructions for where I go to grab the bits
15:30stuarthallowaystuartsierra: is inclusion of the file "clojure.iml" by design?
15:31stuartsierrayes. I think I tried to include everything that was included in previous releases.
15:31jweissstuarthalloway: 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:31stuarthallowayjweiss: yes
15:31jweisswas that the right url for it?
15:31stuartsierraFYI, the definition of what goes in the ZIP is in src/assembly/distribution.xml
15:32stuarthallowayjweiss: yes
15:33jweissgreat, thx
15:38jweissi 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:39jweiss(from within clojure.contrib.logging or clojure.tools.logging
15:39ataggartstuarthalloway: 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:39ataggartjweiss: it's slow, that's why it's not used
15:39xkbany of you going to dyncon2011?
15:39stuarthallowayataggart: thanks
15:39jweissataggart: isn't that exactly what the loggers themselves do?
15:39stuarthallowayataggart: did you see you have a logging repo now?
15:39jweiss(if you use the location in your log config)
15:40ataggartstuarthalloway: what does "have" mean, and where would I see that?
15:40stuarthalloway:-)
15:40stuarthallowayAaron sent you a direct email
15:40stuarthallowayand copied the dev list
15:40stuarthallowayand it got mentioned here a few minutes ago: logging became its own top-level project this morning; https://github.com/clojure/tools.logging
15:40ataggartjweiss: if you configure it to do so, but it's rarely used due t the performance hit. Class:linenum usually suffices
15:41stuarthallowayand I just told you directly :-)
15:41ataggartheh
15:41jweissataggart: 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:43ataggartjweiss: ok, open an enhancement once you're able. Aside: j.u.l sucks.
15:43jweissbut I do see your point ataggart that using that patch will mean slowness all the time, not just when the formatter uses it
15:43jweissataggart: yeah i know, we've been using it just because it made one less dep
15:44jweisswith java code it worked fine. w clojure not so much.
15:44mlimotteI'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:44amalloymlimotte: coll.cons is polymorphic
15:45amalloyList implements it by adding to the front, Vector by adding at the end
15:46jweissataggart: afaik log4k does not support any metadata (aka params) in logs. j.u.l does
15:46jweisss/log4k/log4j
15:46sexpbot<jweiss> ataggart: afaik log4j does not support any metadata (aka params) in logs. j.u.l does
15:46mlimotteamalloy: thanks for the response. not sure i get it, though. i thought cons was always supposed to ad to the front.
15:47amalloymlimotte: (cons foo bar) doesn't call the collection's cons method
15:47amalloyit creates a new Cons object
15:47amalloy$source cons
15:47sexpbotcons is http://is.gd/yyphKM
15:49mlimotteamalloy: ahh, i see. "cons" on the collection class is really a "conj" implementation; and the cons fn is imlpemented in RT.
15:49mlimottethankks for the explanation.
15:50amalloyyeah. not an ideal state of affairs imo, but not *too* confusing once you realize
15:51mlimotteYea. Fine once you know it. I jumped to some conclusions based on names without reading all the code.
15:52ataggartstuarthalloway: CLJ-426 updated
15:58ataggartstuarthalloway: could you please provide an example to reproduce the errors with CLJ-445
16:00stuarthallowayataggart: not quickly or simply, but I will get to it
16:19TimMcSomeone please write a program prover (like ACL-2) in Clojure and call it "Conjecture". :-P
16:20companion_cube:D
16:20stuartsierrastuarthalloway: 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:21stuarthallowaystuartsierra: awesome
16:21stuarthallowayis that just a config change, or will you be sending me a patch
16:21stuartsierraJust Hudson config.
16:21stuartsierraWe won't really know if that works until the next release.
16:30abedrastuartsierra, can you give tools.logging a once over
16:30stuartsierrayes
16:30stuartsierraDeleting stuff in the -testbuild-SNAPSHOT chain on oss.sonatype.org.
16:30abedraok cool
16:40edbondhow to execute raw sql in clojureql?
16:41fliebelthanks for the alpha. are these fn meta changes in there?
16:45ataggartstuarthalloway: 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:45stuarthallowayataggart: ruling that out was my next todo item
16:47ataggartstuarthalloway: having nothing better to do, I'll make a patch with those overloads put back in place.
16:48fliebeldnolen: ping
16:48dnolenfliebel: hullo
16:49fliebeldnolen: 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:49fliebel(just randomly trying that)
16:50stuartsierraabedra: There's more in the pom.xml than you need.
16:50dnolenfliebel: 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:50stuarthallowaystuartsierra, abedra: make sure what's needed is documented somehere, I will be trying to promote jmx over the weekend
16:50fliebeldnolen: Totally cool, I was just checking out :)
16:52stuartsierrastuarthalloway: should all be on the wiki, which just stopped responding again
16:53dnolenfliebel: 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:55fliebeldnolen: Interesting, I love lasy seqs :) What was the name of the paper you mentioned again? I might want to read it tomorrow.
16:56dnolenfliebel: http://pqdtopen.proquest.com/#abstract?dispub=3380156
16:56stuartsierraWow. Old Contrib managed to crash the JVM. http://build.clojure.org/job/clojure-contrib/339/org.clojure.contrib$condition/console
16:57fliebeldnolen: Thanks… Whoa! that is a lot of dead tree to read.
16:58stuartsierrastuarthalloway: http://dev.clojure.org/display/design/How+to+Create+New+Contrib+Projects
16:58dnolenfliebel: 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:58dnolenfliebel: you only need to read Part I to understand how it works.
16:59stuarthallowaystuartsierra: 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:00stuartsierrastuarthalloway: We never had 1.2.* builds releasing directly to a public Maven repository.
17:00stuarthallowayno, the hudson stuff
17:00stuartsierraI don't think there was anything special in Hudson.
17:00stuarthallowayit is calling mvn:deploy under the covers in ant
17:01stuarthallowayI was thinking some sort of ssh config thing
17:01stuartsierraYes...
17:01stuartsierraIt deployed to build.clojure.org
17:01stuartsierraVia SCP.
17:01stuarthallowaynot working on my box atm. Gotta go, will try again tonight
17:01stuartsierra'k
17:03fliebeldnolen: 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:04dnolenfliebel: ? Clojure relies just as heavily on recursion, it does so itself with lazy-sequences.
17:04fliebeldnolen: I know, I know...
17:05fliebelHm, not recursion maybe then, but something… Oh, well, nvm.
17:08dnolenfliebel: 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:27TimMcdnolen: Then why not one of the Schemes?
17:27dnolenTimMc: lack of persistent datastructures, lack of good concurrency story.
17:28TimMc*nod*
17:28dnolenboth of these things contribute to how fast Logos is and can be.
17:38puredanger&(.equals Double/NaN Double/NaN)
17:38sexpbot⟹ true
17:38puredanger&(= Double/NaN Double/NaN)
17:38sexpbot⟹ false
17:38puredangeranyone know what's up with that?
17:39dnolen&(== Double/NaN Double/NaN)
17:39sexpbot⟹ false
17:39dnolen&(identical? Double/NaN Double/NaN)
17:39sexpbot⟹ false
17:41dnolenpuredanger: that's Java, NAN is not equal to itself.
17:41dnolenpuredanger: http://www.concentric.net/~ttwang/tech/javafloat.htm
17:41puredangerdnolen: shame on me :)
17:42puredangerand Java can suck it
17:42stuartsierraI think that's part of the floating-point spec.
17:43stuartsierraJava .equals is object-identity, Clojure's = on a Number dispatches to clojure.lang.Numbers, which eventually uses the Java == operator.
17:44tsdhIs there a function that finds the first item matching some predicate in a possibly nested seq?
17:44puredangerfloating-point also can suck it :)
17:45stuartsierraheh
17:45stuartsierratsdh: try 'some' and 'flatten'
17:45puredangersorry...long Friday afternoon implementing inadequately specified specs has made me grumpy :)
17:45tsdhstuartsierra: thanks
18:02Tomsik_Hi
18:02Tomsik_I'm new to both clojure and java, how do I .add this createHorizontalStrut thing?
18:03Tomsik_http://download.oracle.com/javase/1.3/docs/api/javax/swing/Box.html#createHorizontalStrut(int) this thing
18:04brehaut(javax.swing.Box/createHorizontalStrut 1)
18:05longfin(Class/static-method args)
18:05Tomsik_Oh, I see.
18:06Tomsik_Thanks :)
18:06Tomsik_Is there a shorter way to write it?
18:07brehaut(import javax.swing.Box) (Box/createHorizontalStrut 1)
18:07Tomsik_Ah, like with these constants
18:09brehautTomsik_: http://clojure.org/java_interop
18:13longfinis there suitable java lib for simple clojure interop demo?
18:14stuartsierralongfin: String and Math aren't bad.
18:15longfinhm.. thanks.
18:15stuartsierraEven Swing leads to some nice examples
18:16stuartsierrahttp://stuartsierra.com/tag/swing
18:16longfinIt's cool.
18:20raekanyone know why clojure-mode highlights some symbols in (for me) green? it happens for: "deftest", "join" and "list-model"
18:22hiredmanlist-model is most likely because list* is in some list without the * being escaped
18:22hiredman(some list of symbols in clojure-mode)
18:23mattmitchelli'm going to attempt using jparsec in clojure, using this tutorial: http://docs.codehaus.org/display/JPARSEC/jparsec2+Tutorial
18:24mattmitchelli just don't know how to do "implements" in clojure!
18:25amalloymattmitchell: reify
18:26mattmitchellamalloy: ok i'll check it out
18:26amalloy&(doc reify)
18:26sexpbot⟹ "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:26amalloyblech. formatting is terrible for that; use your repl
18:27mattmitchellamalloy: ha ok np
18:27mattmitchellamalloy: so something like this:
18:27mattmitchellenum BinaryOperator implements Binary<Double> {}
18:27mattmitchellis possible?
18:27amalloyi don't think clojure has a way to declare enum types
18:27mattmitchellok
18:27amalloyand certainly not to do this Generics stuff which doesn't really exist at the bytecode level
18:28mattmitchellamalloy: ok. you think maybe a bad fit for clojure?
18:28amalloyso you'd really be writing class BinaryOperator implements Binary { public Double perform(Double, Double) {...}}
18:28amalloymattmitchell: it's not the sweet spot for sure, but it's not impossible either
18:28clojurebotPardon?
18:29mattmitchellok cool. good to know.
18:29hiredmanyou should look at how clojure.lang.Numbers does it
18:31hiredman(some list of symbols in clojure-mode)
18:31hiredmanwhoops
18:38KirinDaveDoes 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:38KirinDaveI have a friend who's curious and I don't have time to go over it with him this weekend.
18:38brehautKirinDave: Stuart Halloway's clj conj presentation about 'Simple' might cover some of it?
18:40KirinDavebrehaut: got a link? Google is being unhelpful to me
18:40brehautlet me dig
18:42brehautKirinDave: heres the slides https://github.com/downloads/stuarthalloway/clojure-presentations/Clojure-Simplicity.pdf http://clojure.blip.tv/file/4824610/
18:42KirinDavety
18:45amalloyKirinDave: just google for "clojure simple". how many people can there be who think clojure is simple? :)
18:45KirinDaveamalloy: Ha.
18:45KirinDaveamalloy: The boolean opeartors; they do nothing!
18:46amalloy&(= 1)
18:46sexpbot⟹ true
19:28TimMc,((juxt #(.equals %1 %2) identical? = ==) Double/NaN Double/NaN)
19:28clojurebot[true false false false]
19:28TimMcWhat I don't understand about that is why identical? gives a different result than .equals
19:32TimMcBoth c.l.Util/equiv and c.l.Util/identical use Java's == as a first check.
19:33TimMcand Clojure's = uses Util/equiv
19:40tomoj"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:40tomojhttp://download.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html#equals(java.lang.Object)
19:44TimMcOh.... Double.NaN is a primitive?
19:44TimMcYes, it is.
19:44TimMcThat's what I was missing.
19:45TimMc,(#(identical? % %) (Double. Double/NaN))
19:45clojurebottrue
19:46tomojwait, wat?
19:47tomojso in java `Double.NaN == Double.NaN` is false, but `new Double(Double.NaN) == new Double(Double.NaN)` is true?
19:49amalloytomoj: certainly it won't be true if you use == instead of .equals :P
19:50TimMctomoj: ##(identical? (Double. Double/NaN) (Double. Double/NaN))
19:50sexpbot⟹ false
19:50tomojoh, missed that it was the same Double up there
19:51TimMc,(#(.equals % %) (Double. Double/NaN))
19:51clojurebottrue
19:51TimMc,(#(= % %) (Double. Double/NaN))
19:51clojurebottrue
19:51TimMc,(#(== % %) (Double. Double/NaN))
19:51clojurebotfalse
19:51tomojcrazy
19:59chouserhm, that == might be a bug.
20:11ataggartNaNs are not well supported
20:13ataggarthttp://dev.clojure.org/jira/browse/CLJ-738
20:15TimMcchouser: Java doesn't think so.
20:29chouserTimMc: == is not Java .equals, though.
20:30chouser& (.equals 5 5.0)
20:30sexpbot⟹ false
20:30chouser& (= 5 5.0)
20:30sexpbot⟹ true
20:30chouser& (== 5 5.0)
20:30sexpbot⟹ true
20:55ataggart& (= (Long. 5) (Double. 5.0))
20:55sexpbotjava.lang.IllegalArgumentException: No matching ctor found for class java.lang.Long
21:22sritchie_hey all -- if I have a series of nested maps, like this -- (def test-map {:first {:ffirst true} :second {:fsecond false}})
21:23sritchie_is there a function like (nested-replace {:ffirst false}), or something, that would recursively find and replace some map entry, or return nil?
21:23sritchie_I don't ever need to add anything new, here
21:24brehaut&(assoc-in {:a {:b 1} :c 2} [:a :b] 3)
21:24sexpbot⟹ {:a {:b 3}, :c 2}
21:24brehautits not quite what you want
21:26sritchie_brehaut: I like assoc-in, but let me explain what I'm trying to do --
21:26sritchie_I've got three configuration files, with options split between each
21:27sritchie_I want the user to be able to specify configuration options, without specifying which file they live in, and replace defaults
21:27brehauti think you want a recursive merge-with
21:27sritchie_yes
21:27brehautdetails are left as an exercise for the reader :P
21:28sritchie_you would have written it in the margins of the IRC chat, but there wasn't enough space
21:28sritchie_anddd dead.
21:28sritchie_sorry, not predicting your demise, there
21:28brehauthaha
21:28ieureIs there some way to get at the contents of my project.clj from inside my app?
21:36stuartsierraieure: not unless you open the file
21:36stuartsierraand read it like any other file.
22:14tufflaxIs there a better way to do (assoc a-vector an-index (inc (the-same-vector the-same-index)))?
22:16tufflaxHm, (update-in the-vector [the-index] inc) maybe
22:17danlarkinupdate-in is the greatest
22:19tufflaxhehe
22:26tufflaxWhat's the best way to create a vector of only zeros of length n? (vec (take n (cycle [0])))?
22:37mlimotteHi. 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:43sattvikmlimotte: I think that is the 'correct' result given floating point mathematics.
22:44sattviktufflax: You can try (vec (repeat n 0))
22:45tufflaxmlimotte 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:45tufflaxsattvik thanks
22:49mlimotteStill, 3.9 should work. And this example does work: (/ (math/round (* 10 (+ 7.9 -4.0))) 10.0)
22:51tufflaxWhat is the result of (/ (math/round (* 10 (+ 7.9 -4.0))) 10.0)?
22:52sattvikmlimotte: 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:53tufflaxsattvik how come (def a 3.9) and then asking for a gives 3.9 then? :P
22:54tufflaxoh, you said 7.9, but same thing
22:56sattvikWell, 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:58sattvikThe two numbers are off by the smallest possible difference between those two numbers in double precision floating point arithmetic.
22:58mlimottei see. so what's best practice? The multiply-round-divide trick? Or Use BigMath? Or is there something else?
22:59tufflaxmlimotte try to use integers if you can, that's the best thing you can do
22:59sattvikWell, that depends on your application. For something like money, don't use floating point, stick to integers.
22:59tufflaxOtherwise when comparing doubles, allow for some small error
23:00mlimottealright. thanks for the insights.
23:01tufflaxor maybe ratios :)
23:04sattvik,(+ 79/10 -4)
23:04clojurebot39/10
23:04sattvik,(+ 7.9M -4)
23:04clojurebot3.9M
23:09pdk,3.9
23:09clojurebot3.9
23:09pdk,7.9
23:09clojurebot7.9
23:11tufflaxfinally after some staring at that page you linked to sattvik i understand what's going on :P
23:11pdkdo tell, link it up
23:12tufflaxhttp://www.ecs.umass.edu/ece/koren/arith/simulator/FPAdd/ was the page
23:13tufflax3 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:16tufflaxnot the best explaination, but look at the page :P
23:25tufflaxor 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