#clojure log - Sep 24 2012

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

2:21 tomoj: amalloy: do you want a port of ordered in cljs, or should i

2:21 fork

2:22 I mean, do you want a cljs port in ordered, I guess

2:23 amalloy: i think i'd rather be a separate project, since none of us flatlanders do any cljs to speak of and shouldn't pretend to be maintaining it

2:24 tomoj: cool, thanks

2:28 bizarre, (read-string "#ordered/set (1 2 3)") works but #ordered/set (1 2 3) at the repl gives "Unable to resolve classname: IPersistentMap" at Compiler$HostExpr.tagToClass

2:28 ..at the swank repl

2:29 amalloy: probably the same problem REPLy has with reader tags

2:29 well, maybe not, since the swank repl should be in the same jvm

2:30 tomoj: saweet, clojure.data/diff on ordered sets returns ordered sets :D

4:53 clj_newb_234: holy shit, I just got webkit to embed in java in clojure

4:53 this is like equivalent to 24 hours of work

5:01 kral: namaste

5:02 qerub: Good morning.

5:10 scottj: clj_newb_234: so long as webkit is already installed on the system?

5:10 qerub: Could somebody give me a second opinion on http://dev.clojure.org/jira/browse/CLJ-1067? I'm note quite sure which semantics Stu is referring to.

5:31 amalloy: qerub: you answered your own question in the comment

5:32 the type of the thrown exception changes, so code that used to catch the old type of exception will now break

5:32 Sgeo: Maybe my problems with Eclipse+Counterclockwise are just not knowing how to use it properly?

5:32 My attempted usage was merely trying to expolore the UI, maybe that's ineffective?

5:37 qerub: amalloy: OK, that is what I guessed. Thanks for answering! Personally, I wouldn't mind breaking code (in a major release) relying on that Keyword.run throws UnsupportedOperationException because even if it is Runnable, it can never be run.

6:17 pisketti: Hi, is clojure.contrib.mock deprecated? (or how should I use it with clojure 1.3?)

6:18 http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go Doesn't list anything for it

6:18 clgv: pisketti: yeah. everything starting with clojure.contrib.* is ^^

6:18 pisketti: ;)

6:18 clgv: pisketti: there are builtin macros that enabled some mocking. `with-redefs` and such

6:19 pisketti: Let me rephrase. Where can I find the equivalent functionality now?

6:19 clgv: I know. I just would have liked to use the lib

6:20 So, what you are saying is that the whole mock lib is gone in 1.3?

6:20 clgv: pisketti: well, you can try to use it. you can copy that namespace and it might just run.

6:20 pisketti: well, I wouldn't like to go there

6:20 I guess I need to take a look at midje

6:21 I've been postponing that since I just wanted to get stuff done :)

6:22 If midje is compatible with my current test suite, that won't be a problem.

6:22 Well, thanks anyway

6:24 clgv: pisketti: well midje has some nice capabilities there too, which are more advanced than just mocking^^

7:45 powrtoc: hey ppl

7:46 Does nrepl support having multiple nrepl client buffers open?

8:54 MrDev: any core.logic wizards about? :)

8:54 http://stackoverflow.com/questions/12563351/listing-unique-dag-parents-with-core-logic

8:56 pandeiro: what would be the import statement to be able to use com.foo.Bar and com.foo.helpers.Baz w/o their full paths?

8:59 chouser: (ns ... (:import (com.foo Bar) (com.foo.helpers Baz))

9:00 clgv: MrDev: you could rewrite it to return the collection instead of single parents and impose a unique constraint on it

9:04 MrDev: or you need to build an analogon to a "visited state"

9:11 pandeiro: confusing trying to re-implement java code that uses factories in clojure... http://code.google.com/p/subethasmtp/wiki/SimpleExample

9:21 chouser: pandeiro: do you have that figured out?

9:21 clgv: I get "CompilerException java.lang.IllegalArgumentException: Cannot assign to non-mutable: comm," when trying (set! comm a) although I declared ^{:volatile-mutable true} comm in the deftype definition

9:25 chouser: clgv: this works for me: (deftype T [^:volatile-mutable x] clojure.lang.IDeref (deref [_] (set! x (inc x)) x))

9:26 clgv: chouser: it's nested some levels deep. I currently try to add the code incrementally until it blows up

9:26 pandeiro: chouser: could i show you what i got?

9:27 chouser: http://sprunge.us/IiSC - i am about to run it now

9:29 chouser: pandeiro: I think that will work. Will you need to pass a Factory instance to something else eventually?

9:30 pandeiro: chouser: honestly i don't know, i am at the very beginning of this, first time doing smtp, first time using a java lib like this

9:30 eventually i will need to parse multipart so i imagine it will become more complex

9:31 chouser: :-) ok. I would tend to recommend reify over defrecord in situations like this.

9:32 pandeiro: chouser: ok cool, i will re-implement w/ reify

9:32 getting a class cast exception too :)

9:32 fn can't be cast to MessageHandlerFactory

9:32 chouser: Yeah, so you'll need an actual Factory

9:33 pandeiro: having a tough time mapping that concept to clojure

9:33 i am a java ignoramus too which doesnt help

9:33 chouser: using defrecord or deftype you'll end up with a couple deftypes, and an ever-growing list of instance fields

9:33 reify lets you use what amount to closures

9:34 pandeiro: so the factory would use reify as well?

9:34 chouser: so you can do: (defn mk-factory [] (reify MessageHandlerFactory (create [_ ctx] (reify MessageHandler (from [_] ...)))))

