#clojure log - May 31 2011

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:00 bpr`: so you're working with a complete graph right?

0:00 bdesham: I love clojure to pieces but sometimes I just want to set a variable ;-)

0:00 bpr`: well, sometimes it's the right thing to do

0:01 though, i'm not convinced that this is such a case

0:01 bdesham: well, theoretically, yes... I'm implementing the graph as a hash so that d[i,j] corresponds to (d [i j])

0:02 bpr`: I assume (= (d [i j]) (d [j i)) ?

0:03 bdesham: actually, no

0:03 one of (d [i j]) and (d [j i]) is zero

0:04 bpr`: oh, ok

0:04 bdesham: oh wait, sorry

0:04 I was thinking of p

0:05 you're right, d is symmetric, as in the table at http://en.wikipedia.org/wiki/Schulze_method#Example

0:05 ...er, not symmetric

0:05 bpr`: i was going to say, that if not then your "voters" are silly lol

0:05 bdesham: sorry, little scatterbrained on this one

0:05 bpr`: yeah, that's symmetric

0:05 bdesham: heh

0:06 bpr`: wait, but that table's not symmetric

0:08 oh, ok, yeah that doesn't need to be symmetric

0:22 would something like https://gist.github.com/999855 work?

0:26 bdesham: hmm... recur has to be the last form in the loop or else it won't work

0:27 there needs to be a conditional in here somewhere

0:27 let's see...

0:27 bpr`: i clearly didn't run that

0:27 bdesham: oh, no, I think the final "map" just isn't in the right place

0:28 hehe

0:28 bpr`: right

0:28 you'd have to do (id (done?) map (recur ...)) in there

0:28 and there's a typeo in the assoc form

0:29 and i'm not sure what would happen with that for loop

0:29 err, for form lol

0:29 it might keep resetting your i j k s

0:29 so you might have to pull the i j k stuff up into the loop and then use recur to update them

0:30 bdesham: yeah, I'm not sure you'd still be able to use for when you're recursing

0:30 if that's a word

0:42 kornys: hi folks - is there something like get-in that will get multiple values from a nested structure?

0:43 i.e. something better than {:screen-name (get-in tweet [:user :screen_name]) :tweet (:text tweet)})

0:44 to get just the screen name and the tweet values from {:text "foo" :user { :screen_name "fred" } }

0:44 bdesham: hmm... better how

0:44 ?

0:44 amalloy: kornys: you can't really do a lot better, i think? i mean, you can avoid repeating the "tweet" identifier, but everything else there is carrying real information

0:45 kornys: If I wanted to pull 5 or 6 values out of a twitter message, it would mean repeating :tweet a lot

0:45 I can't immediately think of a better syntax though :)

0:45 amalloy: kornys: give an example where having this magic function would actually help, then we can build the magic

0:46 bdesham: bpr`: I tried an implementation with refs: https://gist.github.com/999873

0:46 though it seems to give the same results

0:46 so I'm not sure whether the process is actually wrong or if I'm relying too much on wikipedia

0:47 kornys: if you were going to use those values a *lot*, you could use (let [screen-name (get-in tweet [:user :screen_name]), tweet (:text tweet), date (:date tweet)] ...) or whatever

0:48 kornys: amalloy: trying to extract parts of a twitter response, like the ones at http://dev.twitter.com/doc/get/statuses/public_timeline

0:48 bdesham: kornys: although that probably wouldn't be worth it unless you were going to refer to those values a bunch

0:48 kornys: anyway, if there's no simple idiomatic way, i can live with what I posted

0:48 just new enough to clojure to always suspect there's some obvious thing i've missed :)

0:49 bdesham: kornys: that takes a while to wear off ;-)

0:53 amalloy: kornys: https://gist.github.com/999885 maybe?

0:54 solves some of the problem without making the rest worse

0:55 kornys: amalloy: nice - thanks.

0:55 amalloy: if the things you want to get are hardcoded, you can probably get something more concise with nested map destructuring

0:55 kornys: probably wouldn't use it for 2 fields, but for 5 or 6, it'd be great.

0:56 yeah - need to get my head around nested destructuring. I've done it in scala, but the clojure syntax is still confusing me a bit

0:58 amalloy: kornys: updated gist with a destructured example

0:59 kornys: amalloy: thanks - I think that's what I need. I tried something similar, but I think I just got the syntax wrong.

1:00 amalloy: yeah, it's easy to do that especially with map destructuring

1:00 you probably had the keys and bindings switched

2:02 seancorfield__: i have a seq and want to apply a function f to every other element - what's a slick idiomatic way to do that?

2:03 amalloy: seancorfield__: leaving the other elements untouched, or what?

2:04 seancorfield__: given f and [1 2 3 4 5 6] i want [1 (f 2) 3 (f 4) 5 (f 6)]

2:04 yeah, apply identity then f then identity then f

2:04 amalloy: &(let [xs (range 10)] (mapcat (fn [[a b]] [(/ a 2) b]) (partition 2 xs)))?

2:04 sexpbot: ⟹ (0 1 1 3 2 5 3 7 4 9)

2:05 amalloy: not exactly gorgeous, but reasonable

