0:00 alexbaranosky: amalloy: any interest in working on Midje? we could use your skills :)
0:00 amalloy: alexbaranosky: the case i'm concerned about is (.foo IBar b) => 10 (.bar IBar b) => 9
0:01 alexbaranosky: amalloy: I wonder what Midje does now for the fn analog of that? Probably just uses the last defined provided
0:02 devn: midje is great.
0:02 alexbaranosky: amalloy: oop misread
0:02 hey devn
0:02 * devn waves
0:03 alexbaranosky: devn: I'm the dude you were talking about pair programming and philosophy with first day of the Conj
0:03 devn: oh, right! how's it going?
0:03 alexbaranosky: amalloy: I see your point now and will add it to the notes I'm accruing on the Github Issue
0:03 devn: good!
0:04 devn: alexbaranosky: working on midje, eh?
0:05 alexbaranosky: dev: yeah, I've got three features on my list of things that seem most useful:
0:06 devn: colorized console, auto/lazy-test powers, mocking java methods (including static ones)
0:06 if you've got the burning urge to do any, that could be arranged :)
0:07 devn: If I commit to anything else I think I might implode
0:07 I absolutely want to, but wanting does give me extra hours :(
0:07 alexbaranosky: me too, he
0:07 reiddraper: anyone know if there's a quickcheck for clojure that's actively maintained?
0:07 i've found a couple but they seem abandoned
0:08 alexbaranosky: well, you can always give more feedback on GitHub issues, or to me; that stuff is really useful
0:08 devn: reiddraper: how abandoned is abandoned in your estimation?
0:08 reiddraper: devn: no commits in 2011
0:08 amalloy: reiddraper: halloway has test.generative, which i think is similar
0:08 devn: alexbaranosky: yeah, I will definitely do that. I haven't used midje a *ton*, but when I have used it I've really enjoyed it.
0:08 reiddraper: so clojurecheck is out of the picture, yes?
0:09 amalloy: and i think he's working on it
0:09 alexbaranosky: devn: we don't get enough people adding their two cents to issues imho
0:09 reiddraper: devn: that's the one i was looking at, perhaps it's great and just hasn't needed anything since 2010
0:10 devn: alexbaranosky: i have spent a fair amount of time on the wiki for midje. next time I'll peek at issues. :)
0:10 reiddraper: amalloy: I'll look more at test.generative. It wasn't well documented and I didn't dig further than that
0:11 devn: reiddraper: haskell ports seem to have the property of standing the test of time
0:11 reiddraper: but they require some care and feeding
0:11 reiddraper: have you looked at test.generative?
0:12 reiddraper: devn: just enough to see there weren't many docs. should look more.
0:12 devn: reiddraper: I think you're right -- there aren't many docs, but I believe there are examples under src/
0:12 reiddraper: devn: i coudldn't tell if it indented to be like quickcheck, or just a random input testing facility
0:12 devn: reiddraper: also, fogus' libraries clache and unk use test.generative, so that might be helpful
0:13 reiddraper: honestly I don't know, but if you check out fogus' projects that might give you the answer you're looking for
0:13 reiddraper: devn: ok, will take a look at those as well. I'm particularly interested in the "simplification" of failing cases that haskell/erlang QC provide
0:14 I suppose there's always the possibility of using a Java lib too :)
0:14 bartj: I thought re-seq returned a sequence of matches
0:15 brehaut: ,(re-seq #"a+" "aababaabaababbbba")
0:15 clojurebot: ("aa" "a" "aa" "aa" "a" ...)
0:15 bartj: , (re-seq #"(?i)\b(Mission Road|Bangalore)\b" "45, Mission Road, Bangalore")
0:15 clojurebot: (["Mission Road" "Mission Road"] ["Bangalore" "Bangalore"])
0:15 bartj: but, it seems to return a sequence of matches
0:15 where the matches seem to be vectors!
0:16 brehaut, ?
0:16 brehaut: bartj: its because you have capture groups
0:16 devn: ,(doc re-groups)
0:16 clojurebot: "([m]); Returns the groups from the most recent match/find. If there are no nested groups, returns a string of the entire match. If there are nested groups, returns a vector of the groups, the first element being the entire match."
0:17 devn: ,(doc re-seq)
0:17 clojurebot: "([re s]); Returns a lazy sequence of successive matches of pattern in string, using java.util.regex.Matcher.find(), each such match processed with re-groups."
0:17 devn: "each element is processed with re-groups"
0:17 brehaut: ,(map first (re-seq #"(a+)" "abaabaaa"))
0:17 clojurebot: ("a" "aa" "aaa")
0:23 bartj: brehaut, devn cool, thanks
0:27 amalloy: can i just say, this kind of "you can't predict the return type" seems pretty evil to me?
0:32 tensorpudding: how does clojure do error handling?
0:32 can you specify your own errors?
0:32 amalloy: &(/ 1 0)
0:32 lazybot: java.lang.ArithmeticException: Divide by zero
0:32 amalloy: i created an error right there. awesome
0:32 tensorpudding: okay, so it uses java's exceptions
0:32 how do i throw an exception
0:32 how do i create new exceptions
0:33 amalloy: tensorpudding: i seem to recall you hate reading docs, right?
0:33 tensorpudding: is the only facility in java?
0:34 i skimmed the clojure docs but couldn't find anything talking about exceptions
0:36 alexbaranosky: &(throw (RuntimeException. "boom"))
0:36 lazybot: java.lang.RuntimeException: boom
0:37 alexbaranosky: tensorpudding: also checkout slingshot on github
0:37 tensorpudding: where is throw defined?
0:37 choffstein: If I am trying to upgrade a project to 1.3 and have a dependency that is still on 1.2, is there anything I can do to stop some conflicts?
0:37 tensorpudding: i didn't see it in the api docs
0:38 alexbaranosky: clojure.core??
0:38 lazybot: alexbaranosky: What are you, crazy? Of course not!
0:38 clojurebot: this is not IRC, this is #clojure. We aspire to better than that.
0:38 alexbaranosky: (doc throw)
0:38 clojurebot: It's greek to me.
0:38 amalloy: tensorpudding: the compiler
0:38 tensorpudding: sorry
0:38 i meant to say, which module is it in
0:39 alexbaranosky: clojurebot is pissed man
0:39 brehaut: tensorpudding: amalloy already told you: the compiler; its a special form
0:39 tensorpudding: oh
0:39 brehaut: http://
0:40 choffstein: anyone use weavejester's hiccup library?
0:40 alexbaranosky: tensorpudding: http://
0:40 amalloy: choffstein: most webapps use hiccup, though not all
0:41 tensorpudding: dang
0:41 choffstein: amalloy: yeah, I realized after typing it that it was a pretty stupid question
0:41 tensorpudding: i forgot
0:41 to check the clojuredocs instead of the api page on clojure.org
0:41 choffstein: I'm trying to figure out if its dependence on 1.2.0 is breaking my 1.3.0 move
0:42 amalloy: choffstein: probably not. if you have the latest hiccup you're fine
0:42 choffstein: I can't find which dependency is breaking. I'm getting a strange error: java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: clojure.contrib.pprint/*format-str*
0:42 amalloy: even if it depends on 1.2, so long as it doesn't use contrib
0:44 that's pretty much what happens to everyone who tries to upgrade (including me).
0:44 tensorpudding: why does the api page on clojure.github.com not cover throw
0:44 amalloy: some dependency uses contrib, and old-style contrib isn't 1.3 compatible
0:45 brehaut: tensorpudding: because its not part of the api, its part of the compiler?
0:45 tensorpudding: hmm
0:45 i had assumed let was a special form
0:45 but it's a macro?
0:45 amalloy: so you have to track down who's using contrib, and update those
0:46 tensorpudding: brehaut, except clojuredocs has it
0:46 brehaut: let is a macro that wraps let* which is a special form
0:46 amalloy: try: $ lein pom && mvn dependency:tree
0:46 this will at least tell you about *one* of your deps that uses contrib
0:46 brehaut: tensorpudding: clojuredocs is not an autogenerated project, its a curated by humans
0:48 tensorpudding: well
0:48 it'd be more helpful if the info on clojuredocs were front-and-center on the clojure.org page
0:49 choffstein: amalloy: so does that mean I either need to a) fork the dep with the contrib dependency and try to move it to 1.3, b) not use the dep, or c) something else?
0:49 devn: tensorpudding: not always.
0:49 brehaut: tensorpudding: everything that makes clojuredocs great in some areas means its very weak in others
0:49 devn: tensorpudding: i agree, but it is not always the case that I want to see potentially mediocre example code. the clojure.org docs are very clear.
0:49 they describe intent, philosophy, etc.
0:49 clojuredocs is icing
0:49 amalloy: choffstein: often you can (c) use a more recent version of the dep that's already updated
0:50 tensorpudding: that's a reasonable point, that clojuredocs has possibly mediocre content, but it seems clearer and more helpful
0:50 devn: tensorpudding: yes, but now you probably see the issue: not everyone is looking for API docs
0:50 choffstein: I'm confused because none of my deps seem to depend on clojure-contrib :-\
0:51 devn: they could make relatively short documentation pages long and difficult
0:51 tensorpudding: you could always create a greasemonkey script or something that adds them to the page
0:51 tensorpudding: api docs are the main thing that i want when i go there now
0:51 i read the reference
0:52 devn: tensorpudding: why not just use clojure.repl?
0:52 ,(doc +)
0:52 clojurebot: "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"
0:52 tensorpudding: i use doc 99% of the time
0:52 but it doesn't help if i don't know what i'm looking for
0:52 devn: tensorpudding: do you have an example? not trying to grill you, just trying to understand
0:52 tensorpudding: browsing vs. querying
0:52 well, i wanted to know how to throw an exception
0:53 turns out that you use throw, a special form
0:53 it wasn't in the api docs, i missed it
0:54 devn: tensorpudding: so you went to clojure.org and you weren't satisfied with the documentation there, so you went to clojuredocs?
0:54 tensorpudding: is that correct?
0:54 tensorpudding: well, clojuredocs was pointed out to me
0:55 for the second time
0:55 i had heard of it before
0:56 devn: tensorpudding: so you think clojure.org should prominently display clojuredocs.org for the purposes of additional information?
0:56 tensorpudding: no
0:56 devn: tensorpudding: sorry, I'm just trying to understand what might have made your life easier.
0:57 tensorpudding: i just really wanted throw to have appeared in the place i expected to find it, the docs
0:57 devn: tensorpudding: 1.4.0 looks like it's going to get some documentation love FWIW
0:58 tensorpudding: http://
0:58 tensorpudding: better docstrings would be nice
0:59 helpful exceptions would be a lot nicer
0:59 devn: tensorpudding: you're in luck! http://
0:59 tensorpudding: well, that's good news
1:00 devn: nothing is done yet, but those concerns have definitely been heard before and there is an effort to make people's lives a bit easier in clojure land
1:01 amalloy: we should elect devn as Chief Finder-of-Things From dev.clojure.org
1:01 devn: amalloy: I am sort of a librarian
1:03 amalloy: along those lines, I have a friend who thinks the idea of "architects" as they have been traditionally defined in large software development companies is wrong, but that what a lot of projects need is someone who knows the terrain, the papers to read, etc.
1:04 amalloy: it's an interesting thought. "team librarian" -- the guy who knows which library you should use because he's reviewed its code and kicked its tires.
1:06 tensorpudding: in the meantime, if i could suggest to you another tool you might use to avoid a trip to clojure.org: clojuredocs-client @ http://
1:06 woops: https://
1:06 tensorpudding: i'll check it out
1:06 devn: you can include that in your project and query clojuredocs' api from the REPL
1:08 Raynes: $examples clojure.core/defmulti
1:08 lazybot: https://
1:08 clojurebot: eg, https://
1:08 Raynes: $cd defmulti
1:08 lazybot: clojure.core/defmulti: http://
1:08 clojure.core/defmulti: http://
1:08 Raynes: Or you can just use lazybot. ;)
1:10 amalloy: Raynes: seems like you could put those on one line
1:10 Raynes: amalloy: You proposed that before and I told you no then as well.
1:10 amalloy: well, i'll get back to you in a month when you've forgotten
1:37 ~logs
1:37 clojurebot: logs is http://
2:40 tuubow: in clojure if (= '(1) (quote (1))) is true then why (= '(1) (first '('(1) '(2)))) is false..is this a bug or i am doing something wrong..
2:41 hiredman: what do you think is more likely?
2:42 tuubow: i am doing something wrong i guess
2:42 hiredman: and what do you think the best way to figure out what you are doing wrong is?
2:42 tuubow: but (first '('(1) '(2))) is (quote (1))
2:43 so it should be true.
2:43 hiredman: tuubow: is it?
2:43 and what is '(1)?
2:43 ,'(1)
2:43 clojurebot: (1)
2:44 tuubow: same thing isn't '(1) is same as (quote (1))
2:44 hiredman: thats not (quote (1))
2:44 yes '(1) is the same as (quote (1)), but (list 'quote (list 1)) is not the same
2:44 neither is ''(1)
2:45 or (first '('(1)))
2:45 Raynes: &(first '('(1)))
2:45 lazybot: ⇒ (quote (1))
2:46 hiredman: http://
2:46 tuubow: but how come then (= '(1) (quote (1))) is true
2:46 hiredman: be cause they are equal
2:47 look, you need to spend sometime learning about quoting and how it works, sit down with a repl somewhere
2:48 tuubow: in repl when i type this (first '('(1) '(2))) it gives (quote (1))
2:48 hiredman: sure
2:48 ,(= (+ 1 2) 3)
2:48 clojurebot: true
2:48 hiredman: ,(= '(+ 1 2) 3)
2:48 clojurebot: false
2:48 hiredman: ,(= '3 3)
2:48 clojurebot: true
2:48 hiredman: ,(= ''3 3)
2:48 clojurebot: false
2:49 hiredman: ,''3
2:49 clojurebot: (quote 3)
2:49 hiredman: ,3
2:49 clojurebot: 3
2:49 hiredman: ,'3
2:49 clojurebot: 3
2:49 tuubow: (= '(1) (first '('(1) '(2)))) so if replace (first '('(1) '(2))) with (quote (1)) it should be true
2:49 hiredman: like I said, sit down with repl and figure it out, a solid understanding of quoting will serve you well
2:49 tuubow: as (= '(1) (quote (1))) is true
2:50 hiredman: ,'(1)
2:50 clojurebot: (1)
2:50 hiredman: ,(quote (1))
2:50 clojurebot: (1)
2:50 hiredman: ,(quote '(1))
2:50 clojurebot: (quote (1))
2:51 hiredman: anyway, I am going to put you on ignore now
2:51 tuubow: sorry i will look at it thanks.
2:59 raek: tuubow: '<foo> is just a shorthand for (quote <foo>). quote is also a special form
2:59 when you evaluate a quote expression, the value is the "content" of the quote
3:00 (quote x) evaluates to the symbol x. (quote (quote x)) evaluates to (quote x), i.e. a sequence of length two where the first element is the symbol quote and the second element is the symbol x
3:02 so to evaluate (= '(1) (first '('(1) '(2)))) you first eval the arguments to =, namely '(1) and '('(1) '(2))
3:02 (quote 1) evaluates to 1
3:02 sorry
3:03 '(1) is (quote (1)), which evaluates to (1)
3:03 '('(1) '(2)) is the same as (quote ((quote (1)) (quote (2)))), which evaluates to ((quote (1)) (quote (2))))
3:04 (1) and ((quote (1)) (quote (2))) are not the same data, so (= ...) returns false
3:08 tuubow: thanks raek
3:18 jidotnet: Hi! Anybody knows if/when the videos of the Conj will be available?
3:18 amalloy: jidotnet: they will be available, supposedly sooner than last year's were, but i don't know details
3:19 G0SUB: amalloy
3:20 jidotnet: amalloy: thanks, is there a way to get an alert when that happens?
3:21 raek: tuubow: btw, you usually use vectors as sequence literals
3:21 ,(= 1 (first [1 2 3]))
3:21 clojurebot: true
3:21 amalloy: jidotnet: probably if you follow @clojure_conj and #clojure_conj on twitter you'll find out
3:22 tuubow: well i am trying to implement set with this although clojure already has it.I would have gone to scheme for doing that but preferring clojure
3:23 so was trying to implement a member function as there is one scheme
3:24 Raynes: jidotnet: @confreaks is supposed to tweet when videos are ready.
3:24 tuubow: and as scheme doesn't have vectors so can't use it
3:25 it is a part of the assignment i am doing
3:26 * amalloy starts following @confreaks
3:27 raek: tuubow: in Clojure lists and quote work the same as in Scheme, except that you cannot have "dotted pairs"
3:27 amalloy: wait, they tweet all kinds of stuff i don't care about. i'll just assume someone i follow retweets
3:29 raek: (in Clojure-land you will hear about sequences which is a generalization of lists)
3:29 tuubow: raek, cons is there so i don't think i will need dotted pair,but i would have loved to have the member function on lists but i have implemented it now.I am loving clojure
3:30 raek: tuubow: yes, but you cannot have a non-sequence as the cdr
3:30 ,(cons 1 1)
3:30 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
3:31 amalloy: clojure makes it so easy to get a generalized version of member, so you don't really need member
3:31 &(some #{5} (range 10))
3:31 lazybot: ⇒ 5
3:31 amalloy: &(some #{50} (range 10))
3:31 lazybot: ⇒ nil
3:31 amalloy: &(some #{1 5} (range 10))
3:31 lazybot: ⇒ 1
3:33 tuubow: &(cons 1 '(1))
3:33 lazybot: ⇒ (1 1)
3:35 tuubow: &(defn member "Looks for the member in the lists return false if not found else return part of the list" [key list] (if (nil? (first(seq list))) false (if (= key (first list)) list (member key (rest list)))))
3:35 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!
3:36 amalloy: tuubow: (member nil '(1 nil 2))
3:36 tuubow: sorry i didn't know the lazybot don't expect functions
3:36 G0SUB: amalloy: isn't it possible to play with lazybot in a PM window?
3:36 amalloy: G0SUB: yes?
3:37 G0SUB: amalloy: I was thinking if people could just use the bot in a private window the channel noise could be reduced
3:38 tuubow: amalloy: yeah that is the corner case.
3:38 amalloy: indeed you can do that, and if people are being super-noisy i encourage it. but it's not like we're trying to have a philosophical conversation and being drowned out by lazybot
3:38 G0SUB: amalloy: not really, was curious about the possibility. thanks.
5:19 cataska: any one has "Practical Clojure" book ? I have a question on page 160
5:21 G0SUB: cataska: I can try. have the book.
5:22 cataska: last sentence on page 160, "..., and because the update-average involves just processing and waiting for IO"
5:23 but update-averate is only processing with no IO, right ?
5:23 update-average
5:23 G0SUB: cataska: should read "and no waiting for IO..."
5:24 cataska: G0SUB: ok, thanks
5:24 it seems not in official errata
5:25 G0SUB: cataska: if IO in involved, you're better off using send-off
5:25 &(doc send-off)
5:25 lazybot: java.lang.SecurityException: You tripped the alarm! send-off is bad!
5:25 G0SUB: &(doc 'send-off)
5:25 lazybot: java.lang.SecurityException: You tripped the alarm! send-off is bad!
5:25 G0SUB: :(
5:26 cataska: G0SUB: :)
5:26 G0SUB: &doc
5:26 lazybot: java.lang.RuntimeException: Can't take value of a macro: #'clojure.repl/doc
5:27 G0SUB: hmm, this thing is broken.
5:28 &(:doc (meta #'clojure.core/send-off))
5:28 lazybot: java.lang.SecurityException: You tripped the alarm! send-off is bad!
5:28 G0SUB: amalloy: are you guys using regex on the command as well?
5:28 it seems the var itself is blocked somehow.
5:29 amalloy: yes, it is. not using regexes, though; i don't see why that would be relevant
5:29 G0SUB: amalloy: can't I even see the docs of all the core fns?
5:30 amalloy: evidently not. it would be nice if we could tell you're using doc, and take out the blocks in that case; patches welcome
5:30 G0SUB: &(keys (ns-publics (:ns (meta #'clojure.core/first))))
5:30 lazybot: java.lang.SecurityException: You tripped the alarm! ns-publics is bad!
5:31 G0SUB: :-)
5:31 amalloy: cool
5:34 amalloy: what about a doc plugin? won't that be easier?
5:37 Fossi: ,(doc 'send-off)
5:37 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol>
5:38 Fossi: ,(doc send-off)
5:38 clojurebot: "([a f & args]); Dispatch a potentially blocking action to an agent. Returns the agent immediately. Subsequently, in a separate thread, the state of the agent will be set to the value of: (apply action-fn state-of-agent args)"
5:39 amalloy: G0SUB: sure
5:55 fliebel: I forked and basically rewrote a small utility. Not likely to get merged back, but I'm using it in a project. How should I distribute it?
5:56 Actually, I did this twice.
5:57 For now I just did lein install, but one way or another, I need to get it on Clojars or something.
5:59 fbru02: hey guys how do i make the repl/swank overshadow some function when i evaluate it ? i think it's 1.2.1 onwards that the overshadowing doesn't occur automatically
6:18 tsdh: fbru02: What do you mean with overshadowing? Can you given an example?
6:18 fbru02: tsdh: sorry, i just meant re-writing when re-evaluating
6:21 tsdh: fbru02: I still don't get it... You want to redefine some clojure functions when you do "lein repl" or M-x clojure-jack-in?
6:22 fbru02: what i'm doing now : i load a bunch of functions using "(use 'ns1)" one of the fns is called foo. I want now to load foo from my souce code so i step on another function called foo and evaluate it, that doesn't work i get an exception
6:22 is there a way no to get an exception ?
6:23 fliebel: drewr: https://
6:29 Hm, how do I push a project to org.clojars.pepijndevos/whatever?
6:30 clgv: fliebel: create an account. add an ssh public key of your computer and copy it per scp there.
6:30 it = jar
6:30 fliebel: clgv: Yes, but the namespace.
6:31 clgv: oh right. I have no idea about that. I would have liked a description on my jar as well - but no idea ho to get it there
6:31 fliebel: clgv: Another project I pushed just ended up under foo:foo
6:31 clgv: yeah, my only project also landed there under its plain name
6:32 I miss some editing/managing functionality on clojars when you are logged in
6:32 fliebel: clgv: just, maybe puting the namespace in the project.clj or editing the po file might do the trick. let me see.
6:33 clgv: fliebel: there is a chance that you can provide metadata via project.clj, but the question is how^^
6:34 fliebel: clgv: I'm pretty sure that if I change groupid in the pom, it'll work.
6:34 clgv: oh, I never touched the pom^^
6:35 fliebel: clgv: ah, if I change project.clj to (defproject org.clojars.pepijndevos/ring-http-basic-auth, the pom changes its groupid to that.
6:35 clgv: ah, interesting
6:37 fliebel: clgv: What is your one project on clojars?
6:37 clgv: a leiningen plugin: lein-checkouts
6:37 clojurebot: leiningen is a build tool designed not to set your hair on fire (http://
6:39 clgv: fliebel: changing the project name to contain the group-id is also suggested in some tutorial I found
6:39 fliebel: clgv: As well as in my Java book :P
6:40 clgv: Doesn't lein already do checkouts?
6:40 clgv: fliebel: I wanted to build all "checkouts" projects from the project that is using them.
6:41 like "lein checkouts uberjar" will "install" all "checkouts" and then build an uberjar of the current project
6:41 fliebel: oh, nice
6:42 clgv: yeah. that was a missing piece since I structured my main project in several libraries that I might share with students
7:01 Blkt: good day everyone
7:36 clgv: fliebel did it ;)
7:36 fliebel: clgv: ?
7:36 clgv: pushing to clojars ;)
7:37 fliebel: ,botsnack
7:37 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: botsnack in this context, compiling:(NO_SOURCE_PATH:0)>
7:37 fliebel: hm
7:37 clgv: clojurebot: botsnack
7:37 clojurebot: thanks; that was delicious. (nom nom nom)
7:41 * clgv finally wrote a pmap version that is "lazy" only in respect to memory consumption provided that the function is a kind of projection
7:50 fliebel: clgv: ?
7:51 clgv: fliebel: the pmap implementation is a nightmare briefly said - if you want to apply a function on a sequence.
7:53 I turned it into a producer-consumer scenario with a bounded queue which fits better for most parallelization purposes on sequences.
7:53 fliebel: clgv: ok, that is briefly, what is the full store? (maybe you could write it down in a Jira issue?)
7:54 clgv: Talking about producer-consumer, seque is just as much of a nightmare.
7:54 clgv: fliebel: a jira issue does not fit. it has no bug - but is inappropriate in all cases I wanted to parallelize something.
7:54 &(doc seque)
7:54 lazybot: ⇒ ------------------------- clojure.core/seque ([s] [n-or-q s]) Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n bu... https://
7:55 fliebel: Try running that with a priority queue. It makes invalid assumptions about what a que is.
7:55 clgv: &(source seque)
7:55 lazybot: ⇒ Source not found nil
7:55 fliebel: $source seque
7:55 lazybot: seque is http://
7:56 clgv: I hate the slow github highlighting :(
7:56 humm lazybot linked another defn
7:58 fliebel: clgv: This is my implementation: https://
7:59 clgv: its hard to diff between two tabs ;)
8:01 fliebel: clgv: Basically the core version just puts and takes until it encounters itself. My version uses a second FIFO queue, to send to the other end what to do next.
8:02 clgv: ah ok
8:03 fliebel: my implementation definitely applies f to all items of the passed sequence but has a bounded queue size so that it wont run out of memory (I'll process big files with it)
8:04 fliebel: clgv: So it is basically like (pmap f (seque s limited-queue))?
8:04 $source pmap
8:04 lazybot: pmap is http://
8:04 clgv: fliebel: no pmap only processes a sliding window on consumption
8:05 fliebel: clgv: I don't get it. source?
8:07 clgv: fliebel: (lazy-)seq -> producer takes elements puts them into bounded queue -> queue -> consumer threads process items from queue and put the results in a result queue -> result queue -> returned lazy-seq reads from result queue
8:07 the producer will block when the bounded queue is full
8:08 so the entire calculation is async but you can acces already computed elements via the lazyseq as soon as they are calculated
8:08 fliebel: clgv: in order? Or just asap?
8:08 clgv: at the moment order is preserved but I also want a version where first calculated is first in result seq
8:09 I use it like (pprocess f coll :thread-count 4 :queue-size 8)
8:11 fliebel: clgv: I don't see why you have a queue for the producer. Presumably, f takes long, so the queue is just a buffer of realized items?
8:12 clgv: fliebel: to bound the items that are in memory the producer reads only as much as allowed
8:12 *many
8:13 fliebel: clgv: But if the input is a lazy seq, why realize even a buffer full of them?
8:14 clgv: fliebel: I dont understand your question
8:15 one problem there is that I cant let multiple threads access one lazy-seq like a queue
8:16 fliebel: clgv: Well, you have a lazy seq of unrealized items. You realize 8 ahead of time. Why not realize none at all?
8:16 hmm, is that true? hm, I guess
8:16 clgv: fliebel: and how can the 4 consumer threads access the sequence like a queue?
8:17 fliebel: clgv: Not, unless you put it in an atom or something.
8:18 ref, even
8:18 clgv: fliebel: extracting something from the lazy-seq means calculating it anyways
8:18 so I have to realize an item to pass it into a thread
8:18 fliebel: clgv: Yea, so you just go ahead and put it in a queue, I get it.
8:20 clgv: fliebel: indeed you have to be aware to put all of the expensive computation in the function and not some of it in the lazyseq
8:26 fliebel: one could think of a concurrent lazy-seq that acts like a queue by passing elements out as futures one-by one
8:26 notostraca: How do I pass the contents of a seq as arguments to a constructor that takes lots of arguments?
8:26 Like apply, but for a constructor
8:27 clgv: notostraca: if you cant write a function for it in advance (manually or as part of a macro) you probably have to fall back to reflection
8:27 fliebel: notostraca: (apply new object seq)?
8:27 notostraca: clgv, I never quite figured out macros
8:27 fliebel, I will try it
8:27 clgv: fliebel: that works?
8:28 fliebel: clgv: No idea...
8:28 clgv: ,(apply new java.util.Date [])
8:28 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0)>
8:28 fliebel: no, new is a special form :(
8:29 clgv: I dont think it is possible. but for a defrecord you can enhance the defrecordmacro to create a factory function in 1.2 or use the automatically generated one in 1.3
8:30 notostraca: clgv, I am using defrecord...
8:30 clgv: clojure 1.3?
8:30 notostraca: no, not yet
8:30 I am using CCW in Eclipse, which hasn't updated yet
8:31 is there a better way, I wonder...
8:31 clgv: notostraca: thats not an issue simply delete the clojure jars and replace them with 1.3 ones if nothing else helds you back
8:31 notostraca: so what would I use in 1.3?
8:31 for this particular problem
8:32 I will switch now if it fixes it...
8:32 cemerick: notostraca: you can use 1.3 in your projects with ccw without a problem
8:32 clgv: (->Rec 1 2 3) for (defrecord Rec [a b c])
8:32 in your case: (apply ->Rec [1 2 3])
8:33 notostraca: clgv, great
8:33 clgv: CCW: just installs default clojure 1.2 in your new project but that doesnt prevent you from switching to 1.3
8:34 maybe it should have an option for selecting 1.2.1 or 1.3.0
8:35 fliebel: Would it be possible to somehow proxy an instance of a class? I want to extend it, but it doesn't have a public constructor.
8:35 omg, I can of course just define a protocol and extand that to it.
8:35 clgv: fliebel: you can call the constructor via reflection anyway and use it as aggregate
8:36 protocol approach is much better if possible ^^
8:37 pyr: i supposed core.incubator is meant to get into core eventually
8:37 fliebel: clgv: Yea, I'll do that. I'm trying to handle java.xmail.* objects nicely, so i converted them to maps, but now I can't use the methods of the objects anymore of course.
8:38 clgv: fliebel: writing the next spambot? ;)
8:39 fliebel: clgv: Almost... more like a... web mail rss twitter client... I need to work on my elevator pitch.
8:39 clgv: "elevator pitch"?
8:40 fliebel: clgv: short introduction, like you stand in the elevator with an investor, and you have 10 seconds to explain your product.
8:41 clgv: fliebel: ah. you got a startup?
8:41 fliebel: clgv: hmmm, dunno, I guess you could call it that. A serious project at least.
8:43 clgv: fliebel: so you are still hanging out in elevators waiting for the investors? ;)
8:43 fliebel: clgv: nope, I just started building, and i want to take it to WebFWD.
8:44 clgv: didnt know about that program, yet
8:45 fliebel: clgv: Random question: where are you from?
8:45 clgv: fliebel: seems not that random. germany.
8:47 and you?
8:47 fliebel: clgv: How is it not random? Netherlands.
8:49 clgv: fliebel: scientifically speaking "cant judge since we didnt tie the model". personally, it just doesnt seem random like 11111 doesnt seem ;)
8:50 fliebel: clgv: Well, yea, it's a perfectly normal question, but one moment we're talking about clojure, the next I ask where you are from.
8:51 notostraca: OK, I'm debugging now, it is getting the wrong number of arguments somehow
8:51 fliebel: (tbh, I mostly assume everyone who speaks reasonable english is an american)
8:51 notostraca: It might be that I defined the record with 1 field?
8:52 fliebel: notostraca: paste?
8:53 notostraca: sure, it's kinda a mess and it is meant to read in a TSV table
8:54 http://
8:55 the TSV file is pasted directly from a spreadsheet
8:55 the column names are the first row, everything after that is data
8:56 clgv: notostraca: I have the feeling you are using defrecord strangely
8:56 notostraca: clgv, yeah
8:56 clgv: notostraca: the defrecord contains the header and the map part of the defrecord the values?
8:56 notostraca: I need to define it at runtime
8:56 clgv: notostraca: defining at runtime is not a problem
8:57 notostraca: clgv, I am calling defrecord with a vector drawn from parsing the file
8:57 I don't know if that works
8:57 clgv: notostraca: did you have a look at incanter and how they manage their datasets?
8:57 notostraca: I don't know what incanter is
8:57 clgv: $google incanter
8:57 lazybot: [Incanter: Statistical Computing and Graphics Environment for Clojure] http://
8:57 clgv: thats it^^
8:58 if you need any visualization for your data you should consider it
8:59 notostraca: clgv, no I don't think I need that
8:59 clgv: ok, you might have a look at their dataset implementation - they have a defrecord for it as well
8:59 notostraca: I just need to get this in a hashmap of things, so I can persist it as clojure code with prn
8:59 it doesn't need to be records
9:00 clgv: afaik they divided it into a headerfield and a rows field
9:00 notostraca: there's some old code in that paste that gets the TSV into a sorted-map of hash-maps of strings
9:01 clgv: the header contains the keywords for the columns and the rows field contains the row data with each row beaing a hashmap from column name (keyword) to value
9:01 notostraca: but ideally it would be able to take integer fields in the TSV and convert them to ints instead of strings
9:01 pyr: is there a cleaner (simpler) way to sanitize a map
9:01 clgv: that layout could work for you as well
9:01 pyr: than this:
9:02 notostraca: pyr: pastebin
9:02 pyr: (->> {:a nil, :b :foo} (filter #(val %)) (reduce merge {}))
9:02 notostraca: clgv, it doesn't seem like it needs a lib dependency honestly
9:03 clgv: yes. you can easily build it like that as well.
9:03 pyr: notostraca: i don't think it's warranted
9:03 clgv: notostraca: ^^
9:05 pyr: you could do a reduce + dissoc approach to keep sharing structure
9:06 pyr: reduce dissoc on keys ?
9:08 clgv: pyr: (let [m {:a nil, :b :foo}] (reduce #(dissoc % %2) m (filter nil? (keys m))))
9:08 &(let [m {:a nil, :b :foo}] (reduce #(dissoc % %2) m (filter nil? (keys m))))
9:08 lazybot: ⇒ {:a nil, :b :foo}
9:09 fliebel: clgv: filter is wrong
9:09 clgv: damn... somehting missing. #(let [m {:a nil, :b :foo}] (reduce #(dissoc % %2) m (filter #(nil? (m %)) (keys m))))
9:09 &(let [m {:a nil, :b :foo}] (reduce #(dissoc % %2) m (filter #(nil? (m %)) (keys m))))
9:09 lazybot: ⇒ {:b :foo}
9:10 fliebel: clgv: ##(+ 1 1)
9:10 lazybot: ⇒ 2
9:10 clgv: yeah. typo^^
9:10 pyr: actually, mine should read (->> {:a nil, :b :foo} (filter val) (reduce merge {}))
9:10 ,(->> {:a nil, :b :foo} (filter val) (reduce merge {}))
9:10 clojurebot: {:b :foo}
9:10 pyr: &(->> {:a nil, :b :foo} (filter val) (reduce merge {}))
9:10 lazybot: ⇒ {:b :foo}
9:11 clgv: pyr: yours doesnt share structure with the old map. thats only not that optimal if the map is large and there are few "nil keys"
9:12 pyr: clgv: agreed
9:14 fliebel: I really wish clojure used protocols, so I could extend java.foo.Bar to clojure.lang.IBaz
9:16 notostraca: what is the equivalent of (last) that drops the last element instead of the first?
9:17 like first, but all of the entries but the last
9:17 joegallo: butlast, drop-last
9:17 notostraca: thanks
9:18 joegallo: http://
9:18 ;)
9:18 notostraca: butlast doesn't show up?
9:19 in clojure.core
9:19 huh, nvm
9:21 clgv: you can use lazybot as well
9:21 $findfn [1 2 3 4] [1 2 3]
9:21 lazybot: [clojure.core/butlast clojure.core/drop-last clojure.core/pop]
9:22 bendlas: wut?
9:22 that's advanced
9:25 pyr: $findfn {:a nil :b :foo} {:b :foo}
9:25 lazybot: []
9:28 clgv: it cant build functions compositions although that should be doable as well until the timeout strikes ;)
9:29 marchdown: hello
9:31 notostraca: hmm, maybe that's it
9:32 can you create records with string keys?
9:32 or do they have to be symbols?
9:32 clgv: defrecord will always have keywords of the symbols you provide
9:32 notostraca: ah
9:33 clgv: but you can easily create a keyword via ##(keyword "bla")
9:33 lazybot: ⇒ :bla
9:33 notostraca: so there's the problem
9:33 and if there's a space in "some random phrase" ?
9:33 ,(keyword "something happy...")
9:34 clojurebot: :something happy...
9:34 notostraca: woah what
9:34 clgv: thats probably a bad idea since it works but is not supposed to, i.e. you cant read it back
9:34 ,(read-string (with-out-str (pr (keyword "something happy..."))))
9:34 clojurebot: :something
9:35 notostraca: is there a way to format a string nicely as a symbol?
9:35 clgv: there is also ##(symbol "bla")
9:35 lazybot: ⇒ bla
9:35 clgv: &(class (symbol "bla"))
9:35 lazybot: ⇒ clojure.lang.Symbol
9:35 notostraca: (symbol "oh yeah")
9:35 ,(symbol "oh yeah")
9:35 clojurebot: oh yeah
9:36 notostraca: ah
9:36 joegallo: ,(name 'foo)
9:36 clojurebot: "foo"
9:36 joegallo: oh, that's backwards from what you want. :)
9:36 marchdown: I'm struggling to install clojure. $ java -cp clojure.jar works, but lein barfs out an error.
9:36 notostraca: marchdown, lein should grab its own clojure
9:36 i think it needs maven
9:37 maybe you need to run "lein self-install"
9:37 joegallo: mmm.... i'm not sure about that. marchdown, can you gist the error you're getting?
9:37 notostraca: maybe you need to run "lein selfinstall" instead, not sure what the word is
9:37 duck1123: lein uses maven stuff, but it doesn't actually need maven installed
9:38 marchdown: I don't know the first thing about maven, but I've run 'mvn install' in clojure repo as per instructions, and it did something. I'm on a mac with system-provided java.
9:39 joegallo: yeah, i don't think that does what you'd like it to do
9:39 that's "install this jar into my local .m2 directory"
9:39 which isn't quite as awesome as it sounds... :)
9:39 notostraca: marchdown, have you run lein just as "lein" ?
9:39 duck1123: Some clojure projects use maven, also as part of lein install, a basic pom file is created
9:40 marchdown: https://
9:40 joegallo: don't try to install leiningen 2.0.0
9:40 it's a highly experimental in-development version -- i think
9:41 notostraca: use stable -- https://
9:42 you can probably just wget that
9:43 download that into somewhere on your PATH, like /usr/bin , "chmod 755 lein", "./lein"
9:44 you may need to run the last two as sudo if you put it somewhere where you need root permission to write
9:45 duck1123: I prefer to put mine in ~/bin or similar, that way I can upgrade without sudo
9:45 marchdown: cool, thanks. I'm feeling so stupid now for not noticing it was a plain old 404. The reason is, this is the second box I'm installing clojure on, and the first time I had an error at the same stage, but it was far more cryptic.
9:45 duck1123: just have to make sure that dir is on PATH
9:46 marchdown: Okay. So, how'd I hook it up with emacs now?
9:46 I need a clojure-runner script, right?
9:46 joegallo: no
9:47 notostraca: marchdown, are you familiar with emacs? Because I'm not, and there are good IDE plugins too
9:47 and the IDE plugins probably have better support for Java, though I can't be certain
9:47 marchdown: I am.
9:47 notostraca: ok
9:48 joegallo: you need clojure-mode
9:48 marchdown: Got that.
9:48 joegallo: you need lein-swank-[latest stable version].jar in you ~/.lein/plugins/ directory.
9:48 notostraca: in that case, I imagine you will be sticking with mostly- or pure-clojure projects, which will be pleasant compared to switching your mindset from one to the other
9:55 dabl: hi all, /quit
10:06 notostraca: is there a good way to get an Integer or int or some number from a String in clojure?
10:07 kephale: ,(read-string "1")
10:07 clojurebot: 1
10:07 notostraca: huh good to know
10:07 ,(read-string "1 2 3 4"
10:07 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
10:07 notostraca: ,(read-string "[1 2 3 4]")
10:07 clojurebot: [1 2 3 4]
10:07 notostraca: ,(read-string "1 2 3 4")
10:07 clojurebot: 1
10:08 joegallo: ,(doc read-string)
10:08 clojurebot: "([s]); Reads one object from the string s"
10:09 notostraca: ,(/ (read-string "1") 3)
10:09 clojurebot: 1/3
10:10 Wild_Cat: ,(Integer. "2")
10:10 clojurebot: 2
10:12 clgv: notostraca: there is also Integer/parseInt
10:13 notostraca: I'm going to read-string on every value, individually -- it handles string data so I don't need to have types as part of the data
10:16 fliebel: notostraca: read-string is a bit of a security issue, I think. I don't know if that matters to you.
10:18 jcromartie: So I was playing with this on the train this morning: https://
10:18 creating a temporary memoization context for certain functions... is there any chance that this is already idiomatic?
10:18 notostraca: fliebel, I am making the data in a spreadsheet, so it will be fine
10:18 jcromartie: it makes writing this kind of math code very nice
10:19 fliebel: notostraca: I just saw you already evaluated a list.
10:19 clgv: ,(read-string "(System/exit 0)")
10:19 clojurebot: (System/exit 0)
10:20 clgv: ,(read-string "(eval (System/exit 0))")
10:20 clojurebot: (eval (System/exit 0))
10:20 clgv: lol
10:20 ,(eval (read-string "(System/exit 0)"))
10:20 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>
10:20 clgv: hehe ok^^
10:20 so read-string cant do any harm I guess, since it is not evaling
10:21 ,(read-string "#=(System/exit 0)")
10:21 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
10:21 clgv: ,(binding [*read-eval* true] (read-string "#=(System/exit 0)"))
10:21 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.ClassNotFoundException: System>
10:21 floatboth: clgv: sandbox won't let you eval anyway
10:21 fliebel: jcromartie: You should talk to fogus, he's putting a memoization lib in contrib.
10:22 jcromartie: I got my math wrong :P
10:26 fliebel: Do there exist functions for translating and selecting keys from a map? {:foo 1 :bar 2} -> {:baz 2}
10:28 wee, armagedom :)
10:28 clojurebot: botsnack
10:28 clojurebot: Thanks! Can I have chocolate next time
10:28 fliebel: I'll see...
10:29 clgv: fliebel: select-keys, rename-keys
10:30 $findfn {:bar 2}{:baz 2}
10:30 lazybot: []
10:30 clgv: $findfn {:bar :baz} {:bar 2}{:baz 2}
10:30 lazybot: []
10:30 clgv: $findfn {:bar 2} {:bar :baz} {:baz 2}
10:30 lazybot: [clojure.set/rename-keys]
10:31 fliebel: ah, it's hiding in set...
10:31 clgv: yep, they always do ;)
10:33 fliebel: clgv: Maybe it should be named clojure.map then...
10:33 I should revive clojure-quiz
10:34 clgv: &(keys #{1 2 3})
10:34 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry
10:34 clgv: &(rename-keys #{:a :b :c} {:a :z})
10:34 lazybot: java.lang.RuntimeException: Unable to resolve symbol: rename-keys in this context
10:34 clgv: &(use 'clojure.set)
10:34 lazybot: ⇒ nil
10:35 clgv: &(rename-keys #{:a :b :c} {:a :z})
10:35 lazybot: java.lang.ClassCastException: clojure.lang.PersistentHashSet cannot be cast to clojure.lang.Associative
10:35 clgv: fliebel: yes it should be renamed indeed ^^
10:35 fliebel: hm, what about rename-keys-in? [:foo bar] [:baz] :D
10:36 apgwoz: has anyone used the ring-netty-adapter ?
10:37 clgv: no I meant clojure.set -> clojure.map
10:43 fliebel: apgwoz: *netty*? Interesting. No, but I've used Aleph, which uses Netty.
10:43 .. and provides a ring wrapper.
10:44 apgwoz: fliebel: might be worth finally jumping into aleph if that's the case. cool, i'll have a look
10:45 is there a specific ring-aleph-adapter? or were you just doing (respond! (ring-handler whateer)) like i saw in an old clojure list thread?
10:46 fliebel: nevermind. gonna research aleph. the answers probably sitting there waiting for me to read it
10:46 :)
10:47 fliebel: apgwoz: I can't remember either.
10:48 apgwoz: fliebel: looks like aleph.http has (wrap-ring-handler ...) that is the magic button
10:50 clgv: $inc aleph
10:50 lazybot: ⇒ 2
10:51 * clgv gotta research aleph as well
10:57 cemerick: huh, didn't realize you didn't need a handle for that
10:57 $inc kittens
10:57 lazybot: ⇒ 1
10:59 jidotnet: cemerick: just had a look at your conj slides
11:00 cemerick: any idea when the code will be available?
11:02 cemerick: jidotnet: should have been out already. I'm running behind on about 83 different things. :-|
11:02 I'll definitely make some noise when it's up :-)
11:04 jidotnet: cemerick: cool thanks; i'll keep whatching ;)
11:16 jweiss: can someone recommend a way to have metadata added to an object (eg, with ^{:my :meta} that doesn't overwrite the meta that is already there?
11:17 or can i not use ^ at all, must i do (with-meta obj (merge (meta obj) newmeta))
11:25 clgv: jweiss: there is vary-meta - see ##(doc vary-meta)
11:25 lazybot: ⇒ ------------------------- clojure.core/vary-meta ([obj f & args]) Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata. nil
11:26 jweiss: clgv: thanks, was hoping to be able to use ^ but that does not appear possible. i'll just make a function with a short name to make it convenient for my users :)
12:02 fliebel: Where and how do you usually store configuration?
12:03 for a web app
12:05 duck1123: I have a library that allows you to store config maps in the root of the project and then query them like (config :foo :bar :baz)
12:05 It'll merge the default environment with the specified environment
12:06 It works well enough for my needs
12:11 fliebel: duck1123: Nice idea.
12:13 duck1123: fliebel: If you're interested https://
12:16 reiddraper: I'm trying to understand the difference between clojure.lang.Seqable and clojure.lang.ISeq, could just be that my java-reading skills are rubbish
12:17 cemerick: Seqables can provide an ISeq
12:18 reiddraper: cemerick: If I'm making a new type with deftype, which should I be looking to implement, both then?
12:18 cemerick: The tricky part is that `seq` provides polymorphism that isn't entirely captured by Seqable.
12:18 joegallo: sounds like iterables which can return an iterator, from java collections
12:18 cemerick: That's the right corollary.
12:19 reiddraper: if your type *is* a seq, then implement ISeq (or some derivative). If it can provide a seq, Seqable.
12:19 'course, the former extends the latter
12:20 reiddraper: cemerick: ok that makes sense. I'm making a Set, so it sounds like I want to provide a seq
12:20 on second that, i suppose a set *is* a seq
12:20 s/that/thought
12:21 cemerick: how is a set a seq?
12:21 hiredman: no
12:21 reiddraper: maybe i have a poor seq definition
12:21 Chousuke: most things aren't seqs
12:21 but lots of things are seqable
12:22 in core only lists are true seqs (and lazy seqs of course)
12:22 cemerick: The only built-in that are their own seqs are lists
12:22 hah
12:22 oh, Cons too :-P
12:24 reiddraper: i remember coming across definitions for these before... so are all things that *are* seqs, sequential?
12:28 cemerick: for want of a reasonable class hierarchy viewer online
12:28 oh, hah
12:29 reiddraper: http://
12:29 reiddraper: cemerick: cool, thanks
12:52 shequo: I'm interested in learning about how clojure implements efficient creation of modified datastructures via structural sharing etc...can anyone point me in a good direction to research this?
12:52 fliebel: What kind of magic could be going on here? I have a ring handler, if I call it on the repl, I get a result, if I launch jetty with it, a weird NullPointerException.
12:53 shequo: You could try the research papers for them.
12:53 dnolen: shequo: Okasaki - Purely Functional Data Structures
13:00 fliebel: Magic: The handler has no default route, returns nil, end of story.
13:12 antares_: hey. I have a question: where do I need to sign up to publish jars to oss.sonatype.org? Looks like clojars.org is having some issues, my freshly published jars cannot be accessed even though project page loads fine and displays the version I pushed.
13:44 gfredericks: anybody know what's messed up if my `lein repl` goes nuts whenever I backspace?
13:45 by "goes nuts" I mean continues functioning properly, but deletes a bunch of characters so I can't tell what's going on
13:48 duck1123: gfredericks: does it do this even if you open a new terminal?
13:49 gfredericks: hmm, no
13:49 it's been happening for a day or two now, across different terminal instances. I'm not sure what the common thread is
13:50 oh let me try it with this particular project...
13:50 duck1123: are you printing out "odd" values?
13:50 gfredericks: nope
13:51 okay, it does do it for this project
13:52 * gfredericks looks at his project.clj
13:52 gfredericks: maybe it's this dependency on jruby
13:53 yep, remove jruby dep and it's better
13:53 well if there's one thing you can count on ruby to do, it's magical crap in the background that you have no hope of ascertaining.
13:54 duck1123: don't forget screwing up your UTF-8
13:55 gfredericks: duck1123: thanks for rationally talking me through it. Being punished for backspacing can make you go batty.
13:56 duck1123: bah! real programmers don't need backspace. Everything is perfect the first time.
13:57 gfredericks: That'd be a funny feature for an elite keyboard
13:57 moogatronic: or a mode for emacs.
13:57 amalloy: gfredericks: but ^H would still work
13:58 gfredericks: if jruby was a problem, i bet it's because it pulls in a ruby version of readline, conflicting with the one your system wants to use
13:58 gfredericks: amalloy: holy crap this might drastically improve my life
13:59 by which I mean my finger pain
13:59 does ^H work everywhere?
13:59 amalloy: anywhere that expects emacs/readline-style stuff
13:59 on a mac, i think that's pretty much anywhere
13:59 duck1123: most of the emacs commands work in terminals
13:59 gfredericks: I'm on ubuntu
14:00 it works on irssi and in the bash terminal at least
14:00 duck1123: I always feel so awesome when I make use of C-t correctly
14:00 moogatronic: i'd be surprised if it didn't do the same everywhere in ubuntu
14:00 amalloy: gfredericks: like i said, anyplace that uses readline
14:00 gfredericks: I bet it doesn't work in vim, but I'm sure that can be changed
14:00 amalloy: moogatronic: prepare to be surprised, bro
14:00 duck1123: it's an option
14:00 gfredericks: is there a key shortcut for enter as well
14:00 amalloy: gfredericks: ^J
14:01 gfredericks: omg.
14:01 amalloy: *now* will you learn emacs?
14:01 gfredericks: no.
14:01 amalloy: gfredericks: you can also configure readline to use vim bindings instead of emacs bindings
14:01 in your .inputrc i think
14:02 duck1123: gfredericks: https://
14:02 gfredericks: oh ^H and ^J both work in vim
14:02 duck1123: that looks like a good link
14:02 amalloy: it seems weird to me that you'd want to use them in vim, though. doesn't vim encourage you to go into edit-mode and then type d<something>?
14:03 duck1123: actually, not as good as I'd hoped for the key shortcuts
14:03 amalloy: dh, i guess
14:03 gfredericks: amalloy: true, I probably don't really use backspace and enter in vim. I just expected I could get annoyed if I got used to ^H/J and then vim didn't support them
14:03 but you're right, probably wouldn't have mattered
14:04 I'll think about emacs.
14:05 I don't remember what my objections were.
14:05 moogatronic: also ^? .. (http://
14:06 gfredericks: moogatronic: oh. that helps explain it better.
14:09 amalloy: haha that dang ^S. i've accidentally frozen a few consoles with that. i guess this was back when i had readline set up in vim mode, though, because ^S does something different normally
14:22 R4p70r: Let’s try this again. Is anyone in Canada looking for an entry-level Clojure dev? I’m in Montreal but willing to relocate.
14:34 amalloy: duck1123: thanks for that ascii link, btw. i knew most of that already, but noticing that escape characters get sent as ESC [ helped me figure out a problem i've been having, actually
14:41 gfredericks: Look maybe I'll think about emacs but not for another couple weeks. Gotta graduate first.
14:44 moogatronic: gfredericks: yeah, graduation > emacs. =)
14:44 gfredericks: huh. I just realized that ^J and ^H mirror the functionality of vim's 'j' and 'h'
14:46 At least in not-insert-mode
14:50 kephale: are you sure emacs doesn't have a key bind for degree completion?
14:52 gfredericks: even if it does I'm sure I'd forget it when I actually needed it
15:11 amalloy: like C-t
15:13 fliebel: amalloy: ?
15:13 kephale: never used that one
15:14 amalloy: fliebel: an emacs command you forget whenever you acutally need it (see what i did there?
15:14 kij: hey guys. Is there an form that would let me do a (dissoc { :a 1 :b 2 :c 3 } (unlist '(:b :c)) ) ... unlist would just return :b :c
15:14 amalloy: &(doc apply)
15:14 lazybot: ⇒ ------------------------- clojure.core/apply ([f args] [f x args] [f x y args] [f x y z args] [f a b c d & args]) Applies fn f to the argument list formed by prepending intervening arguments to args. nil
15:14 amalloy: &(apply dissoc {:a 1 :b 2 :c 3} [:b :c])
15:14 lazybot: ⇒ {:a 1}
15:17 gfredericks: works because ##(dissoc {:a 1 :b 2 :c 3} :b :c)
15:17 lazybot: ⇒ {:a 1}
15:18 fliebel: amalloy: You wrote {:keys [tag attr content]}, do you mean that every node is actually a map?
15:18 amalloy: yes
15:18 kij: thanks!
15:19 '(:a :b) -> :a :b, is not possible ? what should i read to understand why ?
15:20 amalloy: kij: because one thing is not two things
15:20 fliebel: amalloy: oh, ok. I'm just using sequences.
15:20 gfredericks: kij: you're saying you want dissoc to return the keys that you removed?
15:21 kij: if so, then it doesn't do that because you want it to return the map instead. Clojure maps are immutable, so dissoc creates a new map that doesn't have the keys. If it returned the keys, you wouldn't have the new map, so nothing would have happened.
15:21 amalloy: fliebel: hiccup uses vectors: [tag attrs & content]
15:21 kij: gfredericks: no, i would like to remove the list and get the single values.
15:21 amalloy: kij: it is not possible to return two values from a function
15:21 fliebel: amalloy: I do the same, without the attrs, which is really convenient, because of the first/rest concept in Clojure.
15:22 amalloy: just like it is not possible to do that in c, or python, or...
15:22 gfredericks: kij: I'm not sure what that means
15:22 amalloy: gfredericks: he wants (unlist [1 2]) to return both 1 and 2, but not as a list
15:22 so that he can splice it into some function call
15:22 gfredericks: amalloy: ah, that makes some sense of it
15:23 kij: gfredericks: what amalloy says :)
15:23 Raynes: So, he wants apply?
15:23 gfredericks: kij: then amalloy's original recommendation of using 'apply' is what you want
15:23 fliebel: kij: You can use destructuring: ##(let [[a b] '(1 2)] b)
15:23 lazybot: ⇒ 2
15:23 Raynes: But doesnt know it?
15:23 (apply + [1 2 3])
15:23 amalloy: Raynes: arguably he should know it, because i said that already
15:23 Raynes: &(apply + [1 2 3])
15:23 lazybot: ⇒ 6
15:24 kij: i understand now. Thanks!
15:25 fliebel: How can I setup, run and test a Maven Clojure project, such as data.xml?
15:25 gfredericks: mvn clojure:[compile|test]?
15:26 fliebel: gfredericks: uhm, okay. Let me try...
15:26 duck1123: mvn test and mvn compile work as well
15:26 amalloy: fliebel: just $ mvn test
15:26 duck1123: or mvn clojure:swank or mvn clojure:repl
15:27 amalloy: duck1123: oh, good to know. i just added a project.clj locally to get swank
15:27 duck1123: amalloy: be careful. lein install will clobber your pom.xml (but that's what git is for)
15:36 fliebel: amalloy: Huh, weird output... It sets the namespace as an attribute? Did you setNamespaceAware, as the ticket suggested?
15:37 amalloy: fliebel: that's actually a perfectly valid way to set the xmlns of a node
15:37 fliebel: amalloy: Okay, so the test is incorrect?
15:37 amalloy: by declaring "everything from here (inclusive) on down, is implicitly in the api namespace"
15:37 fliebel: i think the test is *probably* over-specific, but like i said i don't know a ton about namespaces
15:38 last time i had to know anything at all about them was five years ago
15:39 fliebel: amalloy: You are using SAX for everything, right?
15:39 amalloy: fliebel: no idea
15:39 that stuff is all chouser's - mostly i just wrote the converter from hiccup-style to enlive-style
15:40 fliebel: amalloy: Which is which?
15:40 amalloy: hiccup: [tag {attrs} & content]
15:40 enlive: {:keys [tag attrs content]}
15:41 fliebel: ArmageDOM: ^{attrs} [tag & content]
15:41 amalloy: MADNESS
15:41 brehaut: what
15:41 amalloy: i know, right? someone tell fliebel that attrs are not metadata
15:42 fliebel: in fairness though i can see how that would be handy, and i can't immediately think of any ways it would cause a problem or be hard
15:43 fliebel: meta = about itself, data about the data: <link rel="base">http://
15:43 brehaut: ,(= ^{:href "http://
15:43 clojurebot: true
15:43 brehaut: thats why its bad
15:44 amalloy: hah
15:44 yes, wow that's bad. thanks, brehaut
15:44 brehaut: no problem
15:45 amalloy: brehaut: if you care to follow along, the discussion started at http://
15:45 fliebel: hmm, good point.
15:45 brehaut: amalloy: ah right. /me catches up
15:45 amalloy: the metadata discussion isn't really germane, i was just astonished by his choice
15:46 dnolen: fliebel: attributes are not definitely not metadata
15:46 metadata is not just data about data, it's data about data that should never be considered under equality
15:46 amalloy: btw fliebel: "at frist glance, mine doesn't have 20-line functions." i didn't get your point here
15:48 fliebel: amalloy: I mean to say the emit code is rather ugly, if you ask me: https://
15:49 dnolen: That is indeed a detail of clojure meta data I had not considered.
15:49 brehaut: wait. core.xml is seperate to clojure.xml ?
15:50 fliebel: brehaut: According to the readme, it might become clojure.xml later.
15:51 amalloy: i'm in favor of pulling the configuration out into a separate function, fliebel, but i suspect there's a good reason the code exists (ie, you couldn't just throw half of it away)
15:51 brehaut: fliebel: thanks; ive had to hack about with clojure.xml's emit for necessary-evil (thanks python xmlrpc imp); core.xml looks like it might fix the issue for me
15:51 (https://
15:52 fliebel: amalloy: My initial iteration of ArmageDOM looked like that, but now it's broken into small bits.
15:53 amalloy: brehaut: so is python's impl incorrect and you need to cover for it, or clojure's is incorrect and you need to send python something more-correct
15:53 brehaut: amalloy: its python's thats dodge; new lines throw it out, which i dont believe should be a problem
15:54 amalloy: and 1.2's emit-elements hardcoded emitting new lines (with println)
15:54 amalloy: i see. so you copied the code but changed println to print. very funny
15:55 brehaut: indeed; i couldnt think of a better way to do it :P
15:55 amalloy: wow clojure.xml is *really* old
15:55 brehaut: oh! https://
15:56 im not sure if i was using the xml tools wrong, or if its an actual bug
15:56 fliebel: yea, structs and all
15:56 amalloy: check out the last three lines:
15:56 ;(export '(tag attrs content parse element emit emit-element))
15:56 ;(load-file "/Users/rich/dev/clojure/src/xml.clj")
15:56 ;(def x (xml/parse "http://
15:56 brehaut: but that version of emit wasnt escaping < > and &
15:56 * brehaut wonders why he never raised these as issues in the past. sorry!
16:22 fliebel: amalloy: I think setting http://
16:24 call setFeature on *something*
16:25 amalloy: fliebel: indeed, that is the crux of most of the data.xml problems. "how do we set a damn feature"
16:25 fliebel: "Turn features on or off using setFeature."
16:25 amalloy: right, but features aren't standardized
16:25 across the various impls
16:26 fliebel: amalloy: but, but... these are "SAX2 Standard Feature Flags"
16:26 amalloy: there are *some*. did you find one for indentation/pretty-print?
16:26 fliebel: amalloy: scroll down here: http://
16:29 amalloy: fliebel: i see the one for namespaces, but not for whitespace
16:29 fliebel: amalloy: me neither....
16:32 amalloy: http://
16:33 amalloy: fliebel: that's for parsing, not output. but not relevant anyway because it's apache-specific. we already set the apache indent-amount, but not every transformer is an apache transformer
16:33 which is why this whole thing is a mess
16:34 fliebel: amalloy: so the project is waiting for a minor whitespace issue?
16:34 amalloy: yes, absurd as i personally think that is
16:34 that's why a number of forks have sprung up on clojars
16:36 technomancy: we should have clojars alert a library maintainer once a threshhold of forks have been created
16:36 "hey dude, I don't know if you've been paying attention, but you might want to do something about this..."
16:38 brehaut: technomancy: thats a great idea
16:42 fliebel: meta data counter-argument: href/src is so far the only one that would matter for equality. counter-example: <content type="xhtml">foo</content> <content type="html">foo</content> <content type="text">foo</content>
16:43 amalloy: fliebel: that is so, so wrong. what about ant build files?
16:43 fliebel: amalloy: What does an ant buidl file look like... googles.
16:43 amalloy: shield your eyes
16:44 i'm just saying, attributes are an integral, important part of an xml element
16:44 pretending they're metadata is bizarre
16:45 in html, if you prefer: <input type="button" name="submit" /> vs <input type="text" name="name" value="your name here" />
16:47 brehaut: fliebel: i think what you are confusing is that in most xml applications, the attributes are treated as a kind of meta data, but in a tool that is handling xml data, then that isnt meta data, its straight data
16:47 fliebel: amalloy: well, they are metadata, only not of the same kind as clojure meta data.
16:50 brehaut: that is true.
16:52 tolstoy: Is there a handy clojure lib to deal with uint type of issues?
16:52 brehaut: tolstoy: most people just use one size larger primatives
16:53 fliebel: Now I have a problem, because I like neither the enlive or the hiccup syntax. The one is verbose, the other ambiguous.
16:53 tolstoy: brehaut: Okay. I've done all that before. I was hoping someone had a handy lib that could read byte-buffers and Do The Right Thing. ;)
16:53 brehaut: tolstoy: i dunno sorry
16:54 amalloy: fliebel: hiccup isn't ambiguous at all, it's just a teeny bit non-trivial to parse
16:54 tolstoy: brehaut: No prob! Just curious.
16:55 brehaut: fliebel: enlive is verbose because xml is verbose :P
16:56 fliebel: brehaut: I thought the point of a DSL was to... nvm, I'll just use (format "<xml>" foo bar) ;)
16:57 brehaut: fliebel: but you almost never need to reference the node enlive structure directly in either enlive or the older clojure.xml stuff
17:00 fliebel: amalloy: [:tag {:foo 1} "bar"], now did I make an attribute, or added a map as a child?
17:00 amalloy: you can't add a map as a child, because children are always vectors
17:01 you can't have attrs free-floating in an xml document: they're attached to a tag
17:01 you're right that it's awkward to add an attribute to a node that might or might not have an attr-map already; you can avoid this by creating nodes that have empty attr-maps instead of no map at all
17:02 i guess you're saying that hiccup isn't a format that's easy to modify programmatically once it's been written - i agree with that
17:04 fliebel: amalloy: What I'm saying is that tag and content map nicely to key/value or first/rest, attr is why we can't have nice things.
17:05 Chousuke: that's a fault in XML :p
17:05 at least regarding a Clojure DSL design
17:06 fliebel: Chousuke: true
17:10 * kephale shakes fist at amalloy. I keep pressing C-t now
17:10 amalloy: kephale: i rebound C-t to transpose-sexps, which is something i use a lot more often
17:10 kephale: amalloy: ooo good tip
17:14 fliebel: amalloy: What is C-t? I don't have emacs.
17:15 btw, solution: (defn =m [& args] (and (apply = (map meta args)) (apply = args))) :P
17:15 amalloy: fliebel: transpose-characters
17:16 fliebel: amalloy: like.. rot-n?
17:16 amalloy: turns e|t into te|
17:16 (where | is point)
17:17 transpose-sexps turns (map (some-seq) | f) into (map f (some-seq)|)
17:17 fliebel: nice
17:17 Raynes: That makes me happy.
17:20 schaefer: hi. anyone here familiar with the insides of core.logic? i'm interested in implementing the IUnify* protocols and would like a little direction
17:20 clojurebot: http://
17:21 Raynes: ambrosebs is totally not familiar with core.logic.
17:21 amalloy: well, clojurebot, i guess maybe he wanted to know about protocols in general. good try
17:21 schaefer: heh
17:22 ambrosebs: well i didn't write them :P
17:22 schaefer: ah.. i missed your nick on the list :)
17:22 ambrosebs: but I can open the source and make some sense of it
17:22 what are you try ing to do?
17:22 schaefer: so, i'm looking to incorporate a database as a source of facts
17:23 i just started looking at the code about an hour ago and it looks like i need to implement the IUnify* protocols but i'm a lost on what each one of them does
17:25 klutometis: What do you call the property of `defn' such that I can do: (let [] (def x 2)) x => 2. Doesn't that break lexical scoping in the sense that `x' shouldn't be visible outside the `let'?
17:25 Doing e.g. `(let () (define x 2)) x' in Scheme gives me ``Error: unbound variable: x'', which is lexically consistent.
17:25 s/defn/def/
17:26 schaefer: i don't know if you're familiar with mandarax (a java backwards reasoning system). it defines an interface which supplies a set of constraints and return a resultset-like lthing. an RDBMS implementation simply converts the constraint parameters into SQL and returns a wrapped JDBC result set
17:26 fliebel: klutometis: clo*s*ures
17:27 oh, no
17:27 klutometis: fliebel: That's my point, dude: x shouldn't be visible outside of that closure. Clojure is breaking lexical scoping.
17:28 fliebel: klutometis: yes, in Clojure def just defines a var outside of the let scope. Going to bed now...
17:28 technomancy: klutometis: vars are totally different things from locals; you seem to be confusing the two
17:28 klutometis: fliebel: Thanks.
17:28 aperiodic: klutometis: def doesn't create a closure, it defines a var in the namespace
17:30 klutometis: aperiodic: Oh, ok; I'm used to Scheme, where even `define' won't break lexical scoping.
17:30 * klutometis must erase the def-define analogy from his neurons.
17:31 amalloy: "break" is a strong word
17:31 technomancy: def doesn't create locals; it has nothing to do with lexical scope.
17:31 klutometis: technomancy: This whole locals/vars dichotomy is another way of saying: "we don't respect lexical scope."
17:32 amalloy: scheme just guarantees that if the first "chunk" of expressions in a define are themselves defined, they get given lexical scope
17:32 klutometis: amalloy: Good point.
17:32 technomancy: klutometis: lexical scope is for locals
17:32 it's totally unrelated
17:32 gfredericks: dangit ^J won't work in the browser.
17:32 amalloy: define normally creates dynamically-scoped variables, even in scheme
17:32 klutometis: technomancy: Right; circular argument, though.
17:32 amalloy: there's just this crazy exception for if it's at the beginning of another define
17:32 gfredericks: i think most browsers do have a shortcut for that though
17:32 klutometis: amalloy: Really? I'm trying to conjure up an example.
17:33 amalloy: in the url bar, anyway
17:33 * brehaut restrains himself from a web framework pun
17:33 klutometis: amalloy: Oh, in the sense that `let' reduces to `define'.
17:33 amalloy: klutometis: well, i'm not a scheme expert at all. but (define (foo x) (...blah...) (define (bar y) 10)) is undefined, i believe
17:34 i read that in sicp, so it must be true
17:35 technomancy: that's like saying set! "breaks" variables because it changes their value. it's what it's there for.
17:35 klutometis: amalloy: Hmm; I mean, `bar' is visible within `foo' but not outside of `foo'. Is that what you mean?
17:35 The actual return value of `define' is the value `#<unspecified>'.
17:36 amalloy: no, i mean, it's not defined by the scheme standard. your scheme implementation can do whatever it wants
17:36 klutometis: Oh, right; `unspecified'.
17:36 Thanks, guys.
17:40 amalloy: technomancy: heh. set! *does* break variables, which is what it's there for
17:40 technomancy: amalloy: the horror
17:46 aperiodic: is there a handy way to handle posix signals in java/clojure?
17:47 Raynes: aperiodic: http://
17:49 klutometis: technomancy: Heh, missed that the first time around.
17:50 aperiodic: Raynes: so not within the context of my application?
17:52 kd4joa: Anyone here know the Midje testing package well and could help with a question?
17:54 I want to test a function that returns a list of hash maps but only care that the maps have a particular key. I don't care about the rest of the map.
17:54 hiredman: contains?
17:54 clojurebot: contains? is for checking whether a collection has a value for a given key. If you want to find out whether a value exists in a Collection (in linear time!), use the java method .contains
17:54 kd4joa: In other words the function returns [{:id 1 :score 1.5} {:id 2 :score 0.5}] and I only care that the maps have :id 1 and :id 2
17:55 I tried contains but it didn't seem to work right. I tried [{:id 1 :score 1.5} {:id 2 :score 0.5}] => (contains [ { :id 1} {:id 2} ])
17:55 and a couple other permutations of that
17:56 hiredman: well, uh, that is plainly wrong, so I suggest you read some docs
17:58 kd4joa: thanks. that's very helpful.
18:00 aperiodic: ,(contains? {:id 1} :id)
18:00 clojurebot: true
18:00 aperiodic: ,(contains? [{:id 1}] :id)
18:00 clojurebot: false
18:01 carllerche: I'm trying to write some documentation for a async / future library I'm working on. If anybody has some time, i would appreciate feedback: https://
18:06 moogatronic: kd4joa: are you just wanting know know whether every map in your list contains :id ?
18:08 kd4joa: no, I want the maps to have the pair :id 1 and :id 2
18:08 I thought the Midje contains function was for that but can't get the syntax for it right I guess
18:09 I don't care about what the rest of the keys and values in the maps are
18:09 alexbaranosky: k4djoa: I think you're right
18:09 what do you need to test exactly?
18:09 that a certain map contains some key-val pairs?
18:10 moogatronic: looks like he wants to test if a list of maps collectively contain given key-value pairs.
18:11 kd4joa: yes. moogatronic has it right
18:11 alexbaranosky: don't think midje has a built-in checker for that
18:11 kd4joa: ok. thanks. I thought the contains checker might work for it, but I haven't been able to get it to work so it must not
18:11 alexbaranosky: kd4joa: let me investigate further
18:12 you can just write function for it
18:12 kd4joa: yeah that's what I'll have to do then. I just thought I was being dense about the contains checker
18:12 alexbaranosky: then say: (fact (my-function-call) => (partial maps-contain { ......}))
18:13 kd4joa: thanks for the help! much better than "go read some docs" answer I got a little bit ago
18:13 alexbaranosky: kd4joa: though don't quote me on the syntax, I haven't needed to test that kind of thing
18:13 I've used aMidje a lot
18:14 kd4joa: le t me know how it goes, and if you have any more questions
18:14 moogatronic: At first i thought you were asking this:
18:14 (reduce #(and %1 (contains? %2 :id)) true [{:id 1 :score 1.5} {:id 2 :score 0.5}])
18:15 but i think just need a function to or some internal may k/v checks
18:17 Raynes: kd4joa: Don't mind him. He means well.
18:18 You can't have an apple tree without a few rotten apples at some point.
18:18 moogatronic: hard cider!
18:18 technomancy: moogatronic: not for Raynes; he's underaged.
18:18 (at least in the US)
18:19 Raynes: ;)
18:19 moogatronic: I think "hard cider" is a US'ism anyway -- cider means fermented apple juice everywhere else I think.
18:19 alexbaranosky: technomancy: but there's a blue hair law - if your hair's blue you can drink at 16
18:19 moogatronic: alexbaronsky: ONLY when operating a vehicle though, i'm pretty sure.
18:20 Raynes: I only drink when I need to drive long distances. It helps me stay focused.
18:20 kd4joa: Thanks all. I've found the clojure community very welcoming to newcomers. I know there are exceptions in every group
18:21 alexbaranosky: Raynes: but yeah totally legal in 49 states -- if your hair is blue
18:21 Raynes: I'm golden then.
18:21 alexbaranosky: ok, I'll stop polluting the airwaves with bad humor ;)
18:23 moogatronic: the uc davis cop may provide you with some sriracha to the face if you don't stop. =)
18:33 gfredericks: java interop in jruby never ceases to aggravate.
18:33 $inc clojure
18:33 lazybot: ⇒ 4
19:10 yaron2343: Anyone been playing with defrecord? I'm tearing my hear out on an issue and was hoping for some help.
19:11 brehaut: yaron2343: just ask your question, if someone can help they will
19:12 yaron2343: I am using a trivial defrecord (defrecord connection-record [next-state conf-func]) in my clj file. I then C-c C-l the whole clj file into my repl (e.g. via swank). Any attempt to reference the record fails. I try import (e.g. (import lib-phl.core connection-record)) and that fails to.
19:12 I just get class errors.
19:15 tolstoy: Is your repl in the same namespace as the file? (I got nothin.)
19:16 yaron2343: No, it's not. That's why when I try to reference the record I use a fully qualified name (e.g. lib-phl.core/connection-record
19:16 I also tried lib-phl.core.connection-record out of desperation
19:16 brehaut: yaron2343: but if you are sending the record to a different name space then its going to be created there
19:18 yaron2343: I tried connection-record by itself and it doesn't work. Where as other functions I defined in the clj file show up just fine so long as I prefix them with lib-phl.core. For example lib-phl.core/is-connection-record? Shows up just fine.
19:18 It's only the class defined with defrecord that doesn't show up.
19:18 brehaut: oh, dashes in record names is a bad idea
19:18 try ConnectionRecord
19:18 to avoid having name munging
19:19 i would guess that connection-record is being name munged to connection_record for the classname
19:19 yaron2343: I actually figured that as well and tried _ but it didn't make any difference.
19:20 I also tried that with my namespace that also has a dash in it (e.g. typing in lib_phl.core instead of lib-phl.core)
19:20 What's weird is that functions defined in my clj file that use the record work just fine!
19:21 brehaut: yaron2343: records are much more complex than functions
19:21 yaron2343: Indeed, I'm seriously considering just moving all my code back to structs. At least those worked easily. :(
19:21 brehaut: try running your defrecord directly in your repl, rather than sending it to the repl from the editor
19:21 jeez, not structs. just use maps
19:22 yaron2343: Oh if I define the record in the REPL directly then everything works just fine.
19:22 brehaut: ok so its not a defrecord problem, its someting to do with your slime usage
19:22 yaron2343: It's only if I try to load the file C-c C-L or the buffer segment C-c C-R that I'm in trouble.
19:23 Yeah it smells strongly like a class path resolution issue
19:23 It's not finding the class.
19:23 For example, when I try to C-c C-l my test file I get the error lib-phl.core.connection-record ClassNotFoundException
19:24 And yes, I tried changing it to (:import [lib-phl.core ConnectionRecord]) and sure enough I get lib-phl.core.ConnectionRecord ClassNotFoundException
19:24 alexbaranosky: yaron2343: you could always just use maps
19:24 yaron2343: Yup, that's sounding like the right answer. (Just using maps)
19:24 alexbaranosky: yaron2343: does the namespace also have a dash? That becomes part of the class name I think
19:25 yaron2343: Yes, the namespace does have a dash.
19:25 alexbaranosky: that is getting underscorified too
19:25 yaron2343: (ns lib-phl.test.core
19:25 (:use [lib-phl.core])
19:25 (:import [lib-phl.core ConnectionRecord])
19:25 (:use [clojure.test]))
19:25 alexbaranosky: but really maps are the 90+% tool
19:26 yaron2343: I ran into similar problems as you, and was told to just NOT put -'s in namespaces that contain records... It may be your problem. I just decided to screw it and use maps instead for my use case
19:27 yaron2343: Yeah, I think you're right. Records hurt too much and don't give me enough value. I mostly wanted them because they were easier than duck typing and could catch some errors.
19:28 Although before I finally throw in the towel I will recreate my project without any -s. Won't take long and I hate to give up because I'm confused as opposed to understanding the feature and deciding it doesn't work.
19:29 alexbaranosky: yaron2343: let me know how it goes, I would like to know if that fixes the issue or not
19:29 yaron2343: Will do, am trying to throw it together now.
19:34 amalloy: (inc maps)
19:34 lazybot: ⇒ 1
19:34 mindbender1: I hope it's not a stupid question.. but what are the uses of closures in any language?
19:36 alexbaranosky: mindbender1: they have LOTS of uses
19:37 amalloy: consider a simple example: (let [x 10] (filter #(< % x) some-sequence))
19:38 yaron2343: O.k. so the good news is that removing the - did resolve the problems I was having in the main file. But not in my test file I'm getting a new error "libphl/core__init.class or libphl/core.clj on class path FileNotFoundException.
19:38 I'm guessing this is because of my import
19:38 mindbender1: alexbaranosky: please some education
19:38 yaron2343: I have no clue if lein sets up the class path correctly so that the test files see the src files
19:39 alexbaranosky: mindbender1: use closures anytime you want to tell another function HOW - anytime you might use a Strategy pattern for example
19:39 so higher order functions need to be configured with another function -- so you might want to use a closure
19:40 (defn do-something-to-each-twice [f coll] (map f (map f coll)))
19:41 ;; better: (defn do-something-to-each-twice [f coll] (map (comp f f) coll))
19:41 then call it with a given function aor closure
19:42 (do-something-to-each-twice inc [1 2 3]) ;=> (3 4 5)
19:42 mindbender1: how does f tell do-something-to-each-twice HOW
19:42 alexbaranosky: mindbender1: you could replace 'inc' here with any closure
19:43 can you ask a more elaborate question? I don't know what you need to know
19:44 mindbender1: alexbaranosky: from my understanding closures hold a kind of state right?
19:45 alexbaranosky: ahhhh, sometimes
19:45 aperiodic: they're often used that way in javascript
19:46 alexbaranosky: it just means I can create a closure, that references a local var in one context, then pass that closure to another context
19:49 amalloy: one usage of closures is to let you, basically use a variable that "belongs" to one function inside a completely unrelated function
19:49 eg in my example, (let [x 10] (filter (fn [item] (< item 10)) (range 30)))
19:49 how can filter, which knows nothing about x, manage to use that variable? it's because we've packaged x up inside of the function we give it
19:50 gfredericks: amalloy: you left x out there?
19:50 amalloy: hah, yes
19:51 though it still applies equally well. how does filter, in clojure.core, know about the value 10? i didn't pass it 10
19:51 i passed it this function, which knows about 10
19:53 yaron2343: O.k. defrecord really is painful. So with a map both (:a b) and (b :a) work just fine. But with defrecord only (:a b) works.
19:56 TimMc: yaron2343: and (.a b)
19:57 gfredericks: hmmm...what's the reasoning for that?
19:57 yaron2343: Yeah, that makes sense. Although it also argues against using defrecord. I want Clojure to get away from Oop.
19:57 Because the keyword is effectively an accessor and a record is a class.
19:58 So you are asking for property "a" on the record
19:59 gfredericks: but records deliberately have the map interface, so it's strange they wouldn't implement the IFn side of maps as well
19:59 brehaut: yaron2343: why have you decided to use a record over a map?
19:59 gfredericks: I guess records might want to provide their own IFn :/
19:59 yaron2343: The reason for going to a record was that I wanted to do type checking and equality checking and records make that much easier.
20:00 amalloy: gfredericks: more importantly calling records wouldn't be nearly as fast as caling keywords
20:00 yaron2343: I'm also hoping that eventually clojure will make type hints enforceable
20:00 Yes, I'm a typist. :) But Scala hurt too much so I'm sticking with Clojure
20:00 gfredericks: amalloy: I would think uniformity of interface would trump that consideration
20:01 yaron2343: (F# was actually fun, much easier for me than Scala but I there isn't good IDE support on my mac)
20:01 amalloy: gfredericks: if uniformity of interface were all that mattered, we wouldn't have records or structs at all
20:01 brehaut: its fairly idiomatic in clojure maps that are used objectfully to have (:keyword map) access and maps that are used mapfully to have (map index) lookup, and records are specifically an optimized objectful map, so it makes sense that only the former is supported
20:02 yaron2343: brehaut - How do you tell the difference between an objecfull map and a manful map?
20:02 er manful I meant :)
20:02 mapful
20:02 (Damn you autocorrect!)
20:03 brehaut: well to start an objectful map will have all keyword keys
20:03 quite possibly will have heterogenous values
20:03 and as a whole represents one 'object' in the system
20:03 where as a mapful map may have any kind of key, often has homogenous values and represents an aggregation in the system
20:05 gfredericks: amalloy: that second one is harder to imagine
20:05 why homogenous values?
20:05 amalloy: brehaut: sorry, meant to brehaut
20:06 yaron2343: Then I'm fully guilty of being objectful
20:06 brehaut: yaron2343: objectful maps are idiomatic clojure
20:06 gfredericks: because thats often how they are used? perhaps homogenous value _types_ would be clearer?
20:06 yaron2343: Now if I can just figure out why C-c C-l on my core.clj file in my test directory is producing a "Could not locate libphl/core__init.class or libphl/core.clj on class path: [Thrown class java.io.FileNotFoundException]
20:07 Note btw that "lein test" from the command line works just fine.
20:07 gfredericks: brehaut: do you have an example?
20:07 brehaut: gfredericks: im sure i must
20:07 yaron2343: brehaut - Then I suppose using records makes sense for me.
20:07 So whatever my issue is, it's some swank related thing
20:07 brehaut: yaron2343: but its idiomatic to use maps _until_ records are shown to be needed (for protocols, or performance)
20:08 ,(frequencies "aababc")
20:08 clojurebot: {\a 3, \b 2, \c 1}
20:08 brehaut: gfredericks: ^ a really trivial example
20:09 yaron2343: brehaut - What's the flag that should trip one to think about records? My use of maps is to pass around a state object. The only reason I used records at all is that it made it easy to see if someone submitted the right 'type' of map and to do automatically equality testing when I needed to compare states.
20:09 gfredericks: hmm
20:09 brehaut: yaron2343: well, typically clojure programmers dont 'check type'
20:09 gfredericks: yaron2343: why don't maps give you equality testing?
20:10 brehaut: yaron2343: if you profile your code and find map access is slow, then a record may be an option. alternatively if you need to implement a protocol, a map is probably a good choice
20:10 yaron2343: records are surprisingly rare in clojure code
20:10 yaron2343: brehaut - Indeed, I did actually know that. But I'm writing a distributed system where debugging is a nightmare so I need the system to be as helpful as possible in telling me where things went wrong. Checking types helps out a lot with that.
20:10 amalloy: yaron2343: just put another key in your map
20:10 brehaut: yaron2343: pre and post conditions may also help you
20:10 amalloy: {:what-kind-of-thing :my-awesome-state-type ...more keys...}
20:11 using records has way more pitfalls than maps, and taking all of that on just so you can call .getClass for debugging is asking for pain
20:11 yaron2343: gfredericks - Because I'm an idiot. I just realized that works. :( Thanks for pointing this out. At least now I know.
20:12 gfredericks: yaron2343: now all you need to do is loosen up about checking types and you're golden :)
20:12 yaron2343: brehaut - Actually pre and post conditions is where I do the type checking. I use instance?
20:12 gfredericks: yaron2343: why not write a function that checks if the maps has the expected keys and such?
20:13 yaron2343: gfredericks - That's what I originally did but records gave me that for free
20:13 gfredericks: that tells you more than calling instance? on a record, since a record could be initialized with nulls and all that
20:13 tells you more if you examine the values as well I mean
20:13 yaron2343: gfredericks - Which is why the calls after instance walked through the various keys and checked if they were right. And yes, the more I type the more I realize that records were the wrong choice. Just too much overhead for very little benefit.
20:14 Thankfully Clojure produces such awesomely tight code that changing everything from records to maps will be easy.
20:19 BTW is something like this idiomatic? (defn
20:19 create-state [state-function connections]
20:19 (hash-map :state-function state-function :connections connection))
20:19 The goal is to make it easy to remember what a state is supposed to have
20:19 gfredericks: a shallow answer is you could use a map literal instead of the hash-map function
20:20 yaron2343: Yeah, I know. But I find the short syntax makes it harder for me to read the code. That's just a personal thing for me.
20:20 Does it really make any functional difference?
20:20 gfredericks: not that I know of
20:20 I'm like that too with new
20:21 so you're asking about having a map-assembler function instead of creating the maps inline everywhere
20:21 yaron2343: Yup. Just to prevent typos and such.
20:22 gfredericks: I personally like it, but I tend to be on the type-checking-lover side of things, so I expect people around here to disagree with me
20:23 yaron2343: gfredericks - I love type checking. The only reason I'm not using Scala is that it's type inference logic was painfully bad and the community is about as friendly as a bear trap. But that could just be me. :)
20:23 gfredericks: yaron2343: I suspect that testing instead of doing static types is probably more fruitful
20:24 yaron2343: BTW, what is the difference between FN and IFN?
20:24 amalloy: instead, abstract it a level: (defn make-state-object [a b] (...)) (defn is-state-object? [x] (...))
20:24 yaron2343: I did try looking this up but I couldn't find a good answer
20:24 gfredericks: then you're reasonably sure you have your types right, but also reasonably sure the program works right, which static compilers can't tell you
20:24 yaron2343: am alloy - That's exactly what I'm doing. I have a create-state and is-state?
20:24 gfredericks: yaron2343: FN is a class, IFN is an interface
20:25 yaron2343: gfredericks - Bingo! Thank you!
20:25 So if I want to check if a value is a callable function will IFN? give me wider coverage?
20:25 gfredericks: most of the interface names start with I, though for some reason not all of them
20:26 yaron2343: I notice that just about everything in clojure seems to have interfaces on it
20:26 I just want to check if a value is a callable function
20:26 gfredericks: &(instance? clojure.lang.IFn [])
20:26 lazybot: ⇒ true
20:26 gfredericks: depends on if you want vectors, maps, and sets to return true :)
20:26 amalloy: then you can use maps, and later use records if you truly find yourself needing them
20:26 yaron2343: gfredericks - That's actually o.k., if it walks like a duck…. :)
20:27 gfredericks: then yep
20:27 amalloy: (hint, though: you won't find yourself needing records)
20:28 yaron2343: :) Makes sense. Gotta run! Thanks everyone for your help! You helped move my clojure project forward. I appreciate it!
20:29 brehaut: ,@#'clojure.core/global-hierarchy
20:29 clojurebot: {:parents {}, :descendants {}, :ancestors {}}
20:29 brehaut: ,(derive ::a ::b)
20:29 clojurebot: nil
20:29 brehaut: ,(derive ::c ::a)
20:29 clojurebot: nil
20:29 brehaut: ,@#'clojure.core/global-hierarchy
20:29 clojurebot: {:parents {:sandbox/c #{:sandbox/a}, :sandbox/a #{:sandbox/b}}, :ancestors {:sandbox/c #{:sandbox/a :sandbox/b}, :sandbox/a #{:sandbox/b}}, :descendants {:sandbox/a #{:sandbox/c}, :sandbox/b #{:sandbox/a :sandbox/c}}}
20:29 brehaut: gfredericks: ^ global-hierarchy is an objectful map, but its 3 fields are mapful
20:29 gfredericks: also, the homogenous type might be an implicit union type
20:29 gfredericks: for instance the maps in the fields of the hierarchy have a sets of an implicit union of class and clojure.lang.Named
20:29 aperiodic: brehaut: what is the @#' prefix doing there?
20:29 brehaut: its private, so #' is avar quote to access it, and then @ to deref the var to get the actual value
20:29 ,clojure.core/global-hierarchy
20:29 clojurebot: #<CompilerException java.lang.IllegalStateException: var: clojure.core/global-hierarchy is not public, compiling:(NO_SOURCE_PATH:0)>
20:29 brehaut: ,#'clojure.core/global-hierarchy
20:29 clojurebot: #'clojure.core/global-hierarchy
20:29 brehaut: ,(class #'clojure.core/global-hierarchy)
20:29 clojurebot: clojure.lang.Var
20:29 brehaut: aperiodic: make sense?
20:29 aperiodic: huh, i didn't know you could do that
20:29 brehaut: yeah, thanks!
20:29 brehaut: aperiodic: extremely useful for testing things
20:29 aperiodic: i'm still not entirely clear on how vars, environments, and namespaces interact during evaluation
20:29 brehaut: aperiodic: with a sprinkling of magic ;)
20:29 moogatronic: how much documentation does anyone reading this and wanting to reply usually put in their docstrings?
20:29 brehaut: moogatronic: err… not sure i understand what you are asking
20:29 yaron2343: just dont ;)
20:29 but yes
20:29 moogatronic: (defn function "docstring" [] body) how much do you write in the doc string?
20:29 brehaut: moogatronic: as much as is required to describe the intent and contract of the function
20:29 moogatronic: as much as say, a javadoc?
20:29 brehaut: moogatronic: if you use marginalia you may also write more to add to the overall narrative
20:29 * brehaut hasnt written javadoc in years
20:29 moogatronic: brehaut: marginalia is on my list of things to invetigate.
20:29 brehaut: id say its similar to whats normal for python functions, thoguh not classes
20:29 moogatronic: its extremely straight forward.
20:29 moogatronic: I just like the formalism of javadoc... Defined spot for @param @return etc..
20:29 brehaut: moogatronic: none of that nonsense, we have metadata for that
20:29 moogatronic: docstrings are for prose (and perhaps example usage)
20:30 amalloy: yaron2343: "free" is a huge overstatement
20:30 gfredericks: I think my IRC client just went bonkers
20:30 brehaut: gfredericks: i think you mean ifn?
20:31 ,(ifn? [])
20:31 clojurebot: true
20:31 moogatronic: brehaut: do you have a small example demonstrating metadata as a replacement for some of the 'javadoc' ish crap?
20:31 amalloy: gfredericks: no, network issue of some kind
20:31 moogatronic: gfredericks: mine too.
20:31 gfredericks: now I'm doubting everything that happened in the last 10 minutes
20:31 brehaut: moogatronic: i have a large example? https://
20:32 moogatronic: haha large or small, i was trying to minimize imposed burdon.
20:32 brehaut: moogatronic: be aware that :tag is the not just documentation, its used by the compiler so dont go adding it wildly
20:33 moogatronic: overall, there is much less of that stuff than javadoc though
20:34 gfredericks: brehaut: half of the stuff you said about mapful maps came in in a lump just then
20:35 brehaut: gfredericks: huh. sorry about that
20:35 gfredericks: i assume my internet is lagging to crap again
20:35 amalloy: brehaut: gfredericks is accusing you of causing the network issue that all of freenode just felt
20:35 gfredericks: brehaut: I doubt it's your fault :) I was just explaining any apparent lack of ACK
20:35 amalloy: no apologizing
20:35 brehaut: oh! haha
20:36 gfredericks: me and amalloy: ignorant cop, explanatory cop
20:36 amalloy: although... relevant: http://
20:39 gfredericks: oh there goes google wave
20:41 brehaut: gfredericks: it was still around?
20:42 gfredericks: apparently
20:49 amalloy: haha google knol too
20:51 brehaut: are they sending the old dogs to the farm?
20:52 gfredericks: dog foo is expensive
20:53 as is dog bar
20:56 moogatronic: .. i finally discovered what laziness is for. I feel like the world played the "you just discovered a secret room" song from "the legend of zelda"... code I wrote earlier today is now comical.
20:57 amalloy: moogatronic: well then, what is laziness for? you don't really know until you can explain it :)
20:58 moogatronic: amalloy: true enough. In my case it was that I just realized how I could utilize the lazy-sequence to accomplish some list generation tasks that I was using loop/recur for...
20:59 but everyone knows the answer to everything is 42.
20:59 brehaut: nah, the answer to everything is "No"
20:59 gfredericks: brehaut: is it really?
20:59 brehaut: No
21:00 gfredericks: well that explains it then, thanks!
21:00 brehaut: gfredericks: if that seems inconsistent to you, you dont know prolog ;)
21:00 gfredericks: Do I know prolog??
21:00 lazybot: gfredericks: Definitely not.
21:00 brehaut: No
21:01 gfredericks: ~prolog
21:01 clojurebot: Pardon?
21:02 moogatronic: Are we doing the "This statement is false." thing? =)
21:02 brehaut: No
21:02 moogatronic: 42
21:02 amalloy: moogatronic: gfredericks seems to be. near as i can tell, brehaut is enjoying saying "your statement is false, or your question has no correct answers"
21:03 brehaut: amalloy: theres also the 'none of the facts i know imply this'
21:03 amalloy: No further universes exist which satisfy all of your constraints
21:03 brehaut: exactly
21:03 its the extent of my prolog based humour
21:04 i guess i should at least port the joke to core.logic
21:04 amalloy: you've got em rolling in the aisles
21:06 brehaut: sorry #clojure
21:07 aperiodic: got any erlang jokes?
21:08 brehaut: i do not
21:08 gfredericks: there cannot be any erlang jokes because it has no flaws
21:08 aperiodic: that's a pretty big flaw right there
21:09 gfredericks: is nil the only argument for which type returns nil?
21:09 amalloy: uhhhh, i think that's true, yes
21:09 TimMc: ,(doc type)
21:09 clojurebot: "([x]); Returns the :type metadata of x, or its Class if none"
21:10 TimMc: ,(type ^{:type nil} [1 2 3])
21:10 clojurebot: clojure.lang.PersistentVector
21:10 gfredericks: I've a multimethod that dispatches on type and was just curious if (defmethod nil) knew for sure the argument was nil
21:10 TimMc: ಠ_ಠ
21:10 gfredericks: ,(binding [type (constantly nil)] (type []))
21:10 clojurebot: #<IllegalStateException java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: clojure.core/type>
21:10 amalloy: TimMc: i know, i thought of that too. but i remember reading that it does (or (:type (meta x)) (class x))
21:11 as opposed to (:type (meta x) (class x))
21:11 TimMc: "or its Class if none", right
21:11 gfredericks: ,(with-redefs [type (constantly nil)] (type []))
21:11 clojurebot: nil
21:11 TimMc: hrmf
21:12 amalloy: fwiw, putting reader metadata on stuff when you want it to have metadata at runtime makes me super-nervous, TimMc
21:12 (with-meta [1 2 3] {:type nil}) seems a lot safer to me
21:13 gfredericks: that's an interesting distinction
21:13 untrustworthy macros?
21:13 TimMc: I will admit to knowing basically nothing about metadata. :-)
21:14 ,(:type ^{:type 'foo} [])
21:14 clojurebot: nil
21:14 TimMc: ,(:type (with-meta [] {:type 'foo}))
21:14 clojurebot: nil
21:14 TimMc: ugh
21:15 amalloy: gfredericks: not untrustworthy, it's just...reader metadata is for the compiler. in most cases it will leak over into your program and you can use it as runtime metadata
21:15 but depending on that doesn't seem good
21:16 TimMc: &(meta ^{:type 'foo} [])
21:16 lazybot: ⇒ nil
21:17 TimMc: right
21:18 aperiodic: there are two kinds of metadata?
21:19 amalloy: no
21:19 there are two times at which you could attach metadata
21:19 (more than two, really)
21:19 aperiodic: read-time and eval-time?
21:20 amalloy: yeah, that's the distinction i was drawing
21:20 but there's also macroexpansion time
21:21 aperiodic: you say that in most cases metadata attached during read-time exists in runtime, but could you provide an example where that doesn't happen?
21:22 amalloy: &(meta ^{:type 'foo} [])
21:22 lazybot: ⇒ nil
21:22 TimMc: ^
21:22 aperiodic: huh
21:23 TimMc: But a macro would see it, yeah?
21:23 amalloy: yes
21:23 &(meta ^{:type foo} [1])
21:23 lazybot: ⇒ nil
21:23 amalloy: at the moment i can't even find an example where it *does* leak over to runtime
21:24 &(meta ' ^{:type foo} 1)
21:24 lazybot: java.lang.IllegalArgumentException: Metadata can only be applied to IMetas
21:24 amalloy: &(meta ' ^{:type foo} (1))
21:24 lazybot: ⇒ {:type foo, :line 1}
21:25 aperiodic: why does the metadata disappear?
21:25 amalloy: it doesn't. it was never there
21:25 you pass the compiler an object, x, with metadata on it. it emits the bytecode necessary to reproduce x
21:26 aperiodic: up to equality?
21:26 amalloy: at runtime, that bytecode is executed to create a brand-new x
21:26 but the metadata was for the compiler, not for you
21:26 aperiodic: ah, got it
21:27 amalloy: well, that makes one of us
21:27 it's a confusing issue either way
21:30 aperiodic: so if i want to attach metadata visible at runtime, i should use with-meta, rather than the reader macro, because metadata attached at read-time (usually) gets eaten by the compiler?
21:35 brehaut: i pressed some magical emacs chord by accident: all my html got stripped out and left only the text
21:36 moogatronic: brehaut: -x u!
21:36 aperiodic: the compilation process for clojure is way harder for me to wrap my head around than any other language i've used
21:37 hiredman: aperiodic: do go on
21:37 brehaut: aperiodic: and yet its probably much simplier than most of them
21:39 aperiodic: hiredman: well, it seems to start with the reader, which is what takes string data and turns it into clojure forms
21:39 brehaut: aperiodic: so far so good
21:40 aperiodic: but i've seen some references to reader macros that cause evaluation (i think #=?)
21:40 hiredman: oh, well, if that is complicated then you've never used a lisp
21:40 aperiodic: how can you be doing evaluation at read-time? what's the environment?
21:40 i haven't
21:41 brehaut: aperiodic: question: what do you think the compilation unit of clojure is?
21:41 aperiodic: that's undoubtedly part of my woes
21:41 hiredman: which means you don't have a basis for comparison
21:41 I suggest you go write a lisp, even a simple one
21:43 * brehaut seconds
21:43 aperiodic: brehaut: unit ~ atomic to compilation?
21:43 brehaut: aperiodic: so in java the compilation unit is the class (i believe), it might be the package
21:43 in C its the source file
21:43 aperiodic: brehaut: the first thing that popped into my head was namespace
21:44 brehaut: aperiodic: its a single form
21:44 amalloy: man, i don't even know what clojure's compilation unit is
21:44 i'd guess top-level form
21:44 brehaut: amalloy: toplevel or eval expression i think
21:44 which is why we have declare for forward declarations
21:44 amalloy: suuuure, but those are just top-level in a different context
21:46 brehaut: i guess you could think of it that way, but its slightly circular
21:46 aperiodic: the key difference between macros and normal functions is when they run
21:47 aperiodic: brehaut: macros run between read and evaluation, right?
21:47 which is why the arguments are unevaluated forms
21:48 brehaut: aperiodic: macroexpansion is part of the evaluation or compilation process
21:48 its not really 'between'
21:48 gfredericks: where's there a function for transforming keys of a map?
21:48 hiredman: well, it runs ahead of the first pass of the compiler
21:49 brehaut: hiredman: its more clearly seperated with a compiler than a traditional lisp evaluator though right?
21:50 hiredman: yes
21:51 aperiodic: brehaut: well, if it runs after its arguments have been read but before they've been evaluated, i'd call that between the two
21:52 brehaut: gfredericks: theres rename-keys ? but thats not an general transform, just a mapping
21:53 gfredericks: ah
21:53 aperiodic: brehaut: but i see your objection (there's evaluation happening in the macro, so they're not distinct phases)
21:53 gfredericks: well zipmap is pretty easy
21:55 alexbaranosky: gfredericks, there's a function `map-keys` in useful
21:56 gfredericks: I need to start using useful
21:56 but only with :only
21:59 amalloy: i kinda frown on the map-keys/values functions in useful, personally
21:59 alexbaranosky: amalloy, do you think that they're a code smell?
22:00 amalloy, I havent needed them ..... yet
22:00 amalloy: i don't have a very good reason. i just wish people would stop going map->seq->map, which gets you the worst of both worlds performance-wise
22:52 fbru02: ehi guys i have a macro question anybody up to help?
22:53 amalloy: ~anyone
22:53 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
22:54 fbru02: :)
22:56 so i want to check on one of the arguments and recursive call the macro if one of the arguments is not of the specified type (defmacro my-macro [arg1 arg2 & rest] (if-not (map? arg2) `(mymacro arg1 {} ~@rest)))
22:56 so the thing is that i do a macroexpand with this and i never seem to get {} in arg2
22:57 i'm confused
22:58 amalloy: well, there are a couple issues. one is you don't have an else clause for your if; it's unclear whether that's a bad copy/paste or what
22:59 the other is, are you looking at a macroexpand-1 or what? because if you (macroexpand-1 '(my-macro foo bar baz)) from this definition, it should result in '(my-macro foo {} baz)
23:01 fbru02: amalloy: let me try again and if not paste real code
23:01 thanks :)
23:10 callen: okay, you have my attention
23:10 why does the current version of lein not have a "jack-in" verb?
23:10 because that's what my clojure-mode.el is looking for.
23:11 I need to install swank, don't I?
23:11 sigh.
23:11 I forget these things every time.
23:12 * callen kills self
23:16 Raynes: callen: You don't need to install swank.
23:16 And jack-in is definitely in the latest lein.
23:33 callen: Raynes: not by default, had to install swank-clojure plugin.
23:33 Raynes: I just fetched the lein earlier from the repo.
23:33 Raynes: Oh, I thought you meant in Emacs.
23:40 callen: in Emacs?
23:40 clojure-mode just invokes lein.
23:40 there's little that Emacs has to do with it.
23:55 georgek: hi, I have 'clojure-mode-font-lock-setup added to 'slime-repl-mode-hook in my .emacs, but when I connect to a remote swank with slime-connect, I get error in process filter: run-hooks: Symbol's function definition is void: clojure-mode-font-lock-setup
23:55 if I just reconnect, I get the remote repl, but no highlighting
23:55 anyone come across this already?
23:59 spoon16: technomancy around?