9:35 right

9:35 pandeiro: ah wow

9:35 you can nest like that, brilliant

9:35 clgv: chouser: this blows up https://www.refheap.com/paste/5264

9:35 chouser: clgv: ooo, catch block.

9:36 notoriously tricky to get right in the Clojure compiler

9:38 clgv: since you've done the work of creating a minimal example, that may be worth filing a bug about. Until/if that gets changed, I suspect you'll need a work-around.

9:38 clgv: chouser: so what did I do wrong? it works without the final statement

9:40 chouser: https://www.refheap.com/paste/5265

9:40 chouser: you think it is a compiler bug?

9:40 chouser: Hm. I assumed so, but I'm surprised that second form compiles.

9:41 clgv: me too

9:41 chouser: Though it may be "unsupported" rather than a bug.

9:41 clgv: somehow it seems as if the metadata of the symbol gets lost

9:41 pandeiro: chouser: success! thanks a lot

9:41 chouser: pandeiro: ah good.

9:42 pandeiro: yes now for something beyond hello world :)

9:43 chouser: :-)

9:44 pandeiro: java version: 48 SLOC; clojure: 17 SLOC

9:44 rabbler: Anyone successfully run Overtone on OS X 10.8? My JVM crashes (both jdk 1.6 and 1.7) when it loads. Or is there a known issue?

9:54 patience: rabbler: Overtone kills the JVM when it has errors with the audio system. I don't know how else to help you.

9:55 rabbler: patience thanks for the response. I'll keep looking around. I'm probably doing something wrong. Perhaps I'll look for a demo and see if that runs.

9:56 patience: rabbler: I'm not too familiar with Mac, but I do have it running on my Arch machine with Jackd.

9:57 casion: overtone discussion?

9:57 clgv: chouser: http://dev.clojure.org/jira/browse/CLJ-1075

9:57 patience: rabbler: It could be some authentication problem, it could be that the version of overtone you're using is bad, or it could be the version of overtone is incompatible with the version of clojure

9:59 beffbernard: How would you use an existing HttpServlet in compojure?

10:01 rabbler: patience, at the moment, just doing (:use overtone.live) will crash the JVM.

10:02 so, I'm going to pass that up for the moment.

10:02 was trying to hack in something fun to the app, but I have already wasted enough time. Thanks for the info.

10:02 maleghast: beffbernard: I'm not even remotely aware of how you'd do that, but if you crack the nut I would love to know how you did it :-)

10:03 rabbler: patience, now that I have actually used google, I see there are some of the same errors, I'll poke around soon and check it out.

10:04 patience: rabbler: (-.-);

10:05 beffbernard: maleghast: there is a servlet-holder function in compojure.servlet.jetty but I want something that's container agnostic

10:05 rabbler: patience: google doesn't have human interaction though.

10:07 chouser: clgv: At macroexpand time, the environment still has the metadata

10:07 clgv: chouser: yep, I checked that

10:08 chouser: I rewrote that code. it seems to happen outside the catch as well

10:08 chouser: oh!

10:09 clgv: that's important. How do you get the error without a catch?

10:12 clgv: chouser: hmm implicit try-catch in a `locking` statement :(

10:13 chouser: ah

10:14 clgv: damn. only workaround is to implement it via an atom somehow.

10:15 chouser: you can probably add a method that sets the field, and call that method from your catch block

10:20 maleghast: beffbernard: I see… I think

10:21 beffbernard: Like I said, if you crack it I'd love to know, but in fairness you are talking at a levee I have yet to achieve with my Clojure / Compojure experimentation.

10:22 beffbernard: oops, levee = level ^^

10:22 octagon: hi, is there an example of tagged literals in clojurescript? i'm building my project using leiningen (lein-cljsbuild)

10:22 clgv: chouser: yes that seems to work

10:24 chouser: clgv: it might be nice to mention that in the ticket as well, for other people that stumble on to the same problem.

10:25 beffbernard: maleghast: I guess what we need is a servlet to ring handler function, but unfortunately it doesn't seem to exist

10:25 :S

10:25 pandeiro: anyone know the modern equivalent of clojure.contrib.java-utils/as-properties ?

10:26 clgv: chouser: ok. added

10:28 chouser: oh you added black voodoo ;)

10:29 chouser: but unhelpful :-P

10:30 clgv: chouser: so your intention was to add some noise so that the issue is perceived? ;)

10:30 casion: if I have a collection (atm likely a vector) that I want to pad to n items, what's the best way to go about that?

10:31 chouser: clgv: well, it seems like it could be helpful

10:31 noidi: casion, you could concatenate it with an infinite sequence of padding values and take n first

10:31 chouser: it shows that the metadata still exists on the binding inside the catch

10:31 noidi: ,(take 5 (concat [1 2 3] (repeat 0)))

10:32 clojurebot: (1 2 3 0 0)

10:32 casion: noidi: actually, I need to clarify then I think

10:32 I need functions to pad to front and back

10:32 clgv: chouser: right. I did a macroexpand with binding *print-dup* to true

10:32 chouser: oh, ok. That's all I'm doing

10:32 casion: it's the front padding that's primarily confounded me atm, at least an efficient method is

10:33 TimMc: Can the output be a seq, or does it need to be a vector?

10:33 casion: TimMc: I will need fast random access in the future, so right now I'm trying to keep it in a vector

10:35 jkkramer: ,(let [pad -1] (into (vec (repeat 5 pad)) [1 2 3]))

10:35 clojurebot: [-1 -1 -1 -1 -1 ...]