2:06 opqdonut_: ,(let [f (partial * 2)] (map #(%1 %2) (cycle [f identity]) [1 2 3 4 5 6]))

2:06 clojurebot: (2 2 6 4 10 6)

2:06 seancorfield__: hmm...

2:06 opqdonut_: there ya go

2:06 seancorfield__: cycle... ooh... that sounds more like it

2:06 amalloy: ah, cute

2:06 opqdonut_: it's a shame #(%1 %2) doesn't have a name. it's my favourite function

2:06 seancorfield__: lol

2:06 amalloy: opqdonut_: i defined it as invoke

2:06 opqdonut_: or rather, (fn [f & args] (apply f args))

2:07 amalloy: opqdonut_: funcall, if you like common lisp :P

2:07 opqdonut_: :)

2:07 tomoj: amalloy: with juxt I like your version better

2:08 amalloy: tomoj: it doesn't really work with juxt though

2:08 tomoj: &(let [f (partial * 2)] (mapcat (juxt identity f) [1 2 3 4 5 6]))

2:08 sexpbot: ⟹ (1 2 2 4 3 6 4 8 5 10 6 12)

2:08 tomoj: is that not right?

2:08 hmm

2:08 opqdonut_: partition

2:08 tomoj: oh, right

2:08 amalloy: right, but once you partition it you can't easily juxt it

2:08 tomoj: that's wrong

2:09 bpr`: wow, opqdonut_ that was nice (the mapping you just posted)

2:10 tomoj: #(%1 %2) seems like it should have a name somehow

2:10 amalloy: &(-> inc (.invoke 1))

2:10 sexpbot: ⟹ 2

2:10 amalloy: often almost as good as giving it a name

2:14 tomoj: #(apply % %&) ?

2:14 does that do what I think it does

2:17 amalloy: no

2:18 &(#(apply % %&) println 1)

2:18 sexpbot: ⟹ 1 nil

2:18 amalloy: oh. huh. maybe it does?

2:18 tomoj: i have a bad habit of asserting you are wrong. i hope you don't mind

2:18 tomoj: (apply #(apply % %&) f x y z) is (f x y z)

2:18 if people agree with me I see no real need for them to say anything to me mostly

2:19 amalloy: tomoj: sure. it's just that usually i'm *wrong* when i tell you you're wrong :P

2:19 tomoj: er

2:20 (f x y z) is (#(apply % %&) f x y z), right

2:20 amalloy: tomoj: i assumed %& was "all the arguments", not "all the args i haven't touched yet"

2:20 but apparently it's not

2:20 &'#(% %&)

2:20 sexpbot: ⟹ (fn* [p1__17398# & rest__17399#] (p1__17398# rest__17399#))

2:21 amalloy: &'#(%2 %&)

2:21 sexpbot: ⟹ (fn* [p1__17409# p2__17407# & rest__17408#] (p2__17407# rest__17408#))

2:21 tomoj: wacky

2:21 amalloy: tomoj: how so?

2:22 tomoj: the one disappears

2:22 amalloy: well, naturally

2:22 tomoj: that's interesting..

2:22 amalloy: you're not referring to it, and %& can't somehow include it

2:22 tomoj: yeah

2:22 clojurebot: excusez-moi

2:22 tomoj: so is (#(apply % %&) #(apply % %&) f x y z) also (f x y z)

2:22 amalloy: *blink*

2:23 tomoj: &(#(apply % %&) #(apply % %&) #(apply % %&) #(apply % %&) + 1 2 3)

2:23 sexpbot: ⟹ 6

2:23 amalloy: i guess it must be

2:23 tomoj: what is that strange thing

2:24 amalloy: a delegator?

2:27 tomoj: it's $

2:31 amalloy: tomoj: i guess. but $ is only useful because of its order of precedence

2:31 in a lisp it's not much good

2:31 i guess you can combine it with apply to get out something useful

2:31 tomoj: well, `($) ($) ($) ($) (+) 1 2` is 3

2:32 amalloy: &(apply #(apply % %&) [+ 1 2)

2:32 sexpbot: ⟹ 3 ; Adjusted to (apply (fn* [p1__17442# & rest__17443#] (apply p1__17442# rest__17443#)) [+ 1 2])

2:32 tomoj: huh..

2:33 so.. (partial apply #(apply (resolve %) %&)) is almost like eval

2:34 but no macros, no special forms

2:36 amalloy: tomoj: it also doesn't resolve any of the other args

2:44 tomoj: oh, right

2:50 amalloy: $findfn 2 [1 2 3 4 5] [4 5]

2:50 sexpbot: [clojure.core/take-last]

2:51 bpr`: wow, that's a neat feature

2:51 very prolog-y

2:53 it's gotta be fairly limited though.. right?

2:53 amalloy: bpr`: yeah

2:55 bpr`: you have to pass args in the right order, it only tries a few standard namespaces, and it only looks up direct function calls. it would never find (comp last butlast), for example

2:55 there's a $findarg (map % [1 2]) [2 3] version that's supposed to yield inc, but it wasn't very well tested and seems to have stopped working shortly after it was added

2:55 bpr`: is it doing something like prolog? an elaborate pattern match? or something like just call each function that takes 2 args and see if it gives the answer?

2:55 amalloy: the latter

2:56 bpr`: ah

2:56 amalloy: ah, i was using it wrong:

2:56 $findarg map % [1 2] [2 3]

2:56 sexpbot: [clojure.core/unchecked-inc clojure.core/inc]

2:57 bpr`: that's pretty nice

2:57 amalloy: yeah, mec wrote that version

2:58 bpr`: i kinda assumed it would only do clojure.core, but you say "a few namespaces". does that branch out to contrib?

2:59 amalloy: #{clojure.core clojure.set clojure.string clojure.contrib.string}

2:59 $findfn 2 "test" "te"

2:59 sexpbot: [clojure.contrib.string/butlast clojure.contrib.string/take]

5:06 Dranik: how is 1.3 going? when we will see the beta?

5:08 hoeck1: Dranik: http://dev.clojure.org/jira/secure/Dashboard.jspa?selectPageId=10014

5:09 Dranik: hoeck1: thanks

5:09 wow, we're really close to that!

5:10 hoeck: I'm already using the alpha without problems (of course not in production)

5:10 Dranik: yeah, lots of approved tickets :)

5:11 Fossi: given that 3 of 4 remaining items are docs and release notes, yes ;)

5:11 Dranik: hoeck: how is it with error handling there? is it informative at last?

5:12 Fossi: nullpointers are such a treat :>

5:12 or arrayindexoutofbounds ;)

5:12 tons of clojuer programmers wouldnt nkow what to look for anymore if you fix that ;)

5:13 hoeck: Dranik: I updated from a half a year old version, and I believe I actually got linenumbers for compiler errors

5:14 Dranik: u mean 1.3 or 1.2?

5:14 Fossi: i guess it's still more of a "feature" release though

5:14 http://dev.clojure.org/jira/browse/CLJ-742

5:14 oh noes

5:15 it got fixed :(

5:15 Dranik: one more question: where I could read about the main new features of 1.3?

5:15 Fossi: i guess until release notes are done in the bugtracker ;)

5:15 Dranik: I see :-)

5:16 Fossi: as the one open item is Document clojure.org differences between 1.2 and 1.3

5:16 http://dev.clojure.org/display/doc/1.3

5:16 might do actually

5:16 fliebel: I hope this gets in at some point before 1.3 :)

5:16 http://dev.clojure.org/jira/browse/CLJ-803

5:19 Dranik: is there any roadmap to 1.4 or further?

6:02 ilyak: What's the right way to force evaluation of a whole lazy sequence?

6:04 raek: ilyak: doall

6:05 but if you don't care about the values, e.g. you have something like (map prn coll), dorun is better

6:05 ilyak: It would return values won't it?

6:06 I care about values because it's what it's all about

6:07 raek: ilyak: yes, doall returns the exact same sequence. the only difference is that it has traversed the whole sequence once

6:07 ilyak: cool

6:34 clgv: ##(type (range 10))

6:34 sexpbot: ⟹ clojure.lang.LazySeq

6:34 clgv: ##(type (doall (range 10)))

6:34 sexpbot: ⟹ clojure.lang.LazySeq

6:35 clgv: ##(let [l (range 10)] (type l))

6:35 sexpbot: ⟹ clojure.lang.LazySeq

6:35 clgv: ##(let [l (doall (range 10))] (type l))

6:35 sexpbot: ⟹ clojure.lang.LazySeq

6:37 ilyak: For some reason it seems that after I added doall there, the whole outer sequence (where this sequence is used in each element) became eager

6:38 And it doesn't work

6:39 clgv: humm I remember doall returning an array. maybe it was only for map

6:42 cemerick: ilyak: that's the point of doall

6:43 clgv: neither doall nor map return arrays :-)

6:55 ilyak: When I use (first , it works

6:55 when I use (doall, it fails

6:56 cemerick: ilyak: those two functions do entirely different things

6:56 what is failure in this case?

6:57 ilyak: cataska: Failure is that doall majorly disrupts the flow of my program (I can no longer read items by one from the other lazy seq)

6:58 I'll check another possible reason

6:58 ,(take 1 [1 2 3])

6:58 clojurebot: (1)

6:59 cemerick: doall forces the evaluation of each item in a seq provided to it. Don't use it if you want that seq to remain un-realized.

6:59 ilyak: cemerick: I want this seq to remain un-realized, but not the other seq which contains items which contain the sequence i *do* want forced

7:00 However, it seems that my problem is in some unrelated part

7:00 let me check

7:06 It seems that I have a problem in my algorithm

7:13 opqdonut_: "if code is data, where are all my refactoring tools?"

7:13 cemerick: sheesh, where is that chestnut from?

7:16 opqdonut_: co-worker of mine just now

7:17 manutter: heh, and the snippy reply is "if code is open source, why aren't you writing the tools you want?" ;)

7:17 cemerick: opqdonut_: tell him that the availability of refactoring tools is dependent upon the availability of type information, not anything related to syntax.

7:19 manutter: It's an interesting point, though. I'm trying to think what "refactoring" would mean in a non-OO context

7:20 I suppose you could do the "break a long function into several smaller functions called by a parent" refactor

7:20 cemerick: Perhaps not a lot. "rename" is the only one I've missed in any real way.

7:20 opqdonut_: make a protocol, split a protocoll

7:20 manutter: Yeah, rename would make sense too

7:20 opqdonut_: thread extra parameter through a call chain

7:21 cemerick: extra parameter?

7:21 manutter: hmm, those sound interesting

7:22 opqdonut_: cemerick: like "oh, I need to have access to the foo-params map in function bar"

7:27 manutter: how would you automate the process of identifying which functions make up the chain to add the extra param to?

7:28 opqdonut_: 1) calculate call graph 2) ask questions

