0:36 LauJensen: Morning
0:53 Derander: LauJensen: good morning
6:35 noidi: is it possible to use zippers for maps?
6:35 the docs say that "All it takes is a 4-5 line function to support other data structures."
6:36 maybe someone has already written the function for supporting maps? :)
6:53 fbru02: can i tell lein "use this pom , from this url " ?
7:00 or how can i tell him to use this pom ? http://
8:10 noidi: In my program I have a tree made up of nested maps. Now I need to add references from nodes to their parents. In a language with mutable state I'd just do something like `node.parent = self` in the recursive function constructing the nodes.
8:12 But with maps I obviously can't do this, because both the parent and the child would need to be created first so the other could refer to it.
8:12 How can I solve this problem in Clojure? Do I need to scrap my map-tree approach and replace it with zippers?
8:13 pdk: create the parent with the field you want to reserve for the child blank then assoc it to a new map with the reference to the parent?
8:15 noidi: pdk, hmm. yes, that should work. unlike zippers, it will lose data when traversed upwards, but that's fine for my use case.
8:15 pdk, thanks!
8:20 Ah, nope. Now that I think about my use case a bit more, I will need to be able to walk the tree back to the child.
8:21 So I guess I'll need to look into zippers after all.
8:53 chouser: noidi: probably the best way to handle cyclic directed graphs like that is to give each node a 'name', and then they can refer to each other by that name
8:54 {:the-parent {:parent nil, :child :the-kid}, :the-kid {:parent :the-parent, :child nil}} ... or whatever
8:57 noidi: chouser, thanks, I'll think about that
8:58 chouser: so I'm trying to use congomongo via maven, and apparently there's a binary version incompatibility
8:58 NoSuchMethodError clojure.core$meta.invokeStatic(Ljava/lang/Object;)Ljava/lang/Object; clojure.contrib.def/defmacro- (def.clj:39)
8:59 what are my options for resolving this?
9:00 jweiss_: anyone have any pointers on how to add java annotations to a clojure fn (to be used with gen-class)? the only way i can get it to work is by adding it to the gen-class :methods list, not the metadata of the fn itself
9:01 chouser: jweiss_: I think that's the only way that's supported.
9:01 dnolen: chouser: can you't just do a source checkout of congomongo and run 'maven install' from the source dir ?
9:01 chouser: the fn's themselves aren't examined while doing the static class generation.
9:01 jweiss_: chouser: it's not supported in the ns form either? i tried that and it didn't work
9:02 chouser: jweiss_: oh, it should work in the ns form
9:02 jweiss_: hm, ok i'll play around w that some more. thakns
9:02 chouser: dnolen: I'll try that
9:03 though that sounds a lot like failure to me. :-)
9:04 mister_roboto: chouser: usually you have to find the correct version to list as your dependency when there is such a change in the API between versions. don't you have another version to try from the repo?
9:06 chouser: resorting to build from source is a very un-Maven solution :)
9:06 chouser: mister_roboto: I believe I'm using the latest release of congomongo, contrib standalone, and clojure.
9:07 oh, the latest congomongo is listing 1.2-SNAPSHOT deps for clojure and contrib. :-P
9:07 mister_roboto: chouser: is it possible you're trying to use an API method that no longer exists in the new version and, therefore, would have to list an older version to get your code to work?
9:08 ahhh, well there you go :)
9:09 chouser: so the current "solution" would be to use out-dated clojure, until such time as clojure libs stop binary compiling themselves by default.
9:09 * chouser chooses an alternative
9:11 mister_roboto: chouser: you could always build the jar and put it in your local repo cache, keeping the build exactly the same. except for putting your own version that you "install"ed locally
9:12 chouser: that's what I'm pursuing now
9:13 dnolen: chouser: heh - I thought the convention to package up non-compiled jars was well-established by now.
9:13 chouser: this is not easier than resolving dependencies myself and building a classpath by hand.
9:13 mister_roboto: it's kind of like using programs from your linux distro repository: if you wanna stick with the standard packaging for your system, you use what is available in the repo. otherwise you have to mutate your local system away from the standard repo to be on the bleeding edge :)
9:16 dnolen: even if they weren't compiling the jars, if the repo only has the older version of the dependency, it's not going to work
9:16 the new method would still be missing
9:16 chouser: yes. I can ask apt-get to fetch and install all dev deps for a source package, and fetch and prepare the source package itself, so I all i have to do is make my changes and install.
9:17 I wonder if maven supports that workflow.
9:17 mister_roboto: chouser: i don't know but that would make it infinitely harder to support the transitive dependencies, i would imagine
9:18 or not, if you're only changing the leaf node on the dependency list...
9:19 dev deps are what SNAPSHOTs are suppsoed to be
9:19 chouser: grr
9:20 fliebel: morning
9:22 chouser: the jar is empty
9:22 of course, because the pom created by lein can't be used to build the jar
9:22 jweiss_: is there a way to reload a gen-class'd class at the repl?
9:23 it doesn't seem to pick up the new version by importing it again
9:23 chouser: jweiss_: I don't think so. gen-class itself is unfortunately very static in nature
9:24 you can load in new method definition fns, but the gen-class itself has to be re-AOT-compiled and a new JVM started up
9:25 jweiss_: chouser: ok thanks, that should save me some time futilly (is that a word) trying to get it to work :)
9:26 mister_roboto: http://
9:26 can't you just use that chouser?
9:26 chouser: mister_roboto: well ... it just started working
9:26 I'm not sure why.
9:27 cemerick: what's this *new*.clojars.org?
9:27 mister_roboto: hmmm that's usually not a good thing!
9:27 cemerick i have no idea, i just google'd congomongo maven jar to find a repo with maybe some newer artifacts
9:27 chouser: I noticed one of the several snapshot jars in my .m2 had only .clj files, no .classes, and I thought, "well, that should have been working all along"
9:28 so I cleaned all the congomongo stuff from my .m2, re-ran mvn clojure:repl in my own project, and new I no longer get the original exception.
9:29 oh, I know why. I'm no longer specifying a 1.3 contrib.
9:29 so this is clojure 1.3a3 and contrib 1.2
9:29 I bet. Though I don't know how to find oue.
9:29 out
9:33 cemerick: chouser: `mvn dependency:tree` is nifty
9:34 Having a decent maven-capable environment gives you a nice interactive UI for the same data rather than the asciiart, but whatever. :-P
9:36 chouser: I'm not yet willing to admit that dep management is the primary focus of my time in front of the computer. I still like to pretend I'm mostly about writing code.
9:37 cemerick: chouser: Well done, sir! :-D
9:37 chouser: heh
9:37 but I'm probably just lying to myself
9:38 LauJensen: "cemerick - of indian root, means He that does not tire nor give up" :)
9:40 cemerick: LauJensen: and secondarily, He that gives succor to the poor and disenfranchised fellow traveler. ;-)
9:40 LauJensen: I want to buy your vocabulary, but until its available online I'll google 'succor'
9:40 cemerick: And lord knows, maven users need succor. :-P
9:41 LauJensen: oh I see. Well, let me put it this way: You do good screencasts :)
9:43 mister_roboto: cemerick: if you're using a lot of java libs on a large project, letting maven manage all those transitive deps is easier than doing it manually! don't you think?
9:43 edw: I'm trying to use xml/parse to ... parse some xml, and I'm having trouble parsing a string. How do I create a StringInputStream in Clojure? (java.io.StringInputStream. "foo") gives me a "class not found" error.
9:44 chouser: mister_roboto: that's the wrong fight or with the wrong cemerick, that is.
9:44 mister_roboto: not fighting, just asking :)
9:44 chouser: mister_roboto: he's on your side
9:44 tonyl: morning
9:45 LauJensen: mister_roboto: cemerick never writes clojure code directly himself, he's made a maven task for that as well
9:45 mister_roboto: lol
9:45 cemerick: the people that run freenode are really missing opportunities -- they should "embrace and extend" irc to support profiles, message history, global and channel-specific logging, etc.
9:45 LauJensen: He has a 4 year CS education, majoring in XML
9:45 cemerick: LauJensen: Dude, I dropped out. :-P
9:45 LauJensen: cemerick: funny you mention that, I was just thinking about writing that server myself the other day
9:46 dnolen: edw: http://
9:46 cemerick: LauJensen: well, it'd not get any traction unless you own a big network -- and I presume freenode's the largest
9:46 LauJensen: cemerick: I have a Maven task that does a hostile takeover on freenode, so no worries
9:46 cemerick: That they're still all non-profit, taking donations, just scraping by, etc. is almost criminal.
9:46 LauJensen: <attack>freenode</attack>
9:47 dnolen: edw: there's also w/ with-in-str in core
9:47 ,(doc with-in-str)
9:47 clojurebot: "([s & body]); Evaluates body in a context in which *in* is bound to a fresh StringReader initialized with the string s."
9:47 cemerick: mister_roboto: no one's linked to my shot across the bow (as it were), so: http://
9:47 edw: dnolen: Thank you!
9:48 I'm also looking at clojure-contrib's io, which has `input-stream'
9:48 .
9:48 * cemerick ironically yearns for the days of yesteryear when #clojure was about language issues and programming in general :-P
9:50 edw: Should (with-in-str "<a>42</a>" (parse *in*)) work?
9:50 LauJensen: cemerick: my only concern is, you start out saying "its this simple" then demo a 40 line XML script, doesnt look too bad, but before the cast its over its grown to something like 140 lines?
9:51 tonyl: edw: why not just (parse "<a>42</a>") ?
9:51 unless parse messes with *in* implicitly in its body
9:51 edw: Because parse interprets that as a filename.
9:51 cemerick: LauJensen: 140 is certainly exaggerating, but if you're focused on LOC, you're missing the forest for the trees.
9:52 tonyl: ok, but *in* is not a file name either
9:52 LauJensen: cemerick: You've read my blog right?
9:52 tonyl: what parse fn are you reffering?
9:53 dnolen: edw: oops, with-in-str binding *in* to a string reader not an input stream.
9:53 cemerick: LauJensen: Indeed. Any time you mention LOC, you lose me. :-)
9:53 edw: dnolen: D'oh...
9:54 cemerick: Sometimes it matters, very often it doesn't.
9:54 dnolen: cemerick: ha, might as well write Java then.
9:54 cemerick: For stuff like builds, it *really* doesn't IMO.
9:54 dnolen: well, if LOC matters, then I should write everything in ML, right?
9:54 LauJensen: cemerick: ClojureQL is only 700 LOC vs Arel (Ruby) which is 4600+ :) Thats counts for something right?
9:54 cemerick: screw this verbose Clojure thing.
9:55 jetienne: q. core devs are paid to work on clojure ?
9:55 mister_roboto: cemerick: as a long-time maven user, with our own artifactory server and CI server, and using Eclipse (all this for java, btw), it sounds like the clojure plugin for maven is a lot simpler than trying to use cake/lein/whatever and trying to work that back into the existing infrastructure
9:55 dnolen: cemerick: Clojure is about as terse as ML.
9:56 tonyl: edw: maybe using (parse (java.io.StringReader. "<a>my text</a>"))
9:56 LauJensen: cemerick: You should really learn J
9:56 Would provide a good counter weight to Maven
9:56 chouser: jetienne: yes, but not full time.
9:57 afaik, generally just Fridays
9:57 jetienne: chouser: oh ok. thanks them for their dedication then
9:57 edw: tonyl: parse doesn't accept readers.
10:00 tonyl: facepalm
10:01 what about this (ByteArrayInputStream. (.getBytes "<a>text here</a>" "UTF-8"))
10:02 cemerick: dnolen: It's not even close, AFAICT…but then, I'm absolutely no ML/haskell/ocaml expert.
10:02 mister_roboto: well, that's what I've used for some time now. I entirely agree.
10:03 tonyl: edw: or maybe clojure.java.io there seems to be some fn's that would help
10:04 edw: tonyl: Thanks.
10:10 tonyl: Problem solved (stream (http-agent URL)) returns an input stream.
10:11 tonyl: nice
10:15 dnolen: cemerick: I'd say it's pretty close, in fact directly inspired. With macros it's even terser.
10:17 * dnolen remember the horror at looking at core.clj for the first time and see m, x, v, re, pb, etc. for var names
10:25 cmiles74: I read an article about literate programming over the weekend and hacked a little script together to generate the most simplistic sort of documentation you can get. https://
10:29 insomniaSalt: i happen to have my .emacs configuration organized in org-mode files, if that counts :-)
10:29 "real life"
10:31 cmiles74: I think org-mode with babel-mode definitely counts. :)
10:46 Lajla: &(docs fn)
10:46 &(docs +)
10:46 chouser: (doc fn)
10:46 clojurebot: "([& sigs]); (fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+) params => positional-params* , or positional-params* & next-param positional-param => binding-form next-param => binding-form name => symbol Defines a function"
10:46 Lajla: No sexpbot
10:46 Chousuke, thanks
10:46 tonyl: &(doc fn)
10:46 apparently not :(
10:47 Lajla: clojurebot ignores me because I'm a douche
10:47 But ehh
10:47 so doc is a special form and not a function?
10:47 How does the evaluation model work that it can also accept special forms?
10:47 tonyl: doc is a macro
10:47 Lajla: It just does a symbol comparison?
10:47 tonyl: uh, i am trying to learn that too
10:47 looking at the code...
10:48 Lajla: I wonder how it gets out fn
10:48 I mean, fn doesn't evaluate to anything, right, it's a speical form
10:48 tonyl, could you evaluate the symbol fn for me.
10:48 because clojurebot ignores me, because I'm a total douche who worships His Shadow too much
10:49 tonyl: I think fn internally is a macro
10:49 let me find it
10:50 https://
10:50 what I am trying to find out is where fn* is declared
10:51 Lajla: Hmm
10:51 Maybe fn*
10:51 secretly uses a list
10:51 and not a vector
10:51 for arguments
10:55 paulrosania: fn* is a special form
10:55 Lajla: paulrosania, but a primitive?
10:55 paulrosania: it's implemented on the JVM
10:55 https://
10:55 Lajla: And what is its definition?
10:57 How much difference is ther between Java Clojure and .NET Clojure anyway?
11:07 fliebel: Woohoo, my Clojure quiz is done :) https://
11:09 It might be fun to add it to tryclojure or sexpbot later.
11:10 tonyl: yeah fliebel, I'll take a look
11:45 fliebel: tonyl: Still looking? ;)
11:46 tonyl: yeah, in between some stuff i need to do
11:46 no bugs so far, in the code that is. there is some bugs in my clojure knowledge
11:46 :P
11:50 fliebel: tonyl: Yea, especially those things for setting vars and agents nd such
12:24 jaley: hi guys, is there a better way to do this? (:y (bean (:x (bean java-object))))
12:25 Raynes: (-> java-object bean :x bean :y)
12:25 amalloy: jaley: (-> java-object (.getX) (.getY))?
12:25 Raynes: amalloy: Those parens are redundant.
12:26 amalloy: yeah they are
12:26 i was thinking in the wrong context
12:26 jaley: amalloy: Raynes: cool thanks guys
12:26 amalloy: jaley: mine will certainly be faster, and arguably clearer if you just want to get that one sub-bean. if you might want multiple chunks of some object, consider Raynes's
12:26 tonyl: fliebel: now i can't run the quiz script, it run fine the first time. but i'm pretty sure it is me trying to load it with a bash script
12:28 fliebel: tonyl: So it's no bug on my part? Why the bash script?
12:29 tonyl: yeah it's not the code, I am placing it wrong in the command.
12:29 I don't use anything like lein or cake
12:29 just a bash script that runs java with the necessary flags
12:29 it runs something like this java -cp /usr/share/java/jline.jar:/home/tonyl/.opt/jars/clojure-1.2.0.jar:/home/tonyl/.opt/jars/clojure-contrib-1.2.0.jar:/home/tonyl/Projects/clojure-learn/pepijndevos-clojure-quiz/src/clojure_quiz/core.clj jline.ConsoleRunner clojure.main -r
12:30 I am guessing the clojure_quiz/core.clj file doesn't go in the -cp parameter
12:31 fliebel: tonyl: Maybe just ad the dir, and not the file?
12:32 tonyl: maybe, i'll see
12:32 mattmitchell_: I'm getting a "Can't take value of a macro: #'clojure.core/let" error
12:32 how do I assign the value of a macro result to a let binding?
12:32 fliebel: mattmitchell_: You can't use a macro as a function.
12:33 tonyl: fliebel: it worked :)
12:33 mattmitchell_: fliebel: so for example [let my-num (- 10 1)]
12:34 fliebel: mattmitchell_: Don't call it let, and you're out of trouble.
12:34 tonyl: (let [my-num (- 10 1)] ...)
12:34 something like that
12:35 mattmitchell_: oh duh my mistake sorry. i had [let not (let
12:43 i asked this question a few days ago and got a few good answers, but i'm still trying to find the right solution. and seriously can't figure this out: https://
12:48 fliebel: I'm averaging on a 3/1 ratio on my quiz for (name-quiz)
12:49 tonyl: mattmitchell_: maybe using merge-with
12:49 fliebel: name-quiz is the hardest
12:49 fliebel: tonyl: It totally is. What is your score?
12:50 amalloy: mattmitchell_: yeah, merge-with looks applicable. also clojure.set/index might be relevant? it's a little awkward because you have a map rather than a set, but i think it can still work
12:50 mattmitchell_: tonyl: merge-with and concat into the :f vector?
12:50 amalloy: fliebel, tonyl: what is this "quiz" thing. i must take
12:50 fliebel: amalloy: https://
12:51 tonyl: fliebel: I started it, but got a 2 out of 10 so I stopped on that one
12:51 amalloy: fliebel: neat. i see you went a different direction than you were originally going
12:51 tonyl: I am at doc-quiz, but I am starting name-quiz-easy now :P
12:51 mattmitchell_: amalloy: so you think i should use a set instead of a map?
12:51 tonyl: mattmichell_: that could work
12:51 fliebel: amalloy: Yea, the other thing required to much effort for to little fun.
12:53 amalloy: I'm thinking of adding something like this to tryclojure or sexpbot, for much learning fun and multiplayer Clojure quizzing.
12:54 amalloy: fliebel: ratio? surely % is more useful
12:54 tonyl: fliebel: how do you stop a quiz?
12:55 fliebel: tonyl: just kill it.
12:55 tonyl: lol ok
12:55 amalloy: omg doc-quiz is so hilarious. i assume you're just picking three functions at random, getting their docstrings, and randomly choosing one for me to identify?
12:56 fliebel: amalloy: Yea, the top function just spits out a map of a set number of names and doc strings, and you select what you want to question for.
13:01 How do I commit the evil act of changing a var's value?
13:02 tonyl: with (binding
13:02 fliebel: well, I'll use binding for less evilness
13:02 ah, thanks
13:03 tonyl: evil would be def i guess
13:03 fliebel: amalloy_: Try this: (binding [number 5] (doc-quiz))
13:04 Or even this: (binding [number 5 target 'clojure.set] (doc-quiz))
13:06 So you can quiz about contrib, or some specific lib as well :)
13:09 jonaskoelker: (alive? 'channel)
13:09 tonyl: there is people here
13:10 jonaskoelker: true
13:10 cemerick: $max
13:10 sexpbot: The most users ever in #clojure is 317
13:10 tonyl: fliebel: that is a nice touch with the binding of those vars
13:10 jonaskoelker: sexpbot is one small typo away from sounding very dirty... :D
13:11 cemerick: A nice bot feature would be to report on a moving average of active users
13:11 jonaskoelker: you mean like halve-and-add every $interval?
13:11 Raynes: cemerick: Duly noted.
13:13 jonaskoelker: I've had a lot of false starts with various lisps (some CL, elisp, mzscheme). Anyone got a recommendation on how to stick to it?
13:13 cemerick: jonaskoelker: you'd probably want to retain sample data so you can change the window, etc.
13:13 jonaskoelker: cemerick: good point
13:13 I think I see the value of lisp---that is, its unique strengths and when/how/why they will come in handy
13:14 But for some strange reason, lisp just never stuck
13:14 cemerick: jonaskoelker: make sure you are working on a problem where a lisp would offer particularly compelling advantages.
13:14 jonaskoelker: meh, do I _have_ to write a compiler? </caricature> :-P
13:15 seriously though, that's a good point and one well taken
13:15 Lajla: How is fn* defined?
13:15 How is it usd.
13:15 &(doc fn*)
13:15 sexpbot: java.lang.Exception: Unable to resolve var: fn* in this context
13:15 Lajla: Hmm
13:15 &(doc fn)
13:15 sexpbot: ⟹ "Special Form: Please see http://
13:15 cemerick: Many (rightly, IMO) believe that a lisp (Clojure in particular, at least in comparison to others, again IMO) provides compelling advantages regardless of the problem.
13:15 Lajla: don't use fn*
13:16 jonaskoelker: I'm with you on the clojure vs. other lisps
13:16 cemerick: jonaskoelker: But if the question is, how to stick with learning it -- make sure the wow-factor is so high that you absolutely can't let up. :-)
13:17 jonaskoelker: :)
13:17 It seems to me like clojure has the right kind of abstractions when it comes to things "in/out of the box"
13:17 Lajla: cemerick, I want to know what it is.
13:18 Apparently fn is defined in terms of it as a macro.
13:18 jonaskoelker: i.e. lazy sequences being "compatible" with plain ol' lists; IOW, there's interfaces and things that "implements" them
13:18 cemerick: Lajla: fn* is the form that ties into the compiler's implementation of fn
13:24 Lajla: cemerick, but how does it work.
13:24 How would you use it.
13:24 amalloy: Lajla: you don't use it. why would you want to?
13:25 cemerick: Lajla: Like I said, you shouldn't use it -- it's entirely an implementation detail.
13:25 Lajla: I don't want to use it
13:25 I want to know how it works
13:25 And why fn itself can't serve that role
13:25 amalloy: Lajla: look in the jvm source
13:25 er, the java source for clojure
13:26 in Compiler.java
13:26 Lajla: Yeah, but I want to know how fn expands to fn* as a macro.
13:26 I heard it does
13:26 amalloy: $source fn
13:26 sexpbot: fn is http://
13:26 amalloy: like so
13:29 Lajla: &(expand '(fn bla [I Worship His Shadow] (+ I His)))
13:29 sexpbot: java.lang.Exception: Unable to resolve symbol: expand in this context
13:29 Lajla: How do you expand macros?
13:30 amalloy: macroexpand
13:32 Lajla: &(macroexpand '(fn bla [I Worship His Shadow] (+ I His)))
13:32 sexpbot: ⟹ (fn* bla ([I Worship His Shadow] (+ I His)))
13:33 Lajla: Hmm
13:33 &(macroexpand '(fn bla ([I Worship His Shadow] (+ I His)) ([I Worship His Divine Shadow] (+ I His Divine))))
13:33 sexpbot: ⟹ (fn* bla ([I Worship His Shadow] (+ I His)) ([I Worship His Divine Shadow] (+ I His Divine)))
13:34 Lajla: &((fn* [x y] x) 3)
13:34 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox4394$eval6128$fn
13:34 Lajla: &((fn* [x y] x) 3 4)
13:34 sexpbot: ⟹ 3
13:34 Lajla: How is fn* different from fn?
13:34 amalloy: Lajla: /msg sexpbot if you're going to ask him a lot of questions that you don't need to show other people. it clutters up #clojure
13:35 Lajla: I do need to show it to others? I'm asking quaestions about the results which I don't understand at al..
13:36 amalloy: &(fn* add "adds some stuff" ([x y] (+ x y)))
13:36 sexpbot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.ISeq
13:36 amalloy: &(fn add "adds some stuff" ([x y] (+ x y)))
13:36 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character
13:37 amalloy: &(fn add {:doc "adds some stuff"} ([x y] (+ x y)))
13:37 sexpbot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
13:37 amalloy: bah
13:37 anyway fn* won't handle the optional arguments like docstrings
13:37 i suspect
13:38 Lajla: Ahhh
13:38 It won't handle docstrings.
13:38 hiredman: amalloy: fn doesn't take a docstring
13:39 Lajla: If that's all.
13:39 Then I see no real reason to not use fn*
13:39 Espeially for function literals
13:39 Which often lack it.
13:39 amalloy: Lajla: preconditions
13:40 and there's...no reason to use fn* at all? you want to add two keystrokes to each function definition, in order to save a microsecond at compile time?
13:41 Lajla: amalloy, maybe, but that doesn't warrant a 'you shouldn't ever use fn*, it's an implementation detail' statement
13:42 Unless of course fn* has no real spefication and it's just a thing that only this clojure uses as an intermediate step.
13:42 amalloy: Lajla: it is. someday maybe it will do something different, and the fn macro will change to work properly
13:42 Lajla: But as far as I know, clojure has no specs, maybe?
13:42 So fn* is undocumented and unsupported?
13:43 hiredman: how does fn not work properly?
13:43 amalloy: hiredman: if fn* changes in the future, fn will need to change in order to work properly
13:43 Lajla: I never said it didn't, I was just wondering why fn expanded to fn* (answered) and then why fn* "should" not be used. (answered)
13:44 amalloy: but that will happen without us needing to know. if Lajla decides to rely on fn*, s/he will be hurting when that day comes cause nobody will rewrite that code
13:44 Lajla: amalloy, so fn* is unsupported and undocumented at this point?
13:45 amalloy: i'm not exactly a language authority, but yes. * suffixes often mean that, and it seems to here
13:47 Lajla: Ahhh
13:48 Somewhat unhygenic and it could pose a security risk, but I'm cool with that I guess.
13:48 amalloy: ...?!
13:48 kiemdoder: can any one suggest an open source project or something that is a good example of well written clojure code?
13:49 maybe they're all good but I'm just asking
13:49 chouser: it's the lack of docs that indicate fn* is not supported for direct use, not the *
13:50 Lajla: amalloy, well, if there are no docs, then someone could be unaware of its existence. Say someone wants to check input, and then check if the list provided doesn't start with fn, and then feels safe, however, the hacker makes it start with fn* to inject possibily malicious input and influence the runtime
13:55 dnolen: sweet WebSockets works on iPad 4.2, Clojure+Aleph just got that much tastier, http://
13:55 iOS 4.2 rather
13:55 bobo_: dnolen: awesome :-)
13:59 kiemdoder: "rest" and "next" seems to yield the same result
13:59 what is the difference?
13:59 if any
13:59 fliebel: kiemdoder: next return nil for an empt seq, but does realize the first item to do se.
14:03 kiemdoder: fliebel: tx, is see now that (next [1]) returns nil and (rest [1]) returns ()
14:04 I see
14:05 KirinDave: So I see http://
14:05 And it makes me think that increasingly laziness may be a security feature.
14:21 Lajla: &(symbol? '&)
14:21 sexpbot: ⟹ true
14:22 Lajla: If & is a symbol, then why can't I bind to it/
14:22 I assume it makes bindings assume a rest arg?
14:22 &(let [& 3] (+ & 1))
14:22 sexpbot: ⟹ 4
14:22 Lajla: Ahh
14:22 that does work
14:23 &((fn [& r] &) 1 2)
14:23 sexpbot: java.lang.Exception: Unable to resolve symbol: & in this context
14:23 Lajla: Hmm
14:23 Chousuke: hm
14:23 Lajla: &(macroexpand '(let [& 3] (+ & 1)))
14:23 sexpbot: ⟹ (let* [& 3] (+ & 1))
14:23 tonyl: in a function args it is used for the rest binding
14:23 kotarak: Lajla: binding works for me. fn obviously can't because & has special meaning there
14:23 Lajla: &(macroepand (let* [& 3] (+ & 1)))
14:23 sexpbot: java.lang.Exception: Unable to resolve symbol: macroepand in this context
14:23 tonyl: & is a special form
14:23 sexpbot: java.lang.Exception: Unable to resolve symbol: is in this context
14:23 Lajla: &(macroexpand (let* [& 3] (+ & 1)))
14:23 sexpbot: ⟹ 4
14:23 Lajla: &(macroexpand '(let* [& 3] (+ & 1)))
14:23 sexpbot: ⟹ (let* [& 3] (+ & 1))
14:23 Lajla: Damit
14:24 Hmm
14:24 Let is a primitive/
14:24 pjstadig: is there any plan to release 1.2.1 or get 1.3 out the door to fix issues like this http://
14:24 Lajla: let* I mean
14:24 pjstadig: comes up fairly often
14:24 Chousuke: Lajla: let* is an implementation detail
14:24 Lajla: And a primitive
14:24 Chousuke: yeah
14:24 Lajla: I would have expected that let be defined in terms of fn.
14:24 cemerick: tonyl: it's not a special form, & is just part of destructuring syntax.
14:24 Chousuke: Lajla: that's not efficient
14:25 Lajla: You don't say.
14:25 Hmm.
14:25 Why do all other lisps do it then?
14:25 Is it because of the sequential binding?
14:25 Chousuke: they don't?
14:25 Lajla: They do.
14:25 Chousuke: CL doesn't as far as I know
14:25 kotarak: Lajla: I know at least one Scheme which doesn't.
14:25 Lajla: I'm pretty sure that most if not all CL implementations define let as a macro on lambda
14:25 R5RS also lists let as 'library syntax'
14:25 Not sure what the CL specs says about it.
14:25 Chousuke: Lajla: that's inefficient though.
14:26 Lajla: Chousuke, in what way can let be optimized when you don't work like this then?
14:26 Ohh wait.
14:26 Chousuke: at least unless the compiler is smart enough to figure out it doesn't actually need to create an anonymous function
14:26 Lajla: Pardon me
14:26 I forgot that clojure has no TCO.
14:26 Carry on carry on. :')
14:27 Well, in clojure, functions are functions right?
14:27 As in, Java functions?
14:27 In most lisp implementions I guess that lambdas are lambda abstractions, which are much simpler things than java or C functions
14:27 tonyl: they are objects
14:28 Chousuke: java doesn't have functions :/
14:28 tonyl: they implement IFn
14:28 cemerick: Lajla: Java doesn't have function primitives < java 7
14:28 tonyl: java 7 has them?
14:28 Lajla: Well, let me rephrase.
14:28 hiredman: I don't think so
14:28 Lajla: They are more complex than 'lambda abstractions'
14:28 Chousuke: Lajla: they are more complex than that in any real-world language :P
14:29 jarpiain: CL allows any special form to be implemented as a macro
14:29 Lajla: jarpiain, not 'primitives' though
14:29 Depending on what you call your primitive.
14:29 Chousuke, nahhh, a lot of languages explicitly reduce them for optimization's sake.
14:29 cemerick: tonyl: Either 7 or 8, ostensibly. I haven't yet internalized how they got split.
14:30 tonyl: thanks cemerick
14:30 cemerick: pjstadig: one of the various 1.3 alphas doesn't suit your needs?
14:30 Lajla: Basically, what you only need in the purest sense for such a thing is: an expression, which can be like any expression, formal paramatres, and a pointer to the environment in which it was created.
14:30 Return locations and all that can be hacked away by just passing them as arguments to them.
14:31 Chousuke: Theory is interesting but you should sometimes consider reality as well
14:32 cemerick: Chousuke: wait, what? Where's my sufficiently smart compiler? :-P
14:32 pjstadig: cemerick: well for legacy (production) code bases is it a good idea to move to 1.3 (which is alpha)?
14:32 i know there are lots of changes, but i guess nothing breaking
14:32 Chousuke: Doesn't sound like a good idea :P
14:32 At least test first. :D
14:32 pjstadig: is the numerics stuff in there?
14:32 hiredman: yes
14:33 cemerick: pjstadig: Depends on how badly you want the change, etc. If it's just a single patch you're after, I'd just backport that and run your own build, if it's important enough.
14:33 Lajla: Chousuke, well, this is theory of optimization
14:33 cemerick: I'd be pretty surprised if a 1.2.1 or somesuch made an appearance.
14:33 pjstadig: true, but if it's trivial we could get a 1.2.1 out the door
14:33 Lajla: The reason some languages are 'purely functional' is largely an optimization idea, if you have very little side effects, you can better make it none, and then give the compiler a huge assumption it can always make to optimize
14:34 pjstadig: cemerick: weren't you the one complaining about people living on snapshots... now you're suggesting i move to an alpha release? :)
14:35 kotarak: well, at least not a snapshot. ;P
14:35 cemerick: pjstadig: hrm, doesn't sound like me. I was probably pooh-poohing anyone that complained about breakage while following SNAPSHOT.
14:36 * cemerick lived on nothing but snapshots for a year+ until 1.2.0 was final.
14:36 pjstadig: yeah so did we
14:37 Lajla: &(macroexpand '(-> 4 (a (1 4 4))))
14:37 sexpbot: ⟹ (a 4 (1 4 4))
14:37 cemerick: The discussion about patch releases always goes the same. If it's a trivial set of bugfixes, then it's suggested that one build a local patch release, and use it. If it's not a trivial set of fixes, then the question is who is going to shepard the release.
14:37 Lajla: Why doesn't that insert the 4 after the (1 4 4)?
14:38 cemerick: And that's not even touching the question of who decides the working set to begin with.
14:38 kotarak: Lajla: because that's what ->> is for
14:38 Lajla: Ahhh
14:38 I gues
14:39 pjstadig: cemerick: sure, i don't know the answer, i guess i was wondering if anyone else is seeing issues like this that might be useful to backport to 1.2
14:44 cemerick: pjstadig: No one has, at least AFAIK. By all means, open up a thread on clojure-dev and see if there's a plurality around some key issues people are running into.
14:45 mroessler: Is it possible to pull the first four numbers out of a vector of integers? (def numbers [20101122 20101121]). I want just the 2010. With a string I use: (subs (str 20101122) 0 4). I'm uncertain how to apply to the vector.
14:46 arohner: mroessler: 2010 isn't in the vector. 20101122 and 20101121 are
14:46 pjstadig: (/ 20101122 10000)
14:46 clojurebot: *suffusion of yellow*
14:46 arohner: mroessler: you'll have to convert the number to a string, then string manipulate it
14:47 or pjstadig's answer
14:47 pjstadig: clojurebot!!!!!111
14:48 (int (/ 20101122 10000))
14:48 meh
14:49 mroessler: arohner: thanks. Can I convert each integer in the vector to a string? If I convert the whole vector, I'd get only the first 4 numbers of the entire vector, whereas I'm after the first four numbers in each integer within the vector.
14:50 amalloy: mroessler: ##(map str [12 34])
14:50 sexpbot: ⟹ ("12" "34")
14:51 tonyl: using pjstadig ##(map #(int (/ % 10000)) [20101122 20101123 20101122])
14:51 sexpbot: ⟹ (2010 2010 2010)
14:51 mroessler: Thanks everyone!
14:51 amalloy: tonyl: only works if every number is equally long
14:51 tonyl: true
14:51 amalloy: mroessler: ##(map (comp #(take 4) str) [12231414 346531])
14:51 pjstadig: ,(map #(Integer/parseInt (subs (str %) 0 4)) [20101122 20101121])
14:51 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox4394$eval6324$fn
14:51 clojurebot: (2010 2010)
14:52 amalloy: mroessler: ##(map (comp #(take 4 %) str) [12231414 346531])
14:52 sexpbot: ⟹ ((\1 \2 \2 \3) (\3 \4 \6 \5))
14:52 tonyl: &(map #(subs (str %) 0 4) [20101122 20101123 20101122])
14:52 sexpbot: ⟹ ("2010" "2010" "2010")
14:53 pjstadig: ,(map (comp (partial apply str) (partial take 4) str) [20101122 20101121])
14:53 clojurebot: ("2010" "2010")
14:53 pjstadig: err something like that
14:54 mroessler: Thanks all. I'll look at the various suggestions.
14:58 amalloy: mroessler: note that all of the (subs) implementations will fail if the string has fewer than four characters. see clojure.contrib.string/take, which will give you the first up-to-four characters, neatly packaged as a string (unlike the seq of chars core/take gets you)
14:59 mroessler: amalloy: Excellent point. Looking now.
14:59 Lajla: mroessler, http://
14:59 I don't know, I'm fucked at clojure, but it seemed cleaner to me to make a 'digits'function
14:59 It should take in a number and a base, and return a list of the digits that number has in that base
14:59 clojurebot: chouser: Some high-tech profiling with Activity monitor and println shows that I'm doing 100% of one core and not so much IO, though the number of files being read is huge(I estimate 5 per second).
15:01 mroessler: Lajla: looks suspiciously "anti-functional". I'll look at it.
15:01 Lajla: mroessler, why would it be anti functional?
15:01 It's just a function that takes in a natural and a base and returns a list of numbers
15:02 mroessler: Lajla: Hmm. the loop, if, let, I suppose. But I'm not taking issue with you - I'm grateful for the response!
15:02 Lajla: mroessler, clojure loops are not loops like in C.
15:03 They return a value actually.
15:03 As are ifs
15:03 pjstadig: ~loop
15:03 Lajla: Ifs are expressions, not statements
15:03 clojurebot: Pardon?
15:03 pjstadig: ~for
15:03 clojurebot: for is not used enough
15:03 Lajla: Well, a bit of both I guess
15:03 mroessler, basically, loop sets a recursion point
15:04 The function does not feature any mutable state as far as I can see.
15:04 mroessler: Lajla: no, no mutable state.
15:56 KirinDave: Let's take votes for our most used clojure core functions.
15:56 I vote constantly
15:56 I use that shit like 800 times a day
15:57 tonyl: i use map a lot
15:59 aamar: really? constantly? j/k?
16:00 amalloy: KirinDave: map has to be high on the list
16:00 KirinDave: aamar: You want to swap an atom or ref to a value
16:01 chouser: for atom use 'reset!'
16:01 for ref, use 'ret-set'
16:01 'ref-set'
16:02 amalloy: KirinDave: (reset!)?
16:02 KirinDave: amalloy: Oh, because it's a value passed in
16:02 It isn't always constant
16:02 So I just pass in constantly in my interfaces.
16:02 nickik: does anybody how i can read a file and preserve the äöü?
16:02 KirinDave: Like, for examnple...
16:02 amalloy: though i must say, if you ever find yourself doing this to an atom, it's very rarely right. i'm curious what you're doing that you do this 800 times a day
16:02 KirinDave: amalloy: Oh, not atoms 800 times a day
16:02 hiredman: ~google file.encoding
16:02 clojurebot: First, out of 3100000 results is:
16:02 How can I determine the encoding of a file
16:02 http://
16:02 hiredman: useless
16:02 ~google java file.encoding
16:02 KirinDave: CLothesline services need functions which are often constants in practice
16:02 clojurebot: First, out of 128000 results is:
16:02 jGuru: How do I set a default character encoding for file I/O ...
16:02 http://
16:03 KirinDave: Come on gist. :\
16:04 amalloy: An example of why I am always using constantly: https://
16:04 fogus`: I use syntax-symbol-anchor at least 138 times a month
16:04 KirinDave: fogus`: You Might Be A Clojure Badass If.
16:05 amalloy: KirinDave: okay, i see the idea. you might make clients' lives easier by checking the type of the value and behaving sensibly
16:05 KirinDave: amalloy: Sure, but sometimes it can be tricky to do so
16:05 amalloy: E.g., if something is a map it's an fn too, so...
16:06 I guess I don't know how to uniquely isolate FNs.
16:06 Is there a trivial way I don't know about that wouldn't also include things like maps or sets?
16:06 amalloy: &(doc fn?)
16:06 sexpbot: ⟹ "([x]); Returns true if x implements Fn, i.e. is an object created via fn."
16:06 amalloy: &(doc ifn?)
16:06 sexpbot: ⟹ "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"
16:07 amalloy: KirinDave: i hope this is trivial enough :)
16:07 KirinDave: Huh
16:07 fogus`: You know, Rich should have named it konstantly. :p
16:08 KirinDave: For some reason I always assumed fn did what ifn did.
16:08 amalloy: There is one other little problem.
16:08 amalloy: Maybe you can solve all my problems like President Commacho in just 10 minutes.
16:08 amalloy: i want to make it so that it plays nice with java.
16:08 Specifically
16:09 For scala and java and others, what can they pass in to these maps that would be fair game for a function?
16:09 amalloy: &(supers Fn)
16:09 sexpbot: java.lang.Exception: Unable to resolve symbol: Fn in this context
16:09 Raynes: fogus`: Mortal Klojure
16:09 KirinDave: java.util.concurrent.Callable
16:09 amalloy: &(supers (class (fn [])))
16:09 sexpbot: ⟹ #{clojure.lang.IObj clojure.lang.Fn java.lang.Runnable clojure.lang.AFunction clojure.lang.IMeta java.util.concurrent.Callable java.lang.Object clojure.lang.AFn java.io.Serializable clojure.lang.IFn java.util.Comparator}
16:09 KirinDave: Runnable is not appropriate.
16:09 amalloy: yeah, that's kinda a pain. callable or runnable
16:10 KirinDave: Runnable does't return a value
16:10 Callable seems right, but uh
16:10 hiredman: callable returns a value but doesn't take one
16:11 KirinDave: Right.
16:11 cemerick: Clojure functions are IFns; the other implemented interfaces are there for interop convenience.
16:11 KirinDave: :)
16:34 nickik: I have a problem if i read in a file the äüö are showed as a ?. Did anybody else have that problem?
16:34 tonyl: you would have to use file encoding that uses those characters
16:41 hoeck: nickik: encoding problem?
16:42 cemerick: nickik: all clojure source files must be in UTF-8
16:42 nickik: its not a sourcefile its a dic
16:42 cemerick: then you need to use the same encoding to read the file as was used to write it
16:46 mabes: does contrib share the same jira project as clojure itself?
16:48 nickik: cemerick: do you know how i convert the file?
16:52 KirinDave: I dunno what debugger-god I pissed off, but cdt-emacs just aint gonna work for me.
16:54 LOPP: nickik use a text editor
16:55 for instance Notepad++
16:55 nickik: using linux :)
16:55 Raynes: KirinDave: You pissed off the Debugods.
16:56 tonyl: nickik: I think you could open the file as a stream and get the bytes by UTF-8
16:57 nickik: thanks all wort with gedit
17:19 ohpauleez: dnolen: Awesome video
17:20 chouser: ring is hurting me
17:20 make it stop
17:20 hiredman: what are you doing?
17:20 * ohpauleez give chouser the safety blanket
17:20 ohpauleez: what's going on?
17:21 chouser: just trying to use wrap-params, but the resulting req still has no :params
17:21 hiredman: have you considered writing a macro?
17:21 chouser: ooh!
17:22 hiredman: are you sure it has no :params?
17:22 you may want to combine wrap-keyword-prams and wrap-params
17:22 chouser: yes, I'm sure.
17:23 hiredman: clojurebot: works on my machine
17:23 clojurebot: http://
17:23 chouser: (def app (-> handle-dump wrap-params wrap-keyword-params my-thing))
17:24 in my-thing I return a :body that includes prn-str of the req
17:24 it has a bunch of stuff in it, including a :query-string, but no :params
17:25 I'm sure I'm doing something stupid, I just don't see what yet.
17:25 amalloy: chouser: welcome to programming
17:25 chouser: backwards.
17:26 hiredman: right
17:26 kotarak: chouser: the order of functions?
17:26 * hiredman fell offline for a moment there
17:27 chouser: man. ok.
17:27 for some reason I was thinking -> was comp there for a while.
17:27 drewr: also, you don't call those functions on app
17:27 you call the fn those fns return on app
17:27 s/app/req/
17:27 sexpbot: <drewr> you call the fn those fns return on req
17:27 drewr: sexpbot: shut your hole
17:28 Lajla: kotarak, which scheme doesn't by the way?
17:29 I think I read a paper once of someone showing that quote was not a primitive.
17:29 But I think he made a mistake.
17:29 Because in his version (quote (bla balalblbalba)) I think also gets macroexpanded
17:29 Like, if you do (quote (and ...)) or something, it expands, instead of getting a list which starts with a symbol and
17:36 kotarak: Lajla: guile doesn't seem to do create function to handle let.
17:37 Lajla: kotarak, guile is an interpreter and not a compiler right?
17:38 kotarak: Lajla: Ah. Now we start being more and more precise.
17:38 Lajla: also, guile is a marvel of ridiculously badly written technology as to be expected from the masters who have us undocumented and inefficient outdated shat that for some reason has become a staple of C compilers.
17:38 kotarak, praecision is my middle name.
17:39 gave us*
17:40 Adamant: Lajla: what's next, a mortuiri salutant?
17:40 Lajla: Adamant, I have no idea what that means.
17:41 Adamant: probably bad Latin for "we who are about to die, salute you"
17:41 Lajla: This is because I am ignorant, beardless, and do not use gNewSEnse
17:41 All unlike Richard Stallman
17:41 Ahhh
17:41 That is incorrect actually.
17:41 Adamant: I figured praecision was Latin
17:41 Lajla: It means 'those who are about to died salute you'
17:42 third person
17:42 Adamant: probably, I would totally get Pythoned in Latin class
17:42 Monty
17:42 I never had one, just picked up shit here and there
17:42 Lajla: I find it amazing that I said I didn't know what it means when I could read it.
17:42 Just shows how lazy I am.
17:42 Unlike Dr. Richard Stallman
17:43 Adamant: the good Doktor
17:43 Lajla: Though his belly might evidence otherwise.
17:43 Adamant: not for a programmer
17:43 Lajla: That is true
17:43 I heard he's actually pretty bad and basically hacks his shit together into unreadable garbage
17:43 Adamant: doubtful
17:43 he is from another, braver era though
17:44 Lajla: A rumour it may be, but what if it's on wikipedia?
17:44 Adamant: then it's just stupid
17:44 Lajla: Yeah, the era people hacked shit together due to performance problems and because Dijkstra hadn't yet risen to being the leader of the illuminati.
17:44 mroessler: I see a lot of examples in Clojure books/sites about comparing quantities: (> 10 5) true. But I am missing how to I combine comparisons, such as greater than 5 AND less than 7?
17:44 Adamant: no, they assumed everyone was a wizard and if you weren't, tough shit
17:44 Lajla: mroessler, use and
17:44 Adamant: also, documentation was for the weak
17:45 Lajla: Or like (< 3 x 7)
17:45 amalloy: mroessler: ##(> 5 6 7)
17:45 sexpbot: ⟹ false
17:45 amalloy: mroessler: ##(< 5 6 7)
17:45 sexpbot: ⟹ true
17:45 Lajla: amalloy, other way around
17:45 mroessler, but if you want it more complex, you can use and
17:45 Like (and (> 3 x) (<= x 9))
17:46 So
17:46 what I get from this ## notation
17:46 Is that every thing I type
17:46 mroessler: Lajla: thanks!
17:46 Lajla: Is parsed by sexpbot?
17:46 Is that right ##sexpbot?
17:46 Ah
17:46 No, it is not
17:46 Or maybe it is
17:46 tonyl: it has to be a form, i think
17:46 Lajla: Is that right ##()
17:46 sexpbot: ⟹ ()
17:46 Lajla: But a symbol is a form
17:47 tonyl: maybe not then
17:47 just what ever is between ##( and )
17:47 sexpbot: ⟹ true
17:47 tonyl: lol
17:47 Lajla: mroessler, take note
17:47 This is a manly lisp
17:47 Here operations are variadic
17:47 So like (+) is 0
17:47 And (and) is true
17:47 And (or) is false
17:48 And ##(and 3 2 4 7)
17:48 sexpbot: ⟹ 7
17:48 Lajla: And ##(or false nil 3 7)
17:48 sexpbot: ⟹ 3
17:49 msilverman2: (+ 3 4)
17:49 clojurebot: *suffusion of yellow*
17:50 msilverman2: ##(+ 3 4)
17:50 sexpbot: ⟹ 7
17:50 tonyl: what's up with clojurebot replying with that :P
17:51 hiredman: legacy feature
17:51 amalloy: tonyl: 0.5% of the time (iirc), he randomly pretends the previous statement was addressed to him
17:51 msilverman2: ##(car (cdr '(1 2 3)))
17:51 sexpbot: java.lang.Exception: Unable to resolve symbol: car in this context
17:51 hiredman: no, math expressions are always interpreted
17:51 msilverman2: ##(first (last '(1 2 3)))
17:51 sexpbot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
17:52 hiredman: from the days when clojurebot was a single gist
17:52 tonyl: ##(first (rest '(1 2 3)))
17:52 sexpbot: ⟹ 2
17:52 msilverman2: ##(first (rest '(1 2 3)))
17:52 sexpbot: ⟹ 2
17:52 mroessler: Double "pound" or "hash" is to get the clojurebot to execute an IRC line? Sorry for the ignorance.
17:52 hiredman: no
17:52 amalloy: mroessler: there are a lot of ways to get the bots in here to talk
17:52 ,"clojurebot"
17:52 clojurebot: "clojurebot"
17:52 amalloy: &"sexpbot"
17:52 sexpbot: ⟹ "sexpbot"
17:52 Lajla: mroessler, watch this:
17:52 ,"Clojurebot"
17:52 clojurebot: Lajla: Cool story bro.
17:52 mroessler: ##(> 5 7)
17:52 amalloy: mid-sentence with ##"magic"
17:52 sexpbot: ⟹ false
17:52 Lajla: ,"Clojurebot"
17:52 clojurebot: Lajla: Titim gan éirí ort.
17:52 Lajla: Cool eh?
17:53 I am such a douche, they made the bot ignore me.
17:53 Adamant: I don't think speaking Irish is ignoring
17:54 they're just still upset about the Hadrian's Wall thing
17:54 msilverman2: car and cdr is too old school, I guess: http://
17:54 amalloy: msilverman2: yes, we're aware of what car and cdr are :)
17:54 first and rest replace them, although most of the time you're better off with destructuring
17:55 hiredman: Adamant: hadrian's wall was scotland
17:55 amalloy: &(let [[x & nums] [1 2 3 4]] [x nums])
17:55 sexpbot: ⟹ [1 (2 3 4)]
17:55 Adamant: hiredman: a Celt is a Celt
17:55 msilverman2: new to clojure and haven't touched lisp in about 20 years. It's all coming back to me...
17:55 Adamant: to a Roman, anyway
17:58 Lajla: msilverman2, I think it's more that that clojure does not have cons cells.
17:58 A list is a list.
17:58 The rest is implementation abstracted
17:58 pair? or consp does not exist
17:58 I like car and cdr though, because you can cdadar.
17:59 If you have a binary tree
18:00 msilverman2: lajla: agree on cdadar coolness.
18:00 joshua__: Hey guys. I was wondering how I'm suppose to go about converting the params map given in compojure so that it uses :keys rather than "strings".
18:01 Right not I'm trying to wrap the handler with a ring middleware called wrap-keyword-params and it isn't working.
18:02 pjstadig: ,(ffirst '(foo (bar baz)))
18:02 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
18:02 pjstadig: ,(ffirst '((foo bar) baz))
18:02 clojurebot: foo
18:02 hiredman: joshua__: you have to use wrap-params first
18:02 pjstadig: ,(frest '(foo (bar baz)))
18:02 clojurebot: java.lang.Exception: Unable to resolve symbol: frest in this context
18:02 hiredman: ,fnext
18:02 clojurebot: #<core$fnext clojure.core$fnext@1134c4b>
18:02 pjstadig: right
18:03 ,(fnext '(foo (bar baz)))
18:03 clojurebot: (bar baz)
18:05 eyeris: Is there ever any reason to use a ref instead of an atom in a single-threaded program?
18:05 hiredman: is there a reason to use an atom?
18:05 amalloy: &(let [[a [[b]]] [[1 [2 [3 4]]]]] [a b])
18:05 sexpbot: ⟹ [[1 [2 [3 4]]] nil]
18:05 KirinDave: Man, fuck AOT compilation.
18:05 eyeris: To avoid rebinding vars
18:06 KirinDave: I spend 30m because some compiled module doesn't get a new copy of the function when I reload the module via emacs
18:06 hiredman: KirinDave: family friendly
18:06 eyeris: When I tried to do set! I was continually confused by the distinction between root bindings and thread-local bindings
18:06 KirinDave: hiredman: I'm speaking from the heart here.
18:06 hiredman: sure
18:07 eyeris: why use set!?
18:07 eyeris: not the distiction between what they are, but it was hard to keep track of which global defs I rebound with (binding) just to satisfy the runtime
18:07 hiredman: isn't set! the way you change a var?
18:07 hiredman: eyeris: why change a var?
18:07 KirinDave: eyeris: It's a bit unusual to change a var permanently that way. It's relatively unsafe.
18:08 eyeris: It's preferred to reset an atom.
18:08 hiredman: untrue
18:09 it's preferable not to mutate anything and program with values and functions
18:09 eyeris: hiredman: well I'm making what amounts to a poor-mans message broker. clients can make an HTTP request to establish a new queue. I keep those queues in a map. (def queues {}). In order to add a queue to the map, I need to call assoc and then rebind the queues var to the result of assoc.
18:10 hiredman: eyeris: that definitely should be an atom
18:10 eyeris: Okay. Good. That's what I used.
18:10 technomancy: the only reason vars can be changed is to support interactive programming
18:11 *the only reason var roots can be changed
18:11 eyeris: So what I was asking was whether there was any advantage at all to using a ref in a single-threaded app like this.
18:12 KirinDave: eyeris: Oh, in a single thread? If you can really guarantee that, then there is none.
18:12 eyeris: I was basically looking to reinforce whether or not I made the proper decision.
18:12 KirinDave: eyeris: For that, you could set! a thread local binding to ensure it. It's just... threading has a way of creeping into coding in places you don't expect.
18:12 amalloy: eyeris: i'm not sure single-threadedness is relevant. i've had an instance where, with only one thread, doing what i wanted was much easier with a ref
18:13 eyeris: What were you doing?
18:13 amalloy: eyeris: trying to mutate something, unless the new value would break some postcondition; in which case leave it alone and note a failure
18:14 hard to do with swap!, because the only thing you return from an atom is the atom's new value
18:14 eyeris: I see. In that case you found a use for the post-set hooks that come with refs.
18:15 amalloy: eyeris: no, easier than that
18:15 technomancy: couldn't you use a postcondition on the function you pass to swap!?
18:15 hiredman: atoms come with watchers too
18:15 amalloy: technomancy: that would assert, not "leave it alone and note a failure"
18:16 hiredman: amalloy: the ref mutation functions also only return the value of the ref
18:16 amalloy: (dosync (let [newval (whatever @ref)] (when (condition newval) (set ref to newval))))
18:17 hiredman: but dosync returns whatever you did last
18:17 and lets you test the ref before you mutate it, without breaking atomicity
18:18 hiredman: so would any other function you twiddle the atom in
18:18 eyeris: Is there anything in clojure.test that is akin to the OO unit test framework's setUp() methods, letting me create some state to test against? All of my tests need to create a queue and then, after the test, destroy it.
18:20 amalloy: hiredman: i think it's harder than you're suggesting, but i'd love to be proven wrong. try swapping n with n^2, unless n^2 > 1000; in the code calling the swap, handle the swapped/ignored cases differently
18:21 KirinDave: amalloy: For bonus points, error-kit in there.
18:21 hiredman: (fn [a] (let [x (swap! x som-fn)] (when (some-test x) (do-other-stuff-to a)))
18:21 KirinDave: And yes, I know error-kit is unpopular now. :\
18:22 jweiss_: is the "clojure protocols explained" talk from the conj online anywhere? (video or slides)
18:23 amalloy: hiredman: now you've swapped in a value that is illegal for a. i specified leave the atom's value unchanged if changing it would break a rule
18:23 hiredman: amalloy: no I haven't
18:23 nickik: how to get at post data in compojure?
18:24 jweiss: the videos have not been released
18:24 hiredman: amalloy: for a single thread that is the same as your dosync
18:24 amalloy: hiredman: so some-fn leaves x alone if it's too large? now you can't tell whether someone tried to square 25 and failed, or tried to square 5 and succeeded
18:25 hiredman: fine, call it some whatever from your dosync instead of swap!
18:25 the point is, it is exactly the same
18:26 amalloy: hiredman: you're right. i didn't flesh out the dosync well enough to do exactly what i meant
18:26 hiredman: doesn't matter if you did
18:27 amalloy: (dosync (let [newval (whatever @ref), succeess (cond newval)] (when success (set ref to newval))) success)
18:27 mabes: jweiss_: this video may be of interest to you though: http://
18:27 jweiss_: mabes: thanks
18:27 amalloy: hiredman: i really don't see how you can do this with an atom
18:27 _ato`: did I miss a constraint or isn't that just: (swap! a (fn [old] (let [new (f old)] (if (condition new) new old))))
18:27 ie if the condition fails, swap! in the old value (hence in effect leaving the atom unchanged)
18:28 amalloy: _ato`: the constraint is that you want to be able to know whether the atom changed
18:28 hiredman: amalloy: just make the dosync a do
18:29 amalloy: hiredman: hmm. yes, in a single-threaded app that would be sufficient. good point
18:29 Lajla: amalloy,
18:29 could you give hiredman a hug with my compliments?
18:30 amalloy: i prefer coding for multithreading when using STM, but i did (erroneously, i now see) claim that this was a problem for single-threaded apps
18:33 kotarak: amalloy: watches will tell you whether an atom changed or not, and what it's old and it's new value are.
18:34 nickik: How do i simply get the values from a form i submited with the post method?
18:34 amalloy: kotarak: then you have to deal with asynchronous-like callback semantics
18:36 hiredman: if only there was a set of types and a macro that made async programs look like sync programs...
18:38 eyeris: I have one file blabber/exchanges.clj with (ns blabber.exchanges (:use blabber.queues)) and blabber/exchanges/test.clj with (ns blabber.exchanges.test (:use blabber.exchanges)). The first ns macro runs fine but when I run the second ns macro, it complains "No such namespace blabber.queues".
18:38 Actually, "No such namespace: queues"
18:39 hiredman: circular dependencies are not allowed
18:39 eyeris: There is no circular dependency though. blabber/queues.clj uses (ns blabber.queues (:gen-class))
18:41 Since it dropped the blabber. prefix in the error message, it seems like the resolver is looking for blabber.exchanges.queues
18:46 Ahh, it was complaining about a fully qualified use of a function in that namspace
18:47 that I missed when I changed from :require to :use
18:47 slime just lost that line reference in the backtrace
19:04 Is there any way to add jars to the classpath of swank while it is running?
19:05 raek: there is (add-classpath "file:///path/to/jarfile.jar") but it doesn't work in every case (that's why its deprecated)
19:06 eyeris: Okay
19:07 raek: it has something to do with classloaders, I think...
20:59 coldhead: thanks clojurebot
21:10 abedra: build.clojure.org just got and upgrade to the latest bits
21:11 if anyone experiences any strangeness please let us know
21:46 tonyl: does anybody know if there is a roadmap for clojure-in-clojure
21:49 or maybe is there a plan to use protocols, types, records and/or multimethods to help on this?
21:51 dnolen: tonyl: that's certainly the groundwork for moving a lot of the Java bits into Clojure.
21:53 tonyl: ok, do you know if version 1.3 is a step towards that goal?
21:54 dnolen: those things happened in 1.2
21:54 tonyly: I'm not sure what else is planned for 1.3.
21:54 tonyl: yeah, but to replace some of the java bootstrapping with protocols, types, etc...
21:54 ok
21:54 mmm ...
21:55 I'll have to do some digging
21:57 dnolen: tonyl: I'm have suspicion that c-in-c will be primarily community driven, as c-in-c benefits, for now, a small community.
22:00 tonyl: community driven is the only way clojure is being developed, or at least that is what I thought.
22:00 scottj: tonyl: my guess is pods/scopes/invokedynamic/forkjoin stuff will happen before cinc gets much work
22:01 amalloy: tonyl: community + rich *chuckle*
22:01 and rich is busy
22:01 tonyl: yes, there are a lot of milestones besuce cinc
22:02 * tonyl thought rich was an alien from another planet when he read '+ rich'
22:02 scottj: what's rich so busy with?
22:02 dnolen: tonyl: sure what I meant was that rich tends to lead the language design of most things. c-in-c will probably be less lead by him. could be wrong tho.
22:02 amalloy: speaking of pods, dnolen, any news on what they are? i've only heard vague mutterings about constrained mutability
22:03 dnolen: amalloy: constrained mutability?
22:03 amalloy: dnolen: amendment: vague mutterings that could be total nonsense
22:03 dnolen: amalloy: oh yeah, no I think the gist is still the only concrete implementation of the ideas
22:04 amalloy: "the gist"? is there something concrete on github somewhere?
22:04 dnolen: amalloy: I do note some some similarities between the idea and some sections in the last sections of CTMCP where they discuss Cells (old name), http://
22:04 tonyl: I don't see it in the next.release milestone
22:06 dnolen: amalloy: https://
22:07 amalloy: thanks dnolen. looks interesting
22:24 quizme: I'm having a "lein deps" problem: http://
23:18 Licenser: morning
23:18 tonyl: night :P
23:19 trybeingarun: noon :P
23:24 Licenser: night tonyl, noon trybeingarun
23:33 trybeingarun: I am planning to read 1) On Lisp 2) Paradigms of Artificial Intelligence Programming 3) Structure and Interpretation of Computer Programs
23:33 after finishing Programming CLojure
23:33 what order do u guys think would be good/
23:35 dnolen: trybeingarun: PAIP looks pretty hardcore. I know SICP is hardcore, you'll probably need a break between those two.
23:35 coldhead: i'd read 1 and 3 simultaneously
23:35 they're about different things
23:36 trybeingarun: dnolen: have you read SCIP? Is it really worth the credit it gets?
23:36 coldhead: you might get some interesting harmonics between the two
23:37 dnolen: trybeingarun: it is worth and more yes. I worked through all the chapters and almost all the problems of up and including the MetaCircular Evaluator
23:37 7 years ago I didn't see the point of covering lazy eval, logic programming, or the compiler chapter.
23:37 trybeingarun: I am trying to showcase some nice work in Clojure @ work to get more developers interested
23:37 dnolen: I've of course changed my mind about that since then.
23:37 amalloy: trybeingarun: SICP is pretty amazing
23:38 trybeingarun: I want to move in a direction which will get me up and running quickly
23:38 coldhead: most of the exercises in SICP are very satisfying to complete
23:38 dnolen: trybeingarun: neither will do that for you :) On Lisp might be better bet then.
23:38 coldhead: yeah, on lisp is the pragmatic choice
23:38 SICP goes well with a wizard bong
23:39 dnolen: that said I think this is not talked about enough as a rich source for Rich's ideas, http://
23:39 PAIP and SICP are light on concurrency issues
23:39 CTMCP is filled with ideas about concurrency.
23:41 but that's yet another massive tome
23:43 trybeingarun: got disconnected from the chat (actully tripped on my mode and its power chord came off :P)
23:43 *modem
23:43 could you guys repeat your suggestions?
23:44 Licenser: trybeingarun: see your query
23:45 trybeingarun: thanks Licenser :)
23:45 * Licenser bows
23:45 Licenser: if I can't help with suggestions I can with copy & paste ;)
23:46 trybeingarun: is SCIP a good time investment? Lets say, I am able to spend 2 hrs daily on that?
23:46 dnolen: trybeingarun: On Lisp if you want to get moving, SICP and PAIP are for digging in. I recommend Concepts Techniques and Models of Computer Programming for a rich reference for many of Clojure's concurrency ideas. transactions/futures/promises/etc
23:46 trybeingarun: Of course I am considering learning On Lisp also as dnolen had suggested
23:47 dnolen: trybeingarun: SICP great but it's also a rehash of a lot of stuff if you're an experienced programmer.
23:49 amalloy: dnolen, trybeingarun: it goes over some basic stuff, but in a way that is revelatory anyway
23:50 trybeingarun: A few guys (forums) have suggested "How To Design Programs" is "THE CORRECT WAY THAT SCIP SHOULD HAVE BEEN WRITTEN"
23:50 anybody has read that book?
23:52 Licenser: trybeingarun: are you in a big company?
23:53 trybeingarun: I work for ThoughtWorks, if you have heard of that
23:54 it is a medium sized company
23:54 Licenser: hmm
23:55 hmm hmm do you have silly management people?
23:55 trybeingarun: Joined the company last month only dude; so can't say much
23:56 Licenser: heh okay
23:56 trybeingarun: as far as I have observed management's role is to enable and facilitate devs (unlike my previous company *I WONT NAME IT* :) )
23:57 Licenser: was just wanted to suggest how to convince your colegues, show them this http://
23:57 trybeingarun: 25 lines??
23:58 Licenser: yap
23:58 not including html and dataase
23:58 trybeingarun: i hope it is not like rails; you use the entire framework and nothing counts as a line of code :)
23:58 Licenser: but it randomly generates management like phrases and does it very well
23:59 nah I just did not count 50 lines of html strings in there since it would be lame
23:59 trybeingarun: that is okay. Just the code part is nice
23:59 is there any heavyweight web framework available for clojure?