10:36 TimMc: &(-> (repeat 4 0) (into [1 2 3 4]) (into (repeat 4 0)))

10:36 lazybot: ⇒ (0 0 0 0 4 3 2 1 0 0 0 0)

10:36 TimMc: haha, whoops

10:36 casion: I'm taking in a stream of 1 to 5 byte chunks that I need to convert to a vector of chunks of then nearest java primitive width

10:36 TimMc: &(-> (vec (repeat 4 0)) (into [1 2 3 4]) (into (repeat 4 0)))

10:36 lazybot: ⇒ [0 0 0 0 1 2 3 4 0 0 0 0]

10:37 noidi: here's my take https://www.refheap.com/paste/5266

10:37 powrtoc: Does anyone know of any webgl frameworks that can be compiled with closure/clojurescript?

10:37 in advanced mode that is

10:37 casion: so say I encounter a 3byte chunk I need to pad it either right or left, depending on the endianness of the stream, to 4 bytes

10:38 1 byte to 2, 5 to 8

10:38 so with that information, maybe I'm approaching it wrongly? or not :)

10:40 noidi: casion, maybe that would be easier using this library https://github.com/preon/preon

10:40 powrtoc: Or a clojurescript API of the basic vector functions etc

10:41 noidi: or maybe there's a clojure library for parsing binary data

10:41 powrtoc: I mean matrix functions rather

10:41 casion: noidi: there's gloss too

10:42 the problem is that even with gloss or preon, I stlii have to sanitize the stream's goofy 3 and 5 byte chunks

10:42 at least as far as I've figured I do, maybe I'm missing functionality somewhere

10:43 noidi: your code gave me an idea though I think, thanks

10:52 djanatyn: is there any way to have lein use ecj.jar instead of the JDK?

10:52 grettke: Question: Anyone using Clojure or nREPL with JRebel?

10:52 djanatyn: I'm using lein2, and I added :java-source-paths to my project.clj. I want to be able to play with my java code from clojure, with nrepl.

10:53 however, I don't have the JDK installed on my computer. I can still compile java files with ecj.jar; is lein2 just looking for javac?

10:54 chouser: djanatyn: it appears to be using (ToolProvider/getSystemJavaCompiler)

10:57 djanatyn: chouser: thanks! I'll mess around and see if I can get anything working

11:00 looks like it wants the JDK specifically, and getting it working with ecj.jar would not be easy :\

11:43 saml: hey, is clojure-conj.org good conference to attend?

11:51 nDuff: saml: Yes, the conj is well worth attending.

11:52 saml: are you coming?

11:53 nDuff: Not this time.

11:53 * nDuff has been spending his limited PTO meeting the fiancee's family and taking her to meet his.

11:53 nDuff: ...if it weren't for the personal-life stuff going on, though, I certainly would.

11:56 saml: congrats nDuff

11:58 nDuff: saml: Thanks. :)

11:59 duck11231: can you still get tickets to the conj?

11:59 looks like you can, but $550

12:00 nDuff: Ouch -- that's a pretty steep delta from the early-bird price.

12:03 duck11231: one of these years I'll be able to go

12:03 maybe I should start setting $ aside for the next

12:03 chouser: yeah, it simplifies their planning to have people committed early, I think, so they reward that a lot.

12:03 TimMc: I could probably justify the early-bird price ot myself if it were no farther away from the Boston area than, say, NYC.

12:04 Although, if we didn't have an active Clojure meetup group here I'd be a lot more willing to travel. :-P

12:05 holo: hi!

12:06 where is the new address of shell-out, which was living in contrib?

12:06 saml: if i know almost 0 clojure, would conj be useful at all?

12:06 duck11231: you'd know a lot more by time it was done

12:07 uvtc: holo: I'm not familiar with shell-out, but if you want to ... shell out, there's clojure.java.shell, or else conch.

12:08 scottj: saml: well you have time to learn quite a bit before it. but no, if you don't know any I don't think it would be worth it

12:08 saml: i just want to spend company money to go to a useful conference

12:08 before the end of year :P

12:09 scottj: saml: in that case sure :)

12:09 nDuff: saml: ...well, there's training before the conference, if there's still an opening, but that's _quite a lot_ of company money

12:09 saml: :P

12:09 nDuff: saml: ...but the training *does* start pretty basic -- at least, when I took it, it seemed like a fair bit of review.

12:10 holo: uvtc, any of them don't fork to a new process?

12:10 nDuff: holo: How would you do that without forking?

12:10 holo: uvtc, i mean, forking and not leaving

12:10 nDuff: holo: I mean, if you didn't fork, you'd be doing an exec, which would terminate your process

12:10 ..."forking and not leaving", meaning doing a wait()?

12:11 holo: nDuff, don't know what the wait() do, but i don't want the new forked process to be dettached from the terminal

12:11 uvtc: holo: I'm using clojure.java.shell at the moment, and although it uses futures internally for some purpose, it seems to block until the shell finishes what it's doing.

12:12 duck11231: pallet has pallet.shell (or it did, last I used it) that worked pretty well for me

12:12 holo: uvtc, will try again. just a second. and thanks duck11231

12:13 uvtc: holo: Y'know, I haven't tried backgrounding a process that gets started by clojure.java.shell/sh ...

12:14 holo: uvtc, in my situation it would be undesirable that it would be backgrounded

12:14 hugod: there is also https://github.com/raynes/conch - I heven't tried it

12:15 uvtc: holo: Ha. Sorry, I read your message to nDuff incorrectly. :)

12:15 clgv: "conch" works pretty good. used it for interop with "R"

