#clojure logs

2010-07-24

00:29SandGorgonany examples of nifty web apps using clojure ? (I have already taken a look at cow-blog and compojure)
00:39TakeVAre there any other books out there on Clojure, aside from Mr. Halloway's awesome book?
00:55slyruschouser: earlier we were talking about the "type" that extend takes and you said that it's a type/class/interface. can it extend a protocol?
01:31slyrusok, here's the situation I find myself in repeatedly. I define a protocol. I have some "low-level" issues that are handled by, say, a defrecord, then I want to define some operations that work on objects that implement that protocol. I can just have these operations be defns, or I can extend the original protocol and the defrecord to match. Is there anything "in between", like defining...
01:31slyrus...methods that act on all objects that implement the protocol -- not just ones tied to this particular defrecord??
01:32mmarczykslyrus: protocols are backed by interfaces -- see (:on-interface the-interface)
01:33slyrusyeah, but I couldn't seem to make extend extend a protocol. not sure what I'm doing wrong tho.
01:33mmarczykyou wouldn't extend a protocol, but the underlying interface
01:33mmarczyk(defprotocol Foo (foo [this])) -> (extend-type user.Foo ...)
01:33mmarczykuser.Foo as opposed to user/Foo
01:34slyrusoh, I see. brain hurts more.
01:34mmarczykI suppose you could do (defprotocol FooExt ...)
01:34mmarczykand (extend-protocol FooExt Object ...) / (extend-type Object FooExt ...)
01:34mmarczykwhere all impls would use methods from Foo
01:35mmarczykbtw, I was looking at shortcut and got quite excited actually :-)
01:36slyrusah, glad to hear it. i've gone and broken everything though :)
01:36slyrusgit reset --hard to the rescue!
01:36mmarczykhopefully I might be able to use it or perhaps add an algorithm or two and then use it... note I'm not too sure what I'm doing yet ;-)
01:36mmarczykohhhh
01:37mmarczykslyrus: on a second thought, I guess I'd go with regular defns for functions on "anything which implements Foo"
01:39slyrusthere's a way to declare the type of defn args in defn lambda-lists -- um I mean lambda-vecs or whatever they're called in this newfangled lispish --, right?
01:39mmarczykyou can type-hint defn args, yes
01:40mmarczyksee e.g. (source subs)
01:40mmarczykthat's clojure.contrib.repl-utils/source
01:40Lajla((fn [] "I Worship His Thunk))
01:40Lajla,((fn [] "I Worship His Thunk))
01:40clojurebotLajla: Pardon?
01:41Lajlammarczyk, why not?
01:41slyrusmmarczyk: c.c.subs too :)
01:41mmarczykslyrus: hm?
01:41Lajlaslyrus, what wrongs have I wroth upon this bot for her to defy me?
01:42slyrusoh, never mind
01:42LajlaPerhaps hers was the shadow for me to have worshipped.
01:42replacaLajla: you forgot the closing quote
01:42LajlaAhh
01:42LajlaCool
01:42slyrusI thought you were saying it is was c.c.r-u/subs
01:42Lajla,((fn [] "I Worship His Thunk"))
01:42clojurebotLajla: Gabh mo leithscéal?
01:43replacathat oughta work
01:43Lajlaslyrus any more suggestions
01:43Lajlareplaca, you try it.
01:43LajlaI think they hooked the bot upt o ignore me.
01:43replaca,((fn [] "Hello there"))
01:43clojurebot"Hello there"
01:43Lajla,((fn [] "Hello there"))
01:43clojurebotLajla: I don't understand.
01:43LajlaOeh
01:44replacahah!
01:44LajlaThough, in the name os science, I must try this at least 400 times to test if it is reproducible.
01:44Lajlareplaca, be my control group.
01:44LajlaGogogo
01:44Lajla,((fn [] "1"))
01:44clojurebotLajla: It's greek to me.
01:46slyrusok, as I was saying... defprotocol + type-hinted defns is probably what I was looking for
01:48Lajla,,
01:48clojurebotLajla: Huh?
01:48Lajla,
01:48clojurebotLajla: Excuse me?
01:48Lajla ,
01:48Lajla,
01:48clojurebotLajla: Huh?
01:48LajlaAHA
01:48LajlaI have you now.
01:49LajlaYour mind is as an open book to me.
01:51mmarczykslyrus: I wonder how much is the type hint buying you
01:52slyruspeace-of-mind :)
01:52mmarczykslyrus: I mean, if you've got a protocol extended to, say, IPersistentMap
01:52mmarczykthen a type hint on a function which is to operate on such maps with the protocol functions
01:52mmarczykis just... wrong
01:53mmarczykI mean, IPersistentMap instances are not of type user.Foo, even if you extended user/Foo to IPersistentMap
01:53mmarczyknothing will break with the hint afaict
01:53slyrushrm... I see.
01:53mmarczykbut it's just not clear to me if there's any gain
01:54slyrusI think I'm doing something a bit different. take a look at: (defn neighbors [^EdgeSet v node] (map #(first (neighbors % node)) (vals (edges v node))))
01:54mmarczyknow if you had a method called foo
01:54mmarczykand called it as (.foo ... ), not (foo ... )
01:54mmarczykthen there would be a difference
01:55mmarczykbut you can't use (.foo ...) with extend*
01:55slyrusyes, v is likely to be an IPersistentMap, but I'm calling (edges v node) on it. these are methods of the NodeSet protocol, not IPersistentMap.
01:56slyrusand the idea is that this would work on another implementation of NodeSet, one that didn't use IPersistentMap. Am I missing something obvious here?
01:56mmarczykwell, type hints are for avoiding reflection
01:57slyrusoh, I thought there might be some type checking going on.
01:57slyrusok, maybe this should just be an unhinted defn.
01:57mmarczykas I said above, the ^EdgeSet type hint is actually misleading the compiler
01:57Lajlammarczyk, accordingly Sigmund freud your hooking up of that bot to ignore me is the manifestation of a subconscious desire of yours to ban me, hit me and tell me that I'm insane and should have a talk with Signund Freud.
01:57slyrusmy puny brain is still wired for CLOS' defgeneric and defmethod.
01:58mmarczykbecause type hints have to do with Java types and reflection
01:58mmarczyk:-)
01:59mmarczyktry
01:59slyrusi don't suppose defmulti helps here?
01:59tomojclojure is leaky though :(
01:59mmarczyk(defprotocol PFoo (foo [this]))
01:59mmarczyk(defrecord RFoo [] PFoo (foo [this] :foo))
01:59mmarczyk(defn bar [^PFoo x] (.foo x))
01:59mmarczyk(defn baz [x] (.foo x))
01:59mmarczykoh
02:00mmarczykonly you need
02:00mmarczyk(set! *warn-on-reflection* true)
02:00mmarczykbefore all that
02:00mmarczykso now (bar "asdf") and (baz "asdf") give different error messages
02:01slyrusUnable to resolve classname: PFoo
02:01mmarczykactually it's probably going to be user.PFoo
02:01slyrusI see...
02:02mmarczykyou'd need to (import user.PFoo) to leave off the package
02:02slyrusyechh...
02:02mmarczykthen baz compiles with a reflection warning
02:02mmarczykand (bar "asdf") attempts a cast of String to PFoo (and fails)
02:02mmarczykwhereas (baz "asdf") uses reflection to determine if (.foo "adsf") makes sense
02:02mmarczykand still fails, but differently ;-)
02:03mmarczyknow
02:03mmarczyk(defn bar* [^user.PFoo x] (foo x))
02:03mmarczyk(defn baz* [x] (foo x))
02:03mmarczykand there's no difference between (bar* "asdf") and (baz* "asdf")
02:04mmarczyk(that I know of)
02:04mmarczykslyrus: about defmulti... why'd you want to use it?
02:05mmarczykif you want to write a function dealing with EdgeSet instances, just document it as such and call EdgeSet methods
02:05KaaliWhat does the function* naming convention mean?
02:05slyrussure, but the idea is that if i have a function like neighbors then somebody else might come along with a different graph implementation and write an appropriate neighbors function.
02:06mmarczykKaali: no single established meaning, here it was meant as "a variant of"
02:06Kaalimmarczyk: Okay, thanks
02:07mmarczykslyrus: ah, then sure, either a protocol or a multimethod will do
02:13mmarczyka multimethod might be more flexible...
02:43slyrusOk, here's an issue. I've got a protocol, I extend-protocol a primitive type (IPersistentMap) and I want to have a function/method that works on that. Then I have a different defrecord, I want the same-named function/method to work on that. In this case it's the neighbors function. How can I do that?
02:47Chousukeslyrus: just implement the protocol directly in the record definition
02:48Chousukeslyrus: it should be preferred over the more generic implementation
05:30esjFresh MEAP !
05:31Raynesesj: I beat you to it.
05:31Raynes:D
06:10BahmanHi all!
06:13lypanovi start to wonder if the words i don't know of in the
06:13lypanov... clojure books are real words, or typos
06:23tomojlike what?
06:52zmyrgelcould somebody explain briefly whats the difference between defn and defn-
06:52zmyrgelthe non-public def is mystery to me
06:53hiredmanwhat's mysterious about it?
06:54zmyrgelso with defn- I make non-public functions which I can't access from ... somewhere or what?
06:54hiredmancan't access from outside of the namespace where they are def'ed
06:55zmyrgelah
07:52candellerhi, why does the split function return an empty string at the beginning (I want to split on every character) (split "abcde" #"") #=> ("" "a" "b" "c" "d" "e"), isnt that a bug?
07:53candeller(seq str) is ok, but (seq (.split str #"")) isnt
07:54candeller(seq (.split #"" str))*
08:02rubydiamondguys.. getting this error Exception in thread "main" java.io.FileNotFoundException: Could not locate ring/adapter/jetty__init.class or ring/adapter/jetty.clj on classpath: (run.clj:0)
08:03rubydiamondafter running clj script/run.clj
08:03rubydiamondam I missing something
08:03rubydiamondI have followed http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html
08:04RaynesThat means that jetty is not on your classpath.
08:04rubydiamondRaynes: but that tutorial does not mention about classpath
08:05rubydiamondRaynes: also I have 18 jars in lib folder..
08:05RaynesThat is because Leiningen should handle the classpath for you.
08:05rubydiamonddoes it mean .. I have to manully add those classpaths
08:05rubydiamondRaynes: but I am directly running clj without leign
08:05rubydiamondlein*
08:06Raynesrubydiamond: Your clj script should be adding lib/* to the classpath. You should be able to do this: java -cp "lib/*:src" clojure.main script/run.clj
08:07Rayneser, java -cp "lib/*:script" I guess. Whatever needs to be added to the classpath. :p
08:07RaynesAh yeah, it's "lib/*:src/"
08:08RaynesWasn't sure where the tutorial was putting that stuff.
08:08rubydiamondhmm
08:13rubydiamondRaynes: Exception in thread "main" java.lang.Exception: Unable to resolve symbol: a in this context (core.clj:17)
08:14RaynesThat sounds like a bug in the tutorial.
08:14rubydiamondhmm.
08:15rubydiamondRaynes: if you could please try this tutorial..
09:04Rayneschouser: ping
09:56lozhCan anyone see a way to simplify rgb-to-key-colour in http://clojure.pastebin.com/ppuZgdLV get the feeling I'm missing something
09:58raekooh, enlive uses tagsoup...
10:01raeklozh: sort-by comes to my mind
10:02raekand use #(nth % 0) as the keyfn
10:02lozhthankyou
10:02raekhrm, is sort lazy, btw?
10:03raekalso, when the function you pass to map is getting big, consider using for
10:03Raynes-> (type (sort [1 2 3]))
10:03sexpbot=> clojure.lang.ArraySeq
10:06lozhmin-key looks like it should be useful, but I can't figure out how to apply it to a collection
10:07lozh,(min-key (fn [x] (-5 x)) 1 2 3)
10:07clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
10:07lozh,(min-key (fn [x] (- 5 x)) 1 2 3)
10:07clojurebot3
10:08lozhbut I'd like that to be '(1 2 3) as the last argument
10:09rhudson,(apply min-key #(- 5 %) [1 2 3])
10:09clojurebot3
10:10lozhcool, thanks
10:10raeklozh: the rgb-distance-squared doesn't return anything
10:10lozhit does now, sorry, I missed the end off
10:11lozhhttp://clojure.pastebin.com/GABaaeGB
10:13lozhhttp://clojure.pastebin.com/BMdZsJwW using that min-key trick, very nice, thanks
10:15Rayneslozh: You know, gist.github.com and paste.pocoo.org have Clojure-specific highlighting.
10:15lozhI didn't, I was wondering about that, thanks again
10:16Rayneslozh: There are several more that do as well. hpaste.org (I think), ideone (this one can also run your code, but last time I checked, highlighting was a little broken), and probably more.
10:19raeklozh: http://clojure.pastebin.com/idHfFnvE
10:19raekoh
10:20lozhThat's nice too
10:20raekthe min-key is nicer...
10:20raekjust my 2 öre
10:20lozhIt's all a good way to learn the standard libraries though
10:20raekyeah
10:20rhudsonYou can shorten the rgb-distance-squared, if you like, to something like (defn dx2 [c1 c2] (->> (map - c1 c2) (map #(* % %) (reduce +))
10:21rhudsonoops, should be (map #(* % %))
10:21lozhneat
10:22mfexlozh: (-> (sort-by (fn [[k v]] [(rgb-distance-squared rgb-color k) v]) colour-map) first val)
10:23raekthat reminds me of the coordinates-as-maps addition: (merge-with + {:x 1, :y 2} {:x 3, :y 4})
10:24raekthat even works for adding two and three-dimensional vectors (asuming z=0 if not given)
10:25lozhthanks mfex, amazing how many ways it can be done
10:27rhudson-> and ->> are two of the coolest most useful macros in Clojure. I've wondered if they have precedent in older Lispy langs.
10:27sexpbotjava.lang.Exception: Can't take value of a macro: #'clojure.core/and
10:28rhudsonsexpbot I wasn't talking to you
10:31raektutorial.scrape1> (hn-headlines)
10:31raek("Developing and Deploying a Simple Clojure Web Application" ...)
10:32raekwhat are the odds?
10:32dnolen_raek: :)
10:34mfexlozh: this is a bit better than my first suggestion (-> (sort-by #(rgb-distance-squared rgb-color (key %)) colour-map) first val)
10:35raekwhat package is 'cljcp' a part of?
10:37lozhmfex I went for (colour-map (apply min-key (partial rgb-distance-squared rgb-colour) (keys colour-map)) in the end, thanks :)
10:38raekdnolen_: I think your clj script fills the gap between leiningen project management and launching scripts from the command line pretty well
10:39Raynesrhudson: sexpbot apologizes. -> is the new code-evaluation prefix. It's the only thing I could think of that's easy to remember and type that nobody will type in a channel and set it off accidentally. Guess I failed on the latter though. But that has only happened just this once so far. ;)
10:39mfexlozh: I was hoping to find something called "best" or something that combines sort-by and first, to no avail so far
10:39dnolen_raek: my clj script?
10:39rhudsonRaynes, no problem; I realized that's what was going on.
10:40raekoh... wrong person
10:40raekwas reading your enlive tutorial in the other tab
10:40lozhI know min-key does at most one comparison per value in the key-colours map, not sure if sort-by will be the same
10:45mfexmin-key is the "best" function I was looking for
10:45patrkriswhat is the easiest way to get a 'submap' B from a map A, specifying in a seq which keys to include from A?
10:46lozhheh :)
10:48mfexlozh then you can just do (val (apply min-key ...)) no need for the (colours-map ... (keys colours-map))
10:50rhudsonpatrkris: look at clojure.set/project
10:50lozhpatrkris: select-keys (http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/select-keys)
10:50rhudsonah, that looks better
10:50lozhmfex: cool, thanks for that
10:51patrkrislozh: ah, marvelous - thanks
10:51patrkrisi knew there had to be a function to do that
10:53raekI get this when using enlive: (fetch-url "http://clojure.org/contributing") => ({:tag :html, :attrs nil, :content ({:tag :body, :attrs nil, :content nil})})
10:53raekanyone know why?
10:54raekthe fetch-url call becomes (html/html-resource (java.net.URL. "http://clojure.org/contributing"))
10:57raekit works for other sites, but the contributing site seems to be empty for enlive
10:58raekmaybe this is a tagsoup issue, or due to badly configured content negotiation
11:07BahmanHi all!
11:12raekhi
11:23lozhis there an easy way to get for to create a map?
11:25jkkramer,(into {} (for [i (range 5)] [i (* i i)]))
11:25clojurebot{0 0, 1 1, 2 4, 3 9, 4 16}
11:25lozhcool, thanks
11:36KaaliHi everyone, I made a small web form validation library as a practice project on Clojure. http://github.com/Kaali/pour -- I wanted to use assert-args included in Clojure, but it's a private fn. Was it okay for me to copy it to a file with the copyright from Clojure's core.clj included and also Rich Hickey's copyright included in the README?
11:37Chousukeit's under the EPL, right?
11:37Chousukethen it's fine.
11:38KaaliYeah it's under EPL. I figured it would be fine, but it's always good to make sure.
11:51raekKaali: nice library
11:52raekah, it does conversion/normalization too!
12:10Kaaliraek: Thanks, it's first piece of Clojure I have written (except for some SICP excercices). I guess it needs some cleanup and code review. And more validations/conversions.
12:11edbondhow to return first non-nil from seq or nil?
12:11raek(first (filter identity the-seq))
12:12raekor (first (remove nil? the-seq))
12:12raekthe latter treats false distinct from nil
12:14raekKaali: will the requirements of a field always come in [validator-fn error-text] pairs?
12:15KaaliYes
12:16KaaliI had no idea how to approach multi-lingual support, so I though that the explicit error-text is a close enough solution. That's why the validators don't output messages at all.
12:17raeksounds resonable to me
12:17raektranslation is often done as some enlgish-to-other-language mapping, I think
12:17KaaliBut I guess the inner vectors could be removed from the syntax, as they provide no real value vs. just partitioning the outer vector.
12:18raekclojure forms often leave out the "inner vectors": (cond a b c d e f) (let [a b c d e f])
12:19KaaliI actually tried to remove them, but partition converted them to a list, which somehow broke it; but that's just me being a Clojure newbie.
12:19raek(*if* your goal is to mimic clojure syntax as closely as possible, then :password [required "Password is required" (minimum-length 5) "Password should be at least 5 chars long"] could be considered)
12:19raekah
12:20KaaliYeah, that's what I was trying to do, but gave up for now.
12:20raekjust don't get me wrong. I it's really great that you've made this lib
12:20KaaliComments are always welcome, no problem at all.
12:20raekthere shouln't be any problem to use partition in this case
12:22KaaliYeah, I should try it again. I guess the problems I had, had something to do with macros. I might be a bit more wiser now...
12:22raekhttp://gist.github.com/446760 <-- example of a macro that uses partition
12:23KaaliSorry for the lack of comments or documentation, and also the lack of tests. Those are on my TODO list.
12:24raekhow is "pour" pronounced?
12:24Kaalihttp://www.merriam-webster.com/dictionary/pour
12:24raeklike the english word=
12:24KaaliYup
12:25KaaliIt's really an anagram of a finnish name, but matched with english.
12:33raekKaali: instead of (map (fn [item] ...) coll), try (for [item coll] ...)
12:33jliare there many people here who are more used to strongly-typed functional languages? common lisp was my first functional language, but I've been doing OCaml and Haskell for the past couple of years, and I'm just learning Clojure now
12:35Kaaliraek: Yeah, it seems to be a cleaner version of what I do with map all the time.
12:35dnolen_Kaali: pour looks sweet. Nice name too.
12:36Kaalidnolen_: Thanks
12:39raekKaali: do you want me to look into this no-inner-vectors thing?
12:40raekI would want that syntax myself
12:40raekand if it aslo were your original intension...
12:40Kaaliraek: I'm trying to solve it right now, but go ahead.
12:40rhudsonjli: I wouldn't say more used to, but Haskell was my first FP lang, and I'd looked into OCaml (and Scala) before falling in love with Clojure
12:41jlirhudson: hm, okay. how much did you like Haskell?
12:42rhudsonI liked lots of things about it, never really liked its story about state & side-effects
12:42jliyeah, I know what you mean
12:43jliI think I appreciate it, but don't really want to be forced to use it
12:44Kaaliraek: I'll go off for a while, seems like my friends car which he lend to me, might be stolen. Fun.
12:44rhudsonI understand why it is the way it is, and I think it's a tremendous intellectual achievement
12:44raekKaali: this could be useful to have in the library (defn pred-to-validator [pred] (fn [x] (when (pred x) x)))
12:45Kaaliraek: Yeah, I though about that too. Thanks for the note, it means that it should be added.
12:45jlirhudson: yeah, exactly. I think it's just too intellectually challenging to write in :)
12:46rhudsonjli, that was my feeling. I'm so impressed with Clojure's story about state -- to my mind it's just a rigorous, but a lot easier to reason about
12:46rhudson[just a => just as]
12:47rhudsoni.e. a lot easier to write code in!
12:48jliyeah, I haven't done anything with it yet
12:49Kaaliraek: Back again, false alarm about the car.
12:50rhudsonI think you might really enjoy it. Clojure is such a gem of language design, very clean, very usable, very powerful
12:50Kaaliraek: If you wish, you can fork the project and push changes to me, I'll gladly merge them.
12:51jlirhudson: yeah, I'm liking it so far. I'm just afraid that I'm too used to strong typing now. we'll see
12:51raekso nil always means "validation failed"?
12:51KaaliYes
12:53KaaliI thought about using exceptions, as those wouldn't block any return values. But it might make the validator interface a bit more complex.
12:53raekone can use a special sentinel value, such as a let'ed (Object.) or perhaps ::invalid
12:54KaaliAt first I used :error, but I thought it could clash if someone wanted to convert to a keyword.
12:55rhudsonjli, I gave up on Scala because I spent more time getting the type decls right than the actual program logic. "Yes Mr Compiler, I know what I'm doing."
12:55raekusing namespace qualified keywords works as long noone tries to use the keywords of your namespace
12:56raek:pour.core/error
12:57raeknamespaced keywords are made for avoiding clashes
12:57jlirhudson: yeah, you have to sort of think in a "typed" way, but I feel like once you get used to it, you get a lot of power from it in terms of correctness checking
12:57Kaaliraek: Nice. Then the pred-to-validator fn would be more important than now. Well, it's a great abstraction either way.
12:58raek(alias 'p 'pour.core) ::p/error, can be used from other namespaces
12:58KaaliWould that bind the validators too much to pour?
12:59KaaliOr is that a moot point?
12:59raekwell, that is a valid point
13:00raekanother solution would be to return a 2-vector containing the result and whether it was valid
13:00raek=> [123 true]
13:00raek=> [nil false]
13:01raek(output from a number validator)
13:01KaaliThat would also complicate the validator interface a bit.
13:02raekthe nil is error is very simple
13:02raekand simple is good
13:02KaaliYeah, I guess it should be left as is for now, and hope for the best that nobody wants to use nil as a valid value.
13:02raekthen the *user* of the lib could be responsible for choosing his own nil-sentinel-value
13:02raekthat makes more sense
13:03KaaliYeah, a user-based workaround for a rare problem.
13:03rhudsonjli, it seems to be partly a matter of temperament and taste. It's always a little embarrassing to find something in initial testing that a type system would have caught. But my experience is that very very few lingering bugs in dynlang code I've written are things that a stronger type system would have pointed out.
13:04raekor, the validator could take a error-value parameter
13:04raekthat it returns if it didn't validate
13:04raekwell, no reason to change the lib yet
13:04jlirhudson: I think the advantage of strong typing is much stronger when you have a huge code base. the compiler/type system does its error checking over the whole world every time you compile. it's kind of scary to me that you can have obvious bugs in dynamic code that you don't know about just because it's down a code path that is rarely used
13:05Kaaliraek: If the library gets users, I guess the feedback will say if this problem needs a solution.
13:05raekexactly
13:07raekthe required validator is not invoked if the map doesn't containt the key
13:07raekmaybe you should iterate over the keys of the validators, instead of the keys of the map
13:08KaaliAh, that's true.
13:09KaaliCould you explain the suggestion?
13:11rhudsonjli, I won't really argue that point, except to say that I've seen people get a false sense of security on big code bases because it all compiles. :)
13:11rhudsonI do have a sense that Clojure 1.2's protocols and datatypes will help in large code bases. "Types when you need them."
13:13KaaliIt's true that required validator is more like not-empty validator right now. My first hunch would be to fetch the fields and give a default value of nil for the missing fields. This would force the validator evaluation, but this would require some way to short-circuit the validators for optional but nil values.
13:13jlirhudson: yeah, it can absolutely deceive you, like with polymorphic functions in OCaml like compare and equal. Haskell does this better, with its typeclasses, but there are certainly still lots of bugs that aren't catchable with type systems
13:15raekthe input-map might be {:foo ...} and the validator map {:foo ...., :bar ...}
13:17raek(for [[k validator] validators :let [input (get input-map k)]] (...))
13:18raekcurrently it works something like this
13:18raek(for [[k innput] input-map :let [validator (get validators k)]] (...))
13:18raekwhere (...) would be "run validator for value"
13:21Kaaliraek: Could you show that as you would use it with defform as an user?
13:23raek(defform foo :a [[required "a is required"]]) (foo {}) => {:errors {}, :values {}}
13:24raekit should be {:errors {:a "a is required"}, :values {}}, right?
13:24raekfoo does not do validation for :a, since it's not in the map it gets passed
13:25KaaliI understood the problem, but not the solution yet. BTW. I really love your feedback.
13:26KaaliI fixed the inner vector syntax and will push the change soon.
13:26raekthe solution would be to map over the validators, rather than the params
13:27KaaliPushed.
13:27KaaliAh, I'll try that. Thanks.
13:28raekfood. bbl.
13:30raekKaali: I joined #pour, maybe we could move dev talk there
13:36dysingertest
13:37dysingerirssi!!11 seems emacs rcirc is the only thing working for me right now.
13:39dysingerI'm sure everybody knows that we are hiring at Sonian. We currently considering #8, #9 & #10 on our full time work-at-home clojure team. It's all backend/bus work, rest apis, r&d, etc. Fun stuff.
13:40dysingerIf you like contact me offline on irc, skype (tim.dysinger) or jobs@sonian.net
13:42KirinDavedysinger: Speaking of that, sorry I didn't get in touch earlier.
13:43dysingernp :) I'm saving you a spot
13:43KirinDavedysinger: With this wedding coming up I've been super busy with minutiae.
13:54raek...now, how do I change Github's interface back to English?
13:57raekoh, links at the footer of the page...
13:57raek"Forkar hårt och länge"...
14:09TakeVIs there a way to call Clojure files as scripts in Java?
14:13dysingerclojure.main is java
14:13dysingergrab the source and figure it out :)
14:15qbgI believe there are some methods that let you do that in clojure.lang.RT
14:15rhudsonTakeV: One way is an implementation of javax.script interfaces ScriptEngine{,Factory}. (also known as "JSR-223". ScriptEngine provides facilities to bind variables on the Java side and retrieve the results. I've seen a couple of implementations around github etc.; dunno if they're current
14:17qbgloadResourceScript in clojure.lang.RT looks useful
14:23akhudekis there anything like swap!, but that does not use apply?
14:24akhudeki.e. just does (f old-atom-value)?
14:24qbgWhat is wrong with swap!?
14:25akhudekI have a record in there
14:25akhudekand by using apply, it forces me to destructure the record, no?
14:26qbgNo
14:26qbg,(doc swap!)
14:26clojurebot"([atom f] [atom f x] [atom f x y] [atom f x y & args]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."
14:26akhudekright, so if you do (apply (fn [x] x) {:a 1 :b 1})
14:26akhudekyou get a wrong number of args error
14:26qbg(swap! atom f) does (f current-atom-value)
14:27qbg,(apply (fn [x] x) {:a 1 :b 1} [])
14:27clojurebot{:a 1, :b 1}
14:27raek(swap! atom f a b c) does (f current-atom-value a b c)
14:28raek(apply f a b c args) is like (apply f (concat [a b c] args))
14:28qbg,(let [a (atom 0)] (swap! a inc) @a)
14:28clojurebot1
14:28qbg,(apply inc 1)
14:28clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
14:28qbg^ Proof that it will not destructure the atom's contents
14:30raekakhudek: the last arg of apply is a sequence of the arguments to pass to the function
14:30raek(apply (fn [x] x) [{:a 1 :b 1}])
14:30raekthen the map is the first argument, and gets bound to x
14:32akhudekhmm, ok let me look at this further, maybe I've done something odd
14:39akhudekyes, the problem was that I and blind to typos
14:39akhudekexcellent
14:40akhudekam blind even
14:40rhudsoncase in point :)
14:49mcav,(map :out [(clojure.java.shell/sh "echo" "\u0169")
14:49mcav (clojure.java.shell/sh "echo" "\u0169" :in-enc "UTF-8" :out-enc "UTF-8")])
14:49clojurebotEOF while reading
14:49mcav(map :out [(clojure.java.shell/sh "echo" "\u0169") (clojure.java.shell/sh "echo" "\u0169" :in-enc "UTF-8" :out-enc "UTF-8")])
14:49mcav,(map :out [(clojure.java.shell/sh "echo" "\u0169") (clojure.java.shell/sh "echo" "\u0169" :in-enc "UTF-8" :out-enc "UTF-8")])
14:49clojurebotjava.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)
14:51mcavI might be mistaken, but I don't think clojure.java.shell/sh defaults to UTF-8, though the docs say it does
14:52akhudekit did not as of a few weeks ago
14:53mcavlooks like there were commits on July 7th or so, changing the docs to say it does, but I don't think that encoding change was actually made
14:54akhudekchange line 96 to: (with-open [osw (OutputStreamWriter. (.getOutputStream proc) "UTF-8")]
14:56akhudekI think only the coverting of the shells *output* defaults to UTF
14:58mcavit's line 122 in the master branch
14:58mcavhttp://github.com/clojure/clojure/blob/master/src/clj/clojure/java/shell.clj
14:58mcavin-enc is nil by default
15:09jliis there a standard sum function, like #(reduce + %) ?
15:09zooGgrr i'm trying to install the Enclojure plugin on Netbeans, its telling me i need all these updates to the Ant, the Search API, etc. But there's no updates for them.
15:09akhudekjli: (apply + [1 2 3 4])
15:09jlizooG: I saw that too, when I installed netbeans through debian. it's because the debian package was really old - worked when I installed from the netbeans site
15:10jliakhudek: right, but I'm asking if sum already exists. I guess not.
15:10jliI don't want to say "+"
15:11akhudekoh, I don't think so, no
15:11jliokay, thanks
15:11jliI guess the apply is better than reduce though.
15:12zooGjli is it compatible with 6.9 yet?
15:13zooGor do i have to find the 6.8 on the siet?
15:13zooG*site
15:13akhudekit works with 6.9
15:13jliI thought it worked with 6.9 just fine
15:15zooGok cool
15:24qedHello all
15:25jliI'd like to write (fn [x] [x (* x 2)]), a function that takes a number and returns a pair of the number with its double
15:26jliwhen I do #([% (* % 2)]), I get java.lang.IllegalArgumentException: Wrong number of args (0) passed to: PersistentVector
15:26mefestojli: try #(vector % (* % 2))
15:27jlihm, #(vec [% (* % 2]) seems to work
15:27jlimefesto: that too. can you explain why?
15:27lpetitjli:
15:27lpetit,(macroexpand-1 '#([]))
15:27clojurebot(fn* [] ([]))
15:28lpetitjli: see, the vector is placed in call position
15:28jlihuh. not sure I understand what's going on there
15:28lpetit,(macroexpand-1 '#(+ 1 2))
15:28clojurebot(fn* [] (+ 1 2))
15:29lpetitjli: what you place in the first position inside will be what gets called by the function
15:29jlioh, I guess I don't understand the #() macro then
15:30jliyeah, okay. I sort of understand I think
15:30mefestojli: the resulting code was ([])
15:31mefestojli: so it's attempting to call that vector as a function, but when you do that a vector needs a parameter indicating the index
15:31mefesto,([1 2] 0)
15:31clojurebot1
15:31jliI see. I guess the problem is that [1 2 3] is a literal vector, but ([1 2 3]) is a function call, because vectors are functions of indices, right?
15:31jliokay. I think I got it.
15:31mefestoyeah
15:32jlicool, thanks mefesto
15:34Lajla,
15:34clojurebotLajla: Excuse me?
15:37lpetithi emacs paredit.el users. I've a question for you
15:38qedMy reply will be slow I'm on a phone. Shoot.
15:38lpetitIs there so emacs user here willing to help a poor eclipse dev ? :)
15:39lpetiteverybody has already switched to enclojure ? :)
15:39qedWith?
15:39qedNever!
15:39lpetitGiven the following text in the buffer (no more no less), and the cursor represented by the pipe
15:40lpetit"[foo (bar [baz {bleh |blah}))]"
15:40qedYessir
15:40lpetitIf you hit the closing square bracket key : ] , what do you get ?
15:40lpetit(assuming that paredit is installed, and paredit close square bracket is enabled)
15:40lpetit?
15:41qedErm you're not allowed to be unbalanced
15:41qedIt would already be there
15:42qedBut if for some reason you were unbalanced it would just yield a single ]
15:42raekparedit-mode won't activate since they're unbalanced
15:42qedraek: it's possible to delete a bracket though
15:43raekI see
15:43qedYou can't open anything new, but you can fix it
15:43lpetitqed: the question is already ^^^ what behavior ? inserts the ] ? jumps somewhere ? does nothing ?
15:43raekparedit will close with the "right" parent, no matter which one you try to write
15:45lpetitqed: I guessed this one. Now please, assume paredit.el is smarter than today, and that unbalanced things are not a problem. Which behaviour would you like in this precise case ? I have 2 interesting ideas:
15:45lpetitqed: 1. jump to the end of the string, just after the closing square bracket
15:46qedI sort of like my paredit stupid tbqh
15:46lpetitqed: 1. would then become "[foo (bar [baz {bleh blah}))]|"
15:47qedWhat's w?
15:47qed2*
15:47lpetitqed: 2. localise the first enclosing ([ <whatever but not ]>) pair, and insert ] just before the wrong <whatever but not ]> bracket
15:48lpetitqed: 2. would then become "[foo (bar [baz {bleh blah}]|))]"
15:48qedI'd pick 1, but not being allowed to be unbalanced is why paredit is great I think.
15:49qedI think you should only be able to fix a balance issue in general
15:49qedBut not allowing that to happen in the first place is central
15:51lpetitqed: sure, not arguing against that
15:51qedlpetit: do you see what I mean?
15:51lpetitqed: maybe not :/
15:52qedOkay then without a doubt I choose #1
15:52qed Why would you not already have a closing bracket in your example?
15:52qedWhat scenario would allow that?
15:53lpetitqed: degraded mode
15:53qedElaborate please?
15:54lpetitparedit is black / white. It does not have to remain black/white forever. At least not my paredit.clj :p
15:55qedWhen I use an editor that matches pairs but let's you be unbalanced I'm annoyed.
15:55qedFwiw
15:56mmarczyksame here
15:56qedI'm not saying I wouldn't use your version and give it a fair shake, but black/white is sort of the point for me
15:56lpetitI'm currently enhancing my clojure grammar so that even not-well balanced things get you some behaviour. E.g. if you have "([)]" it's analysed as two nested "weird" (chimera) forms. You can stil use the form selection commands on it, it parses correctly so you still have correct auto-indentation ...
15:57qedBut why? That's not valid clojure.
15:57lpetitI would rather think that every people gets used to the behavior his favorite tool gives him.
15:57mmarczykthat sounds technically interesting
15:58lpetitSome people not always have valid clojure code "every time".
15:58mmarczykbut I'm not clear on the meaning of "correct auto-indentation" where incorrect code is concerned
15:58qedIndeed
15:58rhudsonfwiw, La Clojure lets you insert the ], but it then immediately red-marks all the unbalanced ) ] }
15:58lpetitImagine a user that knows *nothing* about paredit. And does not want to activate it yet. I can disable the paredit commands that make paredit "weirdos" at first: open-round for example.
15:59mmarczyksome people use the black/white paredit and get at least the bracketing correct every time :-)
15:59lpetitSo the person starts a new file, hits "(" => my new extended grammar parses this as a ["(" <eof>] form. And when the user hits <Enter>, he gets the correct auto-indentation behavior
15:59qedlpetit: If they don't like paredit, fuck em. lol
16:00lpetitqed: no, it's generally the contrary: it's paredit which f..ks them ! And they don't know how to get rid of it ! :)
16:00mmarczyklpetit: that's what Vim does for me and I've written thousands upon thousands of lines of Scheme like that... sounds perfectly alright, but it's nothing to do with paredit, I think...?
16:00lpetitleaving them with a wrong impression of not controlling things anymore
16:01qedParedit for me generally amounts to 2 commands
16:01qedI'm no super user
16:01mmarczykah, I didn't really want to argue for paredit to be necessarily on by default, if that's what the conversation is about
16:01rhudsonWhat does paredit do if you paste in something that's unbalanced?
16:01qedFreaks out
16:02mmarczykrhudson: it throws a temper tantrum and expects you to fix it asap ;-)
16:02rhudsonsounds ... unhelpful
16:02qedI disable the mode and fix it
16:02qedYeah you got me there
16:02qedBut usually it's just me pasting something from a non paredit user
16:02qedLol
16:03mmarczykyou can insert ([{""}]) wherever you want with C-q
16:03mmarczykwhen fixing a typo / paste error / etc.
16:04qedYeah I know I'm lame in that respect but I haven't internalized bat one yet
16:04qedI almost never need it
16:04lpetithmmm, the fact is I'm partly focusing on this because I've implemented all paredit commands on top of the hypothesis that I have a parse tree. For example if at the end of the buffer there's a problem which makes the parser return no parse tree, it's currently impossible to have auto-indentation even between the first and second line
16:04lpetitmaybe this is a non problem in emacs
16:05mmarczykwell, if you want to sort of mark just part of a buffer unbalanced
16:05mmarczykand still auto-indent below it
16:05mmarczykthen it's an interesting approach
16:06mmarczykI'd still want, at the very least, to have some sort of warning -- red curly underline or whatever -- to tell me I probably ought to fix my brackets
16:06hiredmanhmm
16:07qedSame here
16:07mmarczykbut this sounds like it's about acting reasonably when paredit is disabled...
16:07lpetityeah sure, it's part of the extension. I've a special parstree node for this: currently it's named :chimera :)
16:07hiredmanI am sure someone must have mentioned paredit already
16:07qedlpetit: You might consider the response you get from #emacs?
16:07lpetithiredman: jumping in the middle of the chat ? :-)
16:07mmarczykhiredman: this is in fact a "paredit in ccw" conversation :-)
16:08lpetithiredman: was joking . welcome ! :)
16:09hiredmandoes paredit in ccw let you enter unbalanced expressions?
16:09lpetitwell, I was wrong in asking the question to users of paredit, since the problem almost never happens to them !
16:09lpetithiredman: copy/paste lets you easily enter unbalanced expressions in any editor I know of, ccw and emacs certainly being no exception
16:10lpetitand yes, ccw has 2 "modes" for paredit, one mode that provides the commands which do not "get in the way" of new users
16:10hiredmanwell, thats why you copy and paste using C-k and C-y
16:10hiredmanand don't use a mouse
16:10mmarczyklpetit: incidentally, if you enter a closing bracket in the middle of a bracketed expression, paredit will move the cursor past the closing bracket of this expression
16:10mmarczyklpetit: and bracket type mismatch doesn't matter here
16:11lpetitI know all that, that's what I've implementing in paredit.clj
16:11mmarczykoh, alright :-)
16:11lpetitNevermind
16:21slyrusparedit.clj?
16:21slyrusoh, this is for eclipse?
16:26lpetitslyrus: among other candidate IDEs. paredit.clj is totally "headless" and "framework agnostic".
16:27mmarczyklpetit: I like your multimethod-based design
16:28lpetitmmarczyk: Oh, you've looked the state of the code
16:29mmarczyk:-)
16:41lpetitfor example with the new mode, "paredit expand left" works like this : "(foo bar|]" => Expand left command => "(foo |bar|]"
16:56tomojwhy would you care what it does with "(foo bar]" ?
17:03lpetitwhy wouldn't you want it to be able to recognize bar and select it ? What if bar were a more complex expression, and you don't care for this malformed ] yet. Same if ] is the end of the line.
17:04lpetitFrom the recent conversation in the ml post I started, there seems to be a lot of people who do not want to be restricted to working with always good looking code.
17:07tomojbut if you're using paredit mode, why do you have a malformed expression?
17:07tomojbut yes, that is a good thing
17:08tomojparedit.clj?
17:08tomojnever heard of it
17:09tomojit's a plugin?
17:09tomojoh you could use it from anywhere
17:10tomojI wonder how you would make an emacs implementation of that efficient
17:10tomojand whether it would it be OK to send the entire top-level form at point for every paredit command
17:20lpetittomoj: I'm talking about it here and there, but not yet sufficiently "proud of it" to talk loudly about it
17:23rhallhi, anyone around?
17:23rhallHi rhudson
17:24rhallit's really quiet in here
17:24rhudsonhi rhall
17:24rhallI'm trying to figure out debug-repl... have you ever used it?
17:25rhudsonno, afraid not
17:25LauJensenrhall: debug-repl, is that what the poor kids without swank.core/break are using?
17:26rhalldon't know, but being one of those poor kids you mention., I don't even *know* about swank.core :)
17:26rhallchecking the goog now
17:26rhallizzit better?
17:27hiredmanLauJensen: pretty sure those are the same thing
17:27pablohcan u do something similar to ruby's argument splating in clojure?
17:27LauJensenhiredman: They rely on the same tricks, yea, made by different people
17:27LauJensenrhall: check my latest blogpost, in the screencast near the end I show it off
17:28rhallok, looks like debug-repl has been incorporated in swank.clojure
17:28hiredmanI've never found either to be more useful then just logging/printing
17:30rhallhiredman: so far I've had mixed results with logging... still working on it
17:30rhalllaujensen: where do you blog? I'm not finding it quickly
17:31LauJensenrhall: http://bestinclass.dk/index.clj/2010/07/trail-blazing-innovators.html
17:31LauJensenthats the latest post, back up to /blog.html for the rest
17:31slyrusis there an equivalent to the clhs: <cl identifier> supported by the bots in this channel? e.g.. clojure-api: extend-protocol
17:32rhalllaujensen: thx... reading now
17:32tomoj(doc extend-protocol)
17:32clojurebot"([p & specs]); Useful when you want to provide several implementations of the same protocol all at once. Takes a single protocol and the implementation of that protocol for one or more types. Expands into calls to extend-type and extend-class: (extend-protocol Protocol ::AType (foo [x] ...) (bar [x y] ...) ::BType (foo [x] ...) (bar [x y] ...) AClass (foo [x] ...) (bar [x y] ...) nil (foo [x] ...) (bar [x y] ...)) expands
17:32LauJensenrhall: np
17:32slyrustomoj: well, ok. I was hoping for a link to the web page, but that's nice-ish. thanks.
17:33tomojdon't you have a repl?
17:33tomojmaybe it should link to clojuredoc.org
17:33raekpabloh: apply
17:33tomojclojuredocs.org I mean
17:34raek,(apply concat 1 2 3 [4 5 6])
17:34clojurebotjava.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
17:34pablohraek: is not partial apply waht i'm tring to do
17:34raek,(apply list 1 2 3 [4 5 6])
17:34clojurebot(1 2 3 4 5 6)
17:35slyrustomoj: I was thinking the api docs referenced from clojure.org, but sure.
17:35rhudsonSo far the thing I like best about clojuredocs is the Clojure core quick ref. It's great to see the functions grouped together by topic.
17:35raekwhat does argument splatting do?
17:35tomojreal examples of use are always nice too
17:35pablohraek: at ruby, if u have foo(a,b) u can do foo(*[a,b]) and have the same effect
17:35tomojespecially for things like ns I bet
17:36raek(foo a b) and (apply foo [a b]) is somewhat similar, but not what you are looking for?
17:37raekthey have the same effect and in the latter case you get the args as a collection
17:37pablohraek: humm, i think u're corrent
17:37pablohcorrect*ç
17:38raekall arguments between the function and the arg-list are unsplatted
17:38raeklike in the list example
17:39krunaldo(create-ns 'test) (ns 'test) leads to java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol (NO_SOURCE_FILE:2)
17:39krunaldoWhat am I missing?
17:39krunaldoah
17:39krunaldo'test should be test :)
17:40raekns creates the namespace if it doesn't exist already
17:40raekit is a macro, unlike the other ns functions
17:41krunaldoyeah, I wasn't supposed to give it a symbol :)
17:42krunaldoI guess it macros it into a symbol somewhere down the road
17:42hiredmanit is a symbol
17:43hiredmantest is a symbol, 'test is a quoted symbol
17:43hiredman'test is expanded by the reader to (quote test)
17:43hiredmanwhich is the list mentioned in the exception
17:43raekmacros gets their args unevaluated
17:44krunaldoAh, cool!
17:44krunaldoI coded some common lisp way back in 2004-2005 never really got the hang of macros back then :)
17:44krunaldoas in how to use them not how extremely useful and cool they are
17:45pablohraek: what does apply do at that context?
17:46pablohraek: it return an anonymous function?
17:46raekno, it invokes the function
17:47raekapplies it
17:47pablohits like, call this function with the paramters on this vector?
17:47raekyes
17:47raek(apply f args) = call f with args
17:48pablohok, does it takes only 2 parameters?
17:48raek(apply f a b c args) = (apply f (concat [a b c] args)) ; a convenience extra
17:48raekit can take more
17:48raekthat is a convenience feature
17:49raekthey can always be rewritten into the 2-parameter form
17:49pablohok i got
17:49pablohit
17:49pablohraek, the last argument *can* be a vector ?
17:50raekthe last element must be sequable
17:50rhudson"Clojurians have more fn"
17:50pablohraek: ok
17:50raekthat is, you should be able to call seq on it and get a sequence
17:51raek,(seq [1 2 3])
17:51clojurebot(1 2 3)
17:51raek,(seq 1)
17:51clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
17:51pablohok
17:51raekso you can't do (apply f 1)
17:53pablohraek: so is only a convience way, for the sake of clojure's conventions?
17:53pablohraek: the arity of apply
17:53raekyes
17:53raekexactly
17:53pablohok, i got it, thx a lot!
18:00rhallanyone got any thoughts on why swank.core/break shows "No Locals"? I've searched through clojure-log and found that I need to upgrade to 1.2.0 and clojure mast and contrib... did that... still "No Locals"
18:01rhallneither slime-connect (using lein swank) nor swank-cloure-project show local
18:08tomojI think you have to get the right frame
18:08tomojwhat does your attempt look like
18:09rhallI get the usual slime debug backtrace...
18:09rhall0: user$eval__2351.invoke(NO_SOURCE_FILE:1)
18:09rhallI hit enter or "t" on that and it explands but says [No Locals]
18:10rhallI'm using LauJensens screencast example
18:10rhallthe backtrace looks pretty similar
18:10rhallexcept his has locals :)
18:33tomojweird
18:33tomojrhall: what swank-clojure version?
18:36rhall1.2.1
18:36tomojmaybe try 1.3.0-SNAPSHOT
18:37rhallok, thx.. trying now
18:40rhallno better, but I get this message when I start "slime-connect" -> Versions differ: 20100404 (slime) vs. nil (swank). Continue? (y or n)
18:40rhallwonder what that means
18:40slyrusmmarczyk: there's a new shortcut that cleans things up a bit and adds some functions for paritioning/connected-components
18:40slyrusand I finally bit the bullet and decided that molecules _aren't_ graphs, but rather contain a graph. made that code a bit simpler.
18:41tomojhmm
18:41tomojrhall: what version of slime?
18:42tomoj20100404 from ELPA?
18:43rhallyes, exactly
18:43tomojdunno what to say.. I have the same
18:43rhallah... maybe this is the problem
18:44rhallelpa has swank-clojure 1.1.0 installed slime adapter for clojure
18:44rhallbut I have 1.3.0-SNAPSHOT in lein
18:44rhallwonder which one is winning
18:44tomojswank-clojure from ELPA is sort of deprecated
18:44tomojI don't use any emacs swank-clojure package
18:44mmarczykslyrus: greats, thanks! will look at all that soonish :-)
18:44tomojrhall: lib look like this? https://gist.github.com/ca7eee970e9c0400d4f4
18:45rhallI'm guessing the elpa one is active:
18:45rhallswank-clojure-deps is a variable defined in `swank-clojure.el'.
18:45rhallIts value is
18:45rhall("http://repo.technomancy.us/swank-clojure-1.1.0.jar&quot; "http://build.clojure.org/snapshots/org/clojure/clojure/1.1.0-master-SNAPSHOT/clojure-1.1.0-master-20091202.150145-1.jar&quot; "http://build.clojure.org/snapshots/org/clojure/clojure-contrib/1.1.0-master-SNAPSHOT/clojure-contrib-1.1.0-master-20091212.205045-1.jar&quot;)
18:45rhall
18:45rhalllet me remove it
18:45tomojwonder how you can unload it without restarting emacs
18:46tomoj`M-x unload-feature swank-clojure` maybe
18:46technomancyswank-clojure.el is just about launching swank servers; it shouldn't affect swank's break feature at all
18:47tomojshucks
18:47rhallgood question... not sure I can... I'll restart... back in a sec (I'm using erc)
18:47tomojoh well :(
18:49mmarczyktechnomancy: http://github.com/technomancy/leiningen/commit/c8ce3cd014c8ab3732af4fc90ee3ee9260f3abed commit message seems to explain the intent behind the funky stuff in uberjar to a certain extent... more importantly, it made me check lein's own standalone jar and, surely enough, it does contain a non-empty components.xml
18:50rhalltomoj: same issue... strange
18:50tomojtechnomancy pointed out that swank-clojure.el doesn't affect swank.core/break
18:50tomojmaybe check your (System/getProperty "java.class.path")
18:50tomojfor the right swank-clojure jar
18:51tomojgood luck :(
18:53qedEvening all
18:55rhallhi qed
18:55qedLo
18:58nickikWhy does it not scho :pre and :post when you call meta on something?
18:59qedBecause they aren't part of the meta fields iirc
18:59qedThey are conditions not meta
18:59nickikhow can i print them?
19:00qedUse a let binding and return them as a map along with your result?
19:01nickikhow do you mean that?
19:03mmarczyka function with :pre and :post gets transformed to sth like (fn [& args] (assert pre1) ... (assert preM) (let [res (apply-the-actual-body-to args)] (assert post1) ... (assert postN) res))
19:04mmarczykso you can't print them
19:06nickikI just looked it up on clojure.org the map is metadata of the arg list
19:11mmarczykoh, really? that's cool, thanks
19:13nickikThe condition map may also be provided as metadata of the arglist.
19:13nickiki didnt say it right
19:16mmarczykjust checked (defn foo [...] {:pre ... :post ...} ...) ~> (-> #'foo meta :arglists first meta) and, surely enough, there's a symbolic representation of :pre and :post right there
19:16mmarczykawesome :-)
19:20nickiknice
19:20nickikwhy do you have to right #' ?
19:21mmarczykthe magic happens in clojure.core/sigs
19:22mmarczykwell, there's a bug -- or at least I think it's a bug -- which prevents defn from transferring useful metadata to the function itself
19:23mmarczykI mean, the correct metadata is attached to the Var, but the function itself gets outdated metadata
19:23mmarczykI made a ticket for that ages ago on Assembla... could look for it
19:23nickikI have to try to add them like this (defn testtest (with-meta [n] {:pre (pos? n)}) (* n n))
19:23mmarczykno, not at all
19:24mmarczyk(defn testtest [n] {:pre [(post? n)] :post [(even? %)]} (* n n))
19:24mmarczykI mean, (pos? n)
19:25mmarczykin fact, you can't use with-meta, you'd have to use reader metadata: ^{...} [n]
19:26nickikintressting stuff
19:28nickikI'm trying some diffrent stuff in trammel so I need all infos on that pre post stuff
19:34nickikcould i have a map with conditions and assign that somehow to a function?
19:42bokehI've been pulling my hair last trying to import a Javax Sound nested class
19:42mmarczyknickik: well, you could wrap your function in another function with the conditions in place
19:42bokehCould someone please explain why this works: (import '(javax.sound.sampled.DataLine$DataLine.info))
19:43mmarczykbokeh: does it really?
19:44mmarczykyou don't need the quote (although it doesn't hurt anything)
19:44mmarczykbut more importantly
19:44bokehbut not this: (ns (:import '(javax.sound.sampled.DataLine$DataLine.info))
19:44bokeh) or this: (ns hello (:gen-class) (javax.sound.sampled DataLine$DataLine.Info))
19:44bokehI know, I normally never use quote...
19:44mmarczykwell you need to get your capitalisation right in any case
19:45mmarczykI don't know if it's info or Info, so don't know which to choose, but presumably it should matter...
19:45bokehI'm wondering if the .Info of the nested class name doesn't fool Clojure somehow
19:45bokehsorry, typing from memory here, it's .Info
19:46mmarczyk(import java.util.Map$Entry) works for me
19:47mmarczyknow I can just say Map$Entry
19:47mmarczykdunno if you can shorten this further
19:47bokehyeah, simple stuff works just fine, but try this: (import javax.sound.sampled.DataLine$DataLine.Info)
19:48bokehan official java nested class...
19:49mmarczykClassNotFoundException for me
19:49mmarczykI mean, without the import around it
19:50mmarczykwhere do you get it from?
19:50bokehnow delete the $DataLine.Info and the container class works fine
19:50bokehwhat do you mean?
19:50bokehit's a javax package
19:51bokehI'm wondering if it's a Clojure bug where the .Info throws off the reading of the class name...
19:53dnolen_lancepantz: what about a "bake eval", would make integration with TextMate easy
19:53mmarczykbokeh: ah, shouldn't it be javax.sound.sampled.DataLine$Info ?
19:54bokehGod, I want to marry you mmarczyk :) You've found it!
19:55mmarczykbokeh: I will carefully consider your proposal
19:55mmarczyk;-)
19:55bokehThe doc in Java calls the class DataLine.Info nested in DataLine... I'm a Java newbie, that was enough to fool me ... Thanks again man!
19:56mmarczyknp :-)
19:57pablohwhat's the difference beetwen let and binding?
19:59qbglet is lexical, binding is dynamic
20:00qbgAlso, the bindings bound by binding are mutable
20:01nickikif you let something its only inside your (let ...) with binding its also outside the (binding ...)
20:01pablohqbg mmm, so if u make use of biding with the foo symbol, and call a function that asumes the existence of a foo symbol, it will use the definition given by binding?
20:01nickiki hope thats right
20:02qbgpabloh: As long as it has not been shadowed
20:02pabloh...that asumes the existence of a global foo symbol...
20:03pablohqbg: shadowed by something like 'let', u mean?
20:03qbgCorrect
20:04pablohok, i've been told, that dynamic scoping is evil :P
20:04qbg,(let [a (fn [] +)] (binding [+ 5] (a)))
20:04clojurebot5
20:04pablohqbg: are there some correct use cases for this?
20:08hiredmanbinding is also threadlocal
20:09nickikwe set some global variabls with binding
20:09nickikthread local
20:10qbgYou shouldn't need to use binding very much
20:10pabloho
20:10pablohok
20:12qbgFunctions that use dynamically bound variables are not referentially pure, and so are not functions in the mathematical sense
20:14pablohqbg: is that the same case as using set! ?
20:14pablohregarding referential purity?
20:15nickikyes
21:14daakuis there a way to reference the key and value using %1 %2 in a #(..) when reducing a map?
21:16daakuah, i see. i need fn
21:16daakuhate it when i answer my own question in 2 minutes
21:21rhalloff the wall question... anyone know how to search for a unicode character inside a file using emacs?
21:22rhallI'm getting this error: An invalid XML character (Unicode: 0xdbc0) was found in the comment.
21:22rhall
21:22rhall
21:22rhallusing clojure.xml
21:22rhalland I just can't see it
21:25daakurhall: xmllint?
21:25daakudonno if it checks for unicode errors
21:25rhallthx... checking
21:26rhalllooks like it just does dtd validation more...
21:27rhallI can't see why "parse" cares what's inside the comments anyway
23:16jouberthello
23:16joubertdoes anybody here use clojure-couchdb from the-kenny?
23:16joubert(http://github.com/the-kenny/clojure-couchdb)