7:29 even lower level tools liks "grab me a list of callers of this function and let me edit each one in turn" would be nice sometimes

7:29 manutter: Oh, ok, I thought you meant like a recursive call graph or something

7:29 yeah, the call graph shouldn't be too hard

7:29 opqdonut_: of course with a dynamic language you can't get all callers

7:29 but you can get something that works for 99% of the cases

7:30 manutter: true, and macros make it even more fun

7:40 ilyak: when I'm in a let-block, are let variables guaranteed to eb already evaluated?

7:40 With all the side effects

7:41 opqdonut_: yeah

7:41 Chousuke: let evaluates things sequentially

7:41 opqdonut_: thus the (let [a (foo x y) _ (mutate a) b (bar a)] ...) "idiom"

8:07 markoman: hi i have #:field{:k 1 :l 2 :m 3 ,,,} but I want only selected keys reserved say -> #:field{:k 1 :m 3}

8:09 there are more keys to be removed that reserved and I need to have either the copy of original #:field or same with removed keys

8:12 fliebel: markoman: is field a defrecord?

8:13 markoman: i think its defentity

8:13 app engine entity type / map

8:13 fliebel: ??? ##(doc defentity)

8:13 sexpbot: java.lang.Exception: Unable to resolve var: defentity in this context

8:13 fliebel: ah

8:14 markoman: i got entity from datastore, modified it a lot, and now need to save it, but i think all modified keys needs to be removed