12:15 hugod: pallet is rather a large dependency to just get pallet.shell - I could split it out if there is interest

12:16 duck11231: I can't even seem to find that ns anymore

12:17 hugod: duck11231: it's there on the support/0.7.x branch

12:18 * nDuff likes conch, but doesn't know if it has an option to avoid redirecting the FDs, which is what holo wants.

12:18 nDuff: ...conch _does_ have helpers to copy content coming out of the redirected FDs to stdout

12:18 which at least makes it *look* like what holo wants

12:18 even if it isn't really. :)

12:19 holo: ...so it might be worth deciding _why_ you want what you want, and if having the code copy between the stdin/stdout pipes and real stdin/stdout is good enough.

12:21 pandeiro: is there a way to combine several predicates that operate on the same value into one function call? besides writing another helper fn with (and ...)?

12:22 jkkramer: pandeiro: every-pred

12:23 pandeiro: jkkramer: thanks

12:30 holo: uvtc, i type (shell/sh "bash") and it returns to the repl prompt outputing {:exit 0, :out "", :err ""} . i guess this isn't what i want

12:31 uvtc: holo: that means it ran the `bash` command for you, then returned. I guess bash exited since you didn't have anything for it to do. :)

12:31 holo: nDuff, i want be redirected to the prompt of the new process, so that i can insert commands, and see command output

12:32 uvtc, yeah, it seems so. but maybe i have something for it to do some seconds after

12:33 uvtc: holo: Right. Don't think I can help you there. I see that you want to run a bash shell from your Clojure program.

12:33 nDuff: holo: May I, out of curiosity, ask what you're working on? The projects where I need to do that kind of thing and the projects I use Clojure for don't tend to overlap much.

12:35 holo: ...given as Java's Runtime.exec() doesn't appear to let you specify that you don't want a redirection, it may not even be possible.

12:35 holo: nDuff, i need to automate the process of logging into a postgres shell

12:35 nDuff: (well, not without hackery that would prevent stdout from being a tty)

12:36 ...why use Clojure for that?

12:36 The psql command-line tool definitely works better when connected to a tty

12:36 holo: nDuff, because the process is complicated enough to go and learn bash. i hate bash, thus i prefer to spend my time writting gorgeous clojure code

12:37 * nDuff wouldn't use bash for this either (and he's a #bash regular)

12:37 nDuff: ...well, actually, it depends on just _why_ it's complicated

12:37 clgv: holo: if you want to write to and read from the process you should use "conch"

12:37 nDuff: and you haven't explained the details. But if you actually need to emulate a TTY, that leaves you with the TCL expect, Python's pexpect, or some other equivalent.

12:38 holo: i will explain the details

12:41 i have an heroku .env with a DATABASE_ENV development postgres db that change according to each developer. i want to extract that url and run a psql with it's paramaters. this is a script, but the resulting paramater map is also useful for a project

12:41 the script is already doing it's job, except that the process leaves

12:42 uvtc, thank you for your time and help

12:43 nDuff: Doesn't sound like there'd be anything complicated about doing this in bash.

12:44 ...happy to help you with that in #bash

12:45 holo: nDuff, i'm not a bash regular. i already coded it. i wouldn't dare to ask you to waste time in this again :) i'm going to try conch first like clgv suggested

12:46 nDuff: conch is great, but it has the same limitations that everything using java's Runtime.exec() does

12:46 ...and it sounds like those aren't what you want

12:46 but... *shrug*.

12:49 holo: nDuff, but in conch webpage it says "clojure.java.shell is designed to produce quick one-off processes. There is no way to interact with a running process over time. I've found myself needing to shell out and stream the output of an external process to things in real time and I wasn't able to do that with clojure.java.shell." isn't it the same i want?

12:49 nDuff: holo: conch lets you interact with the subprocesses _from your Java code_

12:50 holo: You want to interact with the subprocesses _from the console_

12:50 holo: nDuff, oh that sucks then :)

12:50 uvtc: nDuff: good distinction.

12:50 technomancy: holo: the JVM doesn't support interactive subprocesses. its process handling API is kind of a joke.

12:52 uvtc: Do the various conferences (Clojure/West, Strangeloop, and Clojure/Conj) usually happen on about the same date each year, respectively?

12:52 Also, I reserve the right to just tack on "respectively" to the end of any complicated sentence and expect the reader to figure out what I mean. :)

12:52 clojurebot: Equal Rights for Functional Objects is Baker's paper on equality and why it's impossible to define sensible equality in the presence of mutable data structures: http://www.pipeline.com/~hbaker1/ObjectIdentity.html

12:53 uvtc: clojurebot, you are a bot among bots.

12:53 clojurebot: thanks; that was delicious. (nom nom nom)

12:54 holo: i feel like whining :o

12:57 duck11231: I wonder if you could build something with lamina to pipe channels to the in/out of a process like that

13:00 clgv: does someone have an idea how I can make a socket to throw on a write attempt if the remote socket was closed? it doesnt seem to work on first write attempt but on the second

13:07 ignacio: @holo: can you used named pipes to communicate with the process?

13:07 Cheiron: Hi, with Compojure. how to access path query for a URI such as? /tickets/users/:user-id/:ticket-id?page=1

13:08 weavejester: Cheiron: (GET "/tickets/users/:user-id/:ticket-id" [user-id ticket-id page] …)

13:08 The parameters are taken from the :params key on the request map

13:09 Which includes both parameters in the route, and in the query string

13:09 Cheiron: weavejester: Oh Cool. Any experience with Liberator?

