#clojure log - Apr 01 2011

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

0:03 amalloy: scottj: i like cake as much as the next guy, but i don't see much relation between those statements

0:04 cemerick: I have some thoughts if we're tossing off proclamations. ;-)

0:04 scottj: they're unrelated, the second is purely a result of Day changed to the date changing

0:04 or yeah

0:05 cemerick: right, time to turn off the internet for the next ~30 hours

0:05 amalloy: indeed

0:05 or spend that time working on your Google Romance profile

0:05 cemerick: I was going to put out a preview of a new project tomorrow, but I think I'll scrap that idea…

0:06 amalloy: well-played, sir.

0:14 * dpritchett quickly deletes half-written "clojure to merge with scala" blog post, hides from cemerick

0:14 hiredman: ~tell me about scala

0:14 clojurebot: Scala often gets in the way when trying to write neat code -- seen in #scala

0:15 Derander: scala always makes me want to learn haskell better

0:17 scottj: scala makes me wish clojure's slime were as good as ensime.

0:44 johnmn3: hello

0:45 I'm looking for a function much like partition, but that returns the last part of the collection, even if there are less than n in the remaining bit

0:46 and that preferably allows me to add padding to that last bit so that it becomes the length of n

0:47 I've built a function that does exactly that, but it's a 12 line loop recursion monster, with two if branches

0:47 and I figure there's probably a cleaner way

0:50 hiredman: clojurebot: partition

0:50 clojurebot: partition is probably not what you want; see partition-all.

0:53 johnmn3: https://gist.github.com/897755

0:55 hiredman: ok, that should greatly simplify my problem then

0:58 amalloy: blast, i'm too late. i was so looking forward to asking clojurebot about partition, when i saw johnmn3's question

0:59 johnmn3: partition includes a padding arg, you know

0:59 johnmn3: did not know

1:00 it's not in the doc

1:00 amalloy: &(partition 4 1 (repeat 100) (range 10))

1:00 sexpbot: ⟹ ((0 1 2 3) (1 2 3 4) (2 3 4 5) (3 4 5 6) (4 5 6 7) (5 6 7 8) (6 7 8 9) (7 8 9 100))

1:00 amalloy: oops

1:00 &(partition 4 4 (repeat 100) (range 10))

1:00 sexpbot: ⟹ ((0 1 2 3) (4 5 6 7) (8 9 100 100))

1:00 amalloy: and yes it is, it's right there: ##(doc partition)

1:00 * devn boggles

1:00 sexpbot: ⟹ "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complet... http://gist.github.com/897763

1:01 devn: 8 9 100 100?

1:01 johnmn3: is that in 1.2?

1:01 amalloy: johnmn3: i suspect it's in 1.0. it's certainly in 1.2

1:02 devn: supplied (repeat 100) as the padding arg

1:02 devn: oh...right

1:02 johnmn3: oh, you're talking about partition, not partition all

1:02 devn: and on that note

1:02 good night

1:02 :)

1:02 johnmn3: goodness gracious.. just what I needed

1:02 amalloy: indeed

1:07 johnmn3: mmm, much prettier

1:10 night time for me too. Thanks amalloy!

1:46 no_mind: in clojure how do I declare application wide constants ? (app is multi module)

2:10 amalloy: huh? the same way you declare anything. you def a var, and then refer to it from whatever namespace you want

2:12 brehaut: no_mind: constant is the default remember

2:15 the http Do Not Fail extension is a brilliant idea

2:16 err

2:16 do not fool

2:23 amalloy: brehaut: i preferred do not fail. i wish my servers all supported that

2:24 also: wow. i see \\\\\\\\\\ in clojure-mode.el

2:24 brehaut: amalloy: regexp escaping?

2:24 amalloy: yeah

2:24 i'm actually not sure if just that snippet is worse, or the whole line: "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *"

2:24 brehaut: elisp is a little famous for its falling toothpicks

2:25 amalloy: yeah. i have a soft spot for perl regexes, but in elisp i want to kill myself if i have to use one

2:26 brehaut: amalloy: i dont know which i think is better :P

2:29 scottj: rx will let you write emacs lisp regexes in sexp

2:33 amalloy: scottj: any applications out there to transform from elisp to perl?

2:33 (just the regexes, obviously)

2:33 scottj: maybe perl to elisp, there's pcre I think

2:34 amalloy: scottj: one of the things i'd like to fix about clojure mode is an indentation issue, but the *very simple* elisp regex is so foreign to me i can't figure out what it's doing

2:34 scottj: re pcre maybe not

2:59 joshua__: Hmm. I just C-zed out of a REPL that had a server up. When I'm trying to grab the server it is saying the port is taken.

3:00 s/grab the server/open another server on the port/

3:00 sexpbot: <joshua__> Hmm. I just C-zed out of a REPL that had a server up. When I'm trying to open another server on the port it is saying the port is taken.

3:00 joshua__: sexpbot, thanks

3:01 Is there some Unix-fu that I should know to free the port? Do I have to close the server prior to exiting the REPL in the future?

3:02 raek: joshua__: the repl is just suspended. you can use 'fg' get it back

3:03 amalloy: joshua__: C-z does not kill processes

3:03 it just starts giving them 0% CPU time until you say otherwise

3:04 use C-c to kill a process (but if you're using eg cake, that just kills the frontend process that's communicating with the jvm daemon)

3:04 more often, use C-d to send "end of file" to a process: "i'm done typing now, please let me go"

3:06 hm. do we use C-a as "start of line" because really old terminals sent that keystroke as 0x0a, carriage-return?

3:08 joshua__: raek, nice. Thanks

3:10 gregh: C-a and carriage-return (C-m) are unrelated

3:11 joshua__: Ugh. So I did that and it didn't work.

3:12 I should have mentioned this was on a remote server.

3:12 It turned out I had a screen inside a screen inside a screen inside a screen..

3:12 or something.. so I didn't realize one of them had a server up..

3:12 I've been getting lost in screen rather frequently of late =/

3:13 I think I'm using it well than I type exit twenty times and still am not out of the screen =/

3:13 Anyways, servers up, so thanks everybody.

3:13 amalloy, woo.. content:

3:14 amalloy: gregh: right, of course, i keep rediscovering that one :P. M for 13=0x0d, J for 10=0x0a, and both of them do vaguely newline-y things. i wonder what 0x01 is

3:15 gregh: SOH = Start Of Header

3:15 I don't think it's meaning as SOH has anything to do with its Emacs-dervied usage of "start of line"

3:15 amalloy: joshua__: does everyone render markdown in client javascript?

3:16 it seems kinda gross, and is just slow enough that i can see a disorienting flash of motion when i load your page

3:19 joshua__: amalloy, No. I was being lazy.

3:20 amalloy, The right way to do it would be to pull out the wiki code and make it so you can store the processed markdown and the unprocessed markdown.

3:20 amalloy, when someone wants to edit the wiki they are given the markdown, when someone wants to view a page you give them the markdown html.

3:25 I know that it can be improved in a million ways. I see the room for improvement. I'm just glad that I'm building things =p

3:25 amalloy: puts you ahead of me, these days. i just write utilities, blog posts, and php

3:27 joshua__: amalloy, Nope. You actually write tons of amazing code. Really. It feels like half the stuff I write has your hand in it somewhere. The other half doesn't run.

3:27 amalloy: well yes. i do rather enjoy writing other people's code

4:29 $source pop

4:29 sexpbot: pop is http://is.gd/g0HpVI

4:39 amalloy: hmmm. suppose i want to get at least one element from a sequence. which is a clearer test? (when-not (or (zero? n) (empty? coll))) ... vs (when (and (pos? n)) (seq coll)))

4:41 ejackson: I think the latter

4:43 AWizzArd: amalloy: what is n?

4:43 amalloy: AWizzArd: the number of elements to take in total. i'm doing it recursively, so i need n to be nonzero, and coll to be nonempty

4:44 if n is greater than coll, i only take one at this step, and find out later which constraint runs empty first

4:44 AWizzArd: ok

4:52 amalloy: thanks for the opinions, folks. i'm headed to bed

5:10 raek: should you be able to edit these page if you have signed the CA? http://dev.clojure.org/display/doc/Getting+Started