8:14 fliebel: Anyway, you could maybe do (select-keys #:field{...} [:k :l]) and pass the result to the constructor for field?

8:14 markoman: or actually added keys

8:15 ok, trying

8:22 its was other good, but its normal map after select, not keeping original form

8:59 ilyak: Cool

8:59 my "stateless" event-based xml-parser is ready

8:59 Got to share it somehow and post to groups

9:00 manutter: oo cool, where is it?

9:00 ilyak: Nowhere yet

9:00 Have to write some kind of example and perhaps replace javolution with some other stax parser

9:35 gtrak`: can you do a tree traversal with fn and recur?

9:37 Vinzent: ,(into {} '((:a 1) (:b 2)))

9:37 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry

9:38 Vinzent: hm, why?

9:39 manutter: gtrak`: you might be interested in http://inclojurewetrust.blogspot.com/2009/11/tail-recursion-and-function-composition.html

9:39 ,(into {} '(:a 1 :b 2))

9:39 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

9:40 manutter: interesting

9:40 ,(doc into)

9:40 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

9:40 stuartsierra: manutter: `into` a map requires a seq of pairs.

9:41 manutter: Makes sense

9:41 gfrlog: ,(apply hash-map '(:a 1 :b 2))

9:41 clojurebot: {:a 1, :b 2}

9:41 manutter: stuartsierra: did you see Vinzent's code?

9:41 gtrak`: hm, well the question is more of principal, the recur just rebinds some bindings and does a jump, so even though it's in the tail position you can't recur on both children of a tree node?

9:41 Vinzent: ,(into {} (map vec '((:a 1) (:b 2))))

9:41 clojurebot: {:a 1, :b 2}

9:42 gfrlog: ,(into {} (partition 2 '(:a 1 :b 2)))

9:42 clojurebot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry

9:43 manutter: gtrak`: Did you see the funky stuff at the end of that blog post about building closures to handle traversing the other child node?

9:44 Cozey: Hi All. Has anybody used Clojure with some of Spring framework? I am particularly thinking aobut using clojure for business logic with Hibernate to access database. Also I'm thinking about using spring-security - since it brings some goodies like OAuth for free. What would be a better approach: to wrap embed clojure code inside spring, or to use clojure as a host and just create some spring contexts with beans?

9:45 stuartsierra: Cozey: Chas Emerick (@cemerick) wrote a blog post about using Spring security with Clojure.

9:45 gtrak`: oh, I see, interesting

9:45 in java you solve problems by creating objects, in clojure you do it by anonymous functions :-)

9:46 stuartsierra: Anonymous functions ARE objects. ;)

9:46 cemerick: stuartsierra: I don't think I did, though I do use spring-security in all my webapps

9:47 stuartsierra: cemerick: I know I read something about that somewhere.

9:47 cemerick: Cozey: spring-security is entirely orthogonal to Clojure or not-Clojure. I agree that it's a good (best? only sane?) option for what it does.

9:48 Cozey: from what I see spring-security works from web.xml as a filter. thats good. Actually I have some team-mates who insist on spring

9:48 but are not agains clojure

9:49 So I thought that if they want to implement db + some data manipulation logic using hibernate, let's do it

9:49 cemerick: Right -- you add its filter to web.xml, and configure it however you like in applicationContext.xml and such.

9:49 Totally reasonable. :-)

9:49 Cozey: I'd really like to use clojure as a host - ie. write the dispatcher of a web app in clojure, and call out to spring context - but perhaps i'm getting myself into trouble going this way?

9:50 (if they will want to use some otherspring things, i'm especially afraid of annotation or AspectJ based things)

9:50 cemerick: "host" here implies that your primary servlet is written in Clojure?

9:50 Cozey: yes

9:50 cemerick: Sure, that shouldn't be a problem.

9:51 Cozey: and just loads spring context

9:51 cool :-)

9:51 cemerick: Annotations are also available, but other things (like runtime classpath scanning and autowiring of Clojure-generated) are probably more trouble than they're worth, if you can avoid them.

9:52 Cozey: I need to do some small project atm using python, and even with python 3 i must say it seems so incoherent.. You guys creating Clojure really do a great job!!

9:52 annotations in clojure? with gen-class or ?

9:52 cemerick: I've never really used spring proper though (only spring security in depth), so all of the above is FWIW. </disclaimer> :-)

9:53 Right.

10:09 clgv: in clojure 1.3 how do I set a new value on a (def ^:dynamic bla nil) ?

10:10 fliebel: clgv: Just as you'd do in 1.2 with any var.

10:10 so that'd be binding and alter-var-root! I think.

10:10 clgv: fliebel: I redefined it with def and another value in 1.2

10:11 probably not clean I guess

10:11 fliebel: clgv: And what happens when you do the def in 1.3?

10:11 clgv: it complains that I have to set :dynamic so it seems not the proper way I guess ;)

10:12 stuartsierra: Repeating def without ^:dynamic will lose the ^:dynamic.

10:12 clgv: since declaring it with dynamic once should be sufficient

10:12 so alter-var-root! is the way to go if I cant use binding?

10:12 stuartsierra: yes

10:12 clgv: thanks :)

10:13 * fliebel 's cake has a very low baud rate :(

10:13 stuartsierra: no `!` on `alter-var-root` by the way

10:13 clgv: thx. saw it in the api already.

10:15 fliebel: Does anyone know if cake has a secret setting for baud rate? because when I paste something, it appears slower than I type.

10:18 clgv: When doing: (alter-var-root *enable-timing* (constantly false)) I get: #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.Var>

10:18 stuartsierra: clgv: Use #' notation to get the Var instead of its value.

10:19 clgv: oh right. thx.

10:21 that's the first time I use alter-var-root

10:34 bendlas: hey, folks

10:34 gfrlog: hey, saw you way too late last time :)

10:34 clgv: what is that supposed to mean: java.lang.IllegalArgumentException: Duplicate case test constant: quote

10:35 __name__: Hey folk.

10:36 bendlas: clgv: code?

10:36 stuartsierra: clgv : Are you using `case` with a quoted symbol or list?

10:36 clgv: stuartsierra: with quoted symbols yes

10:37 stuartsierra: clgv: try it without the quote marks

10:38 clgv: stuartsierra: ok it compiles now. let's see if it still works. I had it running in 1.2 with the quotes

10:42 stuartsierra: ok it still works like intended :) thx!

10:46 humm leiningen fails on my clojure-1.3.0-alpha8 project with Exception in thread "main" java.lang.RuntimeException: java.lang.NoClassDefFoundError: clojure/lang/ILookupHost :(

10:46 it's leiningen 1.5.2

10:47 stuartsierra: try a clean build

10:49 clgv: ok that worked. strange error though but I'll remember cleaning up next time

10:54 fliebel: Do people get notified when I add a file to Jira without a comment?

10:58 gfrlog: is there any good functional approach to the DB auto-increment situation?

10:58 * fliebel is a little worried his patch will not make it into 1.3

11:18 pjstadig: gfrlog: does an atom not work for you?

11:19 or do you mean returning the success/failure of an update statement, and also the auto-increment id?

11:19 gfrlog: pjstadig: I'm talking about using a DB (mysql), and using clojureql or c.c.sql to connect to it. When I insert a record, I don't think either library has a way for me to get the new ID of the record without creating a "SELECT LAST_INSERT_ID()" query

11:19 I need it because I'm creating other records that need the ID for their foreign key fields

11:20 this all works much more seamlessly in rails' ActiveRecord, which of course is not very FP at all;

11:20 pjstadig: there may not be a clean way to implement something like that in a database agnostic way, which is why those libs don't provide the feature?

11:21 in which case you just have to do it the mysql way

11:21 gfrlog: yeah. I was also thinking that it's even schema-dependent. Since you don't have to create a single auto-increment primary key in your table

11:22 activerecord is opinionated about the schemas

11:22 pjstadig: well i'm guessing that clojureql and c.c.sql work at a lower level of abstraction

11:22 stuartsierra: I think JDBC provides a semi-standard way to get the last insert ID.

11:22 pjstadig: yeah AR makes it's own assumptions about how you should do things, and provides higher level abstractions, as opposed to "execute this SQL query", which is the level that the clojure libs live at

11:23 gfrlog: stuartsierra: brief googling backs that up

11:23 pjstadig: I feel like clojureql is a bit higher level, but in a different way than AR. At the very least it could have a method like conj! but that returns the last insert id instead of the table

11:24 pjstadig: could be...honestly i'm not that familiar with either clojure lib

11:25 gfrlog: pjstadig: okay, thanks

11:28 if clojure and haskell had a baby, would it be a good replacement for scala

11:28 ?

11:36 clgv: hmm clojure 1.2 seems to have problems with ^:dynamic -> java.lang.IllegalArgumentException: Unable to resolve classname: :dynamic

11:36 so I can't include this to be compatible to 1.3?

11:37 stuartsierra: 1.2 doesn't support the ^:foo syntax.

11:38 You can use ^{:dynamic true} instead, which is equivalent.

11:38 gfrlog: ^{:supports-foo-syntax true}

11:38 clgv: ok. 1.2 assumes ^:dynamic to be ^{:tag :dynamic} I guess

11:39 stuartsierra: exactly

11:42 bsteuber: it'd be nice to have ^"foo" mean ^{:doc "foo"} in a similar way, wouldn't it?

11:48 stuartsierra: bsteuber: ^"foo" currently means ^{:tag "foo"} as well, which was sometimes useful for primitive arrays

11:48 e.g., tags like ^"[[C"

11:50 imade: is there any function that gives seq of tails? like (tails [1 2 3 4]) => ((2 3 4) (3 4) (4))

11:51 I mean no problem to write it myself, but thought that maybe exists, couldn't find myself tough

11:51 stuartsierra: ,(iterate next [1 2 3 4])

11:51 clojurebot: ([1 2 3 4] (2 3 4) (3 4) (4) nil nil nil nil nil nil ...)

11:52 imade: oh, nice, thanks stuartsierra

11:52 bsteuber: stuartsierra: ic, didn't think of that :)

11:53 gfrlog: ,(keep identity (iterate next (range 10)))

11:53 clojurebot: Execution Timed Out

11:53 gfrlog: oh I see

11:53 well apparently that's not how you use (keep) :)

11:55 stuartsierra: The seq is still infinite.

11:55 Raynes: &(reductions conj [] [1 2 3 4]) ; I love excuses to use reductions, even if the results are backwards.

11:55 sexpbot: ⟹ ([] [1] [1 2] [1 2 3] [1 2 3 4])

11:56 stuartsierra: ,(take-while identity (iterate next [1 2 3 4]))

11:56 clojurebot: ([1 2 3 4] (2 3 4) (3 4) (4))

11:56 bsteuber: ,(take-while identity (iterate next [1 2 3 4 5]))

11:56 clojurebot: ([1 2 3 4 5] (2 3 4 5) (3 4 5) (4 5) (5))

11:56 bsteuber: damn too slow

11:57 stuartsierra: The don't call me The Pareditor for nuthin' :)

11:57 bsteuber: you use paredit for chat? oO

11:57 stuartsierra: well no

11:57 bsteuber: ok copy&paste

11:58 stuartsierra: But I could probably use Emacs.

11:58 Raynes: bsteuber, stuartsierra: I was typing that out as well, but I didn't even bother hitting enter. :<

11:58 bsteuber: :)

11:58 Raynes: I know my place.

11:59 stuartsierra: Good to know I can leave #clojure in your capable hands, bsteuber & Raynes.

11:59 Raynes: :D

12:04 bsteuber: too bad there are sometimes harder tasks than knowing take-while ^^

12:05 stuartsierra: btw, what's your current hair color? :)

12:06 stuartsierra: bsteuber: boring old brown

12:26 Jeffrey04: anyone done 4clojure here?

12:29 manutter: you mean the whole thing?

12:30 Raynes: Jeffrey04: What do you mean?

12:31 Jeffrey04: @Rayes I'm stuck at the problems involving graphs/trees

12:31 Raynes: Oh.

12:31 Jeffrey04: and there's one on word chain, roman literals, game of life

12:31 manutter: I haven't made it that far yet

12:32 Jeffrey04: only started with clojure last week, still can't seem to wire my brain properly to program in FP style :/

12:32 my solutions are still ridiculously long compared to other ppl (according to the graph) :(

12:33 Raynes: If you've made it that far on 4clojure, you're doing better than you think you are.

12:33 manutter: 4clojure is really good for exercising your FP skills

12:33 Raynes: Some of those problems are pretty difficult.

12:33 manutter: I've done a few that needed to be redone

12:33 Jeffrey04: @manutter yea, it is, learned a lot through it

12:35 @Raynes I hope so (:

12:35 been staring at the problem and is still clueless

12:36 bendlas: a

12:38 manutter: I keep getting stuck on little things like how to turn (first coll) into a seq

12:38 ,(cons (first [1 2 3]) nil)

12:38 clojurebot: (1)

12:38 manutter: meh, that works, but it doesn't look right

12:38 maybe I need to go back to my crayolas

12:38 Raynes: &(list (first [1 2 3]))

12:38 sexpbot: ⟹ (1)

12:38 Jeffrey04: ,(seq (first [1 2 3]))

12:38 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

12:39 manutter: Ah, list

12:39 Jeffrey04: oops

12:39 manutter: See, I knew there was some trivially simple keyword I was overlooking

12:39 Jeffrey04: ,(list (first [1 2 3]))

12:39 clojurebot: (1)

12:40 Jeffrey04: lol

12:40 so there are 2 bots here

12:40 manutter: I blame PHP (my day job) for rotting my brain

12:40 Jeffrey04: @manutter i was a php programmer before I started my postgrad too

12:41 manutter: Yeah, it pays the bills

12:41 Jeffrey04: lol

12:42 my supervisor reaction after knowing I am learning clojure: don't learn strange (weird?) language~

12:42 lol

12:42 gfrlog: they only lead to helping you think better

12:44 manutter: If God had meant for us to program in clojure, He would have given us brains.

12:47 imade: can anyone review my solution for the problem? I would like to get some feedback, whether it's idiomatic way to solve or what could I do better. Link https://github.com/imade/clojure-99/blob/master/src/clojure_99/problem26.clj and unit test https://github.com/imade/clojure-99/blob/master/test/clojure_99/test/problem26.clj

12:48 StayInSkool: hi everyone

12:48 I know a bit of Scheme and ML and am a bit puzzled by Clojure specific syntax

12:49 for instance, why are keywords important? what's wrong with just using strings for keys in maps?

12:50 vinzent_: StayInSkool, keywords are faster and idiomatic

12:50 pjstadig: keywords also implement IFn

12:50 technomancy: StayInSkool: keywords communicate intent better, though strings could do the same job in many cases.

12:50 pjstadig: so you can access map values with them

12:51 ,(map :foo {:foo "bar"})

12:51 clojurebot: (nil)

12:51 pjstadig: ,(map :foo [{:foo "bar"}])

12:51

12:51 clojurebot: ("bar")

12:52 StayInSkool: starting with a comma evaluates syntax using clojurebot im assuming? heh

12:57 pjstadig: I don't understand your example. it's a vector, with a single entry that's a map, with :foo as a key of the first key-value pair?

12:58 but, a keyword is also a function?..

12:58 since you map it to the vector?

12:58 pjstadig: i mapped the function across the contents of the vector

12:58 in this case there was just one hashmap

12:58 StayInSkool: so a keyword is a function?

12:58 pjstadig: map called the "function" :foo with the argument being the hashmap

12:59 StayInSkool: i get that part. i just dont see how or why :foo is a function also

12:59 pjstadig: the result of calling a keyword like a function with a hashmap as an argument is to lookup the keyword in the hashmap and return thevalue

12:59 ,(:foo {:foo "bar"})

12:59 clojurebot: "bar"

12:59 StayInSkool: right. i saw that in a few places. the syntax confuses me hah

12:59 imperative language baggage? hmm

13:00 dnolen: ,(:foo nil)

13:00 clojurebot: nil

13:00 dnolen: ,(nil :foo)

13:00 clojurebot: java.lang.IllegalArgumentException: Can't call nil

13:00 StayInSkool: normally i'd do things to a collection, but here it seems like i start off with what i wanna find and then proceed to where it's to be found

13:00 pjstadig: ,("foo" {"foo" "bar"})

13:00 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn

13:01 pjstadig: it's convenient to be able to use the keyword like a function in certain contexts as a shorthand for looking up a value in a map

13:01 you can't do the same with strings

13:01 gfrlog: if strings were functions....

13:02 pjstadig: gfrlog: just wait for C-in-C

13:02 StayInSkool: I see pjstadig. thanks

13:03 what's the sense in having the value as a keyword too?

13:03 vinzent_: but you can also treat maps like a functions

13:04 StayInSkool: {:hello :bye}

13:04 vinzent_: ,({"foo" "bar"} "foo")

13:04 clojurebot: "bar"

13:05 gfrlog: pjstadig: so rhickey wouldn't mind strings as IFn but didn't want it badly enough to wrap them?

13:05 pjstadig: i dunno

13:05 he wanted strings to be java strings

13:05 i don't know his feelings about strings implementing IFn

13:05 StayInSkool: vinzent_: how on earth does That work?

13:05 gfrlog: I assumed strings as IFn would be considered ambiguous perhaps

13:06 StayInSkool: oh i see. that is confusing to read though heh

13:06 gfrlog: dunno. If passed map, lookup self. If passed regex, call (re-matches); if passed string, call substring?... could be fun and multipurpose

13:06 pjstadig: gfrlog: but if clojure's abstractions were written in clojure, then you could extend the IFn protocol to whatever you wanted...and you don't even have to ask Rich!!!!

13:07 technomancy: I asked Rich about making more types implement IFn via prototypes (regexes specifically), but you really lose fast-path inlining that hotspot can do, so he pretty much shot it down.

13:08 gfrlog: pjstadig: ah hah, good point.

13:08 pjstadig: well is that any different with invokedynamic?

13:09 technomancy: pjstadig: I don't know if he was considering that; he probably doesn't want to have to maintain a separate jdk7 codebase

13:09 gfrlog: clojure's doing this dance between dynamic and performant...

13:09 technomancy: if it is possible

13:09 pjstadig: deprecate java 6...problem solved! :)

13:09 vinzent_: StayInSkool, well, as i see it, keyword-first syntax primarily used to access fields of some object, so (:foo qux) is equivalent for Qux.getFoo in Java

13:10 technomancy: pjstadig: I'm all for it

13:10 gfrlog: pass it a positive integer and it returns .charAt

13:11 vinzent_: btw, why map-like functions accepts the fn, not the coll as the first arg? (like assoc and others)

13:12 so i can't do smth like (-> [1 2 3] (map inc) (assoc 0 :x))

13:13 bendlas: vinzent_: b/c it's called "to map a function over a sequence"

13:13 arunkn: vinzent: I think it is because map actually can take multiple sequences as argument

13:13 bendlas: vinzent_: that's what ->> is for

13:13 technomancy: extending IFn was like the main thing I was excited about protocols for =\

13:13 vinzent_: ,(->> [1 2 3] (map inc) (assoc 0 :x))

13:13 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.Associative

13:13 gfrlog: maybe we need to write a ->< macro

13:14 StayInSkool: or a >.< macro

13:14 arunkn: gfrlog: lol

13:14 vinzent_: arunkn, i think it's not a problem - last arg can be fn

13:14 arunkn: vinzent, I mean it would be easy to club variable args towads the end

13:15 gfrlog: vinzent_: when it comes down to it, different ways of composing the functions will result in different patterns that may or may not be compatible with -> or ->>; I don't think you can account for all cases no matter how you arrange the args

13:15 arunkn: and as you said it is also semantically consistent

13:17 vinzent_: gfrlog, it's just strange for me that map-like fns have one agreement for args' order, and assoc-like have other one, and both groups are operating on the same datastructures

13:18 arunkn: -> and ->> forms also take ,,, to visually mark the (first/last) position where the result of the previous form goes right. Why isn't there a macro

13:19 which uses this?

13:19 hiredman: arunkn: huh?

13:19 Chousuke: arunkn: they don't "take" ,,,

13:19 arunkn: ,,, is whitespace

13:20 dnolen: vinzent_: things which can work with assoc won't necessarily work with map.

13:21 arunkn: Chousuke: I din't know that the reader discarded ,,, as whitespace

13:21 Chousuke: arunkn: it's pretty useful sometimes

13:21 manutter: ,(let [x ,,,,,,, 1] x)

13:21 clojurebot: 1

13:22 manutter: :)

13:22 Chousuke: arunkn: to be specific, all commas are whitespace

13:22 arunkn: dude, that's a loooot of commas

13:23 vinzent_: dnolen, but vectors and maps work. I'm just can't see the rationale behind this decision.

13:23 arunkn: Chousuke: I dint know that one either :)

13:24 dnolen: vinzent_: maps and vectors are only two data structures of many possible data structures, there are many others. Some may work with assoc and some may work with map.

13:25 and some may work with both.

13:26 vinzent_: dnolen, ofcourse, but it didn't actually answer my question

13:27 dnolen: vinzent_: what more do you need to know?

13:29 ,(map vector [1 2] [3 4])

13:29 clojurebot: ([1 3] [2 4])

13:29 dnolen: is another reason.

13:32 manutter: ,(map [1 2 3 4] [5 6 7 8])

13:32 clojurebot: java.lang.IndexOutOfBoundsException

13:32 manutter: oops

13:33 vinzent_: (map [1 2] [3 4] vector) can work fine too

13:33 manutter: ,(map [0 1 2 3] [4 5 6 7])

13:33 clojurebot: java.lang.IndexOutOfBoundsException

13:33 manutter: user.stupid.ReadingComprehensionError

13:34 ,(map vector [1 2 3 4] [5 6 7 8])

13:34 clojurebot: ([1 5] [2 6] [3 7] [4 8])

13:34 manutter: ls

13:35 oops, wrong window...

13:35 arunkn: :)

13:35 bendlas: lol

13:36 * manutter has a bad habit of typing "ls" the way some people have a bad habit of saying "and uh..."

13:37 manutter: MySQL particularly resents it when I do that...

13:44 amalloy: (map [1 2] [3 4] vector) would be awkward to work with, from the POV of the guy implementing map. you can't just say (defn map [f & colls] ...), it has to be some nonsense like (defn map [& args] (let [f colls] ((juxt last butlast) args) ...))

13:44 opqdonut_: it's kind of a given that varargs come at the end

13:45 thus (map fn colls...) and (assoc a-map key val key val ...)

13:47 vinzent_: apply is the single exception

13:47 opqdonut_: the argument order of apply corresponds to the argument order of the call it induces

13:47 amalloy: vinzent_: exception to what?

13:48 opqdonut_: amalloy: varargs in the middle

13:48 manutter: I didn't think apply took variable arguments

13:48 amalloy: mmmm. i guess? you're thinking of it like (apply function arg arg more-args)?

13:48 vinzent_: yep, different args order would be confusing there

13:49 manutter: ,(doc apply)

13:49 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

13:49 manutter: oh, I see

13:49 * dnolen doesn't see how infinite var args could possibly be in the middle.

13:49 manutter: wow, that's pretty wild

13:52 amalloy: i always thought of apply as (apply f arg*), where the last "args" gets expanded in place; from that point of view the varargs aren't really in the middle

13:52 but i think that's a silly point of view to have

13:53 manutter: ,(apply + 1 2 3 [4 5 6])

13:53 clojurebot: 21

14:25 icey: is compojure still the standard web framework that people use with clojure?

14:26 bsteuber: icey: now ring is the framework and compojure a set of ring-plugins

14:27 icey: bsteuber: ah right... they did that like a year ago, no?

14:28 bsteuber: I think so, yes

14:28 icey: bsteuber: either way, thanks :)

14:35 wow, bringing up a working environment is so much easier than it used to be

14:37 manutter: icey: what did you use to start it?

14:37 icey: manutter: i used lein for everything

14:37 manutter: Ok, that's what I thought

14:38 Just wanted to be sure I wasn't missing anything new :)

14:38 icey: manutter: i think the last time i seriously played with clojure was < 1.0; everything has matured pretty significantly since then

14:39 manutter: yeah, it's coming along nicely

14:58 dnolen: ooooh, Dan Freidman & Co are working on extending miniKanren to CLP(FD) !

15:02 Moominpapa: I know this is a really stupid question, but how do you provide proxy settings to leiningen?

15:02 I assumed you'd just export HTTP_PROXY like normal, but it appears to be doing exactly nothing :(

15:04 fliebel: dnolen: oooh! What does CLP stand for again? I only remember the finite domain part.

15:05 manutter: Moominpapa: you mean for connecting to remote repositories to download dependencies and such?

15:05 Moominpapa: Yes.

15:05 I'm finally trying to do some clojure at work

15:05 Home is easy :)

15:05 dnolen: fliebel: Constraint Logic Programming, yeah just got an email from Dan Friedman himself, seems like they're working hard on having something done by the end of summer.

15:05 manutter: Well, I don't have *much* of an answer, but what I have is "You don't set proxy for leiningen, you set proxy for maven"

15:06 and even that's just a guess

15:06 Moominpapa: I suspect it's a pretty good guess, thanks.

15:06 manutter: good luck

15:06 fliebel: dnolen: Cool, so that means you don't have to invent a constraint solver yourself, right?

15:06 Moominpapa: Of course, since my work blocks IRC, it'll be tomorrow by the time I figure out if that does the trick :)

15:07 dnolen: fliebel: precisely.

15:07 manutter: :)

15:07 fliebel: dnolen: Awesome. I'm almost beginning to wonder if they have any plans for predicate dispatch :P

15:08 dnolen: fliebel: yeah, I'm very, very curious as to their approach for making it efficient.

15:09 fliebel: dnolen: Is constraint solving a special case of predicate dispatch yet?

15:10 gtrak`: cemerick, someone mentioned earlier you had a blog post for integrating spring security with clojure, but I can't find it, do you have a link?

15:10 stuartsierra: I said it, but I was wrong.

15:10 cemerick: gtrak`: I've not written such a thing. There's nothing special you need to do to use spring-security with Clojure, though.

15:11 gtrak`: ah I see

15:11 * cemerick contemplates writing such a blog post to say just that ;-)

15:11 dnolen: fliebel: no constraint solving's all about making relational programming efficient for certain domains - integers for example (you can solve Sudoku)

15:11 fliebel: but would also be useful for type inference I would think.

15:12 markskil1eck: Why does (use '[penumbra opengl]) work but not (use '[penumbra]) ?

15:13 The latter gives me a "could not locate on classpath"

15:14 stuartsierra: `use` expects collections to be prefix-lists or vectors-with-keyword-options.

15:14 That is, (use '(penumbra opengl)) tries to load penumbra.opengl

15:15 You could also say (use '[penumbra.opengl :only (foo bar)])

15:15 markskil1eck: I see, I see.

15:15 So [a b c] becomes [a.b.c] ?

15:16 stuartsierra: No, it becomes a.b and a.c.

15:16 And it should be a list, not a vector.

15:16 markskil1eck: Why is that?

15:16 stuartsierra: Because that's what the docstring says.

15:16 Anything else may not be supported in the future.

15:17 markskil1eck: Alright

15:17 Thanks, stuartsierra.

15:17 stuartsierra: 'welcome

15:17 markskil1eck: You mean '(welcome)

15:17 * markskil1eck hides

15:18 stuartsierra: heh

15:35 TimMc: Argh, my kingdom for (binding) in Java.

15:36 stuartsierra: Well, Var.pushThreadBindings works...

15:40 scottj: better name for this fn (or is this in core/contrib?) (defn assoc-swap [map key f & args] (assoc map key (apply f (get map key) args)))

15:44 stuartsierra: scottj: I think you want update-in

15:45 scottj: stuartsierra: oh yeah thanks

15:45 stuartsierra: 'welcome

15:45 scottj: for some reason I only think of update-in when I have more than one level of keys

15:46 stuartsierra: Yeah, it's slightly odd that there's no single-key `update` but `update-in` works fine with a vector of one key.

15:49 cemerick: not sure if dropping a vector literal is worth having another core fn

15:49 er, you know what I mean. :-P

15:49 stuartsierra: that's probably why it hasn't been seriously considered.

15:50 TimMc: stuartsierra: Whereas I was disappointed to discover that (update-in m [] v) fails to return v :-P

15:50 technomancy: cemerick: do you know if maven has any existing conventions for handling libraries with native code?

15:50 my googles were unable to turn up anything (in any JVM language, actually)

15:51 stuartsierra: technomancy: people do it, I know that much.

15:54 technomancy: stuartsierra: not enough to have settled on a convention for signaling "this jar has native components" I guess

15:54 ?

15:55 stuartsierra: http://docs.codehaus.org/display/MAVENUSER/Projects+With+JNI

15:55 amalloy: TimMc: you surely mean assoc-in for that example, or else "return (v m)"?

15:56 stuartsierra: technomancy: I think native code often has a "classifier" part of its name in addition to group/artifact/version.

15:57 http://www.sonatype.com/books/mvnref-book/reference/profiles-sect-tips-tricks.html#profiles-sect-platform-classifier

15:57 technomancy: interesting; thanks.

15:58 stuartsierra: 'welcome

16:01 TimMc: amalloy: I surely do.

16:07 thorwil: hmm, how do i get that :pattern past the reader? (html [:input {:type "text" :name "slug" :required "required" :pattern "[a-zäöüß0-9_\-]*"}])

16:07 amalloy: thorwil: what is the backslash for?

16:08 also, those characters after "a-z" are all rendering as question marks. i know my client supports unicode, so i'm inclined to blame yours for mangling the character encoding

16:08 thorwil: amalloy: has beena while since i wrote and tested that, i think \ really does stand for \

16:08 amalloy: &"\-"

16:08 sexpbot: java.lang.Exception: Unsupported escape character: \-

16:09 amalloy: unlikely

16:09 if you wanted to allow literal backslashes you'd need "\\"

16:10 cemerick: technomancy: The only native lib I've (knowingly) used in maven is swt; it's packaged as regular jars, no classifiers AFAICT. e.g. http://search.maven.org/#artifactdetails|org.eclipse.swt.gtk.linux|x86|3.3.0-v3346|jar

16:10 amalloy: and being inside a regex character class would probably mangle it further so that you need \\\\

16:12 thorwil: amalloy: \\ makes it appear as \ in the final html. thanks!

16:12 cemerick: technomancy: I was confused by the discussion about special-casing native deps in lein — as far as I knew, they could be loaded from plain-jane jars.

16:12 Perhaps the swt runtime was unpacking them for me and dynamically updating the library path? *shrug*

16:13 thorwil: amalloy: now i recall it's \- escaping the minus, as that would define a range, otherwise. duh

16:13 amalloy: no, it wouldn't

16:13 - at the start or end of a character class can't define a range

16:14 a lot of people seem to escape them instead of putting them at the end because they don't know any better. i think that hurts readability, but whatever. it just struck me as weird that you'd put it at the end *and* apparently attempted to escape it

16:15 thorwil: well, i probably could count the number of regexps that i wrote in life on 2 hands :)

16:16 gotta run, good night! :)

16:22 gfrlog: I could probably indicate the set of hands that I've used it my life in one regex: #"(lef|righ)t"

16:22 s/it/in

16:22 sexpbot: <gfrlog> I could probably indicate the set of hands that I've used in my life in one regex: #"(lef|righ)t"

16:24 TimMc: amalloy: I always put the "-" at the end of the range, but I worry that I'll go to add another character...

16:25 amalloy: TimMc: i put it in the front, possibly for that reason

16:28 TimMc: hah

16:28 Why didn't I think of that?

16:29 gfrlog: I think I once read somewhere that you HAVE to put it at the front, so I always did.

16:29 Apparently that's not strictly true.

16:29 amalloy: i actually worry about escaping it because i never know if that will accidentally include a literal backslash in the class

16:29 gfrlog: at least in the same sense that you don't HAVE to close your HTML tags.

16:30 amalloy: gfrlog: the difference is that you do have to close your (x)html tags, and you don't have to put the - at the front :P

16:30 gfrlog: I was talking about the difference between strict specification and actual outcome

16:31 if the browser does what you wanted it to, that could be "good enough", but there's no guarantee it'll work in the next version of the browser

16:36 amalloy: gfrlog: right. and regexes *do* specify that you don't have to put it in front

16:37 scottj: with ring/compojure is there a wrapper/middleware to turn form-params that are "false" or "true" to true and false?

16:37 gfrlog: That was th possibility I was leaving open when I said "at least"

16:41 edw: Has anyone else had problems with SLIME exploding when Clojure returns a Unicode string. (Using CLOJURE-JACK-IN, that is...)

16:41 raek: edw: yes. either SLIME or swank-clojure is configured for the wrong version

16:42 edw: try customizing the slime-net-coding-system variable

16:42 edw: raek: What should it be? UTF8?

16:42 raek: *version -> encoding

16:42 edw: yes, UTF-8

16:42 amalloy: holy cow. edw, lisp channels are only allowed a couple dozen capital letters per day. i think you just used them all up

16:43 edw: Sorry about that; it's the case-insensitive Schemer in me.

16:43 Should I give 1.7 a try? That looks new...

16:44 raek: edw: sorry, I meant encoding, not version

16:45 edw: So: slime-net-encoding-system?

16:45 raek: edw: did you manage to customize the slime-net-coding-system variable (mine has the value utf-8-unix)

16:45 yes

16:46 or was it already set to utf-8-unix?

16:46 edw: Durn. Yeah. It's set to iso-latin for some reason. Odd.

16:46 raek: yeah, Slime defaults...

16:47 edw: I'm wondering what the deal is, as I don't believe SLIME was pooping the bed on Unicode previously.

16:47 raek: edw: try reconnecting and evaluating the expression (seq "åäö"), it should yield (\å \ä \ö)

16:47 fliebel: What's that Clojure deployment thing called? Thought it was based on Crane or Pallet or whatever.

16:48 edw: Will (whispers)SLIME stomp on the slime-net-coding-system in my .emacs which clojure-mode loads?

16:49 cemerick: fliebel: Both crane and pallet are used for deployment automation, with different approaches.

16:49 edw: Should I add a hook or something?

16:50 cemerick: fliebel: http://pallet.github.com/pallet/

16:50 my preference, for whatever that's worth

16:53 edw: Ah, so much better! Thanks amalloy and raek!

16:53 amalloy: haha, i get credit? all i did was complain about upper-case

16:54 edw: Hey, every little bit counts.

16:56 I have a grad student project: build a text classifier that rates input text from 0 (the Dude in the bathtub pre-ferret) to 9 (the Dude, squealing ferret in the tub).

17:21 scottj: I seem to remember there being a new webmachine inspired framework for clojure other than clothesline, anyone know the name? google fail

17:27 edw: Is `sort' stable?

17:28 Google says: Yes, it is.

17:29 amalloy: edw: yeah

17:29 stuartsierra: Yes, it uses java.util.Collections.sort

17:34 scottj: https://github.com/malcolmsparks/plugboard is what I was looking for

17:34 raek: speaking of clothesline, anyone know there it lives nowaday? I was going to read about it, but got 404...

17:34 scottj: ah, will check that out...

17:35 scottj: raek: kirindave/clothesline was updatd yesterday

17:36 amalloy: has anyone used java's piped input/output streams? i would expect that if i .close the output stream that would cause the input stream to still be readable until it gets to the end of data, but i'm not sure that's what's happening

17:38 hiredman: everytime I start using piped i/o it eventually vanishes

17:38 technomancy: cemerick: yeah, I was wondering how it knows to do the unpacking and setting java.library.path, but if the swt runtime is handling that then it can't be generalized for other native libraries.

17:39 amalloy: and i can't find docs saying what happens when you close them

17:40 hm. but the docs for .read say that it throws an exception if the pipe is broken. so i can't figure out how to signal end of stream

17:42 hiredman: amalloy: if you write an EOF, it will be read

17:45 amalloy: hiredman: so (write-actual-data) (.write out -1) (.flush out), and let the guy with the input end close it himself?

17:45 hiredman: amalloy: yes

17:48 raek: hrm, why doesn't the javadoc for OutputStream mention that passing -1 to .write signals end of file?

17:49 (InputStream.read mentions -1 though)

17:49 amalloy: raek: i don't think it's true

17:50 if i write -1 to a ByteArrayOutputStream, it writes a 255 byte

17:51 as seen at https://gist.github.com/1001356

18:01 chewbranca: technomancy: ping

18:04 technomancy: chewbranca: hallo

18:08 amalloy: fwiw i think there must be something wrong aside from my use of pipes. if i write a million 0 bytes to a POS then .close it, then my PIS reads a million 0s followed by a -1, no exception

18:17 technomancy: http://news.ycombinator.net/item?id=2604558 <= clojure on heroku

18:18 chewbranca: technomancy: hey

18:18 technomancy: hahaha yeah was just going to ask if you saw that yet

18:20 technomancy: I actually helped them test it =)

18:20 but now I can talk about it

18:21 chewbranca: just replied in that hn thread

18:21 oh cool

18:22 getting charged for the heroku app

18:24 or at least a worker associated with it

18:45 heh... never mind, heroku changed their billing so you don't get a free dyno per app, but basically get one free dyno worker overall

18:46 gotta love this quote: "On June 1, 2011, Heroku switched from billing for “dynos” to billing for “dyno-hours”, which is more clear. "

18:46 talking about changes to be made tomorrow in the past tense

18:49 amalloy: chewbranca: happen to know what time it is in japan?

18:51 chewbranca: amalloy: most likely june 1st, but heroku is an american company running on american servers (primarily speaking, I'm sure they have expanded out past america)

18:51 technomancy: chewbranca: you coming on thurs?

18:51 chewbranca: technomancy: yeah definitely

18:52 amalloy: chewbranca: that's fine, but it seems parochial to tease them for calling june 1st "the future" when they presumably have clients in japan, who are even now being billed in this new way

18:52 technomancy: cool; maybe we can throw together a web app.

18:52 amalloy: errr, that's worded badly but i think you see what i mean

18:52 chewbranca: amalloy: not when my invoice says time used on may 31st

18:55 __name__: They should have specified the timezone.

18:56 chewbranca: amalloy: I hear what you're saying, which is why I commended them on their progress, and I am rather excited by their support for other languages, especially clojure

18:56 __name__: And the time, for that matter.

18:56 chewbranca: __name__: exactly, or on a per user basis

18:56 __name__: But ‘1st of June’ is a completely vague statement.

18:57 I also hate how some use ‘month’ as a time-span.

18:57 A ‘month’ is everything from 28 to 31 days.

19:00 chewbranca: __name__: yeah I can't stand working with month intervals, currently have to break up a monthly rate down to amount per day for some billing stuff

19:00 __name__: chewbranca: Tell them that is impossible :D

19:01 chewbranca: heh... kind of funny, I recently switched from hourly rate to monthly rate, and technically its far more costly for me to take a day off in february than it is in may

19:01 well 'far more' is exagerating, but definitely more expensive

19:02 __name__: It's just insane.

19:03 technomancy: yup; about time we switched to metric time anyway

19:15 ugh; would it kill clojure.core/memoize to expose the cache atom in metadata?

19:31 cemerick: technomancy: good idea; seems like something that could slip in without much fuss, too

19:46 technomancy: I thought it was intentional, but I guess it wasn't practical back in the day because functions couldn't have metadata when memoize was written.

19:48 hiredman: ~help

19:48 clojurebot: http://www.khanacademy.org/

20:56 scottj: was there a project/library that made scala/jruby/clojure integrate better, like making it as easy to call each of them as it is to call java?

21:00 technomancy: scottj: I had a clojure-gem that allowed calling clojure data structures and STM from jruby, but it was one-way and stuck with clojure 1.0

21:35 hiredman: dnolen: you mentioned that core.logic does pattern matching, I guess for "does pattern matching" I would expect to see something like cond pattern expr, pattern expr, pattern expr

21:36 which I don't see an example of anywhere in core.logic

21:39 Ownatik_: k I'm just starting to take a look to clojure, starting with 4clojure. in the following expression: (= __ (conj '(2 3 4) 1) what does the ' mean

21:40 gfrlog: it means quote

21:40 it is equivalent to (quote (2 3 4))

21:41 which means that the list is unevaluated

21:41 scottj: Ownatik_: if you quote a list when it's evaluated it's just a list, otherwise a list is evaluated to a function call

21:41 gfrlog: I was trying to put just those words together but was having trouble

21:44 Ownatik_: ok I definately don't get functional programming yet

21:45 my brain won't parse what you just said

21:45 lol

21:45 scottj: Ownatik_: this isn't functional programming related

21:45 Ownatik_: most languages have separate syntaxes for lists and function calls, lisp doesn't

21:46 Ownatik_: so in other languages you could have foo(a,b) and (foo, a, b) perhaps. in lisp you just have (foo a b). if you want it to be a list it needs to be quoted, otherwise it will be a function call

21:47 Ownatik_: ok I understand now

21:47 and got the solution

21:47 thanks

21:47 so the quote just mean it's a list

21:48 tomoj: &(list? (read-string "(+ 1 2)"))

21:48 sexpbot: ⟹ true

21:48 tomoj: &(eval (read-string "(+ 1 2)"))

21:48 sexpbot: java.lang.SecurityException: You tripped the alarm! eval is bad!

21:48 tomoj: oh, duh

21:50 scottj: Ownatik_: not exactly, the quote means when evaluated give whatever is quoted. so 'a evaluated is a

21:50 Ownatik_: oh ok thanks for the clarification

21:51 scottj: Ownatik_: lcojure uses [a b c] for list like things more than '(a b c)

21:51 amalloy: Ownatik_: land of lisp has a good explanation, near the beginning iirc, of what ' really is

21:51 scottj: Ownatik_: note that if a = 1, [a] is evals to [1] and '(a) evals to (a)

21:53 amalloy: hm. not land of lisp. i seem to have meant http://lisperati.com/casting.html

21:53 scottj: even better consideringit's freely available online

21:54 amalloy: yeah, http://www.lisperati.com/clojure-spels/syntax.html and the page after that talk about quoting

21:56 Ownatik_: you might find the above a good resource for learning, as well as 4clojure

22:12 netrealm: Hey, I have a question about ring; if this is the wrong channel, please let me know where a better place is. If I wanted to dynamically add/remove routes, how would I go about that?

22:13 amalloy: netrealm: that's actually a question about compojure (or moustache), not ring

22:14 netrealm: Oh, okay.

22:14 amalloy: ring just takes a request map, gives it to you, and receives a response map

22:14 compojure has defroutes , which constructs a function (for giving to ring) that decides what to return based on the url

22:15 hiredman: dnolen: looks like there is a typo in binding-map'

22:15 amalloy: so really, i suspect the answer is "don't bother with compojure for the dynamic part of your routes"

22:16 hiredman: dnolen: when I fix the typo in binding-map' (binding-map' '{:foo ?foo} {:foo 5 :bar 5}) throws an exception

22:16 does logic have jira issues yet?

22:17 netrealm: amalloy: and instead use...?

22:18 amalloy: define a subtree of your application that you want to match "dynamically", like (GET "/dynamic/*" (do-runtime-whatever)). i don't know off the top of my head the compojure syntax for getting out the full request map

22:19 but it's not that hard to work with a raw ring request map: see https://github.com/mmcgrana/ring/raw/master/SPEC for the spec

22:19 scottj: (GET "/dynamic/*" request (do-runtime-whatever))

22:19 (GET "/dynamic/*" request (do-runtime-whatever request))

22:20 amalloy: thanks scottj

22:20 netrealm: ah...I see...I missed the part where I could have a wildcard match

22:21 amalloy: netrealm: compojure does a fair bit of stuff that looks magical but isn't really very complicated. i recommend getting at least comfortable with the underlying ring stuff so you can fall back if you want

22:22 Ownatik_: scottj, amalloy: had to go afk, sorry for the lack of response and thanks for the tips.

22:23 netrealm: amalloy: cool, thanks. I'll working on digesting the ring docs.

22:23 amalloy: (i had basically no idea how the web frameworks worked like two months ago, and now i'm giving advice. you should (a) marvel at how cool the frameworks must be, and (b) take advice with caution)

22:24 netrealm: Haha, okay. I'm pretty new to clojure, so I'm still working on understanding how to read example code and reason about what it's doing.

22:38 dnolen: hiredman: thx for the report. was more than a couple of typos, a couple of bugs as well, fixed now, latest pushed to github and Clojars.

22:39 hiredman: http://dev.clojure.org/jira/browse/LOGIC

22:45 hugod: dnolen: prelude/defnu has a typo - lgoic

22:46 dnolen: hugod: oof thx

22:47 hugod: fixed.

22:48 hugod: thanks

22:53 hiredman: http://clojars.org/core.logic is awesome

22:53 anyway, what I just pulled from clojars seems to be the same as what I had ealier

22:54 dnolen: hiredman: yeah, that Clojars page is weird, not sure what the deal is.

22:55 hiredman: I see the fix on github though

22:58 dnolen: hiredman: I repushed to Clojars, still not work?

Logging service provided by n01se.net