13:09 weavejester: Naturally there's also keys for :route-params, :query-params, :form-params when you need more precision about where things come from.

13:10 Cheiron: Unfortunately not. I've been meaning to take a closer look at it, but there are too many keys for my liking.

13:10 Cheiron: page query parameter is optional. it might exist and it might not. in this case, the vector [user-id ticket-id page] still valid?

13:14 holo: duck11231, ignacio, will look more into your suggestions

13:20 jro__: how do I set ring route to respond HEAD-requests properly, when resource is not found. Not it throws NPE in at clojure.lang.RT.intCast(RT.java:1065) ~[clojure-1.3.0.jar:na] at aleph.http.core$ring_map__GT_netty_response.invoke(core.clj:341)

13:20 weavejester: Cheiron: Yep. page will just be nil if it's not there

13:21 jro__: I mean compojure, HEAD with existing resources works perfectly with (compojure.route/resources "/")

13:21 weavejester: jro__: There's some middleware called wrap-head to do this. The latest Compojure should add it by default to any routes.

13:22 Cheiron: weavejester? what about these URIs? /pages/:id /pages/:id?AddAt=:pos /pages/:id/?append

13:23 weavejester: Cheiron: What about them?

13:24 Cheiron: how to declare the mapping and the vector of params for them ? after :id it might be ?AddAt=:pos or ?append . both of /pages/:id?AddAt=:pos /pages/:id/?append should accept POST

13:25 ignacio: @holo: how much interactivity do you need?

13:26 weavejester: Cheiron: Well the parameter names are AddAt and append

13:27 langmartin: I'm experimenting with building functions from runtime data, and it'd be sweet if I could name the generated functions. I'd rather not use eval, and I don't have the function names available at syntax time... is it possible to decorate functions with meta data so that a stack trace can return a meaningful name for a function created at runtime?

13:29 nDuff: Creating functions is by definition something that happens either at compile time or when using eval

13:29 Cheiron: weavejester: sorry not following

13:30 langmartin: nDuff: (defn [x] (fn [] x))

13:30 nDuff: langmartin: yes, but the function is created at compile time, even then

13:31 it's just _returned_ at runtime.

13:31 weavejester: Cheiron: Well, you have access to the query string, and the map of parsed parameters

13:31 Cheiron: So I'm not seeing why you think changing the name of the parameter makes it different?

13:32 langmartin: nDuff: even though it's closed over different values of x?

13:32 weavejester: Cheiron: So for AddAt: (GET "/" [AddAt] …)

13:32 nDuff: langmartin: There's no recompilation involved in that.

13:32 weavejester: Cheiron: Although you might want to access the parameter map directly

13:32 Cheiron: (GET "/" {params :params} …)

13:33 Cheiron: weavejester: so in my case, the URI mapping should only be /pages/:id only I guess. AddTo=:pos at a page to a specific position. append will add a page

13:33 langmartin: nDuff: fine, but I get distinct objects iwth different values, which is fine

13:33 nDuff: Yup.

13:33 langmartin: I want to say (defn [x] (with-meta (fn [] x) {:name "foo"}))

13:33 and have that inner function use it's name when it breaks

13:33 nDuff: they're distinct objects, but the class names aren't going to differ

13:33 weavejester: Cheiron: ?append isn't a valid query parameter, by the way. It won't be encoded in the query parameter map, but will be accessible via the query string itself.

13:34 nDuff: see distinction between compile-time and runtime metadata

13:34 weavejester: Cheiron: But I'm not really seeing what you want. Are you trying to interface with a legacy system? Is that the reason for the strange query parameters?

13:35 Cheiron: weavejester: yes

13:35 as I said. /pages/:id?AddTo=:pos to set a page at specific index via POST. /pages/:id?append to add a new page via POST

13:36 weavejester: do you suggest a better URI design?

13:36 langmartin: nDuff: fn itself uses with-meta to set the name of the generated function if it's provided, you're saying that with-meta does different things at compile-time (flattens it into a java class thing) then at runtime (stashes it in a map)

13:37 nDuff: langmartin: with-meta can't be used for compile-time metadata at all.

13:37 weavejester: Cheiron: Well, you can use that, but it's a bad design.

13:37 Cheiron: Hang on, phone...

13:37 jro__: weavejester: thanks, adding wrap-head solved the problem

13:37 holo: ignacio i need to insert commands from the keyboard, and read output from the terminal

13:37 langmartin: nDuff: what's it doing in the definition of fn then?

13:37 Cheiron: weavejester: ok :)

13:38 weavejester: Cheiron: You know that Ring requests are maps right, and Compojure routes are functions that return nil or a response map?

13:38 Cheiron: yes

13:38 nDuff: Hmm. I'm probably wrong somewhere, then.

13:38 (still can't do what you're trying without an eval somewhere, though)

13:39 Cheiron: weavejester: yep i know

13:39 weavejester: Cheiron: So: (GET "/" {q :query-params} (if (= (q "AddTo") ":get") …))

13:39 pandeiro: i have this nagging feeling i should not be implementing multipart email parsing

13:39 weavejester: Cheiron: The if-statement will return nil if the parameter isn't there, and the route will then cascade

13:40 Cheiron: weavejester: hmmm. actually I'm using Liberator REST toolkit that uses Compojure as the router. i need figure out how to do what you are suggesting

13:40 nDuff: langmartin: ...okay, straightened things out: with-meta can be used to attach metadata to symbols that are used during compilation and then thrown away.

13:40 weavejester: Cheiron: hang on...

