#clojure log - Mar 15 2011

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

0:10 sproust: Helo Clojurians, haven't been here in a while. I have a quick question:

0:10 ,(let [a (range 1 12)] (format "%s" (str a)))

0:10 clojurebot: "clojure.lang.LazySeq@f49de165"

0:11 sproust: ,(let [a (range 1 12)] (format "Values: %s" (str a)))

0:11 clojurebot: "Values: clojure.lang.LazySeq@f49de165"

0:11 sproust: What's the idiomatic workaround for this?

0:12 (I'd like to see the %s expand into a list of values.)

0:14 brehaut: &(let [a (range 1 12)] (format "%s" (apply str (interleave " " a)))

0:14 sexpbot: ⟹ 1 ; Adjusted to (let [a (range 1 12)] (format "%s" (apply str (interleave " " a))))

0:14 brehaut: thats differently wrong

0:15 &(let [a (range 1 12)] (format "%s" (apply str (interpose " " a))))

0:15 sexpbot: ⟹ "1 2 3 4 5 6 7 8 9 10 11"

0:16 sproust: Thx brehaut; I understand I can manually concatenate; just wondering if there's any way to automatically get a good default representation without having to do it manually (as in Python).

0:17 brehaut: sproust: i dont think so.

0:17 sproust: Thx.

0:17 brehaut: sproust: best i could think of for 'automatic' would be ##(let [a (range 1 12)] (format "%s" (apply list a)))

0:17 sexpbot: ⟹ "(1 2 3 4 5 6 7 8 9 10 11)"

0:19 sproust: Ah... I see. (format) will do the right thing if this isn't a seq. I'd love a version of (format) which does this automatically, for quickly printing stuff for debugging (where I don't care for precise output).

0:21 brehaut: sproust: pr and prn

0:21 &(prn (range 1 12))

0:21 sexpbot: ⟹ (1 2 3 4 5 6 7 8 9 10 11) nil

0:22 sproust: Right, but goes to stdout, we need (fr) I guess :-)

0:23 brehaut: &(with-out-str (prn (range 1 12))

0:23 sexpbot: ⟹ (1 2 3 4 5 6 7 8 9 10 11) ; Adjusted to (with-out-str (prn (range 1 12)))

0:23 sproust: ,(defn fr [x] (with-out-str (pr x)))

0:23 clojurebot: DENIED

0:23 sproust: (defn fr [x] (with-out-str (pr x)))

0:23 brehaut: you cant def with the bots

0:23 sproust: Ha! You beat me to it.

0:23 Thx.

0:24 brehaut: (def fr (comp with-out-str pr))

0:25 sproust: That won't work; with-out-str is a macro.

0:25 brehaut: sproust: may is suggest https://gist.github.com/c93c37345c49c47dcfa2 as something to look at too

0:26 stink

0:28 sproust: Nice.

0:28 brehaut: I think we've been redefining (pr-str).

0:29 brehaut: ha

0:30 sproust: That's what happens to my rotting brain when I go do some C for two months and then I come back. I forget.

0:32 brehaut: yeah dont do that :P

0:32 waxrose: :D

0:48 phenom_: oh jeebus ... i've got some clojure code that's beginning to look very imperitive with lots of mutable state :(

0:48 i need a mentor or something

0:48 bah

0:49 brehaut: dont we all

0:49 waxrose: me too

0:49 brehaut, You should be my mentor! :P

0:49 brehaut: haha i dont think should be anyones mentor

0:49 waxrose: lol why not?

0:50 brehaut: do you really want to be mentored in regexp abuse, unnecessary point free and misunderstanding monads?

0:50 waxrose: Ehh, depends on how much alcohol is involved.

0:51 phenom_: anyone know how much clojure/core is charging :P

0:51 waxrose: lol

0:52 tomoj: "unnecessary" :D

0:52 brehaut: :D

0:52 waxrose: I've been configuring files more than I have been reading. So you're not the only one in need of a mentor.

0:54 phenom_: yea ... ive got about 500 loc ... i need a checkpoint review

0:54 ill post it on github and request on the list or here

0:54 waxrose: what's your github?

0:54 phenom_: it's not up yet :P

0:55 waxrose: oh okay haha

0:55 Darn, now I can't stalk your commits.

0:55 phenom_: if you're interesed in helping out, that's always welcome

0:56 waxrose: Maybe :)

1:00 phenom_: well then I'll let you know when it's up

1:03 waxrose: Cool. :P

1:17 sproust: Is there a way to terminate all the threads I started in my VM/REPL?

1:20 tufflax: ,(. String getName)

1:20 clojurebot: java.lang.NoSuchFieldException: getName

1:20 tufflax: ,(. (identity String) getName)

1:20 clojurebot: "java.lang.String"

1:20 tufflax: I don't get it. :P

1:27 tomoj: don't use . anyway

1:27 tufflax: Ok may I do get it now.

1:27 tomoj I'm just trying to understand what's going on.

1:28 s/may/maybe

1:28 tomoj: sure

1:28 have you read http://clojure.org/java_interop ?

1:28 tufflax: I'm reading now

1:29 Maybe I should have read further before I started asking, but it just looked so strange to me. :P

1:30 tomoj: strange indeed

1:31 . deserves its 'special' title

1:31 tufflax: hehe yeah

5:00 angerman: anyone mind lending me a hand with library packing?

5:01 Currently I build the jReality package with https://github.com/angerman/planarity/blob/master/mkjr/Makefile

5:02 it's actually getting pretty large and packages up all the native libs for all architectures in one package. Can that be broken apart?

5:04 It also gives this: [WARNING] POM for 'org.clojars.angerman:jreality-native-deps:pom:2011-01-29:compile' is invalid. It will be ignored for artifact resolution. Reason: Not a v4.0.0 POM

5:35 xkb: hi all

5:37 A colleague and I are thinking about organizing the first european Clojure conference. We are trying to find a way to see how many ppl would be interested. Any hints/tips?

5:42 mduerksen: xkb: i'm not sure, but what about hackernews?

5:42 xkb: mduerksen: hmm good idea, just to see whose interested

5:43 there's no such thing as a clojure developers directory right?

5:43 like haskell has

5:43 ejackson: xkb: I'd to LauJensen or cgrand, as they've been doing Clojure training and will have the pulse of european clojure

5:43 s/to/talk to/

5:44 xkb: for now it's more of a wild idea, but it might be good to include as many ppl as possible, early on

5:44 we spoke at dyncon2011 in sweden this weekend, and there was quite alot of interest in clojure

5:44 so that's where the idea was born

6:05 pyr: hi

6:05 for a given agen i have the guarantee that no two functions will be executed in parallel, right ?

6:05 s,agen,agent

6:06 xkb: pyr: an agent will queue functions send to it, as far as I know

6:06 pyr: ok

6:06 xkb: why do you ask?

6:07 pyr: i have an agent that i use to serialize access to redis

6:07 xkb: ah ok

6:07 So it's an agent without state?

6:07 pyr: pretty much

6:08 i use this because Jedis the java redis library i'm using isn't thread-safe

6:08 but i still end-up with boggled data in redis

6:08 xkb: so did you use send or send-off and to one agent or multiple? :)

6:09 send-off is for potentially blocking functions

6:09 pyr: which is why i use it

6:09 xkb: not that it would matter, as the redis lib wont block

6:10 you could still get into trouble with multiple agents and send-off doing the same work

6:10 pyr: there's only one agent

6:10 xkb: ok..

6:10 pyr: i'll try using send instead

6:12 well send just barfs on me

6:13 xkb: odd.. any error?

6:13 pyr: earlier on, which'll help me find what happens

6:13 xkb: is the agent in an error state?

6:13 pyr: yep, and i wired up a backtrace to failed agents

6:13 so i'll have smth to look into

6:14 xkb: ok :) Good luck

6:51 pyr: xkb: heh, thx

7:02 * angerman just figured that the binding maybe lost in case of lazy evaluation … ouch.

7:16 fliebel: dammit, I never see to be able to get the brackets right in the require/use syntax. How obvious… (:require [clojure [set :as s]])

7:18 clgv: fliebel: I know that problem. when using the square brackets I always forget one of them or a bracket ;)

7:19 ejackson: fliebel: you and me both, I can never seem to remember which way it goes around

7:23 angerman: what's wrong with https://gist.github.com/870608

7:25 I always get Can't embed object in code, maybe print-dup not defined: clojure.lang.Atom@f2f8f5f

7:30 clgv: angerman: skip the unquote before atom and it works

7:30 ejackson: clgv: beat me to the punch :)

7:30 clgv: :P

7:31 angerman: hmm… thanks clgv. (& ejackson) … trying to wrap my head around that.

7:33 ejackson: angerman: I'm no macrologist, but in your version I think it evals the (atom 0) call and splices that into the code using print-dup (hence the misleading error), whereas you really don't want anything evaluated at macroexpansion time.

7:34 macroexpand-1 of the original:

7:34 (clojure.core/binding [user/*node-counter* #<Atom@4d0948bd: 0>] (clojure.core/deref *node-counter*))

7:34 angerman: ejackson: that's what I'm "guessing" as well… been using macroexpand a little…

7:34 fliebel: Hm, is there any elegant way of getting to the squares of a sudoku puzzle? So for a seq of 81 items, that would be positions 1, 2, 3, 10 11 12, 19, 20 ,21, and then 4, 5, 6, 13… It gets a mess of take-nth-partition really quick.

7:34 ejackson: and the unsplice free:

7:34 (clojure.core/binding [user/*node-counter* (clojure.core/atom 0)] (clojure.core/deref *node-counter*))

7:35 fliebel: i'd use modulo and friends

7:36 fliebel: ejackson: How? Which friends?

7:37 clgv: fliebel: write an adressing function addr [square-idx, field-idx] -> field

7:38 ejackson: to turn an index in a 1D structure that represents a 2D structure you use side*x + y to go from 2D to 1D, and to reverse you get x = (round (mod (1D-index)) and y = 1D-index - x*side

7:38 off the top of my head, could have error, but you get the idea.

7:39 shouldn't be much of a leap from that to [square-idx] -> 1D-indices

7:40 angerman: Ok, I've another question https://gist.github.com/870623

7:40 why does (:render (Node. 0 0 0)) return nil?

7:40 fliebel: ejackson, clgv: Thanks, but that sounds just as complex if not more complex than what I have now.

7:40 opqdonut: angerman: why :render and not render

7:41 (:render (Node. 0 0 0)) tries to access the field named :render in (Node. 0 0 0)

7:41 clgv: fliebel: you could also organize the square in data structures in advance

7:42 angerman: opqdonut: ok, how do I get the render symbol?

7:42 ejackson: angerman: I think your want (.render ...) ?

7:42 clgv: no. he wants (render (Node. 0 0 0)) - I'd say ;)

7:42 opqdonut: yes

7:43 clgv: it's clojure so you don't need that dot afaik

7:43 angerman: … if only (render (Node. 0 0 0)) would work .. :(

7:43 ejackson: aah, yes.

7:43 angerman: it complains about not knowing about render. and .render doesn't work either.

7:43 clgv: it works here

7:43 but you have an error in it: java.util.IllegalFormatConversionException: f != java.lang.Integer (repl-1:13)

7:44 it's the floating number template "%f" you have ints here

7:44 angerman: clgv: yes.. that 0 0 0 was just a sample…

7:45 should have been 0 0.0 0.0

7:45 still need to figure out why it doesn't work for me...

7:45 clgv: angerman: I copy and pasted your gist and simply called: (render (Node. 0 0 0))

7:45 angerman: weird.

7:45 clgv: maybe you should make sure you recompile everything

7:46 angerman: if i juts copy it into the repl it work. if I try to call it from it's namescape it doesn.t

7:46 clgv: oh that might be a problem indeed. I had some weird behavior with namespaces and protocols as well.

7:47 angerman: you are about to write a Clojure Layer for TikZ?

7:47 angerman: yes. A second one ...

7:48 the first one was to rigid.

7:52 clgv: sounds interesting. I did some "programming" in TikZ which was really hard to do, since there isnt much more than that foreach-statement and latex definitions ;)

7:53 angerman: that's right. but you can get quite far with that already.

7:53 clgv: yeah. and I did, but it took some time ^^

7:53 angerman: Currently I need 3d stuff though. and tikz doesn't do 3d well.

7:59 clgv: I think I consider a Clojure TikZ DSL next time, I want to do some complex animation ;)

8:15 fliebel: $findfn {:a 1 :b 2 :c 3} [:a :c] 1 3

8:15 $findfn {:a 1 :b 2 :c 3} [:a :c] [1 3]

8:16 &(println "Sorry, I was sleeping")

8:16 clgv: he seems to be on vacation again

8:17 fliebel: ping amalloy_, Raynes

8:17 Hm, then I'll never know the name of that function...

8:17 clgv: does findfn search for a function that fulfills your testcase?

8:18 fliebel: yea

8:18 clgv: cool^^

8:18 fliebel: if I tell it 1 1 2 it will list all the functions that return 2 given 1 1 as argument

8:20 It's select-keys I was lookign for

8:31 clgv: is there a better way for parallel computation than pmap, if I do not want the sequence to be lazy?

8:31 and do not need the sequence to be lazy

8:48 fliebel: clgv: I think pcalls and pvalues uses pmap under the convers as well, so a thread pool or a future could work.

8:48 clgv: fliebel: threadpool was what came to my mind as well

8:50 chouser: clgv: there's been some work to integrate the forkjoin lib which I think would get you what you want. Not sure about the state or availability of that work though.

8:50 clgv: yeah that sounds like what I might need. but with current java it was not working a while ago

8:52 fliebel: chouser: Oh! I really want parallel reduce :)

8:53 chouser: In my work, I rarely have use for it, but the integration of forkjoin and clojure vectors sounds really clean and powerful.

8:55 mec: Is there a way to do def- like defn- ?

8:57 sattvik: mec: (def ^{:private true} myvar …), there's also a contrib lib

8:58 cemerick: mec: or if you're on 1.3, (def ^:private varname …) is all you need.

8:58 sattvik: defvar- from clojure.contrib.def

8:59 mec: Is this not normal since it isnt in core?

9:00 cemerick: There are just too many desirable variations of var metadata for there to be macros for all of them.

9:00 sattvik: I think its common enough. There has been some debate as to why defn- is in core but def- is not.

9:00 cemerick: defn- is probably considered a mistake in retrospect.

9:00 mec: cemerick: why's that?

9:01 cemerick: mec: especially given the easy metadata syntax in 1.3, there's not a lot of value in it.

9:01 mec: ah

9:02 clgv: how can I type hint function parameters to be double? ^double does not work

9:02 is ^Double right?

9:05 sattvik: clgv: I think so. At least in 1.2.

9:05 clgv: yeah 1.2 it it

9:05 *is

9:12 fliebel: Is there something like index-of in Clojure?

9:13 chouser: (doc map-indexed)

9:13 clojurebot: "([f coll]); Returns a lazy sequence consisting of the result of applying f to 0 and the first item of coll, followed by applying f to 1 and the second item in coll, etc, until coll is exhausted. Thus function f should accept 2 arguments, index and item."

9:14 fliebel: chouser: Yea, I'm using that now.

9:30 tufflax: Hm how do I specify an encoding to slurp? The doc doesn't say.

9:34 mids: (slurp f :encoding enc)

9:46 tufflax: thank you

9:55 I'm trying to read a file that contains the letters åäö, but it just comes out as "???". Anyone got any idea of what I should be doing? I'm saving the file with encoding UTF-8 and giving :encoding "UTF-8" to slurp.

9:55 cemerick: tufflax: your terminal / REPL is probably not using a suitable encoding itself.

9:56 tufflax: If I just type "åäö" in the repl it comes out as "<e4><f6>" etc, not "???"

9:57 cemerick: what does (System/getProperty "file.encoding") return for you?

9:59 tufflax: "Cp1252"

10:00 cemerick: And your terminal's encoding is?

10:01 TimMc: tufflax: First step is to check the actual bytes on disk.

10:01 tufflax: cemerick hm I dunno, I'm in vim...

10:02 not run through a terminal

10:03 TimMc: Open the file in vim, what bytes do you see?

10:03 Chousuke: it might help to set java's encoding to utf-8 using the -D switch to the JVM

10:03 it uses weird archaic encodings by default :(

10:03 chouser: there are a dozen places where encoding can go wrong. It's best to do something approaching a binary search if at all possible.

10:04 tufflax: TimMc i see åäö if that's what you mean

10:06 TimMc: Can you switch to a hexedit view?

10:07 vim might be guessing encoding

10:07 tufflax: -D did the trick

10:07 thank you

10:18 raek: tufflax: and easy way to verify that everything works is to eval something like (seq "köttfärssås") and check that the number of characters returned is right.

10:18 tufflax: ok :)

10:20 raek: (it also helps when determining if the problem is in the decoding of the input or in the encoding of the output)

10:21 tufflax: are you from sweden too?

10:21 tufflax: yes

10:30 raek: tufflax: in case you live in the Linköping area, you might be interested in that Linköping Clojure User Group will have a meeting next wednesday

10:31 tufflax: I don't live there :P

10:31 I live in Stockholm

11:06 angerman: wow. the geometry -> TikZ render works.

11:06 finally. After getting the transformation wrong multiple times :D

11:11 TimMc: angerman: Coordinate transforms?

11:12 angerman: TimMc: yes.

11:12 TimMc: Tricky little buggers, they are.

11:13 angerman: At first I got it almost right. It just felt completely inverted...

11:14 running circles, until i figured out that the z coordinate was negative and caused the inversion. Being negative was anticipated, just didn't make sure that x and y got divided by -z instead of z...

11:40 I'm always happy to find new strange errors :/

11:41 ,(clojure.contrib.string/join "/" ["foo" "bar"])

11:41 clojurebot: "foo/bar"

11:41 angerman: and what I get is: "wrong number of args (3) passed to string$join"...

11:45 jeffthink: am looking at the api docs, but can someone explain the difference between "->" and "-->" functions, and is the difference between those and ".." that the latter operates specifically on java objects?

11:45 * angerman has the very feeling that that had to do with lazy evaluation..

11:45 angerman: ,(doc —>)

11:46 clojurebot: I don't understand.

11:46 angerman: ,(doc -->)

11:46 clojurebot: Excuse me?

11:46 angerman: jeffthink: what is -->?

11:46 did you mean ->>?

11:46 jeffthink: sorry, typo...yes

11:47 angerman: well. -> puts the the form in position one while ->> puts it last.

11:47 (->> some-list (map some-fn))

11:47 that's where you want ->> for example.

11:47 (-> some-value (cons some-list))

11:47 that's where you might want to use ->

11:48 jeffthink: ah..yea, that makes some....thanks...and is ".." specifically for java op?

11:49 angerman: I would say so… but what does that mean :D

11:49 jeffthink: haha...good question :)

11:51 so, I've been using the ".." syntax to chain together a set of java functions on a java instance (.. instance method1 method2)...would that also be possible with "->"

11:52 angerman: (-> instance (.method1) (.method2)) ?

11:52 I guess.

11:53 jeffthink: yea, ok...so not as nice looking, but doable...not going to use that in this case, but am just trying to wrap my ahead around the different macros and how they relate

12:01 TimMc: jeffthink: macroexpand-1 might help

12:01 nickik: ,(macroexpand-1 '(-> 5 (cons '(6 7 8 9)))

12:01 clojurebot: EOF while reading

12:01 angerman: anyone has a magic mouse that's losing bluetooth most of the time?

12:01 nickik: ,(macroexpand-1 '(-> 5 (cons '(6 7 8 9))))

12:01 clojurebot: (cons 5 (quote (6 7 8 9)))

12:01 angerman: It's been going on/off the whole day… very confusing.

12:01 nickik: mmh

12:02 ,(macroexpand-1 (-> 5 (cons '(6 7 8 9))))

12:02 clojurebot: (5 6 7 8 9)

12:02 jeffthink: TimMc - thanks, didn't know about that

12:02 nickik: ,(macroexpand (-> 5 (cons '(6 7 8 9))))

12:02 clojurebot: (5 6 7 8 9)

12:03 nickik: cant i expand this to (cons 5 ' (6 7 8 9))

12:03 TimMc: nickik: jeffthink: Use syntax-quote: ##(macroexpand `(->> foo (bar qux) baz))

12:03 nickik: ah sorry i already did with quoting it

12:04 angerman: ,(macroexpand-1 '(-> 5 (cons '(6 7 8 9))))

12:04 clojurebot: (cons 5 (quote (6 7 8 9)))

12:04 angerman: ah yea.

12:04 TimMc: Hmm, why didn't ##(+ 3 4) that work...

12:05 Oh, sexpbot is missing.

12:05 ,(macroexpand `(->> foo (bar qux) baz))

12:05 clojurebot: (sandbox/baz (clojure.core/->> sandbox/foo (sandbox/bar sandbox/qux)))

12:07 TimMc: nickik: The argument to macroexpand has to be syntax.

12:07 ,(macroexpand (+ 3 4)) ; the args are eval'd

12:07 clojurebot: 7

12:10 TimMc: Huh... I thought macroexpand would get the inner ->> as well.

12:14 chouser: is there a function that resolves all class names the way type hints are resolved?

12:15 for example: 'Integer -> java.lang.Integer, and 'bytes -> [B

12:16 hiredman: the bytes thing and similar are special cased

12:17 everthing else is just resolve I think

12:17 chouser: they haven't been pulled out into a commond function yet?

12:17 hiredman: ,(resolve 'Integer)

12:17 clojurebot: java.lang.Integer

12:17 chouser: Yeah, I'm using resolve now, but I would like to support bytes, etc.

12:18 TimMc: ,(class (int-array 2))

12:18 clojurebot: [I

12:18 hiredman: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L981

12:18 TimMc: Ah, but you want 'ints -> "[I"

12:18 chouser: hiredman: ugh. thanks.

12:19 TallAdam: has anyone had a their main thread of execution just die (no exception)?? I use pmap to go http-fetch some pages and about half way through (the 6000 pages), it just stops. no exception. nothing???

12:19 chouser: TallAdam: how do you know it's dead?

12:20 TallAdam: chouser: its not dead (the repl still works), but it only makes it a random percentage through the job

12:20 mec: Is there a better way to express (fn [arg f] (f arg))

12:20 TallAdam: then it just stops

12:22 I don't think its the heap getting too big either

12:30 amalloy: TallAdam: have you considered that your threads may be choking due to server failures???

12:30 TallAdam: I have the http fetch wrapped in a try - would it miss anything?

12:30 amalloy: mec: my little utility library has an invoke function (fn [f arg] (f arg)) and a reorder function, so i would define that function as (reorder invoke)

12:36 user=> ((reorder invoke) 1 inc) ;; results in 2

12:41 fliebel: hm, i see. i'll go kick him

12:42 * amalloy leaves you to wonder whether he means Raynes or sexpbot

12:43 amalloy: fliebel: that said, i don't think your findfn was going to return anything

12:44 juxt would have required ((apply juxt [:a :b]) m) which he certainly wouldn't find, and select-keys would return a map, not a vector

12:45 TimMc: amalloy: reorder assumes a binary fun by default?

12:45 amalloy: TimMc: it reverses the args by default

12:45 TimMc: ah

12:45 amalloy: atm invoke is in amalloy/utils, and reorder is in hot-potato/hot-potato (maven artifacts). that's kinda silly so i'm going to merge them shortly

13:03 mec: well apparently -> works as (reorder invoke) too bad you cant pass it like a function

13:05 amalloy: mec: like (-> 1 inc)? sure, but as you note it's a macro

13:06 and wouldn't work anyway for functions that aren't literal symbols: (-> 1 (fn [x] (inc x))) is a compile error

13:06 mec: gotta love findfn

13:07 true enough

13:10 amalloy: mec: you can get my reorder and invoke if you want them, by depending on [amalloy/utils "0.3.1"]

13:11 TimMc: ,(-> 1 ((fn [x] (inc x)))) ;-P

13:11 clojurebot: 2

13:12 amalloy: fliebel: clojure collections all implement Collection, which specifies .indexOf

13:14 nickik: sexpbot tolerates mismatched parens like those clojurebot barfed on a while ago: ##(macroexpand-1 '(-> 5 (cons '(6 7 8 9)))

13:15 oh, but probably not for inline

13:15 &(macroexpand-1 '(-> 5 (cons '(6 7 8 9)))

13:15 sexpbot: ⟹ (cons 5 (quote (6 7 8 9))) ; Adjusted to (macroexpand-1 (quote (-> 5 (cons (quote (6 7 8 9))))))

13:17 TimMc: amalloy: Can you just have it say "closed some parens"? It's shorter and easier to understand, especially since some forms are rewritten.

13:18 &'(no quote here

13:18 sexpbot: java.lang.Exception: EOF while reading

13:18 amalloy: TimMc: i could certainly do that. i thought it might be helpful to have a pastable correct version

13:19 TimMc: hmm

13:19 amalloy: $mail brehaut why doesn't it work on &'(no quote here

13:19 sexpbot: Message saved.

13:20 TimMc: &(+ 3 4

13:20 sexpbot: ⟹ 7 ; Adjusted to (+ 3 4)

13:20 TimMc: &(+ '(3 4

13:20 sexpbot: java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number

13:21 TimMc: bah

13:21 &(list '(3 4

13:21 sexpbot: ⟹ ((3 4)) ; Adjusted to (list (quote (3 4)))

13:21 TimMc: Well, nothing obvious.

13:22 amalloy: TimMc: i bet it just doesn't work if there are meaningful characters before the parens

13:22 the *first* parens

13:24 yeah, i think that's it. i'm not exactly a superhero at reading fnparse nonsense, but it looks like we assume the list will start with an open-paren of some kind

13:30 TimMc: &(+ 2 3))

13:30 sexpbot: ⟹ 5

13:34 amalloy: TimMc: that's always worked

13:34 ,(+ 2 3))

13:34 clojurebot: 5

13:35 TimMc: ,(+ 2 3) So I guess I can have whatever out here?

13:35 clojurebot: 5

13:35 amalloy: indeed

13:35 (read) stops as soon as it gets to the end of a sexp

13:35 TimMc: &(+ 2 3) ##(+ 5 6) maybe...

13:35 sexpbot: ⟹ 11

13:40 raek: ,"clojurebot" ##"sexpbot"

13:40 clojurebot: "clojurebot"

13:40 TimMc: ,"clojurebot" ##(identity "sexpbot")

13:40 sexpbot: ⟹ "sexpbot"

13:40 clojurebot: "clojurebot"

13:44 TimMc: It's a bot race!

13:45 amalloy: did sexpbot actually win, or does it just look that way to me because we're sharing a server?

13:45 __name__: It won.

13:46 jcromartie: have you guys seen http://threecrickets.com/prudence/ ?

13:49 TimMc: I suspect you could map out the IRC topology by sending very long messages between users on different servers and checking how much is lopped off.

13:51 choffstein: Hey all. I have a quick question -- if I have written a bunch of clojure libraries for personal use, how can I set up a local repo directory to point leiningen towards? Is there a repo format I should follow

13:51 TimMc: choffstein: Look into lein install

13:52 choffstein: will do. thanks.

14:09 TimMc: What is the difference between = and ==? Does the latter just enforce numbers?

14:09 amalloy: TimMc: i guess i'm too late for choffstein, but why not put them on actual clojars? unless they're IP of some kind, this makes it easy to get up and running if you're working from a different machine

14:10 TimMc: yeah, i think so

14:12 jcromartie: ,(doc ==)

14:12 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums all have the same value, otherwise false"

14:20 __name__: &(== 2 2 2)

14:20 sexpbot: ⟹ true

14:20 __name__: &(= 2 2 2)

14:20 sexpbot: ⟹ true

14:20 nickik: it ignors types

14:21 * __name__ nods

14:21 nickik: so you can do int == float

14:21 __name__: &(= 2.0 2)

14:21 sexpbot: ⟹ true

14:21 __name__: &(== 2.0 2)

14:21 sexpbot: ⟹ true

14:21 __name__: huh?

14:21 nickik: mmhh

14:21 &("test" == "test")

14:21 sexpbot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn

14:22 nickik: oh

14:22 hehe

14:22 &(== "test" "test")

14:22 sexpbot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

14:22 amalloy: nickik: go put on the Java hat and sit in the corner

14:22 nickik: i am feeling dirty atm

14:23 I was just was doing java

14:23 *were

14:23 __name__: amalloy: What's the use case for ==?

14:23 amalloy: __name__: it's faster for numbers, i expect

14:24 &(time (dotimes [_ 1e6] (let [[x y] (repeatedly rand)] (== x y))))

14:24 sexpbot: ⟹ "Elapsed time: 1401.258589 msecs" nil

14:25 amalloy: &(time (dotimes [_ 1e6] (let [[x y] (repeatedly rand)] (= x y))))

14:25 sexpbot: ⟹ "Elapsed time: 1763.939619 msecs" nil

14:25 __name__: Thank you amalloy.

14:25 nickik: If i can do this in java Runtime.totalMemory() i should be able to do (Runtime/totalMemory) in clojure right?

14:26 or do i have to import runtime from somewhere

14:26 amalloy: nickik: that's hoping that totalMemory is a field

14:27 (. Runtime (totalMemory)) is the way to be explicit about it being a no-arg method, i think

14:27 nickik: amalloy, its a static method with no arguments

14:27 ,(. Runtime (totalMemory))

14:27 clojurebot: java.lang.IllegalArgumentException: No matching method: totalMemory

14:27 tsdh: Hi

14:28 __name__: &(. Runtime totalMemory)

14:28 sexpbot: java.lang.NoSuchFieldException: totalMemory

14:28 tsdh: Is there something like `doto' which returns the last expression's result?

14:28 __name__: &(Runtime/totalMemory)

14:28 sexpbot: java.lang.NoSuchFieldException: totalMemory

14:28 amalloy: tsdh: are you looking for ->?

14:28 nickik: &(Runtime.)

14:28 sexpbot: java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Runtime

14:28 TimMc: You can't instantiate Runtime.

14:28 You have to get the current one.

14:28 __name__: Ah.

14:29 &(.. Runtime getRuntime totalMemory)

14:29 sexpbot: ⟹ 17592320

14:29 nickik: sure you can, http://stackoverflow.com/questions/1885487/how-do-i-find-out-javas-heap-size-on-my-computer

14:29 __name__: Thanks MC Tim.

14:29 nickik: ah

14:29 amalloy: (.totalMemory (. Runtime getRuntime))

14:29 TimMc: Like I said, you can't instantiate it.

14:30 tsdh: amalloy: Oh, thanks. :-)

14:30 amalloy: nickik: have you actually *tried* that guy's suggestion in java? totalMemory is not a static

14:30 so there's no reason his code should work

14:31 the guy with fewer upvotes is more right

14:31 nickik: TimMc, right (not= instantiate get_back_an_object) mixed that up

14:32 amalloy, both work

14:32 amalloy: blurg, really? well they shouldn't :P

14:32 tsdh: amalloy: Ah, -> is not what I want. I don't want to chain the result through a pile of functions, but I want (doto java-obj (.foo) (.bar) (.baz)) and have the result of (.baz java-obj) returned.

14:33 amalloy: (-> java-obj (doto (.foo) (.bar)) (.baz))

14:33 tsdh: amalloy: Oh, indeed. That's pretty cool. :-)

14:33 amalloy: doto and -> are powerful magic

14:35 tsdh: Yes, but it still returns java-obj. :-(

14:36 Argh, sorry, paretheses match error when reading your example.

14:37 amalloy: indeed

14:38 &(-> 1 (doto println) inc)

14:38 sexpbot: java.lang.IllegalArgumentException: Bad binding form, expected vector

14:38 amalloy: dang it

14:38 ,(-> 1 (doto println) inc)

14:38 clojurebot: 1

14:38 2

14:38 amalloy: Raynes: please fix my clojail bug, it's making you look bad

14:39 tsdh: Wow, now I can write java code in clojure in half of the lines I wousd need in "native" java.

14:41 amalloy: tsdh: code that automates writing code will speed things up a lot

14:41 (if it really takes you half as many lines there's a lot of room for improvement)

14:42 for example check out the other way you can combine -> and doto: (doto obj (-> .getSummaryList (.addSummary s)))

14:43 tsdh: amalloy: What's that s?

14:43 amalloy: some local variable

14:43 i'm just demonstrating that you can modify nested mutable objects as well

14:44 tsdh: I see, although in that example the doto is not really needed, right?

14:44 amalloy: tsdh: well, it makes you return obj instead of the result of .addSummary

14:44 tsdh: (-> obj (.getSummaryList (.addSummary s))) is equivalent

14:45 Oh, right.

14:45 amalloy: but yes, it's more interesting if you have other fields to set

14:45 * tsdh loves it.

14:45 amalloy: (doto obj (.setSize 10) (.setName "ffgdga") (-> .getFriends (.add steve)))

14:46 tsdh: Nice

14:53 I've heared there was some special syntax for defmultis that dispatch on the type of the first parameter: (fn [c & _] (class c))

14:53 amalloy: tsdh: not exactly. there are protocols, which are similar to multimethods but (among other things) dispatch on class of first param

14:56 tsdh: Ok, then I'll stick to the simple anonymous dispatch functions until I find some time to read about protocols.

14:59 amalloy: you can just write (defn class-dispatch [c & _] (class c)) and make your multis dispatch on class-dispatch. no need to keep writing the same function

14:59 tsdh: Right.

15:00 When recuring in a defmethod, will that recur to that exact defmethod or to defmethods with different dispatch value, too?

15:01 amalloy: tsdh: even wrap it up in a macro: (defmacro ez-multi [name] `(defmulti ~name ~'(fn [c & _] (class c))))

15:01 it will have to go to the same method. recur is just goto; it can't leap over function boundaries

15:04 tsdh: Hm, ok. The usecase is that I want to unpack into native clojure sequences from a Java union type. There I have basic classes, for which I only need to call (.toObject), and collections, where I iterate the contents and call the (unpack) on the elements.

15:04 So this is a kind of mutual recursion.

15:04 amalloy: trampoline?

15:04 clojurebot: trampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10

15:04 amalloy: ~o/

15:04 clojurebot: \o ... High five!

15:05 tsdh: Found it in the docs.

15:06 So I simply say (def unpack (trampoline unpack-internal)), where unpack-internal is the multimethod?

15:07 rata_: hi

15:08 amalloy: i'm not sure trampoline will do you any good if you need to iterate over contents. you really need a whole stack

15:08 just (defmethod unpack j.u.Collection [c] (map unpack c))

15:09 tsdh: Oh, right, that is much better.

15:11 rata_: does anybody know how can I make the get-activities fn faster? it takes ~70% of the time of my program https://gist.github.com/871248

15:15 amalloy: rata_: you could avoid some overhead by writing (into {} (for ...)) instead of (let [v (for...)] (zipmap ... v))

15:17 i think it comes out to something like (into {} (for [{:keys [lhs rate] :as a}] [(inner for) a]))

15:23 edw: js

15:23 rata_: oh thanks amalloy, it's even cleaner code now... I'll test how it performs as soon as I finish another fn I'm writing in the same file

15:23 edw: D'oh. Sorry.

15:25 tsdh: amalloy: Wow, I'm done for simple values, collections and now for maps: (apply hash-map (mapcat (fn [e] [(jvalue-unpack (.getKey e)) (jvalue-unpack (.getValue e))]) (.entrySet jv)))

15:26 amalloy: tsdh: (into {} (map (fn [e] [(...) (...)]) jv))

15:27 avoiding the messy apply hash-map

15:29 tsdh: Yes, that's even better.

15:29 amalloy: into {} is a fabulous idiom once you use it often enough to remember it

15:30 tsdh: Oh, I have several intos in my code, not with empty literals, but anyway.

15:30 pyr: amalloy: especially when working with java libs

15:31 amalloy: love it

15:31 amalloy: see, intos with *non* empty literals is something that i always forget to think of :)

15:33 tsdh: Wow, just verified that my multimethod works for JValueMaps from Object to JValueMaps to JValueTuples. And that in 23 lines of clear, self-explaining, functional code.

15:34 amalloy: of course!

15:35 Raynes: Heh, sounds like you're translating Real World Haskell to Clojure or something.

15:35 amalloy: that's just how clojure rolls

15:35 rata_: what's an empty literal?

15:35 * tsdh thinks he wasted huge parts of his life with programming java...

15:35 amalloy: rata_: he means {} and [] and such

15:35 literal empty collections

15:35 tsdh: Yep

15:36 rata_: oh ok

15:37 yes, I always forget to use into with non-empty collections... yesterday I found myself changing a (into {} (cons [:foo :bar] ....) to (into {:foo :bar} ...)

15:40 raek: I would like to take this opportunity to advocate using 'for': (into {} (map (fn [e] [(...) (...)]) es)) --> (into {} (for [e es] [(...) (...)]))

15:41 Raynes: This has been a public service announcement brought to you by Svenson Enterprises.

15:41 rata_: hahahaha... I also find for better here

15:41 it's cleaner

15:42 tsdh: raek: Oh, that's even nicer. Can anyone come up with a one-char-er? ;-)

15:42 choffstein: Is there a function similar to ruby's 'zip'? Basically, if I called [1,2,3].zip([4,5,6]) in Ruby, I would get [[1, 4], [2, 5], [3, 6]]. Zip in clojure seems to be for trees.

15:42 amalloy: map

15:43 &(map vector [1 2 3] [4 5 6])

15:43 sexpbot: ⟹ ([1 4] [2 5] [3 6])

15:43 choffstein: Perfect. Thanks!

15:46 amalloy: clojure's map is more general, allowing it to take the place of several usually-disparate functions

15:47 angerman: Is someone willing to help me with optimizing a package for clojars? It is currently build using this Makefile: https://github.com/angerman/planarity/blob/master/mkjr/Makefile

15:47 But it creates a rather huge pacakge, containing all native libraries for win32/win64/osx/linux32/linux64

15:55 amalloy: sritchie: ping

16:00 sritchie: never mind. i was trying to duplicate nmarz's cascalog demo and hadn't realized i should be in the cascalog.playground namespace

16:01 tomoj: seems funny how rarely the right namespaces are revelead in the docs

16:02 er, how often they aren't, maybe

16:13 choffstein: is there a way to perform a map in clojure and pass in a variable as if it were a reduce? so basically I want to carry an accumulator through, but retain a list of the accumulators along the way

16:13 amalloy: &(doc reductions)

16:13 sexpbot: ⟹ "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

16:13 amalloy: see also iterate

16:14 choffstein: amalloy, you're like my personal clojure API :D

16:18 Raynes: choffstein: I taught him everything he knows.

16:19 amalloy: this explains why i'm so good at claiming credit for stuff i didn't do

16:22 tomoj: bravo

16:25 chouser: What kind of methods is this?? "tried to access method com.mongodb.CommandResult.()V"

16:25 s/methods/method/

16:25 .()V ?

16:25 amalloy: no args, returns void

16:25 maybe?

16:26 chouser: no name?

16:26 no name, no args, returns void?

16:27 * chouser is suspicious

16:27 amalloy: i'd guess inner local, but then it should have a different classname

16:27 raek: as a descriptor (from the class file spec), "()V" does indeed mean no args, returns void

16:28 looks like the method name is missing between the class name and the type descriptor, or something

16:34 bhenry: any clojure developers currently residing in maine?

16:35 choffstein: is there any way to globally alias a keyword to a macro? For example, can I map 'try' to a special macro?

16:35 amalloy: no

16:35 choffstein: Figured.

16:36 amalloy: you can't even do it locally without wrapping the whole thing in a macro. special forms can't be redefed

16:36 and try is a special form

16:36 choffstein: So I wrote a macro that basically injects code into a try block, called 'my-try'. This works great for all my code, but if I import a library, they all use 'try'. Is there a way to hook into their code?

16:36 amalloy: (or maybe try* is)

16:38 raek: no. try is a (real) special form and is hard-coded into the clojure compiler

16:40 choffstein: herm. bummer.

16:40 so if I wanted to execute an action anytime an exception was caught, anywhere, be it in my library or someone elses library ... I probably couldn't do that without hacking the clojure code itself, huh?

16:41 mattmitchell: i am trying to mock a function in another namespace using clojure.contrib.mock

16:41 amalloy: yuck. if you want to do that you're probably wrong. a lot of exceptions get thrown and caught that you just don't care about

16:42 mattmitchell: using "expect", shouldn't this be as simple as (expect [blah/fun (times once)]) ?

16:42 raek: sounds like this is something that would be part of a debugger rather than a library...

16:44 choffstein: so, what is your use-case for this anyway? :)

16:44 angerman: http://dl.dropbox.com/u/281539/temp.pdf

16:44 choffstein: raek: I am just playing around, learning clojure.

16:44 angerman: Hmm I guess that has some "artistic" value

16:44 but that's not really what I intended...

16:45 raek: choffstein: well, you're deep into JVM/Java-land when you want to override behaviour of the exception mechanism... :)

16:45 choffstein: raek: I was playing around with the exceptional library (getexceptional.com) for rails. I am thinking about tearing down my rails web-apps and replacing them with clojure ones, so I was seeing how easy it was to replicate the getexceptional functionality. I realized I could write a macro to wrap around try for my own code

16:46 raek: choffstein: have you tried the good ol' top-level catch block approach?

16:47 choffstein: raek: haha, yeah, I have. That works, of course. I just also wanted to catch all exceptions, whether caught or bubbled to the top.

16:47 raek: choffstein: also, note that java code some times use exceptions for control flow

16:47 choffstein: raek: yeah, I think I might get in trouble there.

16:47 raek: so caught exceptions might not be errors...

16:48 (for instance, Integer/parseInt is often used when you want to try to interpret something as a number, but fall back to sometihng else)

16:48 choffstein: Yeah. Whatever. Good learning experience at the end of the day I suppose.

16:48 amalloy: choffstein: like i said, a lot of exceptions get thrown and then caught. i really doubt you want to see them

16:48 choffstein: Maybe it is good that it is just for my own code and anything that bubbles to the top level

16:48 raek: choffstein: sounds like the ideas of getexceptional.com could be turned into a great ring middleware

16:49 mfex: hi all, in emacs how do i "paste" an s-expr to the repl? Instead of running C-x e to eval, just paste to repl?

16:49 raek: the wrap-stacktrace does the job, but does not exactly have a lot of features

16:51 choffstein: raek: It would be nice if wrap-stacktrace allowed you to pass your own dispatch functions

16:53 raek: mfex: C-c C-p does something similar. (I have looked for the feature you described myself)

16:53 tsdh: How do I refer to the class java.util.Map.Entry for the usage as a type hint?

16:54 amalloy: mfex: you can C-M-<SPC> to mark a whole sexp, copy it, and paste manually :P

16:54 raek: (also, I like to use C-M-x for eval)

16:54 choffstein: If a library uses a defed *variable* for configuration, say a delimiter, how do I change that variable if I have the library as a jar?

16:54 amalloy: tsdh: Map$Entry

16:54 tsdh: amalloy: Thanks.

16:54 amalloy: which is the way to import it too

16:55 mfex: thanks all

16:58 raek: mfex: just found this: http://bc.tech.coop/blog/070424.html

16:58 technomancy: choffstein: vars like that are meant to be changed using binding.

16:58 choffstein: technomancy: I'm a moron -- can you explain that?

16:59 chouser: aw, shoot. I think it might be a bug in proxy.

16:59 mfex: raek: thanks, will have to dig through that, but looks to contain what I'm looking for

16:59 technomancy: choffstein: something like this: (binding [*warn-on-reflection* true] (my-code-goes-here))

17:00 choffstein: gotcha. awesome. thank you.

17:00 technomancy: you don't actually change anything other than inside the context of binding

17:02 raek: mfex: just tried it myself. works great! (though, I had to change copy-region-as-kill-nomark into copy-region-as-kill-nomark as the note at the bottom of the page said)

17:10 patrkris: is there an easy way to get a seq of pairs from a seq of an even number? i.e. ["a" 1 "b" 2 "c" 3] => [["a" 1] ["b" 2] ["c" 3]]

17:10 *seq of an even number of elements

17:10 opqdonut: ,(partition 2 ["a" 1 2 "b" :hello #{}])

17:10 clojurebot: (("a" 1) (2 "b") (:hello #{}))

17:11 patrkris: oh yeah! thanks!

17:11 raek: also, note ##(partition 2 [1 2 3])

17:11 sexpbot: ⟹ ((1 2))

17:12 raek: and compare with ##(partition-all 2 [1 2 3])

17:12 sexpbot: ⟹ ((1 2) (3))

17:12 patrkris: yes - i guess it's fine since the number of elements is guaranteed to be even

17:12 chouser: oh, not really a bug. Just can't use proxy to create an instance of a class whose only ctor is non-public. Ugh.

17:13 raek: hrm. can you even do that in Java?

17:16 rata_: amalloy: it didn't help, get-activities still takes upto 80% of the time https://gist.github.com/871248

17:17 can typehinting help there?

17:18 chouser: raek: not from outside, I imagine. It's the JVM that's complaining

17:36 Bennyl: Is there a way to define an un parses string? Like @"/w" = "//w"

17:38 amalloy: Bennyl: ##(java.util.regex.Pattern/quote "\\w") maybe?

17:38 sexpbot: ⟹ "\\Q\\w\\E"

17:38 amalloy: not really sure what your actual goal is so it's hard to answer :P

17:38 raek: you certainly can do that in java

17:39 brehaut: Bennyl: are you meaning like dotnet's verbatim strings?

17:39 amalloy: public class Singleton {private Singleton() {} public static Singleton get(){return inst;}} // needs some code for actually creating the instance

17:40 chouser: right, but you have to be within scope

17:40 raek: I assumed you had to call a constructor of the superclass in any constructor, which might not be the case

17:41 chouser: com.mongodb.CommandResult is a concrete class with only a private ctor

17:41 raek: a/any/every/

17:41 amalloy: raek: you do have to. i think my definition makes Singleton de facto final

17:41 chouser: not private, sorry -- non-public, so I think the caller has to be in the package

17:41 amalloy: ew

17:42 default/package visibility is so gross

17:42 it is hard to imagine any good reasons for it

17:42 but who am i to judge

17:42 chouser: and there are places that cast things to CommandResult

17:43 I have a reify instance that is ending up in some of those places

17:43 So -- I'm stuck. I can't create a CommandResult or derive from it, but I must provide one.

17:43 amalloy: I'm willing to judge. :-)

17:43 Time to go home.

17:44 Bennyl: brehaut: yes exactly like verbatim string

17:44 clojurebot: Cool story bro.

17:44 brehaut: Bennyl: then no, you cant

17:45 Bennyl: brehaut: well worth the try :)

17:46 amalloy: chouser: (in-ns 'com.mongodb.blah) (proxy ...)?

17:47 the fact that this is a viable solution is one of the reasons package is so dumb

17:47 tomoj: viable?

17:47 brehaut: Bennyl: however (str #"\w")

17:47 amalloy: i guess it couldn't work if you proxied it

17:47 brehaut: bah ##(str #"\w")

17:47 sexpbot: ⟹ "\\w"

17:47 tomoj: is it even a solution?

17:48 amalloy: you'd have to gen-class

17:48 tomoj: oh, to sneak it into the package?

17:48 brehaut: Bennyl: but thats horrible because its tunneling your string through the regexp implementation

17:48 amalloy: tomoj: right

17:49 sattvik: chouser: It seems like there are two options: 1. Try a variation of amalloy's suggestion, or 2. use reflection to suppress access checks

17:50 tomoj: sucks there are so many weirdnesses in java libraries that make trouble for clojure interop

17:50 amalloy: tomoj: that's a weirdness that makes trouble for anyone

17:50 sattvik: The second works so long as there is no security manager that disallows that from happening, which isn't true in all deployments.

17:52 dnolen: brehaut: I tried out the monkey banana in miniKanren last night, pretty short, https://github.com/swannodette/bratko-logos/blob/master/src/bratko_logos/monkey_banana.clj

17:53 brehaut: dnolen: cool :) i'll go have a read

17:53 dnolen: brehaut: it'll be about as terse as Prolog when I wrap up the pattern matcher.

17:54 brehaut: dnolen: i'll be interested to see the changes

17:54 dnolen: its still pretty clear nonetheless

17:54 dnolen: brehaut: there's a preview at the bottom.

17:54 brehaut: ah so there is

17:57 dnolen: thats cool :)

18:00 dnolen: brehaut: curious how quickly does your implementation solve the problem?

18:04 brehaut: dnolen: 10000 runs takes 15000 msec (clj 1.2)

18:04 dnolen: logos should be much faster right?

18:05 fliebel: brehaut: You have an miniKanren implementation?

18:05 brehaut: fliebel: nope, monads

18:07 fliebel: Uh, oh. So what is this about? I'm late to the party :( I see monkeys and logos, so it got to be great :)

18:07 dnolen: brehaut: miniKanren version takes ~7s for 10k runs. clj 1.3, 2.66 i7 MBP

18:07 brehaut: fliebel: https://github.com/brehaut/monkey-and-banana/tree/master/src/monkey_and_banana

18:08 2.53 i5 MBP here

18:08 fliebel: im trying to learn more about logical programming but working towards it from a naive functional perspective

18:08 fliebel: ah so you;re comparing monads to logos for a monkey problem? Lets see if wikipedia has a page that explains the problem...

18:09 yup: http://en.wikipedia.org/wiki/Monkey_and_banana_problem

18:09 dnolen: fliebel: gotta run, but I'm porting bits of Bratko's Prolog Programming for AI to miniKanren, https://github.com/swannodette/bratko-logos

18:10 fliebel: sounds cool :)

18:11 brehaut: fliebel: monkey and banana is a pretty simple problem so it's not resulted in a huge naive clojure solution which has helped me a lot :)

18:13 fliebel: brehaut: Cool. I'm working on a regular and logos version of sudoku at the moment.

18:13 brehaut: fliebel: cool :) have you read Bird's Functional Pearl on solving it via proof in haskell?

18:16 fliebel: http://www.cs.tufts.edu/~nr/comp150fp/archive/richard-bird/sudoku.pdf

18:17 fliebel: brehaut: no, I do not read programming books much. I read TRS recently, now I have 5 other books, but the book before that was a Java book, that is before I did PHP, and that is before I did Python and that is before I did Clojure. ;)

18:18 brehaut: fliebel: i dont get to read as many as i would like. that paper lost me once it got real clever, but its pretty amazing

18:19 fliebel: brehaut: I did try to read a few prolog solutions, but they all use all_different, which uses negation, both are not yet present in logos.

18:20 brehaut: fliebel: interesting. my prolog-fu is very weak; ive forgotten almost all i learnt at uni

18:30 amalloy: sritchie: you might be interested in https://github.com/nathanmarz/cascading-thrift

18:31 which it looks like nmarz open-sourced just after i asked him if there was a thrift tap for cascalog

19:18 Frsss: say, what's the word on CLR clojure?

19:25 fliebel: Frsss: The word?

19:25 Frsss: is it being actively developed?

19:25 does it use CLR specific advantages

19:25 fliebel: I believe so, it has 1.3 stuff at least.

19:25 Frsss: or is just just bare bones port

19:26 fliebel: dunno, I only know it does not run Mono :(

19:26 Frsss: I would imagine yield keyword being useful in language that has lazyness

19:27 it also has "var" variable type

19:27 something java doesn't

19:27 fliebel: Frsss: Have a look at the github page, it will tell you the latest commit, and chances are the author is in here.

19:29 Frsss: I really wanna test the performace of Clojure vs Clojure CLR

19:30 largest sticking point of clojure right now tbh

19:30 technomancy: is var like invokedynamic or more of a compile-time type inference?

19:30 brehaut: Frsss: yield is implemented as a compiler transformation; its not a runtime feature

19:31 technomancy: compiletime inference

19:31 technomancy: dymanic is the invokedynamic equiv

19:32 fliebel: weee, my iterative sudoku solver is done: https://gist.github.com/871708 Now the logos version...

19:32 technomancy: so that wouldn't really affect Clojure then

19:32 Frsss: I hope for clojure to be one day performing at least half as fast as java

19:32 Raynes: Clojure is insanely fast compared to how slow it could be.

19:33 technomancy: languages aren't fast or slow; programs are.

19:33 Frsss: I didn't really use java until it got it's performance to factor 2 compared to C

19:33 Raynes: You can do some performance optimizations and get near-Java performance.

19:33 fliebel: Raynes: Define 'could'. Is inserting Thread.sleep every other line 'could'?

19:34 Frsss: optimize all you want, you aren;t getting near 2:1 with java

19:34 Raynes: fliebel: My point is that Rich Hickey and friends think performance is important. It's a goal.

19:35 fliebel: Raynes: I figured that, with all these nth/get performance guarantees.

19:35 technomancy: Frsss: sounds like you may have some catching up to do: http://meshy.org/2009/12/13/widefinder-2-with-clojure.html

19:35 brehaut: Frsss: CLR Clojure has a greater impedance mismatch with the host platform (remedied somewhat by dynamic types in 4) than JVM clojure

19:35 Raynes: Frsss: No, seriously, people do it. Easily.

19:35 Frsss: brehaut Interesting

19:35 I would assume CLR was more suited

19:35 because it has several features stolen from LISP :P

19:36 brehaut: Frsss: nope; type errasure in JVM means that its a more friendly host for dynamic languages

19:36 Frsss: ah k

19:36 brehaut: CLR 4 still has relatively small deployment

19:36 Frsss: funny.... I hate generics in java

19:36 C# ones are better

19:37 brehaut: Frsss: additionally the CLR VM and JIT is tuned quite differently to the JVM - out of the box CLR feels nicer for desktop applications: it starts relatively hot. JVM starts slow but as it heats up it becomes super fast, which suits long running services better

19:37 Frsss: it is very hard to make claims about the relative performance of each platform as a result

19:39 Frsss: and dont confuse features of C# with the CLR and Java with the JVM

19:40 Frsss: technomancy: isn't that benchmark IO bound?

19:40 brehaut: fliebel: that looks quite reasonable

19:40 fliebel: brehaut: The sudoku? okay, good to hear.

19:40 technomancy: Frsss: depends on your implementation, disk speed, encoding, and many other factors.

19:40 brehaut: fliebel: yeah, although im no guru!

19:41 technomancy: once again: programs are fast or slow, not problems, languages, or VMs.

19:42 Frsss: still I think that you wont get much difference from CPU usage when benchmark is IO bound. Clojure's problems are mainly with CPU and memory

19:42 technomancy if that were true, people would be making computer games in clojure instead of C++

19:43 or any other expressive language

19:43 brehaut: Frsss like GOAL ?

19:44 Frsss: GOAL?

19:44 technomancy: yeah, let's take a deep dive into the turing tarpit here...

19:44 what could go wrong?

19:44 brehaut: (inc technomancy)

19:44 sexpbot: ⟹ 8

19:44 brehaut: Frsss: http://en.wikipedia.org/wiki/Game_Oriented_Assembly_Lisp

19:45 Frsss: just saying... C/C++ are used in giant majority of cases for games. having 30 FPS instead of 15 FPS with java implementation is a deal breaker.... that being said it doesn't matter for most apps, but to say that languages don't matter is silly

19:46 brehaut: Frsss: go read about why sony stopped using GOAL, it wasnt performance; the crash team were producing some of the best performing games on the PS1.

19:47 Frsss: non-technical reasons dominate almost all technology choices

19:47 rlb: (and naughty dog used scheme, etc. -- though for the planner, not the renderer afaik)

19:55 Frsss: this is weird: "Early on, when I was fighting a memory leak, Rich Hickey suggested using a smaller heap size. I did that, and was astounded."

19:56 "But as I watched the program run, I could see that as the program built up its heap to the ceiling (set via java’s -Xmx argument), it was running much slower, as slow as a tenth of that speed."

19:56 why would having bigger heap make program run slower lol

19:58 brehaut: guessing: more garbage to deal with when it hits the ceiling?

19:59 Frsss: that;'s it...he says it gets faster when it hits ceiling

19:59 that's the counterintuitive part

19:59 brehaut: welcome to the science of garbage collection

20:12 zoldar: is there a more succinct way to write something like this: http://paste.lisp.org/display/120548 ?

20:13 brehaut: zoldar: quick english summary?

20:14 zoldar: also does that ever return? (not v) is always false for any vector (empty or otherwse)

20:14 zoldar: substitute subsequent occurences of given value in one sequence with values from the other one

20:16 brehaut: sorry im still now follow. examples of input and output?

20:16 amalloy: brehaut: that should terminate eventually

20:16 v won't really be a vector, i think

20:16 zoldar: [1 3] , [nil 2 nil] -> [1 2 3]

20:17 it works, rest from empty vector gives nil

20:17 brehaut: amalloy: oh right. huh

20:17 amalloy: brehaut: ##(let [[x :as all] nil] [x all])

20:17 sexpbot: ⟹ [nil nil]

20:17 amalloy: it essentially binds all to the actual value, then binds subelements to (vec value)

20:19 i wonder if macroexpand shows that... ##(macroexpand '(let [[x :as all] nil] [x all]))

20:19 sexpbot: ⟹ (let* [vec__10212 nil x (clojure.core/nth vec__10212 0 nil) all vec__10212] [x all])

20:20 amalloy: sweet

20:26 zoldar: i'd write it more as something like a lazy-seq of two seqs. (fn nil-fix [[a & morea :as as] [b & moreb :as bs]] (lazy-seq (if a (cons a (nil-fix morea bs)) (cons b (nil-fix as moreb)))))

20:27 note untested, probably broken, but a rough draft

20:31 zoldar: thanks, this would be probably more elegant...

20:32 waxrose: Which build tool do you all use, or is suggested? Leiningen? Cake? ..?

20:33 brehaut: waxrose: i use lein

20:33 waxrose: brehaut, Any particular reason instead of the others?

20:33 brehaut: waxrose: i started using it before cake existed and i haven't needed anything else. also technomancy supports it ridiculously well

20:34 waxrose: Okay great, thanks.

20:36 ieure: I also use leiningen, because it is great.

20:36 waxrose: It seems to be the most supported, I guess I'll stick to it. :P

20:40 brehaut: $findfn [1 2 1] [:a :b :c :d] ((:a) (:b :c) (:d))

20:40 sexpbot: java.security.PrivilegedActionException: java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :a (NO_SOURCE_FILE:0)

20:40 brehaut: $findfn [1 2 1] [:a :b :c :d] '((:a) (:b :c) (:d))

20:40 sexpbot: []

20:42 zoldar: $findfn [1 2] 3 [1 2 3]

20:42 sexpbot: [clojure.core/conj clojure.core/merge]

20:42 zoldar: wow, nice feature

20:43 sproust: Is slime-interrupt supposed to work with a Clojure VM? It doesn't seem to have any effect in my setup.

20:43 technomancy: sproust: not all operations can be interrupted

20:43 sproust: Which ones can, and which ones cannot?

20:46 technomancy: sproust: I/O is the main one I think: http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

20:46 (slime-interrupt is built on Thread.stop)

20:46 brehaut: $findfn 1 [:a :b :c] '((:a) (:b :c))

20:46 sexpbot: [clojure.core/split-at]

20:47 sproust: technomancy: Thx.

20:48 technomancy: sure

20:58 sproust: technomancy: Why not just substitute it with (.interrupt thread)?

21:01 Ahhh I think the same problem would occur.

21:01 Never mind.

21:02 technomancy: first rule of swank-clojure: don't assume anything is the way it is for a good reason =)

21:02 mec: Is set O(n)?

21:02 technomancy: there are places in the codebase that use refs where you think to yourself "that should be an atom!"

21:02 then you look at the git log and realize "oh wait, atoms hadn't been implemented when this was written."

21:02 true story.

21:03 sproust: Haha, great... No I think in this case this is a problem without a solution. You can't forcibly kill a thread in a VM, because of the resources it holds. Sure Thread.stop() is deprecated, but Thread.interrupt() probably does similarly (InterruptedException instead of ThreadDeath).

21:03 brehaut: mec: a datastructure generally doesnt have a big O for the whole thing; each operation will have its own. eg adding to the end is different adding random access or whatever

21:04 mec: I meant the function set, specifically applied to a sequence

21:04 brehaut: oh right. at best its O(n), but i think it may be O(n log n)

21:05 as adding to a set is O(log n)

21:05 and it has to do that n times

21:05 tomoj: that's log32, though, right?

21:05 brehaut: tomoj: oh good point

21:05 so O(n) then

21:06 tomoj: eh..

21:06 seems like cheating even though it's practically true

21:06 how big does the set have to get before it matters, I wonder?

21:07 brehaut: thats an interesting question

21:07 mec: Well i've got the infinite primes sequence and im trying to turn it into a prime? predicate, but I'm not sure how to make sure it contains enough primes for the tested number without making a new set each time

21:08 brehaut: mec: memoize or similar

21:08 TimMc: Infinite sets... has anybody made those in Clojure?

21:08 tomoj: (complement #{}) ?

21:08 brehaut: mec, run (source memoize) in your repl and crib ;)

21:09 tomoj: haha

21:09 tomoj: doesn't behave like a set, though..

21:09 TimMc: tomoj: :-P

21:11 OK, trying to write a parser for assembly files written in a subset of MIPS -- best approach? It's a regular language.

21:11 I'm comfortable with regexes, but I'm wondering if there's a better tokenizer or something.

21:13 brehaut: TimMc: personally i'd lean toward fnparse with a simple tokenizer even if it is regular; it makes it very easy to build the AST on the fly

21:14 actually i probably wouldnt even use a regexp tokenizer

21:14 TimMc: Ah, I've never looked into fnparse. I'll read your blog entry.

21:15 brehaut: cool :)

21:15 its pretty simple

21:15 im just a bit verbose

21:16 TimMc: That's good, I tend to skim. >_<

21:16 brehaut: heh

21:16 the headings and code snippets should be all you really need

21:20 sproust: Does slime's compile support have any meaning for Clojure?

21:21 ieure: sproust, Sure, it’ll tell you if you have syntax errors.

21:21 I also use it to hack on code in the slime REPL.

21:22 C-c C-k will compile it and load it up into the repl, so you can (ns 'blah) and dick around with whatever code you’re editing.

21:23 sproust: Thx! I guess the meaning is reduced to "load file."

21:44 technomancy: sproust: there's no interpreter in Clojure, so C-c C-l is overloaded to mean "load this file, but force a reload of all its dependencies"

21:44 (this is very new; a few days old maybe)

21:58 TimMc: brehaut: This is pretty nice, but I'll still need a lexer.

21:58 brehaut: TimMc: not really

21:58 TimMc: Do it as a char seq?

21:58 brehaut: yeah

21:58 its only a problem if you are processing stupidly massive text

21:59 TimMc: Nah, not for this.

21:59 I'll give that a try in the morning. Thanks for the pointer!

21:59 brehaut: no worries

22:08 benglert: hey everyone, recently i have started packaging up a clojure program as a JAR using "cake uberjar". only problem is, it depends on an external data file which it reads in and parses from the filesystem using slurp

22:08 i was wondering if there's anything i can put into project.clj to have it put the data file into the jar, and also what i can use to read the data file from within the JAR - i assume it's some kind of InputStream so slurp won't work

22:10 mec: I swear emacs never makes a backup of a buffer when it crashes, but leaves backups at all other times

22:17 waxrose: mec, Works for me.

22:17 brehaut: benglert: in lein you can put files into a Resources directory in your project

22:18 waxrose: brehaut, Do you build Clojure from Github or do you install from your distro's package manager?

22:19 brehaut: waxrose: i install it via my projects project manager; ie as a lein dependancy

22:19 waxrose: hmm

22:19 brehaut: id only build from source if i was working on clojure itself

22:21 tomoj: benglert: one helper is clojure.java.io/resource

22:21 benglert: brehaut: okay. is there any nice clojure shorthand for reading data out of the jar file or is it going to be the usual java mess with inputstreams

22:21 tomoj: the return value of which is slurpable

22:21 benglert: tomoj: i'll take a look, thanks

22:21 brehaut: benglert: some of that mess is cleaned up for you in the clojure.java namespace

22:22 benglert: http://clojure.github.com/clojure/clojure.java.io-api.html

22:22 benglert: or what tomoj said

22:25 technomancy: brehaut: just be sure not to capitalize Resources, or it will only work on case-insensitive FSes

22:25 case-insensitivity bugs are the worst =\

22:26 brehaut: oh man :S

22:26 thats horrible

22:26 tomoj: do macs also come with case-insensitive tab-completion? I can't remember

22:26 technomancy: yeah, next time you format your OS X machine be sure to pick a sane filesystem

22:27 brehaut: tomoj: not out of the box, despite being case insensitive

22:27 technomancy: unless you use Adobe products, which require the annoying FS

22:27 brehaut: technomancy: we have a choice?

22:27 benglert: technomancy: you're joking, right? adobe CS won't install on a case sensitive FS?

22:27 technomancy: brehaut: yeah, as long as you choose it before you format

22:27 benglert: as of a couple years ago, yeah

22:27 brehaut: they don't make it obvious though

22:28 brehaut: technomancy: yeah apparently so. what are the other choices?

22:29 zfs had been the only other FS i had heard about on modern OS X and thats in the can now i think?

22:34 mec: https://gist.github.com/871908 my implementation for prime? is there any way to improve this, there are a couple spots that seem iffy

22:35 I'd prefer to use take-while and drop-while but then im doing the same thing twice

22:36 Would it be better to duplicate that effort and conj an atom with a bunch of values at once, or the values individually

22:38 benglert: brehaut: tomoj: clojure.java.io/resource works great. thanks much for your help

22:38 brehaut: benglert: did you catch technomancy's comment about case?

22:38 benglert: brehaut: indeed, thanks

22:39 brehaut: mec if you are using take-while and drop-while you could consider split-with

22:39 mec: oo thank you

22:39 oh that does both anyway, is that not inefficient?

22:40 brehaut: mec no its real easy

22:40 actually my bad it does just do both :P

22:41 but it could be written more efficiently

22:41 i'd still use it if it was clearer

22:42 mec: good idea, if it's too slow ill rewrite, but that should make the code a lot clearer

22:42 brehaut: yeah

22:44 huh. im not actually sure how you would write it to be both lazy and only process it once

22:45 mec: good point

22:52 It seems redundant to have to do (apply swap! atom conj seq)

22:54 which also doesnt work

22:55 brehaut: &(set [1 2 3])

22:55 sexpbot: ⟹ #{1 2 3}

22:55 brehaut: &(use 'clojure.set)

22:55 sexpbot: ⟹ nil

22:55 brehaut: &(union #{1 2 3} (set [2 4 6]))

22:55 sexpbot: ⟹ #{1 2 3 4 6}

22:56 brehaut: if you want to pour seqs into sets

22:56 conj if you just want to add one item

22:56 mec: ok, but how come this is saying wrong number of args to conj?

23:01 brehaut: hmm

23:01 good question

23:02 what is atom bound to?

23:02 mec: #{}

23:03 brehaut: ah worked it out; your seq is becoming empty at some point

23:03 &(apply swap! (atom #{}) conj [])

23:03 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$conj

23:03 brehaut: &(apply swap! (atom #{}) conj [1])

23:03 sexpbot: ⟹ #{1}

23:03 mec: that was an off by 1 error i just fixed

23:04 https://gist.github.com/871908 how does that one look

23:04 brehaut: better :)

23:04 why do you have two atoms?

23:05 mec: so i dont have to start over with the primes sequence?

23:05 brehaut: if you capture the head then you wont need too

23:06 im not sure i understand what you are doing with it

23:06 oh are you walking along primes?

23:06 mec: ya

23:06 brehaut: ok fair enough

23:07 mec: if I didnt hold onto it i would have to walk the whole thing each time, and this way i can see if N is possibly in the set before checking

23:07 I still hope theres a better way, this still feels clunky

23:07 brehaut: mems (set mems)

23:08 id drop that from thelet and inline the expression into swap!

23:08 mec: How do you think the performance would be using (@mem n) vs (mems n) ?

23:09 brehaut: i wouldnt think it would matter

23:09 mec: fair enough

23:09 brehaut: swap! returns the new atom anyway

23:10 reorder it so that you do the reset! on primes first

23:10 and you can do ((swap! mem union (set mems)) n) as your tail

23:11 mec: done

23:11 brehaut: is this a toy?

23:12 because it has a race condition

23:12 mec: wheres that?

23:13 brehaut: you have two atoms and their values are dependant

23:13 its probably really minor

23:13 mec: do atoms block until they return?

23:13 brehaut: i think they might spin?

23:14 its syncronous anyway

23:14 anyway if you have syncronous coordinated references you should use STM

23:14 mec: ok, it should be easy enough to use refs

23:14 brehaut: yup, trivial

23:19 mec: im not sure I can see the race condition, but I changed to refs anway, it does seem better symantically

23:23 brehaut: i think there is potential for the walk along primes could occur without updating mem

23:24 because atoms dont have any coordination

23:24 mec: I can see that

23:25 amalloy: mec: ninjudd/clojure-useful has a do-it-only-once version of split-with

23:25 or he might not have taken the months-old pull request, in which case it's in amalloy/clojure-useful :P

23:26 and brehaut, it's lazy too :P

23:26 brehaut: amalloy: i didnt say it wasnt possible; only that i was sure how it would work

23:26 amalloy: brehaut: i don't remember how it work either

23:27 brehaut: im going to assume magic

23:27 amalloy: but it starts with (let [classified (map (juxt identify pred) coll)])

23:27 or similar

23:27 *identity

23:28 mec: is it separate?

23:28 amalloy: yes

23:28 brehaut: haha he has one open pull request ;P

23:28 mec: it maps [x (pred x)] first and then filters

23:29 amalloy: yeah

23:29 which really should have been (juxt identity pred)

23:30 so that causes it to only call pred once per item in the input seq, anyway

23:31 mec: that map map is hurting my brain

23:31 amalloy: brehaut: https://github.com/amalloy/clojure-useful/blob/master/src/useful.clj#L50 if you're trying to follow along

23:32 mec: it's really just [(map first (filter second coll)) (map first (remove second coll))]

23:32 but without repeating anything

23:32 brehaut: amalloy: thats not the same function as split-with though

23:32 amalloy: brehaut: oh right, haha

23:32 no, it's like separate

23:32 mec: is it not?

23:32 oh its not

23:33 amalloy: $source split-with

23:33 sexpbot: split-with is http://is.gd/Iw2auQ

23:33 amalloy: lame

23:33 mec: i would think you could do splot-with using this method

23:34 brehaut: amalloy: i think deep magic would be needed; and it could cause some fun realisation behavior

23:34 amalloy: mec: go do your real work, i'll put together a split-with that doesn't call pred too many times

23:34 brehaut: sure. you have to realize the whole first chunk of the seq if you want to get any of the last bit

23:34 brehaut: yes

23:34 amalloy: not much you can do about that

23:34 brehaut: nope

23:35 mec: worked on prime? so long i cant remember what it was for

23:35 amalloy: so there's nothing *wrong* with c.core's version, which allows you to consume the second half of the seq without realizing the whole first half

23:35 but if that's not part of your plan you might as well call pred less often

23:38 brehaut: amalloy: http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/GHC-List.html#span

23:39 amalloy: brehaut: i don't speak crazy-alien

23:39 executive summary plz

23:40 brehaut: its time to learn :P

23:40 amalloy: lol, i try, i try

23:40 brehaut: it works via the magic of tail call removal and pervasive laziness

23:40 span always returns a pair

23:41 amalloy: xs' is just xs*, right? "prime"?

23:41 brehaut: yeah

23:41 the @ notation is equivalent to :as in destructuring

23:41 only backwards

23:41 technomancy: anyone have opinions re: archiva vs nexus?

23:42 amalloy: i think i see the algorithm

23:42 brehaut: xs@(x:xs') ~= [x & xs* :as xs]

23:42 amalloy: i'll have to translate it to clojure to really grok it though

23:42 phenom_: what;s the functino to add multiple keys to a map in one assoc ?

23:42 amalloy: phenom_: it's called assoc :P

23:42 brehaut: phenom_: assoc

23:42 amalloy: &(assoc {} :a 1 :b 2)

23:42 sexpbot: ⟹ {:b 2, :a 1}

23:42 phenom_: :P i need to go the repl before coming here and looking stupid :P

23:43 brehaut: phenom_: doc is useful

23:43 &(doc assoc)

23:43 sexpbot: ⟹ "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

23:43 amalloy: phenom_: or ask sexpbot:

23:43 $findfn {} :a 1 :b 2 {:a 1 :b 2}

23:43 sexpbot: [clojure.core/assoc]

23:43 mec: I cant imagine programming in any other language anymore with doc source and findfn

23:43 r/with/without/

23:44 brehaut: mec add to your tools clojure.repl/apropos and find-doc

23:44 &(apropos 'split)

23:44 sexpbot: java.lang.Exception: Unable to resolve symbol: apropos in this context

23:44 brehaut: &(use 'clojure.repl)

23:44 sexpbot: ⟹ nil

23:44 brehaut: (&apropos 'split)

23:44 &(apropos 'split)

23:44 sexpbot: ⟹ (split-args split-with split-at split-str-at split-cmds split split-lines split split-lines re-split)

23:45 brehaut: turns out it works better if you arent a munter

23:45 amalloy: brehaut: i asked my mate jason about munted. he was like, i guess i know what it must mean, but i'm not sure i'd ever say it. is it a new-zealand-only thing?

23:45 mec: wow apropos is what i wanted instead of find-doc

23:45 brehaut: i didnt think it was but maybe

23:46 apropos is super great

23:46 amalloy: looking it up on urbandictionary was pretty funny though

23:46 mec: i stopped using find-doc because there are so many definitions that contain function names everywhere

23:47 brehaut: amalloy: haha thats pretty great

23:48 amalloy: brehaut: what is "in" doing?

23:48 brehaut: its syntax demarkating the local variables from the expression they are in

23:49 (let [[ys,zs] (span p xs*)] [(cons x ys) zs])

23:49 would be the clojure eqiuv

23:50 amalloy: okay. that makes sense but is somehow hard to keep in my head no matter how many times i figure it out

23:51 brehaut: i find let a bit horrible in haskell, its where form is much nicer

23:51 amalloy: ugh i keep forgetting i'm trying to implement split-with, not separate

23:51 brehaut: haha

Logging service provided by n01se.net