5:13 ejackson: what it the function equivalent of the sugar (. as in (.method-name Object args) ?

5:16 ah, memfn.

5:16 brehaut: ejackson: thats old

5:16 ejackson: i believe that the idiomatic way now is generally #(.methodName obj args)

5:17 memfn is apparently from before the existence of #( ≥ )

5:17 also args should be %1 %2 etc obviously

5:18 ejackson: yes, that is usually what I do. But I'm making a macro and don't know (gonna check of course) that I can do things like `(.~method-name ...) and have it work.

5:18 brehaut: (that being said, sometimes memfn can be useful because the explicit argument names can add clarity)

5:18 ejackson: if not, I'd like a fallback before I proceed

5:19 brehaut: ,`(.trim " abc ")

5:19 clojurebot: (.trim " abc ")

5:20 ejackson: I'm getting a space between . and the method name :)

5:20 so (defmacro create-command [name & args]

5:20 `(with-redis

5:20 (.~name *connection* ~@args)))

5:20 when expanded goes to

5:20 (macroexpand-1 '(create-command set "k" 3))

5:20 (redis.clojureclient/with-redis (. set redis.clojureclient/*connection* "k" 3))

5:20 brehaut: my guess is that is because of the ~

5:21 ejackson: exactly. I think using memfn should allow me to get around that

5:22 brehaut: (let [n 'foo] `((symbol (str "." n)))

5:22 ,(let [n 'foo] `(~(symbol (str "." n)))

5:22 clojurebot: EOF while reading

5:22 brehaut: ,(let [n 'foo] `(~(symbol (str "." n))))

5:22 clojurebot: (.foo)

5:23 ejackson: sneaky !

5:23 clgv: ejackson: there is another equivalence -> (.instanceMember instance args*) ==> (. instance instanceMember args*)

5:23 ejackson: aaaaah

5:23 that looks most direct

5:23 lemme give it a spin

5:23 brehaut: clgv: much better

5:24 clgv: got it from here: http://clojure.org/java_interop ;)

5:24 ejackson: I'd forgotten than form

5:25 clgv: I vaguely remembered and looked it up ;)

5:25 Chousuke_: yeah, that's the form you should use in macros. Not worth using sugared forms in generated code :)

5:25 ejackson: "No thank you Turkish, I'm sweet enough"

5:26 Thanks for the help guys

5:27 and it even works :)

6:15 Another tip ?

6:15 you can't partial macro's because they aren't functions

6:16 so how do you create the equivalent of (partial redis* "localhost") on a macro like

6:16 (defmacro redis* [host name & args]

6:16 `(with-redis

6:16 ~host

6:16 (. *connection* ~name ~@args)))

6:16 a macro returning another macro ?

6:16 wrapping in a function and partial that ?

6:22 GuySensei: anyone amongst you who has worked with mongodb?

6:22 and clojure

6:23 clgv: ejackson: a macro returning a macro is your best bet

6:23 GuySensei: both in a single project.. ?

6:23 ejackson: clgv: Eeek ! That's above me :)

6:23 GuySensei: i am a newb..could you please elaborate?

6:23 clgv: ejackson: since there is no real equivalent for partial. you wouldnt save much anyway

6:24 fliebel: clgv, ejackson: what kind of a monster are you building?

6:24 clgv: ejackson: it's easy to do. I'll fetch you an example

6:24 ejackson: I guess its time for a gist.... 1 sec

6:24 GuySensei: :)

6:25 @fliebel i bet its a good monster

6:26 ejackson: ok this is it: git://gist.github.com/897978.git

6:26 its meant to be the opposite of a monster

6:26 what I want at the end is to be able to use any of the jedis functions (nice java wrapper around redis) like (redis get keys "*")

6:26 fliebel: https://gist.github.com/897978 I prefer http ;)

6:27 ejackson: right now something (redis* "localhost" keys "*") works

6:28 but I'm trying to get rid of the necessity of including the host each time. My thinking is to do the macro equivalent (whatever that may be) of returning a clojure of the host

6:28 fliebel: oops, sorry.

6:28 fliebel: GuySensei: Are you new to IRC? :) You don't need to prefix names with @, and usually it works best to just ask what you want to know.

6:29 GuySensei: haha.. yes i am

6:29 it is my second day

6:29 to IRC and to clojure

6:29 ejackson: s/clojure of/closure over/

6:30 GuySensei: as an aside, I briefly got Mongo + Clojure working using https://github.com/somnium/congomongo

6:30 but it was a whiles ago

6:30 fliebel: ejackson: I have seen people use a macro over binding like (with-db db body)

6:30 GuySensei: yeah..so any noteable comments? I am currently using mongodb with java.. was thinking of experimenting with that in clojure... just for kicks

6:31 ejackson: GuySensei: yeah, it works :)

6:31 GuySensei: ok.. thanks :) let me go ahead and try :)

6:31 ejackson: enjoy, enjoy.

6:31 clgv: ejackson: you can simply do (defmacro m1 [& args] `(defmacro m2 [& otherargs] `(do-something ~~args ~otherargs)))

6:31 ejackson: aint nothing about that ... :P

6:31 lemme give it a swing

6:34 fliebel: Does Brian Carper come in here? ( http://briancarper.net/blog/520/making-an-rpg-in-clojure-part-one-of-many )

6:34 ejackson: clgv: nope, it complains about "can't use qualified name as parameter

6:34 for otherargs

6:34 clgv: ah right use a "#"

6:35 ejackson: yeah, thanks, I also just tried that :)

6:36 and it works :)

6:36 much obliged clgv :)

6:37 clgv: sure it does ;)

6:38 ejackson: ok, here is the full gist https://gist.github.com/897978

6:38 it was the ~~ trick I was missing in all this :)

6:39 I might even blog (with appropriate credits) this little exercise.

6:39 clgv: you could also do without "~~" by let-ting with "~" in-between

6:40 ejackson: oh right, that took a second to parse, I get you

6:40 clgv: :)

7:00 ejackson: what is that which is to defmacro as fn is to macro ?

7:01 s/macro/defn/

7:01 sexpbot: <ejackson> what is that which is to defdefn as fn is to defn ?

7:01 ejackson: oh for the love

7:01 what is that which is to defmacro as fn is to defn ?

7:01 AWizzArd: ejackson: you want an anonymous macro, generating it on-the-fly?

7:02 ejackson: yes please

7:02 AWizzArd: Can you provide pseudo code for a minimal example of what you want to achieve?

7:03 ejackson: sure, it proceeds from my last discussion

7:03 in line 17 of https://gist.github.com/897978

7:03 we have a defmacro

7:03 this causes issues if we want to use the outer macro from another namespace as it won't let us

7:03 fliebel: You can use a macro and a gensym to sortof generate an anonymous macroe, I think there is such a thing in amallow-utils.

7:03 ejackson: hence I'd like it to return an anon macro and def it to a var in the calling namespace.

7:04 clgv: something like a template comes close to an anonymous macro: `(do-something ~args)

7:04 ejackson: its a morning of much learning for me

7:05 fliebel: ejackson: You can not do that. ##for

7:05 ,for

7:05 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/for

7:05 fliebel: so what you can do is return the list that would be your macro, and defmacro that.

7:05 clgv: $source defmacro

7:05 sexpbot: defmacro is http://is.gd/sFSa15

7:06 fliebel: (. (var defmacro) (setMacro))

7:06 clgv: ejackson: as you can see there, a macro is only a fn with setMarco being called on the var

7:06 as fliebel quoted ;)

7:07 ejackson: now that is interesting... so maybe I could return an anonymous function, bind to a var, the .setMacro it ?

7:07 clgv: why would you want to operate on that low level?

7:08 ejackson: ideally I don't :)

7:08 fliebel: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/macro.clj#L18

7:08 ejackson: its just that current code is unusable outside of its own namespace on acocunt of the defmacro in the macro

7:09 fliebel: oh-hello !

8:05 fliebel: futures run in a bound treadpool, right? So can I create tons of them and expect them to do something useful?

8:06 AWizzArd: fliebel: currently futures and agents use the same pool.

8:07 fliebel: AWizzArd: with send, that is? because send-off does use unlimited threads.

8:07 AWizzArd: I think n=cores+2 threads go into that pool. On a quadcore with hyperthreading ==> 10 threads.

8:07 send-off tries to take one of those 10 first, and if none is free it creates a new one.

8:09 fliebel: So what happens if I run more than 10 forever-running futures?

8:09 pdk: how does send handle running out of pool threads then

8:09 i've heard "use send for cpu bound stuff and send-off for i/o bound stuff"

8:09 but noone explained how they're implemented that makes this distinction

8:09 AWizzArd: send will just block until one of those 10 is back available

8:10 fliebel: AWizzArd: Right, so send/future will just not run the 11th forever-running thread.

8:14 nachtalp: fliebel: http://s-expressions.com/2010/06/08/medusa-0-1-a-supervised-thread-pool-for-clojure-futures-2/ according to this, future uses the same threadpool as send-off (unbounded)

8:16 AWizzArd: fliebel: a future would start off new threa... yes what nachtalp said

8:16 fliebel: okay

8:20 AWizzArd: ejackson: there is also http://richhickey.github.com/clojure-contrib/macro-utils-api.html#clojure.contrib.macro-utils/macrolet

8:20 ejackson: AWizzArd: thanks. I did come across that, but realised I'd waded out into waters deeper than I should have, and just gave up :)

8:21 AWizzArd: Oooh, Oracle just decided that from Java 8 on there will be high license fees for the JDK :-(

8:22 cemerick: AWizzArd: watch those april fool's stories…

8:23 AWizzArd: cemerick: actually this was *my* AF story ;)

8:23 cemerick: ah, sorry for ruining your mojo :-)

8:23 * fliebel refuses to look at any news today.

8:24 cemerick: AWizzArd: try again in another hour or two when a few more timezones are online

8:24 ejackson: it drives me mad ! pollutes my mental namespace.

8:24 nachtalp: AWizzArd: good one :)

8:26 fliebel: I could use a second brain more seasoned in FP than mine for my game engine. So imagine the game loop, which iterates on a set of objects. I could just call a function on every objects and use the result as the new object. Now say the object is jumping. It'd be hard to tell whether it should go up or down.

8:26 ejackson: its like historical fiction - after a while you have no idea was *actually* happend in reality. Poison.

8:28 fliebel: i guess you'd need to so have it store the state of how long its been ascending, with someway of know to start descending at some point ?

8:29 fliebel: ejackson: Possible… But I'm also looking at lazy seqs or Lamina. Such that it can return multiple states using some closures.

8:30 ejackson: yeah, if you had as state a seq of vertical displacements representing a jomp and at each frame you affected the first and returned the rest you might get away with it...

8:32 Chousuke: fliebel: you can use a movement vector for the jumping perhaps? have some gravity and when a jump occurs, set movement vector to something pointing upwards.

8:33 fliebel: Chousuke: Okay, so using velocity, a jump would work. But I'm sure there will be actions that span more than a single frame, jumping being just a simple example of that.

8:35 But to tell you the truth, I can't think of much. So maybe it would work to just have functions.

8:35 Chousuke: a seq of deltas might be useful then I guess.

8:36 that's what I'd try if I were to write something that needs to update a display.

8:36 since redrawing all the time is not very efficient :/

8:37 fliebel: Chousuke: And you'd put (rest that vector) on the object, so that it knows what to do next?

8:39 Chousuke: perhaps

8:40 I have no idea how it'd work in practice but that's what I'd start with :)

8:41 ejackson: i think Chousuke's idea of attempting to calculate the state each frame based on that of the previous time is the best. That way upward velocity will slow, and eventually become negative.

8:42 the seq of deltas, calc'd ahead of time, would be brittle to changes in environment during the jump.

8:42 just guessing here though

8:42 fliebel: ejackson: But that is still only jumps

8:43 ejackson: it should generalise, surely ?

8:43 fliebel: yea, beyond my wildest imaginations :)

8:44 I think Lamina goes pretty far.

8:45 ejackson: link ?

8:45 fliebel: https://github.com/ztellman/lamina/wiki/Channels

8:51 maacl: LauJensen: hey!

9:08 mec: Is there a function like into that just converts rather than conjing

9:09 Chousuke: converts?

9:10 mec: if you mean mutates the vector, then no, not really.

9:10 there are transients but transients are not mutable either.

9:11 mec: like vec or apply list

9:11 Chousuke: ah, hm

9:11 no.

9:11 mec: because (into '() ) reverses the coll

9:12 Chousuke: you can use seq if you need something that looks like a list

9:19 ahihi2: what should I use to show a rational in decimal format?

9:19 mec: you can cast to double or float

9:20 powr-toc: stuartsierra: hey, how're things going with cljque? :-)

9:21 stuartsierra: been talking about it with some folks here...

9:21 still committing on branches

9:22 powr-toc: stuartsierra, Yeah, so I've seen

9:22 I saw your video on it... and I've even played about with it at the repl

9:23 stuartsierra: cool

9:24 powr-toc: how closely have you been following Rx's lead?

9:24 fliebel: cljque?

9:26 powr-toc: because it looks like some of the behaviours differ... for example Rx's select-many lazily subscribes to observers... but your map-events didn't seem to

9:27 stuartsierra: powr-toc: I started from Rx as an inspiration, but drifted away

9:27 gtrak: does clojure have a distributed story?

9:28 fliebel: what is the goal of cljque?

9:28 powr-toc: I'm curious as to why you've chosen to drift? Don't you think Rx cuts it in terms of event stream composition?

9:30 damn, I've got to shoot off and catch a train... I'd love to speak more about cljque sometime though

9:31 stuartsierra: I don't really know Rx that well, and haven't been able to find comprehensive documentation on it.

9:32 powr-toc: that is a problem... there's a pretty good pdf file that covers some of the basics knocking about somewhere

9:32 stuartsierra: I think I have that; but that's the only doc I've found.

9:33 powr-toc: and the gui describes all of the combinators etc with marble diagrams quite well

9:33 stuartsierra: gui?

9:34 powr-toc: the RxSandbox

9:34 ok I've got to go

9:35 stuartsierra: nuts, windows-only

9:39 fliebel: stuartsierra: What can I read to understand what cljque is about?

9:44 * devn tips his hat

9:44 stuartsierra: fliebel: The .NET Rx documentation

9:44 Or the video of my presentation at Clojure NYC.

9:48 fliebel: ah http://vimeo.com/18970727

9:49 it oopses :(

9:50 devn: fliebel: oopses?

9:51 fliebel: does not work

9:51 devn: oh...works for me

9:51 blue hair and all

9:53 fliebel: still no go. :(

9:56 ejackson: i've got it, might be your browser etc ec

9:56 fliebel: firefox works

10:01 oh, long talk, so lang the stuart as already left before I can ask him questions about it.

10:03 devn: fliebel: if you've got a question i can try and bug him

10:08 stuartsierra: fliebel: Cljque is an attempt to design a framework for handling asynchronous events in Clojure with the same level of higher-order functions you have to manage lazy sequences.

10:09 fliebel: stuartsierra: So how is it different from Lamina? (I havn't reached that part of the vid yet)

10:09 stuartsierra: They're both aiming for the same goal.

10:10 Lamina is more oriented towards queues, which I'm trying to avoid.

10:10 fliebel: stuartsierra: Ah, so what is you main 'thing'?

10:14 stuartsierra: Two protocols: Observable (things which produce events), and Observer (things which consume them.

10:36 kephale00: Any recommendations for finding bottlenecks in parallel code?

10:38 stuartsierra: kephale00: try to find points where 1 thread is blocked waiting for other threads.

10:42 kephale00: stuartsierra: I have a bunch of agents but only 2 significant send calls. I am wondering if there is a way of discovering which resources/variables they might be competing over. I'll probably have to go into a number of functions and print output, is there a good way to discover how many threads are currently active?

10:42 pdk: hn

10:42 has anyone here tried running cake on win

10:42 stuartsierra: kephale00: try YourKit

10:43 or some other JVM profiler.

10:43 pdk: apparently it expects a server jvm installed that isn't

10:43 prob doesn't help that it's looking in the 32 bit program files :|

10:43 kephale00: stuartsierra: thanks!

10:44 stuartsierra: 'welcome

10:48 ejackson: too funny: http://www.atlassian.com/en/angrynerds

10:49 kephale00: a quick guess: if I am passing a map containing functions that read globals to the agents, could that lead to blocking?

10:49 stuartsierra: Reading global vars will not block.

10:49 kephale00: ok

10:49 ty

10:49 thats what i suspected

10:54 powr-toc: stuartsierra: so I'm really just wondering what your plans for cljque are... Do you see yourself as competing with aleph? Or do you see yourself as providing a new event stream abstraction?

10:55 I've not really looked too much into alephs pipelines and channels, but they don't seem as nice as the kinds of abstraction Rx provides

10:56 stuartsierra: I aim to produce a low-level abstraction upon which libraries like Aleph could be based.

10:57 powr-toc: great!

10:57 fliebel: stuartsierra: What can events do that lazy seq cant? OH, I think someone in the vid asked that...

10:57 stuartsierra: It could potentially be useful for network applications, GUIs, and faster I/O.

10:58 fliebel: waiting for an event doesn't block a thread; consuming a slow lazy seq does.

10:58 powr-toc: fliebel: sreams are different from lazy-seqs as they're push based rather than pull based

10:59 stuartsierra: agreed... what are your thoughts on extending the observer/observable protocols to other java types, and possibly other apis?

10:59 stuartsierra: powr-toc: I'm all for it. I experimented with extending them to Netty ChannelFutures.

11:01 powr-toc: yes I saw...

11:03 basically I have a bit of a dillema... cljque currently seems to be very much a playground for ideas, and I'm not yet convinced of alephs abstractions

11:04 so basically I've built myself a simple stomp broker on top of netty directly... but obviously I've reinvented some bits of aleph / cljque in doing so

11:05 stuartsierra: Yeah, I kept doing the same thing, which is why I went to work on cljque.

11:06 powr-toc: anyway, I'm really wanting to start making use of event stream composition, so I can more elegantly handle the application level concerns

11:07 the low level network streams etc... I'm ok with being handled in my code just now, but ideally I'd like to bring them in line with whatever abstraction I use higher up too

11:08 so I was wondering what you think I should do :-)

11:09 stuartsierra: powr-toc; Afraid I can't help much.

11:09 powr-toc: lol

11:09 stuartsierra: I'm hoping to nail down the low-level API within the next few months.

11:09 powr-toc: by low-level api, you mean observer/observable and combinators right?

11:10 stuartsierra: yes

11:10 powr-toc: well, that's the bit I really want :-)

11:10 stuartsierra: If you need it right now, you can always pick a commit that has what you need and use it in your code.

11:11 powr-toc: stuartsierra: Is there a mailing list for cljque?

11:11 stuartsierra: no

11:12 rhickey: name game - so, we're doing factory fns for records and deftypes - one positional, one taking a map (deftypes get only the former)

11:13 the fns will be generated in the ns of the defrecord

11:13 stuartsierra: ooh, naming! Always fun.

11:13 rhickey: and will involve the record/type name

11:14 so we need two names, one for positional, one for map

11:14 e.g. ->MyRecord, map->MyRecord have been proposed

11:14 fogus`: Those are my current favorites

11:14 rhickey: make-, create- new- Record

11:14 dakrone: is there a class to (extend ...) that will dispatch on 'nil'?

11:15 stuartsierra: dakrone: you can extend nil

11:15 rhickey: I always disliked -> in names because there's no way to pronounce it, and the order is backwards from how s-exprs are evaluated.

11:15 fliebel: rhickey: Are these fns created with the types, or a separate function, like new vs .object

11:16 rhickey: stuartsierra: it's pronounced "to"

11:16 stuartsierra: yeah, I know, but it still goes in the wrong direction.

11:16 rhickey: stuartsierra: you are proposing Record-from-map ?

11:17 fogus`: MyRecord<-map :p

11:17 fliebel: well, <-MyRecord then "[instance] from record"

11:17 dakrone: stuartsierra: thanks

11:17 stuartsierra: No, I like names that are nouns. "record"

11:17 rhickey: fliebel: I don't understand

11:17 stuartsierra: If it needs to be more specific, then "noun-from-noun"

11:18 fliebel: I'ts just the pronunciation. if -> is to <- is from

11:19 rhickey: ooh - Record: ... currently unreadable

11:20 stuartsierra: English suffers here from "record" also being a verb.

11:20 fliebel: for the map, into-record/type

11:20 rhickey: Foobar: ...

11:20 fliebel: oh, no type

11:20 rhickey: (Foo: 1 2 3)

11:20 powr-toc: stuartsierra: If I was to pick a commit, what would be a good starting poi

11:21 nt?

11:21 clojurebot: ¢

11:21 fogus`: rhickey: Guaranteed not to clash with existing names. :-)

11:21 rhickey: (Foo:: {:a 1 :b 2 :c 3}

11:21 stuartsierra: powr-toc: whatever serves your needs really. Different branches have different levels of complete-ness.

11:21 powr-toc: stuartsierra: then what are the goals of each branch?

11:22 stuartsierra: 'master' is my first complete attempt, but has buggy state handling in the combinators.

11:23 'agents' was an attempt to solve the state problems with agents.

11:23 'combined' is my latest work, attempting to get state handling right without forcing the use of agents everywhere.

11:24 powr-toc: so combined, is the future of cljque?

11:24 fliebel: rhickey: So, will : become legal in symbols? Fun for ticking Ruby and Perl people Foo::bar

11:25 rhickey: fliebel: : is only reserved at the beginning or end

11:25 ,(def foo:bar 42)

11:25 clojurebot: DENIED

11:25 fliebel: ,'foo::bar

11:25 clojurebot: Invalid token: foo::bar

11:25 sritchie: ,(let [foo:bar 42] foo:bar)

11:25 clojurebot: 42

11:26 stuartsierra: powr-toc: yes

11:26 fliebel: So, why the end?

11:26 rhickey: also "A symbol can contain one or more non-repeating ':'s"

11:26 reserved so I have it for things like this :)

11:27 fliebel: oh, good :) I like it. Only, the distinction between a single and a double one is weird.

11:27 powr-toc: stuartsierra: whats your current focus on?

11:27 rhickey: just throwing stuff out there in the absence of input

11:27 fliebel: I vote for -into for the map case

11:28 rhickey: ?

11:28 raek: I like the recemblance between Foo. and Foo:

11:28 fliebel: (into-foo: {:bar 1 :baz 2})

11:28 stuartsierra: powr-toc: flexibility around threads: e.g., if you're using a library that manages its own thread pools, you can stay on those threads

11:28 fogus`: -into implies some operational semantics to me. But the same could be said about ->MyRecord I suppose

11:29 rhickey: (into-Record {:a 1})?

11:29 powr-toc: stuartsierra, Yeah, I can imagine that would be useful

11:29 raek: so Foo: will be be just #(Foo. %1 %2 ... %n) ?

11:30 fliebel: raek: I hope it caries across nses better than that

11:30 oh wel.. yea

11:30 powr-toc: ok, I'm going to have to head off again

11:30 rhickey: raek: no, there will be a fn named Foo: , which you'll get from require, unlike the type name which you don't

11:30 raek: ah, forgot about that point

11:30 powr-toc: stuartsierra: Thanks a bunch for your comments on cljque... I'll maybe invest some more time in looking at it

11:31 is it ok, to drop you some emails if I run into problems/issues?

11:32 stuartsierra: sure

11:33 powr-toc: great!

11:35 raek: is CamelCaps preferred for names of types and records?

11:35 thickey: i would prefer Record: over some (currently legal) prefix/suffix like into-Record

11:36 raek: if so, the Foo:/Foo:: look has the advantage that it doesn't mix the CamelCaps and hyphen-separated-words conventions in the same identifier

11:38 fogus`: The only problem that I have with Foo: and Foo:: is that the names tell me nothing about the expected arguments. Which one is :, map? I forgot already.

11:39 stuartsierra: what if there's just one name: with one arg, that arg is a map

11:40 raek: "{Foo" à la JVM type descriptors, anyone? :-)

11:40 and for a record with only one field?

11:42 fliebel: Or anonymous classes? $Foo

11:42 dnolen: stuartsierra: makes things awkward with apply I think. I like being able to use apply w/ my current ctor fns.

11:42 fliebel: Is # currently used for anything? Otherwise that would eb cool as a *hash*map veriant.

11:42 raek: , `foo#

11:43 clojurebot: foo__4805__auto__

11:43 fliebel: ,#bar

11:43 clojurebot: No dispatch macro for: b

11:43 rhickey: gotta run

11:46 dnolen: nice write up on compiling with continuations - http://matt.might.net/articles/cps-conversion/

11:46 fogus`: fliebel: The pattern #bar is in the works for other usage

11:47 fliebel: fogus`: What?

11:49 raek: hrm, my confluence account does not have write acess to the wiki.

11:49 (I have signed the CA)

11:49 fogus`: fliebel: The basis for record literals

11:49 fliebel: oh! :)

11:50 raek: so, is the old Assembla account supposed to work in Confluence? I recall that I couldn't log in with my old credentials, so I tried to create an account with them, but the username already existed. so I created a new account...

11:51 fliebel: fogus`: But than, isn't the factory fn for records just the same as (into #record-literal {:foo 1})?

11:52 dnolen: So this is what you continuations lib does basically?

11:53 dnolen: fliebel: I think my transformation is naive, this covers the topic much more in depth. I need to dig into it, looking forward to updating delimc based on whatever I learn.

11:54 fogus`: fliebel: Not entirely. I am writing up the current thinking on the Clojure Wiki. I'll probably be done later today

11:55 thorwil: hmm, what is this thing that prints as #<models$created_t tlog.models$created_t@25ca623f>, and how do i get the content?

11:55 dnolen: fliebel: from a quick look, he covers avoids introducing unnecessary bindings, would probably make delimc much more efficient then.

11:55 fliebel: dnolen: I'd think so :)

11:55 fogus`: Okay, interesting :)

11:56 fogus`: I'll post a call for opinions to the dev mailing

12:05 AWizzArd: Oooh, Oracle just decided that from Java 8 on there will be high license fees for the JDK :-(

12:06 raek: AWizzArd: link?

12:07 thorwil: it's not the right day for final decisions and announcements

12:07 raek: thorwil: try (class that-thing)

12:09 thorwil: tlog.models$created_t

12:10 what i expected was some kind of empty value

12:11 arg, i apparently don't know my own code, nm :)

12:13 ejackson: AWizzArd: I saw what you did !

12:17 dnolen: hmm, interesting that conj on a map only supports vector and not a list or seq.

12:17 ,(conj {} '[a b])

12:17 clojurebot: {a b}

12:17 dnolen: ,(conj {} '(a b))

12:18 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.util.Map$Entry

12:18 TimMc: ,(conj {} (seq '(a b)))

12:18 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.util.Map$Entry

12:20 TimMc: ,(into {} '([3 4] [5 6])) dnolen: It takes a list as a seq of entries

12:20 clojurebot: {3 4, 5 6}

12:21 TimMc: That's not documented, though.

12:22 hiredman: ,(type [1 1])

12:22 clojurebot: clojure.lang.PersistentVector

12:22 hiredman: ,(ancestors [1 1])

12:22 clojurebot: nil

12:22 hiredman: ,(ancestors (type [1 1]))

12:22 clojurebot: #{clojure.lang.IFn java.io.Serializable clojure.lang.AFn clojure.lang.Sequential java.util.concurrent.Callable clojure.lang.IObj clojure.lang.Counted clojure.lang.Associative java.util.List clojure.lang.APersistentVector ...}

12:22 fliebel: AWizzArd: Oh, really? Well, that was to be expected, when do we get JDK-Jenkins?

12:23 hiredman: ,(->> (ancestors (type [1 1])) (filter #(.startsWith (.getName %) "clojure")))

12:23 clojurebot: (clojure.lang.IFn clojure.lang.AFn clojure.lang.Sequential clojure.lang.IObj clojure.lang.Counted clojure.lang.Associative clojure.lang.APersistentVector clojure.lang.Seqable clojure.lang.ILookup clojure.lang.Indexed ...)

12:23 hiredman: somewhere in there is mapentry, which is why it is conj'able onto a map

12:24 dnolen: ,(into {} '((3 4) (5 6))

12:24 clojurebot: EOF while reading

12:24 fliebel: &(key [1 2])

12:24 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry

12:24 dnolen: ,(into {} '((3 4) (5 6)))

12:24 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map$Entry

12:24 dnolen: TimMc: in anycase I want to use conj, already looked at the Java source, it's not possible. It's okay I'll just reify IMapEntry.

12:25 AWizzArd: :)

12:25 TimMc: hiredman: I don't see it.

12:26 fliebel: Is there any way to have some hierarchy in records without methods?

12:26 dnolen: hiredman: TimMc: it's not there. line 23-45 in APersistentMap.java, it special cases vector of length 2

12:27 TimMc: ew

12:27 (into {} [3 4 5])

12:27 hiredman: must have changed, two element vectors used to implement mapentry

12:27 TimMc: ,(into {} [3 4 5])

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

12:27 fliebel: So that I can have a record that is guaranteed to have the same key, and till have its own type.

12:28 I believe Java interfaces do have instance variables in them.

12:29 TimMc: fliebel: Never heard of that.

12:29 Java interfaces can carry what are effectively static constants, though.

12:30 fliebel: hm, okay.

12:32 Well, look, the reason to use records would be that you know they'll have all the keys you expect and they have a type. Now I need some sort of subtype of that. There is no way to make that explicit, is there?

12:33 TimMc: Clojure doesn't like subtyping of concrete classes.

12:33 dnolen: erg, APersistentMap looks for concrete Map.Entry instead of IMapEntry.

12:34 fliebel: TimMc: How is it any way concrete to define a class will have the specified keys? It doesn't have implementations, does it? I just need a contract for a few types that they'll be able to give me a set of keys.

12:35 Just as if I had defined a few getters and setters, but then only dictionary keys.

12:36 TimMc: I guess I don't understand what you're asking, then.

12:36 chouser: java.util.Map$Entry is an interface that clojure's MapEntry implements

12:36 ^ dnolen

12:38 fliebel: TimMc: Well, say I define a interface that has getX and getY, any class implementing that would need to be able to provide me with an X and an Y. Now I'm not using getters, but idiomatic Clojure records. Now I need to enforce the same thing, that a record can provide X and Y.

12:39 TimMc: Oh wait, I got into and conj mixed up earlier. >_<

12:40 dnolen: chouser: ah yeah, great thanks. Map$Entry == Map.Entry

12:42 TimMc: fliebel: Do you just want records that have Java-like getters attached?

12:42 stuartsierra: For those I was talking to about Cljque, I just merged the 'combined' branch into 'master'

12:44 fliebel: TimMc: No, I want something that can't be done. I want to have a contract that says (defrecord a [x y z]) and (defrecord b [w x y]) can both provide me with x and y.

12:45 stuartsierra: yay

12:46 And if that is not possible, can I use derive to at least tell Clojure a is a child of b, if only for the sake of multimethods?

12:48 mduerksen: if someone is interesented, i uploaded my own clojure port of peter norvigs sudoku solver: https://github.com/toofuu/sudoku/blob/master/sudoku.clj . i would be glad to hear some suggestions to improve my coding style

12:51 dnolen: fliebel: how do you want to enforce such a contract in your code?

12:52 fliebel: as is the enforcing just for debugging purposes while developing?

12:52 s/as/and

12:52 sexpbot: <dnolen> fliebel: and is the enforcing just for debugging purposes while developing?

12:54 fliebel: dnolen: The enforcing is just for security, the hierarchy is for saving some multimethod. I think this might be possible with derive.

12:56 amalloy: fliebel: security? you can't mean actual security like hackers

12:57 fliebel: amalloy: No, security, that I know that if I do (get record :x) it will actually returns omething.

13:13 amalloy: hey technomancy, did you ever talk to monsieur planet-clojure? page looks like it's still down, and it looks like only SO links are getting tweeted

13:19 jweiss_: is there a standard way of getting around this - my macro doesn't work because I want macros in the args I pass it to be expanded first, but they aren't. should i just call macroexpand in my macro or something?

13:19 amalloy: jweiss_: you could do that, but it seems wrong. could you clarify why you want this behavior?

13:22 jweiss_: amalloy: my macro is generating a map. part of the reason i used a macro, is some items in the map are functions that takes arguments. i wanted access to all the names of the arguments so i could tell callers what info those functions are going to need.

13:22 but i was finding most of my function defs i am passing to my macro looks about the same

13:23 so i wanted to shorten the syntax even more with another macro to expand into `(fn [] ...)

13:27 amalloy: ummm. still a little too abstract for me. but i think you probably only want one macro. have the map-generator be a plain function that the wrapping macro can call

13:29 jweiss_: amalloy: yeah, the problem with the one-macro solution is that the extra sugar i want to add is something my macro shouldn't know about. it refers to symbols it shouldn't know or care about.

13:30 hsuh: how i tell leiningen not to delete my jar in /dev even though it is not listed as a dependency on project.clj ?

13:30 or perhaps i should add another directory with this jar as a repository? if possible..

13:31 * jweiss_ tries the macroexpand solution, ugly as it sounds

13:31 jweiss_: (macroexpand '(+ 1)

13:31 oops

13:32 amalloy: hsuh: if you depend on it, list it in your dang dependencies

13:32 jweiss_: consequence of using erc - irc and swank windows look the same :)

13:32 hsuh: amalloy: but it doesnt exist on clojars and shit :)

13:33 amalloy: so find a place where it does exist, or install it locally

13:33 hsuh: yes, locally... what that means ?

13:33 install a repository locally?

13:33 amalloy: you already have a local repository

13:33 you just need to put this jar in it

13:34 i think cake install has a way to install third-party jars wherever you want

13:34 maybe not

13:36 i know you can do it, somehow, with mvn package and/or mvn install, but maven is a mystery to me. maybe technomancy knows the right way

13:36 technomancy: hsuh: you can put it in ~/.lein/plugins, but really it ought to go in a real repository.

13:36 amalloy: speak of the devil

13:36 technomancy: if you put it in :dependencies and run lein deps; the error message will show you the right invocation to put it in ~/.m2

13:36 clojurebot: leiningen is a build tool designed not to set your hair on fire (http://github.com/technomancy/leiningen)

13:36 amalloy: nice

13:36 technomancy: clojurebot: O RLY

13:36 clojurebot: Cool story bro.

13:37 hsuh: yeah, i saw that and was scared

13:37 jweiss_: amalloy: the macroexpand solutioon seems to work, feel dirty using it but i'll stick with it for now :) thakns

13:37 amalloy: noooo, how will i ever beat chouser in next year's "most-thanked" list, if people are just going to thakn me

13:38 hsuh: technomancy: it did work though

13:38 :)

13:38 TimMc: jweiss_: Remember to use syntax-quote unless you *want* non-namespaced symbols.

13:39 jweiss_: TimMc: yup, used syntax quote except for one symbol i wanted non-namespaced so i added ~'

13:39 * jweiss_ gets distinct impression i now have enough macro-rope to hang myelf

13:40 TimMc: haha

13:40 amalloy: jweiss_: you should be fine until you get enough rope to shoot yourself in the foot

13:40 jweiss_: hehe

13:43 hsuh: is lein uberjar not "the right way" to deploy your apps ?

13:43 TimMc: It's what I use.

13:44 hsuh: does it also make you feel dirty ?

13:44 TimMc: nope

13:44 hsuh: ok :)

13:45 TimMc: I distribute my libs on clojars and github, and my apps (homework assignments, so far!) as uberjars.

13:45 * technomancy uses the lein-tar plugin

13:46 hsuh: then what do you do with a tar?

13:48 technomancy: hsuh: it's deployed with chef. I'd recommend using pallet instead though.

13:48 tar is needed if you have things like init scripts to go with your app.

13:49 TimMc: Oh, right... jar/zip doesn't keep executable permissions around.

14:03 hsuh: technomancy: do you think pallet is useful even when you only intend to deploy to a single machine?

14:08 technomancy: hsuh: in some cases a shell script may suffice instead. what you want to avoid at all costs is deployment that takes human involvement.

14:09 joly: amen

14:09 * joly is currently stuck with human involvement in our build

14:09 TimMc: joly: Just put a dippy bird on the "y" key.

14:09 hsuh: sure, i just mean, its probably overkill to set automate something that is probably only need to be done once... (ok i realize other stuff could happen that would force me to reconfigure this one node)

14:09 joly: :D

14:09 hsuh: s/set//

14:09 sexpbot: <hsuh> sure, i just mean, its probably overkill to automate something that is probably only need to be done once... (ok i realize other stuff could happen that would force me to reconfigure this one node)

14:10 TimMc: (and don't tell your boss!)

14:10 amalloy: hsuh: if you ever write software that you only have to build once in your life you're probably the messiah

14:11 hsuh: i mean write software to automate something that i intend to do just once :)

14:12 amalloy: $findfn [1 2 3] true

14:12 sexpbot: [clojure.core/== clojure.core/sequential? clojure.core/reversible? clojure.core/distinct? clojure.core/boolean clojure.core/vector? clojure.core/counted? clojure.core/associative? clojure.core/< clojure.core/= clojure.core/> clojure.core/>= clojure.core/<= clojure.core/ifn? clojure.core/coll?]

14:13 raek: $findfn [1 2 3] false

14:13 sexpbot: [clojure.core/keyword? clojure.core/chunked-seq? clojure.core/fn? clojure.core/not= clojure.core/nil? clojure.core/string? clojure.core/sorted? clojure.core/false? clojure.core/true? clojure.core/symbol? clojure.core/number? clojure.core/integer? clojure.core/seq? cl... http://gist.github.com/898583

14:14 amalloy: hmph. what's a good way to test whether a vector is empty? i can call seq on it, but i'm planning to keep treating it as a vector and it seems like seq might be expensive

14:17 hiredman: ,(doc empty?)

14:17 clojurebot: "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

14:18 hiredman: have you seen the impl of seq() in APVector?

14:18 amalloy: hiredman: not recently

14:21 TimMc: amalloy: zero? count ?

14:23 amalloy: yeah. i think i'll just rewrite the function to compute the interesting stuff once at the beginning rather than at each recursive step

14:23 TimMc: ,(counted? (type []))

14:23 clojurebot: false

14:23 amalloy: TimMc: ##(counted? [])

14:23 sexpbot: ⟹ true

14:23 TimMc: ah

14:41 Are there any colls that aren't Counted?

14:42 I tried list, vector, array-map, and hash-map already.

14:42 fliebel: set? sorted- ?

14:43 chouser: lazy-seq

14:43 fliebel: ah, of course

14:43 TimMc: Oh, right... seqs are colls.

14:46 duncanm: if i have a seq that's [a b c d], where a-d are vars, is there a quick way to turn it into {:a a :b b ... }

14:46 chouser: ,(take 6 (iterate rest (concat (range 2) (list 3 2 1))))

14:46 clojurebot: ((0 1 3 2 1) (1 3 2 1) (3 2 1) (2 1) (1) ())

14:46 chouser: ,(map counted? (take 6 (iterate rest (concat (range 2) (list 3 2 1)))))

14:46 clojurebot: (false false false true true true)

14:47 chouser: duncanm: Vars? Like [#'a #'b #'c #'d] ?

14:48 duncanm: chouser: hmm, (let [a 1, b 2, ...] ...) what can i put in ... to get {:a 1 :b 2 ...}

14:48 opqdonut: ,(let [v ['a 'b 'c]] (interleave (map keyword v) v))

14:48 clojurebot: (:a a :b b :c c)

14:48 __name__: $(source interleave)

14:48 duncanm: i want a map from the name of the binding to the value of the binding

14:48 __name__: ,(source interleave)

14:48 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

14:48 duncanm: i dunno waht to call them, binding, variable

14:49 __name__: $source interleave

14:49 sexpbot: interleave is http://is.gd/DTpwq1

14:49 duncanm: kinda like the reverse of the :keys thing in destructuring

14:49 __name__: $(interleave [:a :b :c] [:d :e])

14:49 ,(interleave [:a :b :c] [:d :e])

14:49 duncanm: __name__: i know about interleave

14:49 clojurebot: (:a :d :b :e)

14:51 raek: duncanm: that would need to be a macro, since you want to build a :foo foo pair for each foo (which presumes that the arguments are symbols in the code)

14:51 duncanm: raek: sigh

14:51 __name__: ,(map [:a :b :c] [:d :e])

14:51 duncanm: i just don't want to type this

14:51 clojurebot: java.lang.IllegalArgumentException: Key must be integer

14:51 __name__: ,(map list [:a :b :c] [:d :e])

14:51 clojurebot: ((:a :d) (:b :e))

14:51 duncanm: (let [[a b c d] [1 2 3 4]] {:a a :b b :c c :d d})

14:52 chouser: macros have visibility into the names of all the locals in the scope where they're expanding

14:52 duncanm: doesn't matter if it's :a or 'a

14:52 raek: (defmacro m [& syms] (into {} (zipmap (map keyword syms) syms))))

14:53 duncanm: raek: okay, i'll try that out - thanks!

14:53 raek: (just remove the last paren...)

14:54 duncanm: raek: that worked, thanks so much

14:55 raek: now to the hard part: what name should the macro have? ;-)

14:55 fliebel: Is derive used anywhere besides multimethods?

14:55 raek: I'm thinking about "unkeys"

14:56 amalloy: duncanm: i wrote this a while back. called it keywordize

14:58 https://github.com/cognitivedissonance/sexpbot/blob/master/src/sexpbot/utilities.clj#L16 and https://github.com/cognitivedissonance/sexpbot/blob/master/src/sexpbot/plugins/markov.clj#L194

15:06 GuySensei: hey guys .. whats the best way to pass on meta-information from one function to other?

15:07 in an efficient way.. i would like the behavior of the next function be dependant on the meta-information fed by the previously called function.any efficient way?

15:09 chouser: GuySensei: options that come to mind: pass another argument, attach metadata to one of the existing arguments that is guaranteed to support it, or bind a dynamic var

15:10 GuySensei: what is a dynamic var?(sorry i am new to clojure) is it just a var you mean?

15:11 chouser: It's a Var yes. You'd create one with 'def' and give it a thread-local value with 'binding'

15:12 GuySensei: ahh ahh.. i get it now :) it will be something visible to just this thread.and cease to exist beyond the scope within this thread.. thanks.. makes sense!

15:15 chouser: beware, they act a bit squirrely in the face of laziness, multiple threads (such as with pmap), etc.

15:15 please consider the other options, especially just passing another argument.

15:16 GuySensei: is that squirelly behavior because of something lacking in the current platform?

15:16 chouser: no, it's real semantic mismatch

15:17 dnolen: chouser: is pmap still a problem with binding conveyance?

15:17 GuySensei: but i get your point nonetheless.. multi function you mean?(passing another argument)

15:17 amalloy: GuySensei: it's because you're (considering) using them for a weird reason

15:17 chouser: dnolen: on 1.3 I think not

15:18 amalloy: just pass another argument. why do you want to make function g "magically" aware of things that were said to function f, instead of just having f say "hey g, please behave in the following way this time"

15:18 GuySensei: weird reasons? yeah could be :D

15:18 chouser: GuySensei: static scope and dynamic scope are different things and can change indepedently of each other. lazy sequences are built on static scope (lexical context) and dynamic vars are of course dynamic scope.

15:19 GuySensei: ok ok.. absorbing it....

15:19 thanks though..let me mull over it a bit.. and understand better

15:20 amalloy: hey chouser, what does "Approval: Test" mean in jira?

15:20 chouser: Not to project too much onto your situation, but I entirely empathize with the desire to write clever code. It is probably currently my most dangerous design temptation. hard to shake.

15:21 in the end, simple always makes me happier than clever, regardless of how I feel when I'm writing the clever code.

15:22 amalloy: I have trouble keeping track. I think it means they want some people to try it out and comment on whether the patches is good, does what it should, etc.

15:26 cemerick: I think I committed to putting together a proper JIRA workflow at some point, but it never struggles far out of the bottom of my list. :-(

15:28 stuartsierra: Diagram near the bottom, here: http://dev.clojure.org/display/design/JIRA+workflow

15:30 chouser: Any chance we could rename "test" to "screen" or "clojure screeners" to "clojure testers"? Just sayin'

15:31 anyway, thanks for that chart -- helps a lot!

15:31 stuartsierra: 'welcome - I made that because I couldn't understand the process myself. :)

15:32 dnolen: stuartsierra: excellent diagram.

15:32 stuartsierra: thanks

15:46 cemerick: stuartsierra: ach -- except there is an actual workflow engine with state transitions and such that is self-documenting through the UI

15:47 nm, shouldn't complain unless I'm gonna go fix it :-)

15:49 stuartsierra: cemerick: yes, I'd like it to be implemented directly in JIRA

15:49 By someone not me. :)

15:50 cemerick: stuartsierra: it's actually *really* easy.

15:50 stuartsierra: I'm sure it is, but I spend enough time on Maven. :)

15:50 cemerick: I just haven't wanted to shepherd that particular bit.

15:50 right-o :-)

15:51 stuartsierra: Did I see a tweet go by about spikes of a new c-m-p being done-ish?

15:53 stuartsierra: very ish, but yes

15:53 https://github.com/stuartsierra/new-clojure-maven-plugin

15:53 Only 'compile' and 'eval' goals so far.

15:54 Currently trying to figure out if I can implement more of it in Clojure source code which get invoked as scripts from Java.

15:56 cemerick: stuartsierra: hugod experimented with building maven plugins using pure clojure a while back. Not sure it's suitable, but…

15:56 stuartsierra: I don't want any AOT-compiled Clojure code in the plugin, that's for sure.

15:57 But doing stuff like `binding` in Clojure source is certainly simpler.

15:59 chouser: "doing stuff...in Clojure source is certainly simpler."

16:00 TimMc: stuartsierra: Why not? (re: AOT)

16:13 cemerick: TimMc: because we want the same build of the clojure-maven-plugin to work with multiple versions of Clojure, and AOT compilation does not guarantee compatibility across releases.

16:47 TimMc: Ah, that makes sense.

16:47 Very good reason not to AOT.

16:56 mec: How might I define a custom toString for a record

16:57 Oh wow, I can just use Object

16:57 brehaut: (defrecord MyRec [] Object (toString [this] "foo"))

16:57 TimMc: mec: Do you need toString, or is changing the behavior for Clojure's print methods sufficient?

16:59 mec: This is so strange, i could have sworn defrecord, deftype, and reify only allowed protocols and interfaces

16:59 brehaut: mec and Object

16:59 mec: ya i see that now in all the docs

17:00 brehaut: mec: think about it: if you couldnt define a type that derived from object, there is no way you could produce native types on a jvm host

17:00 TimMc: brehaut: Hah, I never thought about that before.

17:00 clojurebot: I don't understand.

17:01 * TimMc pats clojurebot on the carapace

17:01 brehaut: mec: however, without knowing what your usage is, overriding tostring does seem a bit of a smell

17:03 TimMc: having said that, i wonder if Object as the root class is a property of the jvm or of javac; even if it were javac, it seems that clojure would still want to abide by it for interop reasons.

17:04 mec: ok reify says protocol-or-interface-or-object but (reify JPanel ...) says "IllegalArgumentException only interfaces are supported"

17:04 TimMc: I'm sure it's a JVM thing. Type erasure gives you an Object.

17:04 Also, I can't imagine the JVM supporting multiple hierarchy roots.

17:07 brehaut: TimMc: i suspect you are right, but i dont want to claim definite things in domain im quite a noob in

17:07 mec: ooo specifically Object not any object

17:19 __name__: Why does IPersistentSet have public Object get(Object key);?

17:24 hiredman: ,(.get #{'a} 'a)

17:24 clojurebot: a

17:27 __name__: hiredman: I don't understand the use.

17:27 hiredman: To use it as a dict that maps keys to itself.

17:28 danlarkin: that's how sets are implemented in clojure

17:32 dnolen: __name__: (aset key) is faster then contains?

17:33 __name__: $source aset

17:33 sexpbot: aset is http://is.gd/hxIvQT

17:33 amalloy: __name__: poorly-chosen name. he meant "some-set"

17:33 dnolen: __name__: i don't mean aset the fn, I mean like a-set

17:33 * __name__ nods.

17:33 __name__: Thank you, nice people of #clojure.

17:34 amalloy: &((juxt map filter) #{1 4 7 10} (range 10))

17:34 sexpbot: ⟹ [(nil 1 nil nil 4 nil nil 7 nil nil) (1 4 7)]

17:35 amalloy: you couldn't really do this kind of stuff as easily if all sets had were a contains? method and had to be treated differently from maps

17:36 __name__: I understand

17:38 mec: Is there any way to define the empty constructor of a defrecord or deftype

17:40 amalloy: no. why would you? that implies you either want mutable state (evil!) or plan to assoc keys in gradually - in which case you're losing the performance benefits of records over maps anyway

17:40 you can call (Myrec. nil nil nil) if it's a three-field record, but that has the same performance issues

17:42 akhudek: hey all, I'm encountering some very bizarre performance profiles in a project I'm working on

17:42 mec: more for default values

17:42 akhudek: in particular, VisualVM is claiming that the vast majority of the time is spent in clojure.lang.Keyword.hashCode

17:42 and clojure.lang.PersistentVector.count

17:43 but looking at the source, hashCode is just returning an int

17:43 and vector count should be a small constant time op too I would think

17:44 mec: are you making a lot of keywords or counting a lot of vectors?

17:45 akhudek: well, vector counts I could see happening

17:45 and I certainly do hash code lookups on keyword number pairs

17:45 but why these two constant time functions would be dominated over, say, actually adding to vectors or maps, is beyond me

17:46 I can't see any spurious tight loops around these functions, at any rate

17:47 dnolen: akhudek: adding anything anything to a collection will trigger a call to hashCode on the key.

17:49 akhudek: hm, interesting

17:50 I really wish VisualVM would show me the call stack

17:50 looking at naked function calls make it really difficult to figure out what's going on here

17:50 keyword.hashCode is at 44% of the runtime, and Vector.count is at 28%

17:51 Vector.createOwning is next at 5.5%

17:52 could a large enough vector perhaps cause a display like this I wonder?

17:52 dnolen: akhudek: if your code is mostly bashing away at a collection those numbers might not be surprising.

17:54 akhudek: Hmm, so I'm using the versioning on data structures in an odd way that may be the problem.

17:55 Essentially, consider a world state to be a big long vector.

17:55 Every time the vector is modified, a new world is created containing the new vector.

17:55 The worlds themselves are stored in a vector.

17:56 When worlds get into the high thousands, like 7-8k, then I'm observing a very, very, slow step size.

17:56 err step time rather

17:59 amalloy: why store the worlds in a vector instead of a list/cons chain? vectors are fast, but they do have some overhead; unless you're doing random-access it might be faster to use a list

18:00 akhudek: I do need random access.

18:00 This is in a formal logic prover.

18:00 And some worlds are "active" and moves are made on these.

18:01 the active worlds are not always exclusively at the end of the list either, mostly, but they can be interleaved with recently closed worlds.

18:01 but what I'm observing is some sort of quadratic slow down in speed

18:01 so something else is going on

18:02 for instance, I'd expect this if for some reason, it was visiting every item in every world on each step

18:03 I'm going to see if I can replicate the behaviour in a small example.

18:18 Geisteskrankh: ,(symbol "I worship your shadow")

18:18 clojurebot: I worship your shadow

18:18 Geisteskrankh: ,(symbol? (symbol "I worship your shadow"))

18:18 clojurebot: true

18:19 Geisteskrankh: ,(let [a-symbol (symbol "I worship your shadow")] (eval (list 'def a-symbol 3)))

18:19 clojurebot: DENIED

18:19 Geisteskrankh: =*

18:37 akhudek: wow, I can't replicate it

18:37 and this profiler is returning some wonky things

18:38 I did disable one part the prover and now it's supposedly spending 90% of it's time on Keyword.hashCode

18:38 that just doesn't make the slightest sense

18:40 I guess it must be not catching something

18:42 dnolen: akhudek: what you're seeing sounds odd. are you giving the JVM enough memory?

18:43 akhudek: it's using less than 80mb at the moment

18:43 dnolen: akhudek: the only time I've seen "quadratic" slowdowns is when the JVM is running of memory. Then you see crazy GC thrashing, and things get very slow.

18:43 akhudek: hm, I'll try bumping it just in case

18:43 dnolen: akhudek: Clojure is memory hungry, I rarely do anything w/o at least 512mb

18:44 akhudek: add multiple threads and you got start adding a lot more memory very quickly.

18:44 danlarkin: haha yeah 80m to the jvm is nothing

18:44 that's like the startup cost

18:49 Dantas: Hi everyone !!! Does anybody have a good link explain the clojure protocol ?

18:50 akhudek: http://min.us/lm9sVg

18:50 http://min.us/lm4WqI

18:53 Dantas: $google protocols

18:53 sexpbot: First out of 5780000 results is: Communications protocol - Wikipedia, the free encyclopedia

18:53 http://en.wikipedia.org/wiki/Communications_protocol

18:53 lancepantz: heh, yeah...

18:55 TimMc: I saw a video on clojure protocols recently...

18:55 dnolen: akhudek: interesting, what are the call counts?

18:56 TimMc: Dantas: http://vimeo.com/11236603

18:56 akhudek: good question, let me see if I can get it to count those

18:58 TimMc: Dantas: http://clojure.org/protocols also exists, but doesn't really motivate protocols inmy mind

18:59 akhudek: ah, I think I've found it, VisualVM "sampling" doesn't really work all that well, or rather always samples at some predictable time

18:59 doing an actual profile gives me different results

18:59 thanks!

19:00 mind you, a full profile is so slow I'll probably have to leave it here for a day to get useful results :/ such is life!

19:02 Dantas: TimMc: Thanks for the video !

19:02 TimMc: i found this article , http://www.ibm.com/developerworks/java/library/j-clojure-protocols/?ca=drs-

19:03 TimMc: seems to be nice !

19:28 ataggart: ,(into-array Byte/TYPE [1])

19:28 clojurebot: java.lang.IllegalArgumentException: argument type mismatch

19:29 ataggart: *clojure-version*

19:29 ,*clojure-version*

19:29 clojurebot: {:major 1, :minor 2, :incremental 0, :qualifier ""}

19:29 amalloy: &(into-array Byte/TYPE [(byte 1)])

19:29 sexpbot: ⟹ #<byte[] [B@f51e5b>

19:29 ataggart: thx

19:30 &(byte-array [1])

19:30 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte

19:30 ataggart: think that discrepancy is a bug, missing feature, or works-as-intended?

19:30 amalloy: discrepancy?

19:31 you mean the different error messages from byte-array and into-array?

19:31 ataggart: into-array will make a byte array out of a seq of longs, but byte-array won't

19:31 the former does a cast, the latter doesn't

19:31 amalloy: what? no it won't. you just tried doing it and saw it didn't work

19:32 &(byte-array [(byte 1)])

19:32 sexpbot: ⟹ #<byte[] [B@1ec452c>

19:32 amalloy: they both work under the same conditions: each element of the input vector is a Byte

19:32 ataggart: into-arrya owrks without explicit casting

19:33 amalloy: &(into-array Byte/TYPE [1])

19:33 sexpbot: java.lang.IllegalArgumentException: argument type mismatch

19:33 ataggart: &*clojure-version*

19:33 sexpbot: ⟹ {:major 1, :minor 2, :incremental 0, :qualifier ""}

19:33 amalloy: this does not look to me like working

19:33 ataggart: that's why

19:33 try 1.3

19:34 * amalloy is not going to go find another clojure version to test out a possible bug. if you're really excited about it you can gist a repl session

19:35 ataggart: yes, I'm not asking whether one works and one doesn't. I can see my terminal and look at the code for RT.seqToTypedArray. Just wanted input before I open the ticket

19:36 nevermind

19:36 dnolen: ataggart: does it work correctly in 1.3?

19:37 ataggart: in 1.3 into-array does not require explicit casting since RT.seqToTypedArray does a cast. Whereas byte-array throws a classcastexception because Numbers.byte_array just does a hard (Byte) cast.

19:38 dnolen: ataggart: so a 1.2 bug yes?

19:39 ataggart: With respect to casting, in 1.2 they both behave the same (an error), in 1.3 they behave differently.

19:40 I'm inclined to think they should both have the same behavior, and in 1.3 I think that means automatically casting

19:43 dnolen: ataggart: ah yeah, byte-array is broken.

19:43 unpleasant in 1.3

20:53 hiredman: meta data getting eval'ed twice? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L379

21:11 TimMc: hiredman: I was able to observe that in a 1.2 repl

21:12 (defn blah {:foo (println 5)} [x] x)

21:16 amalloy: hiredman: i asked a while ago on the mailing list about something that i think is related: http://groups.google.com/group/clojure/browse_thread/thread/09becb05362fb59c

21:19 but now looking more at your link i think it probably isn't

21:37 duncanm: does anybody know how to tell emacs to indent the body of proxys differently?

21:37 maybe i just need to update my clojure-mode

21:38 oh, amalloy has code in clojure-mode

21:38 hmm, i really should update

21:39 sigh, no updates from ELPA

21:41 amalloy: duncanm: elpa is for sissies. git pull

21:41 * amalloy relies on elpa for several packages, so feel free to ignore him

21:45 duncanm: heh

21:48 amalloy: do you know what i mean about proxy and its indent?

21:48 amalloy: duncanm: i don't use proxy much. i suspect technomancy will tell you that if you get the latest version and/or enable backtracking indent, it gets proxy right

21:49 duncanm: amalloy: https://gist.github.com/899147

21:49 so right now, i'm moving the arg list to its own line

21:50 amalloy: duncanm: c-h v clojure-mode-use-backtracking-indent

21:51 with latest from git, and backtracking on, i get the right indentation

21:51 duncanm: what's the convention for a non-nil value in elisp?

21:51 t?

21:51 clojurebot: We don't have the time.

21:51 TimMc: I believe so.

21:51 amalloy: t

21:52 or :holy-smokes-yes-please

21:52 duncanm: oh, awesome

21:56 amalloy: thanks for the tip

21:59 amalloy: duncanm: welcome! feel free to accept other tips such as git pull :)

22:00 sritchie: guys, I'm a little wary posting about this bizarre macro again, but i've got one tiny little issue that's eluding me, and would love input -- https://gist.github.com/899155

22:00 duncanm: amalloy: didn't even do that, just turned on backtracking-indent ;-P

22:01 amalloy: i know. i meant, in addition to turning that on feel free to git pull :P

22:01 duncanm: oh, i was wondering about the doto macro

22:01 amalloy: sritchie: s/example if/example of

22:01 duncanm: i changed the code already, but i think had trouble mixing methods and functions

22:02 sritchie: amalloy: thanks

22:02 * amalloy hopes that's all the advice you wanted

22:02 duncanm: something like (doto obj (.someMethod foo) (a-function bar)) didn't work as I expected

22:02 amalloy: duncanm: really?

22:02 duncanm: i thought that would turn into (do (.someMethod obj foo) (a-function obj bar))

22:02 i dunno

22:02 amalloy: ah

22:02 sritchie: amalloy: actually, I promise I'm going to come up with a better solution in production code

22:02 duncanm: i had some issue with it, and i routed around it

22:03 sritchie: but the problem is the when checkers is unrolled by the unquote spliced list comprehension, the vars inside of it aren't namespace qualified

22:03 amalloy: no, to get that you want (-> obj (doto (.someMethod foo) (a-function bar)))

22:03 duncanm: amalloy: oooh, that's a bit much

22:03 amalloy: er, i think my parens are wrong there

22:03 but it looks vaguely like that

22:04 i'm currently not-writing a blog post about how to combine doto and ->

22:04 duncanm: amalloy: oh great, that's basically it

22:04 i think i want a way to get (do (.someMethod obj foo) (a-function obj bar) obj)

22:04 and group all the objs together syntactically

22:05 oh wait

22:05 maybe that's the issue

22:05 my clojure functions are functions....

22:05 aha

22:05 sritchie: amalloy: so, since I have (defthreadfn phase-fn check-session), using (phase-fn [] first-form ..) will only compile in the namespace where check-session is declared

22:05 anyway, just a weird one, no problem if it's too bizarre for treatment

22:05 duncanm: so what i wrote first was kinda correct

22:05 amalloy: i get what you mean now

22:06 amalloy: maybe a super 'with' macro could be written that merges the features of both 'doto' and '->'

22:06 amalloy: sritchie: replace '~ with `~?

22:06 duncanm: that macro is called let :P

22:06 duncanm: haha

22:07 * amalloy is pretty sure his suggestion to sritchie doesn't make sense

22:08 sritchie: yeah, (defthreadfn phase-fn check-session) returns No such var: pallet.crate.hadoop/checkers

22:10 I'm doing a list comprehension on a collection of symbols, which is a problem -- would modifying the top-level let to include resolved-checkers (map resolve checkers) help?

22:10 amalloy: sritchie: i don't think you want to do that

22:11 then the user can't use any kind of checker except a top-level var

22:20 hugod: sritchie: should it just be ~checkers

22:22 amalloy: hugod: i don't think that will get it to resolve them. i'm not sure anything will do what he wants in every case

22:22 sritchie: that almost works, yeah, but then the macroexpansion tries to evaluate check-session with no arguments

22:23 amalloy: sritchie: ~(vec checkers) would do that

22:23 but it's not really going to work in general

22:26 sritchie: amalloy: that helped, now (phase-fn [] (+ 2)) expands with (#<hadoop$check_session pallet.crate.hadoop$check_session@1a86ddb> "subphase ... etc

22:26 I'm just getting loopy, I shouldn't be taking up time here with this

22:27 amalloy: yeah, i was about to retire. you're chasing unicorns here

22:27 sritchie: hugod had an idea for a different approach that's promising

22:27 I may shift all resources there

22:27 I'll let you know if I catch a unicorn

22:27 amalloy: heh

22:28 sritchie: I still like the idea of this! but this may be the point of monads, not special-case macro writing macros

22:29 amalloy: good idea

22:29 sritchie: that's hugod's. okay, time to catch a mythical creature

22:30 amalloy: thanks a lot

22:35 mec: anyone by chance have an emacs color theme like what is used on http://kotka.de/blog

22:35 sritchie: amalloy: actually, ~(vec checkers) works, for both top-level vars and functions passed in, defined on the fly

22:35 amalloy: neato

22:36 sritchie: thanks for the help, time to shelve this!

22:42 TimMc: technomancy: I still can't get retest working.

23:13 technomancy: Specifically, it keeps whining about not finding robert/hooke, even though I've tried that both as a dep and dev-dep.

23:33 technomancy: TimMc: you re-ran deps after adding hooke?

23:33 TimMc: yeah

23:34 technomancy: it's pretty clear about only spitting out that message if (resolve 'robert.hooke/add-hook) fails

23:34 and there's not really any way that could fail if hooke weren't on the classpath afaik

23:38 TimMc: OK, I've got [robert/hooke "1.1.0"] in deps, [lein-retest "1.0.0"] in dev-deps, and :hooks [leiningen.hooks.retest]

23:39 I do lein clean, deps, test

23:39 ...and I get the error.

23:40 Blowing away classes and lib doesn't help.

Logging service provided by n01se.net