13:41 nDuff: langmartin: Attaching name metadata to the fn won't do any good -- it's already compiled at that point.

13:41 Cheiron: weavejester: okidokie

13:41 nDuff: ...now, you can use eval to compile at runtime...

13:41 ...but you're stating that you don't want to do that.

13:42 langmartin: ok, well it's fine

13:42 I just wanted it for the stack trace

13:43 and it looked like the namespace resolver went through enough of a trampoline kind of thing that it might still do a dynamic name lookup

13:43 thanks for the help, nDuff

13:44 weavejester: Cheiron: Liberator doesn't replace Compojure routing

13:46 Cheiron: weavejester: no it is not. I hope i'm not wrong but i said Liberator is using Compojure as the router. but not really digesting (GET "/" {q :query-params} (if (= (q "AddTo") ":get") …))

13:47 weavejester: Cheiron: Hm, oh, I see. Liberator supplies handling of GET and POST

13:47 Cheiron: In which case, I think you might be using the wrong tool

13:47 Cheiron: weavejester: yes exactly

13:47 weavejester: Cheiron: Liberator is designed for creating RESTful web services

13:47 Cheiron: And you look like you want to create a non-RESTful web service for a legacy client

13:47 Cheiron: weavejester: that is what I'm doing

13:48 weavejester: hmmm. actually I'm trying to create a REST API

13:48 weavejester: Cheiron: The routes you've supplied aren't really RESTful though...

13:49 Cheiron: weavejester: i have the permission to change the URIs. do you suggest a better design for the three previous URIs?

13:50 weavejester: Cheiron: Well, let me get a sense of the problem. It's possible I don't understand and I'm giving bad advice :)

13:50 Cheiron: i will paste at pastie, just a minute

13:50 weavejester: Cheiron: Okay :)

13:53 Cheiron: weavejester: thanks a lot! http://pastie.org/4792355

13:54 weavejester: maybe AddAt and append should be prefixed with " : " ?

13:56 weavejester: Cheiron: When you add a page to the book at a specified index, will it replace the page there, or shift all pages after up a space?

13:56 Cheiron: weavejester: replace it

13:58 weavejester: Cheiron: Okay, so in HTTP, when you want to overwrite a resource, that's usually a PUT, and when you want to add a new resource, that's a POST.

13:59 Cheiron: weavejester: true

13:59 weavejester: Cheiron: Or to be slightly more accurate, a PUT is when you know the index of the item you want to write to, and a POST is when you want to create a new element with a generated index

14:00 Cheiron: So I'd have written it more like: http://pastie.org/4792383

14:00 Cheiron: The PUT is used to overwrite a page, and the POST is used to create a new page.

14:00 ro_st: weavejester: how do i know what env my ring app is in, from within that ring app? using lein2 and noir

14:01 i'm inspecting the output of (System/getenv) but nothing's standing out

14:01 ignacio: @holo: i'm not advocating this as the best solution to your problem at a high level

14:01 but i think you can do what you want by doing something like

14:01 weavejester: ro_st: You don't really have environments in Ring. I guess you're asking this from the Lein-Ring docs? They're not very clear on the subject of environments.

14:01 Cheiron: weavejester: a lot neater ! thanks a lot !

14:02 ignacio: (sh "bash -c "psql < in.cmd > out.cmd")

14:02 (sh "bash -c \"psql < in.cmd > out.cmd\"")

14:02 ro_st: weavejester: i suppose i could just use my own env var and be done with it

14:02 ignacio: where in.cmd and out.cmd are pipes made with mkfifo

14:02 ro_st: thought perhaps ring/noir had some notion of environments built in

14:03 weavejester: ro_st: Nope. My advice is to not use environments, as in, don't have a single string that defines how your app acts.

14:03 ro_st: yeah. better to use specific configuration to drive specific behaviour

14:03 weavejester: ro_st: Right :)

14:04 ro_st: Have you come across Environ?

14:04 ro_st: i have yes, thank you

14:04 weavejester: ro_st: That's what I use along with Lein2 profiles

14:05 ro_st: my particular use-case is actually just a stop-gap until we have user profiles with admin rights up: staff-mode

14:07 weavejester: ro_st: Perhaps something just like, :profiles {:dev {:env {:staff-mode true}}} ?

14:07 ro_st: yup. that's pretty much what i've just done

14:08 question. if i uberjar or uberwar a lein project, does running that project as a jar with lein2 still use profiles.clj?

14:09 ie, could i use profiles.clj to manage production configuration

14:18 weavejester: ro_st: If you run it with Lein2, then yes… but not if you create it with Lein2, and then run it directly.

14:18 ro_st: cool. we're using lein trampoline, i believe

14:19 we aren't using jars yet; we just run from disk for the moment. i just want to check we aren't painting ourselves into a corner down the line

15:37 QUACKALPACATRON: ##(symbol? (symbol "I worship his Shadow"))

15:37 lazybot: ⇒ true

15:37 QUACKALPACATRON: Chousuke, fix that

15:48 Negdayen: I have a list of interwoven data, ( x y z c a x y z c a....). I would like to deinterlace into two lists ( x y z x y z x y z....) and ( c a c a c a c a ). I have a couple ideas that seem pretty sloppy (re: imperative). Is there a recommend approach or helpful function(s) for such a scenario?

15:50 romain_p_: Negdayen: partition-by?

15:51 amalloy: depends whether you intend to tell the items apart by value or by index, which your example doesn't make clear

15:53 Negdayen: the values will be fairly random, I know before-hand that it will be 3 values of group a, then 2 values of group b, repeated.

15:53 romain_p_: nI think partition-by might do the trick, thank you.

15:54 Raynes: I don't think partition-by is what you want.

15:56 Negdayen: Hmmm, yes, I suppose not--seems like that is better for when I can tell items apart by value as amalloy alluded to.

16:09 Raynes: Negdayen: https://www.refheap.com/paste/5271 is what I came up.

16:10 amalloy: Raynes: doesn't that return [[x y z] [a b] [x y z]] rather than [[x y z x y z] [a b]]?

16:11 Raynes: Well, yeah.

16:11 But hey, it's half way there.

16:12 amalloy: anyway, it's a tough problem, because a lazy solution is impossible

16:13 Negdayen: Raynes: Ah, that looks quite awesome. Thanks! I was just about to search for a split-at like function.

16:17 Raynes: https://www.refheap.com/paste/5272

16:17 Sequence manipulation after a good night's lack of sleep.

16:21 eduard_: Negdayen, Raynes: my try - https://www.refheap.com/paste/5273

16:23 Raynes: Nice. I just hate multi-value reduce accumulators.

16:23 They never occur to me because I hate how the base accumulator looks.

16:24 Negdayen: Lol, jealous of the mad list manipulation skills. I got a ways to go from my java'ish ways :-P.

16:25 Raynes: eduard_, Negdayen: https://www.refheap.com/paste/5274 formatted version of eduard_'s reduce.

16:25 Both of our solutions are around the same length. His has the benefit of being a self-contained reduce.

16:27 You'll still want to wrap that in a function if you use it though, which is why they're around the same length.

16:28 eduard_: can into changed to zip?

16:29 also it's possible to write ->> z (partition 5) (map #(split-at 3 %))

16:29 pandeiro: how do i best go from input stream to byte array?

16:34 TimMc: amalloy: The question is really *how* lazy you want it to be.

16:34 A partly lazy solution is no trouble.

16:54 amalloy: TimMc: ?

16:54 i would like to see what a partly lazy solution looks like

17:01 TimMc: amalloy: As in, you don't believe it's possible, or you're just curious to see it?

17:01 pingtimeout: Hi #Clojure

17:01 TimMc: I'm not bored enough today to actually write it, you see.

17:08 amalloy: Here's a (more complicated) example of a function that produces a lazy seq of lazy seqs by splitting an input collection: https://github.com/timmc/rand/blob/master/src/rand/core.clj

17:09 thorbjornDX: Hi. I'd like to do map destructuring within a for binding something like this: (for [d seq-of-maps {:keys [a b c]} d] [a b c]), am I doing something wrong?

17:09 hiredman: yes

17:09 you are trying to destructure each key/value pair of the map

17:10 thorbjornDX: hiredman: I don't quite follow

17:10 hiredman: d is being bound to the map right?

17:10 thorbjornDX: correct

17:10 hiredman: destructuring replaces the binding correct?

17:11 ,(for [a [{:foo 1}] b a] b)

17:11 clojurebot: ([:foo 1])

17:11 hiredman: ,(for [a [{:foo 1}]] a)

17:11 clojurebot: ({:foo 1})

17:12 hiredman: each binding in a for presumes it is being bound to an element at a time to a seq

17:12 TimMc: thorbjornDX: You're thinking of the second for clause as if it is a let clause, and it isn't.

17:12 thorbjornDX: ohhh, I follow now, it's treating 'd as a seq

17:13 so to do something like this, I would have to do (for [d seq-of-maps, a (:a d), b(:b d)..., correct?

17:15 amalloy: TimMc: the prefix? function appears to be making each partition eager, right, just like partition-by and friends?

17:15 thorbjornDX: er, actually, I'm not sure if this will work like I want it to. I would like to use an element of the d map as one of the bindings of the 'for', but that binding will only happen once on the first entry in 'seq-of-maps'.

17:19 hiredman: er, maybe I can do this: ##(for [d [{:a [1 2 3]} {:a [4 5 6]}] s (d :a)] [d s])

17:19 lazybot: ⇒ ([{:a [1 2 3]} 1] [{:a [1 2 3]} 2] [{:a [1 2 3]} 3] [{:a [4 5 6]} 4] [{:a [4 5 6]} 5] [{:a [4 5 6]} 6])

17:20 TimMc: amalloy: Only eager in the length of the splitting subsequence.

17:22 e.g. if you are splitting (range) at the subsequence [5 6 7] and then ask for the second element, you have realized this much: ((0 1 2 3 4) (7 8 ...))

17:22 I might be off by one, of course.

17:22 sam__: where's conj 2012 schedule?

17:37 TimMc: amalloy: Looks lazy in the subsequences: https://www.refheap.com/paste/5275

17:49 amalloy: TimMc: you should use rest rather than next here, so you don't realize 7 as part of (first b)

17:53 austinh: What is the secret to getting helpful stacktraces while developing a Ring app?

17:54 wrap-stacktrace rarely helps at all, and often doesn't print anything at all in my SLIME repl.

17:54 I'm getting the impression the Jetty adapter is also catching some exceptions; I'd love to be able to disable that, if that is the case.

17:55 TimMc: amalloy: All instances of next?

18:01 Hmm, that breaks it for sure.

18:05 amalloy: TimMc: no, certainly you can't change the ones in prefix?

18:06 i meant in split-at-subs, and maybe also collapse-subs

18:11 TimMc: Mmm, I think I can do it in prefix? if I change nil? to empty?.

18:11 not that it matters for the 'sub loop var

18:30 nkoza: if I destructure in this way: (let [{:as p} [1 2 3 4]] p) I get [1 2 3 4] as expected, but if I do (let [{:as p} '(1 2 3 4)] p) I get a map, {1 2, 3 4}. Why? I thought :as always bound to the entire init-expr (as the documentation states)

18:34 casion: ,(let [[:as p] '(1 2 3 4)] p)

18:34 clojurebot: (1 2 3 4)

18:35 casion: interesting

18:36 nkoza: I'm seeing some code that depends on this (undocumented?) behaviour, so I thought it was a common Clojure idiom

18:37 casion: the documentation could be more clear, but it does seem to indicate that {} will be a map-binding

18:37 and [] is a sequential binding

18:38 emezeske: I think maybe a hint as to what's going on is that [] is an associative structure (indexes as keys) and '() is not

18:38 nkoza: but in the map-binding part it says "an :as key in the binding form followed by a symbol will cause that symbol to be bound to the entire init-expr", you can derive the [] and '() different behaviour from that sentence :)

18:39 casion: nkoza: read a few sentences back

18:39 I think you're taking that out of context

18:39 not that the context is particularly clear anyway :|

18:41 nkoza: Is not clear in the documentation what the map-destructuring does when init-expr is not associative

18:43 emezeske: nkoza: It looks like it converts init-expr to an associative structure

18:44 nkoza: emezeske: yes, and the binding to :as is done after that conversion, thats the undocumented behaviour

18:44 ,(let [{x :b} '(:a 1 :b 2)] x)

18:44 clojurebot: 2

18:45 emezeske: It's possible that the behavior is not defined because you're not supposed to use non-associative init-exprs with the map destructuring

18:46 (I agree that it would be cool to mention that or throw an exception)

18:54 SrPx: Hey guys, I have a task in which I must paste several thousands of pages of data from some files in some forms of a site, no other way to do it. Is there a Clojure library or something that allows me to open a site programatically, insert information in a form and click send? (Just sending requests won't work, they do some magic with the typed text.)

18:57 zoldar: SrPx: A short search gave me this: https://github.com/semperos/clj-webdriver

19:02 SrPx: zolder: thanks. Might I ask what did you search for?

19:03 zoldar: SrPx: for Selenium wrapper in clojure

19:06 SrPx: I am trying to understand what *exactly* is that selenium but the thing looks huge from the site. Anyway thank you, this is probably what Im looking for. zoldar

19:07 antares_: SrPx: browser testing automation tool

19:07 nDuff: SrPx: ...yes, it's huge, but it's also about what you're looking for -- a toolkit for automating actions taken by web browsers.

19:08 SrPx: I've got that, but what exactly? It's a tool that finds a browser open and interacts with it? Or a tool that opens the site internally in your favorite language and you can manipulate the browser with functions and such?

19:08 (if it is exactly like the clojure wrapper I've got it, and yes, that's what I need and is awesome!)

19:09 frio: there are multiple ways to drive selenium

19:10 you can click through a site while it records, and the browser plugins can replay it

19:10 you can also script it via the WebDriver (i think it's called)

19:10 which integrates better with your build servers/solutions, but is also (we've found) quite janky

19:15 SrPx: frio: ok, I see. It is huge.

19:15 frio: yep, massive

19:16 ive had more success splitting my Javascript out properly, and then using tools like phantom/jasmine to unit test the functions I can (leaving the UI glue untested, for now)

19:16 but i've not had to make any UIs of significant complexity either

19:56 holo: goodnights

19:56 there are more and more users on this channel

19:56 austinh: For the record, my weak stacktraces in Ring were caused by this clj-stacktrace bug: https://github.com/mmcgrana/clj-stacktrace/issues/14

20:45 justicefries: is Joy of Clojure still relevant or is it dated compared to programming clojure / clojure programming?

20:45 whichs eem to be the most recent books

20:46 brehaut: JoC isnt really a 'heres the standard lib, and how you use it'

20:47 kind of book

20:47 so its still good IMO

20:52 holo: maybe the books should also come with a git repository, and constant updates

20:53 each commit would have an update cost. doing pull would cost the sum of all the commits

20:54 justicefries: not a bad idea really

20:54 that's good to know, brehaut

21:55 casion: I have a java array that I want to take a range of and end up with a vector, does it make more sense to use .copyOfRange and then vec, or vec then subvec?

21:57 amalloy: (vec (for [i (range start stop)] (aget arr i)))?

21:58 casion: would that be more idiomatic?

21:58 amalloy: *shrug*

21:58 casion: seems like there's a dozen ways to do it

22:22 holo: my stock clojure from macports gets all excited Exception in thread "main" java.lang.NoClassDefFoundError: projs/app, whenever he is executed near a project.clj (like grandparent dir). did it happen to any of you?

22:24 arohner: holo: don't use clojure from macports. Just install lein

23:01 holo: arohner, i just wanted to run a clojure script.. using lein for that?

23:11 Raynes: That Clojure 'script' likely depends on other code. If it has a project.clj, you're going to want leiningen. You're always going to want leiningen. In that brief moment when you think you don't want leiningen, you definitely want leiningen.

23:13 clj_newb_2345: given a string, what is the correct way to 0 pad it?

23:29 eggsby: clj_newb_2345: (format "%03" n)

23:29 clj_newb_2345: eggsby: nice, thanks

23:31 eggsby: oops, %03d or %.3f, same as printf

23:40 holo: yeah, they are fiends from hell.. ants, nothing but ants -.-

Logging service provided by n01se.net