#clojure log - Mar 31 2013

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

0:25 olivergeorge: Hello. I'm learning about zippers and parsing html. I can see that the xml zipper lets me go up but it seems like enlive doesn't do that.

0:26 Am I missing something?

0:26 My use case is scraping ugly HTML

0:29 This is an example of scraping the Hacker News homepage:

0:29 https://github.com/swannodette/enlive-tutorial/blob/master/src/tutorial/scrape1.clj

0:30 It does two independent selects, one for titles and one for points. I'd like to be able to do both at once which means finding one and then navigating (up, right, down… or similar) to the other.

1:06 muhoo: i'm confused ny (listen! (by-id "submit") :click (fn [e] (validate-form e))))) in the modern cljs tutorial

1:06 why thr anonymous fn?

1:07 why not just pass validate-form? it only tskes one arg, the evt, anyway!

1:07 tomoj: no reason

1:08 maybe an oversight, maybe they wanted to show explicitly that the function receives a single event param?

1:09 muhoo: huh. weird. seems jarring to me

1:15 tieTYT2: I'd like to be able to rewrite this function named cookie-spec here: https://github.com/dakrone/clj-http/blob/master/src/clj_http/cookies.clj

1:16 but it's defined with defn-

1:16 can I do this with a with-redefs?

1:19 muhoo: sounds monkey-patchy to me, reaching into some other ns and refefining private vars

1:20 i'm sure it's possible,but this ain't ruby

1:20 tieTYT2: exactly, i'm fixing an issue I have

1:21 alternatively I could modify the project myself and use it until my issue is resolved

1:21 My issue: https://github.com/dakrone/clj-http/issues/125

1:37 muhoo: best to fux the bug, xubmit a patvh, and use the patched version in themeantime

1:38 fix, not fux

1:38 damn android keybozrd is POS

1:41 tieTYT2: i can try. This code does a lot of things I don't understand though

1:41 anyway, thanks for the suggestion

1:42 muhoo: good catch on that though. good luck.

1:58 tomoj: (deftype Foo [foo bar] IFoo (-foo [this] foo) (-bar [this x] (bar x)))

1:58 silly?

1:59 mikera: looks sensible if you want ti implement IFoo

1:59 tomoj: otherwise {:foo foo :bar bar} I guess

1:59 mikera: IFoo will be faster.... protocol/interface dispatch is very quick, faster than map lookup

2:00 (marginally... both are very fast....)

2:01 muhoo: crossovers or cljx?

2:01 decisions, decisions

2:02 tomoj: basically I just don't recall seeing functions (fn [x y]) where x, y match up with the two methods in a protocol

2:02 (or [x y z] or whatever)

2:02 and where it just takes those args and slots them in to the protocol

2:03 mikera: btw, I noticed you said you'd proved that protocol dispatch overhead was negligible for the purposes of core.matrix, is that proof published?

2:03 mikera: yep let me find link

2:03 tomoj: if it's in the group I can probably find it myself

2:04 mikera: https://groups.google.com/d/topic/numerical-clojure/_tuW6UaMsxY/discussion

2:04 tomoj: thanks

2:06 mikera: anyone here an expert with core.logic?

2:15 muhoo: wow my project.clj for a clj/cljs web app is starting to get longer and more complex than my .emacs file

2:19 tomoj: haha

2:20 hmm, can you stick code in a project.clj?

2:20 like, instead of writing 3 almost identical cljsbuild builds, can you generate them with code?

2:21 muhoo: i'm pretty sure, i haven't tried it, but it's clojure and the ns gets compiled, so probably

2:21 in my case, i've just got piles of dependencies that keeps growing, and bunch of directives for cljsbuild

2:26 hyPiRion: tomoj: yes, though it's not exactly idiomatic Leiningen use

2:26 not yet at least

2:35 muhoo: this.... madness.... is what it's come to: https://www.refheap.com/paste/13140

2:37 tomoj: huh, cljsbuild is what's breaking trampoline repl?

2:37 my hack for having `lein repl` jump directly into piggieback also seems to have broken

2:38 muhoo: tomoj: note the commented out line in that project.clj :-)

2:38 tomoj: yeah

2:39 I don't have that though.. hmm

2:39 muhoo: cljsbuild also hates not having a controlling terminal

2:39 i have to do lein trampoline repl </dev/null &

2:39 otherwise it hangs like a placerville judge

2:40 tomoj: oh, I'm getting some exception, guess it's a different problem

3:34 arne_: hi, I just started learning clojure and I don't understand why (b) doesn't work. http://pastebin.com/GGpGPS7s It throws: "CompilerException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn"

3:35 using a vector instead of a list doesn't work either

3:35 tomoj: what are you trying to do?

3:36 ( '(a) ) -- in idiomatic style, ('(a)) -- is a list as a function, which is an error

3:36 I mean, it's calling a list as a function

3:39 arne_: I want a function that returns a list of Persons

3:39 tomoj: def is for def'ing values, use defn for functions

3:40 (defn people [] (Person. (Pos. 1 2))) or something

3:40 er, (defn people [] [(Person. (Pos. 1 2))])

3:40 the [] after the name is the parameter list, so to call that you'd do (people)

3:41 if you really wanted a list for some reason, use (list ...)

3:41 ' means quote, so '(a) is just a list of the symbol a

3:42 &(let [a 42] ['(a) (list a)])

3:42 lazybot: ⇒ [(a) (42)]

3:42 arne_: I tried to simpliy the original source code. I'll try it, thx

3:45 tomoj: hmm, cljs doesn't seem to give you ->Deftype functions?

4:31 finally! https://www.refheap.com/paste/daefafbeb953e23d1d8dbd5ef

4:31 only took me.. 1y2m :(

5:01 tieTYT2: i want to filter a list of strings if it contains x and does not contain y. How do I write this in an idiomatic way?

5:04 tomoj: #(and (.contains % "x") (not (.contains % "y"))) ?

5:05 I guess you have to do (fn [^String s] ...) if you care about performance..

5:05 tieTYT2: yuck

5:05 danneu: oh come on

5:05 tieTYT2: i was hoping to eliminate all those parens

5:06 but ok

5:06 tomoj: eliminate parens?

5:06 you are aware this is a lisp..?

5:06 tieTYT2: yes

5:06 and i suppose I'll learn to love it

5:09 tomoj: the more you look at them the less you see them. I have mine dimmed too..

5:11 amalloy: tomoj: or just #(and (.contains ^String % "x"))

5:11 tomoj: oh right

5:11 amalloy: on a tangent here, i wish (memfn ^String contains x) did the obvious thing

5:12 danneu: pick whatever method you want to check if a string contains x, then you can just filter a coll of strings with this (every-pred has-x? (complement has-y?))

5:12 tomoj: the obvious thing being (partial (memfn ^String contains) x) ?

5:13 mikera: `(+ 1 2)

5:14 tomoj: hmm, I don't even understand memfn

5:14 amalloy: tomoj: no, i mean paying attention to the ^String hint

5:14 tomoj: it looks like it does

5:14 amalloy: really?

5:14 tomoj: https://www.refheap.com/paste/faff0c719113d447c00045356

5:14 amalloy: nice. i wonder how old that is

5:15 tomoj: 2012-03-08

5:15 d15a1f0c

5:15 (tassilo)

5:15 amalloy: yeah, i just found it too

5:15 tomoj: oh, I see, the x is just there to tell it how many args it has

5:15 amalloy: right

5:16 tomoj: and so you can typehint I suppose

5:16 danneu: http://clojure.org/java_interop recommends anonymous fn literals over memfn

5:16 someting i happen to remember reading

5:17 mikera: ,(+ 1 2)

5:17 clojurebot: 3

5:17 mikera: ,(let [p (java.awt.Point.)] (set! (. p x) 2) (.toString p))

5:17 clojurebot: "java.awt.Point[x=2,y=0]"

5:17 amalloy: tomoj: btw, it's a bit unintuitive but memfn could also work like (^String memfn contains x) or even ^String (memfn contains x)

5:18 tomoj: aha, a use for &form!

5:18 I don't think I ever thought of one

5:18 amalloy: tomoj: there are actually quite a few macros that, as things are implemented now, should use &form but don't

5:19 tomoj: example?

5:19 clojurebot: api examples is examples

5:19 amalloy: eg, ^String (doto x println) expands to a form with no typehint

5:20 tomoj: I see

5:20 that sucks

5:20 amalloy: for ages i've had a patch in that addresses that, but the details aren't quite thought out, and nobody at relevance was interested in accepting

5:21 tomoj: I mean not that doto doesn't do that, but that many many macros would have to do that

5:21 or rather, should do that

5:22 amalloy: right. my patch isn't to doto, it's to Compiler/macroexpand

5:22 http://dev.clojure.org/jira/browse/CLJ-865

5:24 tomoj: ah, great

5:25 I can stick that fix in my new defmacro and get the benefits on core when I reimplement all of core's macros :/

5:26 mikera: looks like a useful patch amalloy, I could use that in some of my code!

5:31 ambrosebs: Is it possible to invoke a private instance method of a private class? I tried the setAccessible route, and it seemed to give an InvocationTargetException

5:38 mikera: should be possible.... you are using the reflection route right?

5:41 ambrosebs: mikera: yes, I'll do a few more sanity checks.

5:51 mikera: false alarm, didn't realise InvocationTargetException was the underlying method throwing an exception when invoked.

6:10 danneu: Many clojure.java.jdbc methods are marked with "deprecated since 0.3.0" even though the latest release is 0.2.4. Is that just conventional way to mark deprecation targets for a future release?

6:57 jemafeller: hello

6:57 mikera: hi

6:57 danneu: heya

6:57 jemafeller: i'm wondering what would be the possible ways to move an existing Ring application to be nonblocking.

6:58 first, i'm wondering if there's a built-in Ring async interface, then I saw aleph, and then http-kit.

6:58 it looks like Clojure folk are less obsessive over async web than Scala folk, i'm in the process of evaluating both approaches

6:59 weavejester: jemafeller: The Ring 1.2.0 beta has split up its middleware to make integration with async stuff easier

6:59 But fundementally there are two reasons you might want async

6:59 First, performance, if you have a lot of I/O driven calls for instance

7:00 And second to support long polling and other pre-websocket workarounds

7:00 If anyone can think of a third reason I'm all ears, but those are the only two I can think of :)

7:01 tomoj: my third reason is cljs

7:01 and then I want a similar api in clj, so

7:02 weavejester: tomoj: Could you explain a little further?

7:02 tomoj: not particularly relevant to ring -- for that you'd have to imagine implementing ring for node.js

7:02 weavejester: tomoj: Ah, I see.

7:02 tomoj: (which I don't happen to care about..)

7:04 but if you did do a ring-node, it would seem nice to be able to get a similar interface on the jvm but using netty or whatever instead

7:05 weavejester: Doesn't node.js have some thread support now?

7:05 tomoj: fibers?

7:06 weavejester: I thought it had true thread support, but perhaps I'm just misremembering

7:06 tomoj: dunno, maybe

7:06 I haven't paid much attention lately now that cljs is picking up steam

7:08 but would people start writing threaded http servers anyway?

7:09 seems like node.js blasphemy

7:09 weavejester: True… it's not very idiomatic node.js

7:10 But then some of the node.js authors have a thing against promises as well

7:12 Most of the time asynchronous I/O is probably unnecessary in a HTTP server.

7:12 And it complicates things

7:12 tomoj: threads are evil, if you have threads you can only serve like ~10K req/s!

7:13 weavejester: Exactly :)

7:14 tomoj: yeah, I agree though

7:14 I have my own thing against promises

7:14 and wonder if async http with better promises would be less complicating, but haven't thought about it much..

7:15 certainly not as simple as (fn [req] res)...

7:15 weavejester: Yeah, it seems hard to beat a blocking function in terms of simplicity.

7:15 And with a smarter base than the JVM, one could make use of continuations.

7:16 tomoj: well, yeah, that's what I'm thinking -- what's the problem with the JVM?

7:16 just a bunch more work to get continuations working without native support I guess?

7:17 weavejester: Yeah, I mean, someone made a macro that automatically turns a function into using continuation passing style

7:18 https://github.com/cjfrisz/clojure-tco

7:18 For the purposes of TCO in this case

7:19 tomoj: but there's your extra complexity

7:19 weavejester: Yeah

7:20 If you had native continuation support, you could have your async cake and eat it too.

7:22 tomoj: is there an isomorphism between promises and continuations?

7:22 ctco style

7:23 my vague feeling has been that promises only give you part of the power of continuations, but looking at the ctco example I don't see how it's more powerful

7:25 actually I don't even not see that, just confused

7:26 weavejester: tomoj: Hm, well, the idea with CPS is instead of getting a value in return, you pass a callback.

7:26 ambrosebs: Is fireplace.vim supposed to take forever between cq* REPL commands?

7:27 weavejester: So… (fn [x y] (+ x y)) becomes (fn [x y c] (c (+ x y)))

7:28 For recursion and the like, that means you can replace stack frames with continuations.

7:29 tomoj: I guess the ctco README example is unenlightening since it's tail-recursive

7:30 er, or that's all ctco can handle? -- but fact there is already doable with recur

7:31 weavejester: tomoj: The author has a more in detail Clojure Conj talk, and a blog post on it: http://chrisfrisz.com/blog/Research/a-long-overdue-ctco-intro/

7:32 tomoj: If you use CPS, you can essentially pause the execution at any point.

7:32 tomoj: oh, nice, thanks

7:32 pyykkis_: weavejester, tomoj: are you familiar with any of the Promise/A implementations (JS land)?

7:33 http://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/

7:33 weavejester: pyykkis_: Not in any detail.

7:33 pyykkis_: weavejester: Q has a lovely api: https://github.com/kriskowal/q

7:34 pyrtsa: pyykkis_: Take a look at Clojure Futures.

7:34 weavejester: pyykkis_: Yeah, and you can see a relation to CPS in that as well.

7:34 pyykkis_: pyrtsa: They start a thread or wait one from the thread pool, right?

7:36 pyrtsa: pyykkis_: Yeah, I think so. But together with clojure.core/promise, they're pretty close already.

7:38 tomoj: "Promises, on the other hand, don’t care about time or ordering."

7:38 I think this is actually a big problem

7:38 weavejester: The functionality is roughly equivalent, but the mechanism is pretty different. Clojure makes use of blocking threads a fair bit.

7:38 tomoj: pyykkis_: I'm pretty familiar with Q

7:39 weavejester: tomoj: Why is it a big problem?

7:39 tomoj: well

7:39 jemafeller: weavejester, do you think clojure folk are less obsessive about async and nonblocking than Scala folk?

7:40 pyykkis_: tomoj: one can of course synchronize with promise.then (serial) and Q.all (parallel)?

7:40 weavejester: jemafeller: I don't know a lot about Scala's libraries on this front

7:40 tomoj: I guess if I take the author's original meaning there, the problem is that promises DO still care about time and ordering

7:41 weavejester: I do think async is unnecessary in most cases when working with plain HTTP.

7:41 pyykkis_: pyrtsa: as weavejester said, the underlying implementation is quite different

7:41 pyrtsa: Right.

7:41 jemafeller: weavejester, from my survey, almost *all* Scala web service libraries are async by default

7:42 weavejester: tomoj: It's more about cause and effect than time and ordering. If promise B depends on A, then B must block until A is ready, but any other calculations can be done in any order.

7:43 jemafeller: That seems overkill to me.

7:43 tomoj: it looks like Q doesn't define a function which takes two source promises and returns a promise that resolves to whatever the first resolved source promise resolves to?

7:43 jemafeller: weavejester, exactly my feeling. however it is pretty natural for Scala people. I was pretty much mocked for wanting to do straight, normal, linear blocking.

7:44 that is - read from a database, munge data, serve result

7:44 weavejester: jemafeller: Blocking is generally a much simpler mechanism. It's hard to make (fn [req] resp) any easier.

7:45 And you get decent performance. As tomoj pointed out, 10K/s isn't bad for a single server.

7:45 pyykkis_: I kind of feel async is more of a fashion than actually needed. Sure, there are use cases for it, but async apis comes always with a cost. No matter if they are callback or promise oriented.

7:45 jemafeller: I agree. but i'm kind of getting a revelation here.

7:45 i've been doing Clojure and a bit of Scala, and even got a commercial product based on Clojure

7:46 but I never bothered to stop. to go to basics and see what each platforms offered

7:46 i've been doing that for almost a week now and this is amazing - Scala is obsessed with async, while Clojure isn't.

7:46 weavejester: I will say that it's easier to go from async to blocking than the other way around :)

7:47 hyPiRion: oh dear lord gah yes

7:47 jemafeller: for Clojure you have Aleph which is on a distant island, and all the other frameworks are blocking on Jetty, on the mainland

7:47 for Scala, all the frameworks on the mainland are async, and maybe one framework is on a distant island allowing blocking and Jetty

7:47 hyPiRion: Ever tried to do a nonblocking read in Java/Clojure? Well, don't.

7:48 jemafeller: I keep wondering what does that mean

7:48 is Scala people prematurely optimizers? is Scala typically being used in a high-performance scenarios only? etc.

7:49 hyPiRion, truthfully, I don't think Scala's offering in the nonblocking section is much better

7:50 if you don't have something that async by nature (i.e. using IO completion ports / etc), shoving it into a Future is not the real thing

7:51 during my survey I found a ton of Scala projects on github, just shoving every code they have in the request directly into a Future, does't matter if its blocking or not

7:51 in my eyes that is the same as blocking code on Jetty

7:53 So I have the Scala crowd saying, "only do nonblocking", and no library support for real nonblocking IO in things like Cassandra, MongoDB. and a lot of people mis-applying Scala Futures as examples to learn from.

7:53 pyykkis_: weavejester, hyPiRion: Regarding async io, node.js streams are actually quite awesome, e.g., 'process.stdin.pipe(process.stdout);'

7:54 works for files, networking, processes and whatnot with automatic backpressure etc

7:56 pyrtsa: tomoj: "it looks like Q doesn't define a function..." <- No, it doesn't define such function directly, but Q.all([p1, p2]).then(function (ps) { return ps[0] }) gets you going.

7:57 pyykkis_: no waiting for sync responses, resolved promises or anything else. Piping database responses to slow mobile clients becomes trivial.

7:58 tomoj: pyrtsa: I meant the first one to resolve, temporally

7:59 (I think it's a good thing Q doesn't define such a function, it would break the semantics)

7:59 pyrtsa: Oh, right. That would be Q.any if it existed.

8:00 I don't see what semantics it would break.

8:03 tomoj: well, say you do Q.any(a,b) when b is resolved but not a, you get b. later, you do the same Q.any(a,b) after a resolves

8:05 Q.any would reveal the stateful part of a promise, that it goes from unrealized to realized

8:05 arcatan: maybe that could be used for something like polling two database mirrors at the same time. the quickest one wins and you discard the other one.

8:06 tomoj: yeah, if you only want "unamb" -- any where you know the results will be the same -- then no problem

8:06 mpenet: jemafeller: there is an async-ring-adapter too built on top of netty, I think it uses the same abstraction than http-kit (from the same author/maintainer)

8:06 jemafeller: mpenet, indeed, thanks

8:07 mpenet: jemafeller: and some db lib have async support, I think monger has some, a few cassandra client as well, and well, all the http based stuff that you can easily build on top of some http client with async support (http-kit client, aleph, jetty 9 etc)

8:10 but it's rarely the default (it's not a bad thing imo)

8:19 pepijndevos: How can I add a domain to all vars in a list? (core.logic)

8:21 Something like (fd/in ~@l domain)

8:24 pyrtsa: tomoj: I think you can safely assume that when Q.any is used, the user doesn't care which thing is the one that completed. And the different result on later use issue is mitigated by using a temporary value: c = Q.any([a, b]); c.then(...); c.then(...).

8:26 tomoj: from Q's perspective, you're probably right. still, it would be a hole in the otherwise seemingly very nice value-like semantics

8:28 it's OK to have holes sometimes if the user asks for one, but I want perfect value semantics AND the extra operations Q can't do :)

8:28 pyrtsa: :)

8:30 pepijndevos: waaarg!

8:30 pyrtsa: Anyway, it was a very good point that Q.any would behave differently depending on the time called. :)

8:30 But how about if we had Q.any_n(n, promises) that would return the array of all fullfilled promises as soon as there are at least n?

8:31 (Maybe it's time to take this discussion away from #clojure.) :)

8:33 tomoj: a motivating example (outside the scope of Q, back closer to clojure-land): you can think of a lazy seq as being made up of conses where the 'rest' is a delay. if we replace the delay with a lazy version of Q's promises, we get so-called 'push seqs'

8:33 I actually wrote a library with map/filter/etc using Q like this

8:34 but I want to be able to temporally merge two such seqs and always get the same answer

8:37 pyrtsa: tomoj: What does merge mean here? zip?

8:38 ...or did you mean take values from whichever seq pushes more values first?

8:38 tomoj: right, the latter

8:38 every value from both seqs in the order that they appear

8:39 not sure 'seq' is the right word -- you can't do that with normal clojure seqs...

8:39 pyrtsa: tomoj: Do you have experience with FRP, Microsoft's Rx for example?

8:40 tomoj: i.e. (lazy-seq (Thread/sleep 1000) [1 2 3]) and (lazy-seq [1 2 3]) are the same value

8:40 yeah did Rx for a while too. the motto "putting the F back in FRP" has been running through my head lately, maybe you can tell what I think of Rx :)

8:41 pyrtsa: I'm on your side. But having the imperative side there helps to pull those old-schoolers to the "F" side. :)

8:43 tomoj: There's a parallel in your idea of temporal merge to the example of Q.any, though. If you wanted the merge result to always be the same regardless ot the time called, the only way to have the already existing lazy-seq values merge the same way is to remember the timestamps the values were pushed.

8:44 ...and to then push the already evaluated values as sorted by their timestamps.

8:44 pepijndevos: Can I use print-table for just vectors of vectors?

8:44 no headers

8:45 tomoj: pepijndevos: you're gonna have to copy+paste :(

8:45 pepijndevos: :(

8:45 tomoj: and/or patch? :)

8:47 pyrtsa: right, gets a bit tricky I think though

9:00 hmm, can it be that simple?

9:03 jemafeller: what's a good way to initialize a Redis pool? (Jedis) - I always see these ref/deref things for such initializations

9:08 augustl: does Cheshire with "slime" (the binary format) support byte arrays as key values? I'm getting "Cannot JSON encode object of class: class [B: [B@7c4ccb2f" for (generate-smile {:foo my-byte-array})

9:09 s/slime/smile

9:11 pyrtsa: tomoj: Were you talking about the sorting based on timestamps? In that case, not in the general case with computation on multiple processors with independent clocks.

9:14 tomoj: oi, I don't even want to think about that. assume we can serialize everything with one clock

9:14 pyrtsa: In that case, I think it is that simple.

9:18 tomoj: one minor wrinkle is something like (any (delay 1000 a) (delay 1000 b)), need to make sure there is no race

9:20 pyrtsa: Yeah, but I guess your assumption about serializing everything with one clock kind of solves those races.

9:46 mpenet: jemafeller: some people prefer dynamic vars (yuk), others use regular vars and fn arguments. It's a matter of taste. A third option is a fn generator that will make you a fn that encapsulates the "pool" and that you use to call the redis commands later (kinda what aleph.redis does, even if there's no pooling going on).

9:46 jemafeller: mpenet, thanks

9:47 how about this approach https://github.com/jxa/resque-clojure/blob/master/src/resque_clojure/redis.clj

9:47 mpenet: jemafeller: check clj-redis, carmine, and aleph.redis, 3 redis clients with diff approaches to that

9:48 jemafeller: using refs/atoms is problematic imo, you can only have 1 at a time...

9:48 let's say you want to support sharding later, you'll need to rewrite that.

9:48 jemafeller: hmm, make sense

9:50 mpenet: I tend to prefer clj-redis or aleph style, but that's just me.

9:50 but I use carmine in production so...

9:51 jemafeller: relevant post btw: http://stuartsierra.com/2013/03/29/perils-of-dynamic-scope

9:53 jemafeller: interesting.. then I guess my problem stems from the fact that I hold my "Redis" layer in the same file

9:53 so functions are using a pool being 'def'ed on the file itself.. I'm using the file as a module and its quite convenient

9:54 and I don't want to leak Redis specifics to the module that uses the 'Redis module', like the Pool

9:55 mpenet: using something like clj-redis style (a pool argument), you can easily hide that to most of you code using partial

9:56 Glenjamin: mpenet: that's interesting - i've just taken a very similar approach to that in my app =/

9:56 although the dynamic state i'm binding is just some values which are used to create an oauth header when making http requests

9:56 rather than an actual resource

9:57 not sure if that falls into the "dangerous" category

9:57 mpenet: as stated in the post there are valid uses cases, when it's safe and when it prevents making the code very convoluted

9:58 Glenjamin: mm, but having read that i'm not entirely clear where the line is drawn

9:58 mpenet: I use dyn vars regularly, recently on a query generator to hold a stack of parameters for prepared statements, it's safe and prevented to add an additional arg to a dozen of fns.

9:59 Glenjamin: i've got a compojure app, on request some middleware binds some auth credentials based on the cookie, and this is used to authenticate API requests to the backend during the request

9:59 mpenet: but everytime I do, it does feel like I am doing something bad :), but as long as it doesn't hurt, it's ok

9:59 Glenjamin: eg. (with-auth token (make-api-request))

9:59 mpenet: Glenjamin: I am not sure, but if you switch to an async server later you could have some surprises.

10:01 compojure used to do that at the beginning I think, hold a *session* var, but this went away

10:01 jemafeller: mpenet, so you're saying to build something like (make-storage configuration) which will build a (let [pool (build the pool with config)] (fn [record] (actually-store pool record))) ?

10:01 mpenet: or maybe some other framework that built on top of it.

10:01 Glenjamin: yeah, it's similar to noir's *request*, but specific to what I know i'll pull out each time if i passed it around

10:02 in an async server, what would be async?

10:02 mpenet: depends, but in http-kit for instance a single thread manages many connections for instance

10:03 Glenjamin: i suppose i'd only run into issues if a single request was handled via multiple threads

10:04 mpenet: jemafeller: use simple fns, and then build on top of it. ex (defn search [server query]) and in your user ns you can just create a var with (partial search "localhost") and use that

10:04 Glenjamin: oo, that's interesting

10:04 pepijndevos: wow, never had htis before: GC overhead limit exceeded

10:04 Glenjamin: i could have the middleware drop partial functions into the request map

10:05 jemafeller: mpenet, i'll have to lean about partial funcs, i'm looking..

10:05 Glenjamin: although i suppose there'd be an overhead of initialising a bunch of things i wont use on most requests...

10:05 lots to think about :)

10:05 mpenet: aleph.redis has something like that, you create a "client" fn by passing options to a fn that generates it

10:05 jemafeller: i'll check that

10:05 mpenet: https://github.com/ztellman/aleph/wiki/Redis#creating-a-redis-client

10:06 I am not saying it's a silver bullet, but knowing of the alternatives is always good :)

10:06 jemafeller: mpenet, yes i see that. I kind of did that with 'traditional' currying. they solved the case by specifying a command as part of the data structure passed to the client

10:07 which now affirms me its not a bad solution.. kind of implementing a class without a class

10:09 Glenjamin: on another subject, the dev.clojure wiki's coding standards mentions full branch coverage as a requirement

10:10 is there a tool to derive this?

10:15 pepijndevos: core.logic memory is sloooowly rising, after a long time causing the above GC error.

10:21 jemafeller: ahh. love the smell of "done" :)

10:21 6600 req/s for an analytics service built with Clojure is not so bad eh? :)

10:48 pepijndevos: hm, I'm trying to find this graph of work done/time for programmers and other people. Where the one line goes gradually up, the other straight up and the horizontal.

10:52 hyPiRion: pepijndevos: thinking about the mythical man month?

10:53 pepijndevos: no idea where it's from

10:53 it just randomly pop in and out of my internets

10:53 hyPiRion: hm

10:57 Sonderblade: pepijndevos: is it the one where it is claimed that output is n, but communication overhead is 2^n where n is the number of programmers?

10:59 pepijndevos: Sonderblade, no, the one that shows that manually producing a result will be faster initially, but slower in the long term.

11:11 xeqi: pepijndevos: https://plus.google.com/102451193315916178828/posts/MGxauXypb1Y

11:11 pepijndevos: xeqi, YES!

11:23 hyPiRion: xeqi: oh, that's a nice graph. I'll show it to people when they ask why I use so "much time" to setup my emacs config

11:27 Glenjamin: is there a core function with prints a value and returns it?

11:28 hyPiRion: not afaik

11:34 xeqi: nothing builtin, but ##(doto :x println) would work

11:34 lazybot: ⇒ :x :x

11:35 Glenjamin: i'm mostly using it to debug threading

11:36 so (doto prn) is what i'm after, cheers

11:36 been doing ((fn [x] (prn x) x)) every time :)

11:37 btw, i've got a couple more cookie-related bugs to report/fix in peridot

11:38 hyPiRion: oh, doto works for -> threading too

11:39 ,(-> 1 (doto prn) inc (doto prn) (* 10) (doto prn) dec)

11:39 clojurebot: 1\n2\n20\n19

11:39 xeqi: Glenjamin: awesome

11:39 I saw the timestamp pull and it looks great

11:39 (from my phone)

11:40 will look at getting it merged later

11:40 Glenjamin: cheers

11:40 borkdude: yogthos I guess the reason the sample guestbook application creates the h2 db in the same directory as the jar when deployed is because noir.io returns nil, is this intended?

11:40 xeqi: Glenjamin: out of curiousity, what are you using it for?

11:41 Glenjamin: got a small app which talks to my accountant's oauth api

11:41 testing the cookie handling of the middleware that tracks auth

11:42 will probably use kerodon when i get to building the actual app

11:44 borkdude: yogthos|away it is a good place I guess

11:47 Glenjamin: xeqi: is there a way to do https requests in peridot?

11:49 ah, i need to pass a full url

11:51 xeqi: Glenjamin: yep, a full url should work

11:52 I usually do a https proxy in front of my ring app

11:53 Glenjamin: i've got :secure true in my cookie params

11:53 it kept stripping it out :)

11:53 xeqi: ah!

11:53 that would be a good use case there

11:54 Glenjamin: which is where i found the other bug - :http-only cookies gets stripped from https requests

11:54 but http-only just means no javascript access

11:55 xeqi: heh, thats what I get for not reading the spec there

11:55 oops

11:57 Glenjamin: can't seem to find a neater way of expressing this than: (remove #(scheme {:http :secure :https :nothing})) in the ->> though

11:58 (remove #((and (= scheme :http) (:secure %)))) maybe

12:03 xeqi: Glenjamin: yeah... maybe pull the remove out into a function like (defn maybe-remove-secure [scheme cookies] (if (= scheme :http) (remove :secure cookies) cookies)) ?

12:03 nothing is immediatly appealing

12:04 though some of that code is ugly anyways

12:04 Glenjamin: ended up with (remove #(and (:secure %) (= scheme :http)))

12:04 which isn't too bad

12:04 heh, " (sort-by (comp count first)) (map second) (apply merge) (map second)" could be doing anything

12:04 xeqi: yep

12:05 thats the part I was thinking

12:05 who wrote that uglyness... oh, me a year ago...

12:06 Glenjamin: heh

12:06 second PR for the http-only thing sent

12:07 these libs make me feel right at home coming from ruby testing, nice job :)

12:16 yogthos: borkdude: with a jar you can't write to your resources folder

12:16 borkdude: so you have to give it an external path

12:16 borkdude: yogthos yeah, I know, or if it could it would be ugly to do it

12:16 yogthos: borkdude: pretty much yeah

12:17 borkdude: yogthos would you have to do this manually I guess?

12:17 yogthos for examples I could make a directory "resources" in the same dir as the .jar file

12:17 yogthos: borkdude: yeah I'd just give it a path for the db

12:18 borkdude: also you probably don't want it to reside in your public folder either :)

12:18 borkdude: yogthos probably not :)

12:18 yogthos: borkdude: I find the situation with wars is much better, because then the whole things get unpacked into its own directory

12:19 borkdude: yogthos hmm, now you mention it, it is a bit weird that the db gets created in the public folder now ;)

12:19 yogthos: borkdude: but yeah I couldn't think of any good way to handle that automatically with a war, should probably make a mention of this in the deployment docs

12:23 rahcola: lein repl gives "EOF while reading string" in a clean leiningen project under Windows 7

12:23 any ideas?

12:24 muhoo: wha? -?> still hasn't made it into 1.5.1?

12:24 shocked it's still in incubator after like a year

12:25 borkdude: yogthos say I would have this guestbook in production and I have some local data also using the same h2 database model, what is the easiest way to merge these two databases?

12:26 yogthos this is more h2 related than webapps, but maybe you would happen to know this

12:26 yogthos: borkdude: I probably wouldn't recommend h2 for that, it's an embedded db after all

12:27 borkdude: yogthos what would you recommend?

12:27 yogthos: borkdude: it would be much better to setup an actual db at that point like postgres

12:27 borkdude: yogthos what is the reason you have chosen h2 over other alternatives like sqlite etc for this example?

12:28 yogthos: borkdude: was recommended on this channel actually, I started with sqlite and people suggested h2 is more robust and has better drivers in java

12:29 borkdude: also depending on what you need something like mongo might be a good option as well

12:30 borkdude: if you just need a persistence layer and don't care about the relational aspect

12:30 borkdude: yogthos yeah, I tried mongo, but it only works for tree-like data

12:30 yogthos: borkdude: yup

12:30 borkdude: yogthos probably will look more into postgresql then

12:30 yogthos: borkdude: I definitely recommend postgres

12:31 borkdude: if you're on os x this is very nice for testing http://postgresapp.com/

12:31 borkdude: yogthos I am. It's the tooling which makes a big difference. tnx

12:35 stuartsierra: muhoo: -?> is in 1.5, it's called some->

12:52 augustl: anyone used cometd with a lein-ring app before? Not sure what's easier - ditch lein-ring and write my own servlet + jetty stuff, or figure out how to make a web.xml setup with both lein-ring and my own servlet for cometd.

13:00 rebcabin: ,(def xs (map-indexed (fn [i x] (str i x)) (partition 2 '(1 2 3 4)))) -- stuck in lazy form; prints as ("0clojure.lang.LazySeq@3e2" ...) etc. (map doall xs) doesn't force

13:00 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

13:01 rebcabin: any hints on how to un-lazy out the sequences

13:02 hyPiRion: rebcabin: replace `str` with `apply str`

13:02 wait, perhaps you'd like it to print as a list?

13:02 rebcabin: hyPiRion: oh my, that again /slaps forehead; ty

13:03 hyPiRion: yes, printing as a list would also be a great alternative

13:03 hyPiRion: ,(map-indexed (fn [i x] (str i (-> x vec list*))) (partition 2 '(1 2 3 4)))

13:03 clojurebot: ("0(1 2)" "1(3 4)")

13:04 hyPiRion: vec realizes the whole sequence, list* converts it back to a list again

13:04 rebcabin: hyPiRion, clojurebot: lovely

13:12 ,(str "ignore: just testing clojurebot")

13:12 clojurebot: "ignore: just testing clojurebot"

13:13 augustl: is it possible to make lein-ring use web.xml when running it with "lein ring server"?

13:30 looking for general suggestions on how to combine a ring handler with a servlet :) The goal is to make it work with the lein-ring plugin

13:31 I could always roll my own -main that creates the servlets, but then I would need to implement dev mode reloading myself..

13:40 stuartsierra: augustl: I don't think lein-ring even uses web.xml in development mode. It embes the servlet container directly.

13:40 *embeds

13:40 And for building a .war file, lein-ring generates both the web.xml file and the servlet class.

13:42 chessguy: 'afternoon all

13:42 stuart, congrats on the release of pedestal, looks really interesting

13:43 stuartsierra: Thanks.

13:43 augustl: stuartsierra: yeah it seems the web.xml part of lein-ring is only generating it + a war file

13:43 chessguy: you guys just need a "how to build a chat client in 15 minutes" video, and you'll be all set

13:43 stuartsierra: chessguy: Well, there's already a chat sample app. We might make some screencasts soon.

13:44 chessguy: stuartsierra: i know, that's why i picked it

13:44 i've been playing with the chat code, and with the other samples

13:44 it's also a good example for the space where pedestal's going to kick butt

13:45 stuartsierra: That's the hope, anyway.

13:46 chessguy: i am kind of curious why you guys bundled it all together though. it seems like there could have been advantages to having, say, an interceptor library, and a application library, versioned separately

13:49 stuartsierra: chessguy: It's been both ways at different times.

13:49 chessguy: i see

13:49 stuartsierra: I expect we'll release some of the pieces independently in the future.

13:50 To get the alpha out in time for Clojure/West, we took the "easy" route of bundling it all together.

13:50 chessguy: as opposed to the simple route? :)

13:50 sorry, couldn't resist

13:52 stuartsierra: Yes, actually, that was what I meant. :)

13:52 "Simple" is hard.

13:52 gfredericks: hyPiRion: list* does _not_ convert back to a list

13:52 chessguy: agreed

13:52 gfredericks: hyPiRion: I guess that wasn't really the point though, nm

13:54 chessguy: i really hope to see some better documentation/tutorials soon. do you realize that the web site doesn't even really define what it means by "service" vs. "application"?

13:55 stuartsierra: oh yeah, lots more work to be done there

13:55 chessguy: i'd be happy to contribute too, once that's worked out

13:55 (and i can get my brain around it)

13:55 stuartsierra: Cool. We've got a CA process for the source code, I think there's one in the works for docs too.

13:57 chessguy: yeah, i need to get that sent in too

14:00 hyPiRion: gfredericks: I agree though, perhaps seq would be a better fit there.

14:06 gfredericks: hyPiRion: probably just doall?

14:06 Raynes: ping

14:07 hyPiRion: gfredericks: doesn't work

14:07 ,(str (doall (partition 2 '(1 2 3 4))))

14:07 clojurebot: "clojure.lang.LazySeq@8041"

14:08 gfredericks: hyPiRion: ahrighto

14:08 ,(print-str (doall (partition 2 '(1 2 3 4)))

14:08 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

14:08 gfredericks: ,(print-str (doall (partition 2 '(1 2 3 4))))

14:08 clojurebot: "((1 2) (3 4))"

14:09 gfredericks: it surprised me to learn that println prints lazy seqs the good way

14:09 hyPiRion: the good way?

14:09 ,(.toString (partition 2 '(1 2 3 4)))

14:09 clojurebot: "clojure.lang.LazySeq@8041"

14:11 gfredericks: yeah rather than that way

14:11 hyPiRion: ah

14:13 gfredericks: anybody use laser? I'm finding it weird that laser/document does both transformations _and_ conversion to an html string

14:13 no obvious built-in way to do just transformations

14:13 hyPiRion: I think Raynes uses it, since, you know, he built it and all

14:14 Raynes: I wouldn't use that nasty shit.

14:14 Oh wait.

14:14 gfredericks: I pung him and he didn't show up until I started complaining about specifics

14:14 Raynes: I didn't see a ping.

14:14 gfredericks: they are small and quiet

14:15 Raynes: gfredericks: I'm in a new place with no cable internet and the mifi card I'm on is utterly worthless.

14:15 If I don't respond it's probably because the mifi card is tossing me around like a pizza crust.

14:15 gfredericks: Raynes: this project is slowly turning into a bunch of raynes libs; you seem to write only useful stuff.

14:15 Raynes: lol

14:15 So document.

14:15 gfredericks: yes that

14:15 I just took the source and wrote a `transform` but I had to use a private var to do it

14:16 Raynes: document is meant to be the top-level transformation that you build everything up.

14:16 I wasn't expecting a scenario where you'd want to have more than one document call on the same thing.

14:16 Why do you need document to not return a string?

14:16 gfredericks: so it expects I'm doing all my transformations in one place?

14:17 well if I want a top-level transformation to be a composition of several lower-level transformations, for example...

14:17 Raynes: Well, it expects that all of the transformations on that particular document would be done in a single call to document.

14:17 (not saying that's a good assumption)

14:18 gfredericks: okay. so I'm not missing anything by thinking a transform function would be useful?

14:18 Raynes: I think there is one.

14:18 And you just didn't find it.

14:18 I'm looking.

14:19 gfredericks: laser/document certainly doesn't use one

14:19 augustl: why do I get "No matching field found: foo" for https://www.refheap.com/paste/13152 ?

14:19 gfredericks: augustl: you're trying to create a type that has a foo method?

14:19 augustl: yeah

14:19 Raynes: gfredericks: I think 'at' is what you want.

14:20 gfredericks: augustl: I don't think proxy can be used to add arbitrary methods. it would have to be a method on the superclass or an interface

14:21 augustl: ah

14:21 gfredericks: augustl: it's a bit weird that it'll compile the proxy form without error

14:21 Raynes: gfredericks: If 'at' does work for you, one could probably write document in terms of it. I don't I just didn't care enough to try because document has a very short and simple definition.

14:22 gfredericks: Raynes: I think this looks promising, thanks

14:22 augustl: gfredericks: I thought the point of proxy was that method dispatch happened through a normal clojure map

14:22 Raynes: Is this code open source?

14:22 gfredericks: Raynes: no it's for static-generation of my website

14:23 Raynes: gfredericks: You could also use fragment for this, I think.

14:23 augustl: "proxy" returns the instance, right?

14:24 gfredericks: Raynes: yeah I noticed that looked useful too

14:25 Raynes: gfredericks: If you have any trouble let me know.

14:40 chessguy: err, if i'm in just a straight clojure repl (not a lein repl), how do i load some arbitrary clojar?

14:55 gfredericks: you can't within the same repl session

14:56 if by "straight clojure repl" you mean running the clojure jar from the `java` command, you can add any other jar to the classpath

15:05 Raynes: there's not a selector for the enlive-style :div#content.foo is there?

15:07 Raynes: gfredericks: Nope. One of my reasons for making laser is because I hated that. But I also want to implement something like that on top of the existing selectors.

15:07 gfredericks: so you hate it being the low-level thing you mean?

15:12 Raynes: gfredericks: More or less, yeah. I'd rather use the function-based selectors even if I had the other things.

15:42 ghengis: does an ingenious library exist for dealing with complex data structures (e.g. lists of maps of vectors of maps of lists, etc)? i'm getting a headache and wondering if someone has found a way to make performing updates/reads on such structures easier?

15:44 stuartsierra: ghengis: Clojure has some built-in functions to help: get-in, assoc-in, update-in.

15:46 ghengis: yeah i'm aware of those, but still doing some awfully complicated stuff to get inside the structures..

15:46 stuartsierra: You could also look at https://github.com/LonoCloud/synthread

15:46 ghengis: hm, i might just have to rethink the structures themselves

15:46 ok, looking...

15:49 yeah, this looks really nice

15:49 thanks! i'll play around with it

15:58 augustl: how do I call a macro that takes varargs with a list of args? (apply my-macro my-list) throws an error ("Can't take value of a macro")

16:00 lucian: augustl: if you're calling it with apply, you probably want a function instead

16:00 augustl: yeah, I know, apply doesn't work for macros :)

16:00 so how do I call a macro that takes varargs with a list containing the args?

16:07 amalloy: augustl: it is not possible

16:08 macros operate on source-code forms, not runtime data values

16:14 augustl: amalloy: makes sense, thanks

16:25 gfredericks: Raynes: so you'd take a patch for a laser/css function?

16:25 Raynes: gfredericks: I wouldn't name it that if it was enlive's 'css'

16:25 gfredericks: I wasn't thinking of enlive

16:26 Raynes: If it were a real subset of css, I'd take it.

16:26 (with that name, I mean)

16:26 gfredericks: shall I open an issue for discussion?

16:26 Raynes: If it were enlive-style I'd name it enlive-css or something.

16:26 Sure.

16:31 * gfredericks did it

16:31 Raynes: I really object to the goal of "well, css selectors are shorter."

16:32 But other than that, sure.

16:32 gfredericks: why do you object to it?

16:32 Raynes: Because CSS is a different language and isn't functions.

16:32 gfredericks: it's a DSL?

16:32 Raynes: They're nice to have, so I want them, but I'm going to be sad when people use them.

16:33 :p

16:33 gfredericks: you sound very conflicted

16:34 damn do we need a whole CSS parsing lib for this?

16:34 Raynes: Yes.

16:34 gfredericks: can we call it lacsser?

16:34 Raynes: lol

16:35 gfredericks: man this is why I don't write libraries. They always require several other libraries to also be written.

16:37 Raynes: Well, you aren't legally obligated to add this functionality. :p

16:39 gfredericks: so the next question is -- can we start with just the div#id.class1.class2 syntax?

16:40 ivaraasen: Raynes: my goal is to turn every single one of your repos into little, non-composable DSLs and package them as raynesLang

16:41 amalloy: (inc gfredericks)

16:41 lazybot: ⇒ 17

16:41 amalloy: oh, i guess i meant ivaraasen

16:41 Raynes: (dec gfredericks)

16:41 lazybot: ⇒ 16

16:41 Raynes: (inc ivaraasen)

16:41 lazybot: ⇒ 1

16:41 Raynes: Fixed.

16:41 Wow, poor ivaraasen.

16:41 gfredericks: I was a prime for 17 seconds

16:41 Raynes: gfredericks: Yes. That's what subset means.

16:41 :p

16:42 gfredericks: hyPiRion: I'm about to push up a lib that does factoring

16:42 amalloy: gfredericks: 27 seconds

16:42 gfredericks: Raynes: w00t this shit just got feasible

16:42 amalloy: not a prime number of seconds, alas

16:42 gfredericks: I'm thinking of using a regex so the next question is how I will solve the resulting two problems

16:43 amalloy: does your client show seconds?

16:43 amalloy: yes

16:43 gfredericks: that's like magic

16:43 also it's a cube which is nearly as good as a prime

16:43 amalloy: true

16:43 gfredericks: I wrote some code for computing the smallest uninteresting number recently

16:44 Bronsa: what's an interesting number?

16:44 ivaraasen: Bronsa: 6.

16:44 it's a perfect number

16:44 gfredericks: Bronsa: that's determined by your supplied vector of interests

16:45 which you can iterate on once you figure out something interesting about whatever number you missed

16:46 chessguy: (inc Raynes)

16:46 lazybot: ⇒ 26

16:46 gfredericks: e.g., 26 is a semiprime

16:47 chessguy: because any tutorial that starts by referring to its readers as small animals has to be awesome..

16:47 gfredericks: you don't have to get very far before you can say something interesting about every number below 100, which makes you quite a hit at parties let me tell you what.

16:48 amalloy: gfredericks: i imagine you got desperate at some point, and your interesting fact about 43 is "the number of parties at which i've tried to tell interesting facts about numbers"

16:50 gfredericks: actually 40 was the first tricky one

16:50 43 is a prime

16:50 Bronsa: afer the first few primes, being prime is not interesting anymore though

16:50 gfredericks: it's *always* interesting.

16:51 the bigger it is the more interesting it is.

16:51 it is a number which evades all attempts to arrange it into a rectangle.

16:51 Bronsa: well, then any number is interesting because it's the first and only number that can be factorized that way.

16:52 gfredericks: that's not a very interesting definition of interesting

16:52 Bronsa: nor is being the nth prime

16:52 gfredericks: actually I like the idea that any definition of interesting should result in a set with limiting density of 0

16:52 ivaraasen: 19 - "prime. also, the number of blog posts in the last 48 hours trying to explain monads using a horrible metaphor"

16:53 hyPiRion: gfredericks: oh, you'll beat me to it then

16:53 Better just fork your and add in stuff if I need

16:54 Bronsa: also gfredericks the first uninteresting number would be interesting because of that very nature of his, Hofstadter docet

16:54 gfredericks: hyPiRion: just as soon as I can figure out how to mount the damn vm share again

16:54 Bronsa: yeah, that "paradox" is what got me thinking about this

16:55 hyPiRion: gfredericks: Well, no worries. I am not in an emergency situation where I need a factorization lib.

16:55 gfredericks: hyPiRion: my thought was that there isn't an appropriate-in-all-cases implementation

16:55 so I made a protocol

16:56 hyPiRion: gfredericks: what do you mean by that? Well, I guess I'll have to wait and see

16:59 gfredericks: hyPiRion: i.e., different amounts of memory usage might be appropriate

16:59 for factoring one number versus multiples

17:07 hyPiRion: https://github.com/fredericksgary/numth

17:08 hyPiRion: oh, you've seen my prime lib, right? https://github.com/hyPiRion/primes

17:08 Just in case

17:09 gfredericks: heck no

17:09 yours must be better

17:09 thought mine is theoretically broader

17:09 s/theoretically/hypothetically/

17:10 hyPiRion: It doesn't factorize though, it's just doing one thing really.

17:12 gfredericks: factoring and prime-checking and prime-listing are undecomplectable I think

17:14 hyPiRion: hmm

17:14 gfredericks: I also didn't want the lib to necessarily accumulate state in the background

17:14 if you don't want it to

17:15 hyPiRion: right

17:17 gfredericks: could have a prime? implementation that just uses BigInteger#isProbablePrime

17:18 hyPiRion: yeah

17:19 Glenjamin: undecomplectable is an awesome word.

17:20 gfredericks: it's probably an oxymoronic word

17:21 if things are undecomplectable, are they really complected in the first place?

17:21 hyPiRion: may be

17:22 Well, it depends on the definition of undecomplectable

17:27 bbloom: i don't think it is possible to be uncomplectable....

17:36 ivaraasen: well, you could view factorisation as a constraint-based search in a vector space, say R1, and prime number generation as the basis for this space. so you could perhaps decomplect them, should you for some reason wish to factorise different kinds of data (numbers, mathematical symbols)

17:38 finishingmove: when i'm writing a function that can be overloaded, am i limited to one comment or can i have a comment for each scenario?

17:44 n_b: You mean like this?

17:45 tomoj: has anyone tried running something in the background in cljsbuild's notify-command?

17:45 when

17:45 n_b: ,(def foo ("comment" [](foo 1)) ("returns bar" [bar] bar))

17:46 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

17:46 n_b: woops

17:46 tomoj: er, when I do `command-that-takes-3s &` in the shell script that I'm using for my notify-command, cljsbuild blocks waiting, apparently because of the 'pumper' stuff

17:46 even `command-that-takes-3s 2>&1 >/dev/null &`

17:48 which doesn't make any sense to me, because `my-shell-script 2>&1 >test` returns immediately

17:48 n_b: finishingmove: Seems to work.

17:51 tomoj: ah.. http://bugs.sun.com/view_bug.do?bug_id=4850368

17:51 hmm, it's closed though

17:56 amalloy: tomoj: you probably meant `command-that-takes-3s >/dev/null 2>&1 &`

17:56 or, i suppose, `command-that-takes-3s &>/dev/null &`

17:58 tomoj: hmm

17:58 that works! thank you

17:59 I guess I still had stderr coming out?

17:59 (of stdout..)

17:59 moominpapa: Very good understanding, yes

18:00 tomoj: https://www.refheap.com/paste/f7013fe4a77c02cf03abb0945

18:00 my replacement for notify-send, which is incredibly frustrating with cljsbuild

18:01 since 1) you can't configure how long it shows and 2) it always shows every message for the full time, causing a buffer you have to sit and wait through if you save many times in a row

18:03 aaelony: i don't see c3p0 in clojars.org any longer, is it no longer recommended with clojure.java.jdbc ?

18:05 e.g. "No results" for https://clojars.org/search?q=c3p0

18:07 finishingmove: n_b thanks

18:07 tomoj: http://search.maven.org/#search%7Cga%7C1%7Cc3p0 ?

18:07 aaelony: ^

18:08 aaelony: yes, it's in maven, but wondering if there is a reason it is no longer in clojars. Perhaps there is an opinionated way that is better?

18:09 just curious ...

18:09 amalloy: was it ever on clojars? i can't think why it would have been

18:15 aaelony: amalloy: never known you to be wrong yet.

18:15 abe: heya, any incanter folk here?

18:17 aaelony: so… consensus seems to be using c3p0 is ok, thanks

18:17 tomoj: clojure.java.jdbc isn't in clojars either, is it?

18:18 amalloy: neither is clojure :P

18:22 aaelony: well things change and libs that were previously "blessed" sometimes fall out of favor with other libs being preferred. Just trying to get the pulse on c3p0 and see which camp it falls into

18:22 hyPiRion: neither is more or less anything related to Java only

19:01 * gfredericks is using a regex and has two problems

19:03 st3fan: ok i'm done .. http://stefan.arentz.ca/finding-your-way-home-with-clojure.html

19:07 jasonjckn: st3fan: cool

19:07 st3fan: nice ui

19:08 callenbot: st3fan: Mozilla needs less Go and more Clojure :)

19:08 st3fan: also holy hell who did the design on that?

19:08 oh I see the name

19:08 GAWD that is pretty

19:08 Willyfrog: really nice, I'll check the code tomorrow

19:09 good night, everyone

19:09 st3fan: callenbot: yes!

19:09 callenbot: click the link under the screenshot and you will see the blog of my extremely talented colleague :)

19:09 jasonjckn: st3fan: is there a big clj community in toronto?

19:10 st3fan: which companies?

19:10 st3fan: i'm originally from newmarket

19:10 st3fan: i'm not sure .. i think we have a lisp user group that also has a number of clojure folks

19:11 brb dinner cookin'

19:12 miloshadzic: callenbot: Mozilla makes/uses Rust, not Go

19:14 callenbot: miloshadzic: Mozilla experiments with Rust

19:14 miloshadzic: it *uses* Go in production

19:15 Servo is still extremely experimental, don't be ridiculous.

19:15 miloshadzic: callenbot: where do they use go? first time I've heard about that

19:15 callenbot: st3fan: already did.

19:15 miloshadzic: Persona

19:15 They're not silly enough to use Node.js for something important to them :)

19:17 tomoj: :D

19:18 miloshadzic: callenbot: not looking to argue but I can't find a mozilla repo or whatever that they use go

19:22 Glenjamin: pretty sure persona is build on node.js

19:22 or it was anyway

19:22 there's a mozilla node.js guy who works on persona at a javascript user group i go to

19:23 and here it is: https://github.com/mozilla/browserid

19:31 callenbot: Glenjamin: it's entirely possible I was lied to, but I was told the backend stuff, including Persona, of late was Go.

19:32 miloshadzic: It is april 1st, maybe it was a joke? :)

19:32 Raynes: callenbot: Ohai.

19:32 Long time no chat.

19:33 callenbot: Raynes: indeed.

19:33 miloshadzic: whois Raynes

19:33 callenbot: Raynes: my next task is to put together a (better) Clojure equivalent to Fabric.

19:33 Raynes: how's life in the land of fake tits?

19:33 Raynes: Mrh.

19:33 Meh*

19:33 callenbot: as i suspected.

19:34 Raynes: LA is fine. It's me that has problems.

19:47 gfredericks: hyPiRion: holy jackwagon man you wrote java code with locking

19:48 tomoj: hmm, my attempt at detecting the status of cljsbuild in notify-command obviously doesn't work :(

19:50 gfredericks: hyPiRion: also this primes thing makes me want to write an efficiently-indexable lazy sequential data structure

19:50 tomoj: I guess the obvious solution is to allow a notify-fn that takes status info and returns a shell command?

19:55 st3fan: callenbot: most mozilla stuff is Python or Node (Persona is Node)

19:56 we have very little Go. AFAIK we don

19:56 't have any Go code for public sites

19:56 callenbot: st3fan: weird. I have a Go nut to correct then.

19:57 * gfredericks wonders how tasty a gonut would be

20:09 Rich_Morin: I'm a noob at IntelliJ, trying to get La Clojure set up with the Community Edition. I'm getting a nastygram from the plugin manager; "Plugin is incomparible with current IntelliJ installation." Help?

20:12 callenbot: Rich_Morin: IntelliJ version?

20:13 Glenjamin: is there a nicer way to do a 'reverse map' than this? (doseq [test tests] (test state))

20:13 Rich_Morin: latest CE - 12.0.4

20:13 Glenjamin: ie. call every item in a collection as a function, with the same arguments

20:14 callenbot: Rich_Morin: last I used it was 11 or 12 worked fine for me insofar as any IDE works.

20:14 Rich_Morin: you're probably going to need to do the usual Google + bugging the developers kabuki dance.

20:14 Rich_Morin: I think restarting it may have done the trick. thx for responding

20:15 callenbot: typical IDE.

20:15 "have you tried turning it off and on again?"

20:18 hyPiRion: gfredericks: oh, yeah, I wanted the speed. And yeah, I wish there were some lazy-vec out there in the wild

20:20 gfredericks: Raynes: laser/and is just every-pred I think

20:21 likewise laser/or => some-fn

20:22 Raynes: gfredericks: Yes, but we still need them to exist in laser under these names.

20:22 Otherwise people will never find them.

20:22 gfredericks: haha

20:22 Raynes: A pull request would be nice for or though.

20:22 (to use some-fn in the body)

20:22 gfredericks: but not for and?

20:23 Raynes: gfredericks: https://github.com/Raynes/laser/blob/master/src/me/raynes/laser.clj#L155

20:23 You could change it to `(def and <docstring> every-pred)` if you want, gfredericks .

20:23 gfredericks: hyPiRion: also http://gfredericks.com/gfrlog/90

20:24 Raynes: oh I've been looking at 1.0.0 in my repl

20:24 Raynes: I will send a pull request so that I can trivially be a contributor which is all I ever wanted

20:27 why does `lein test` not accomplish `lein midje`?

20:27 Raynes: gfredericks: Because life doesn't work like that.

20:27 hyPiRion: gfredericks: because you forgot to set :alias {"test" "midje"}

20:28 gfredericks: Raynes: (def and <docstring> every-pred) kills the helpful metadata from defn :(

20:28 so I will leave it as defn

20:28 Raynes: Indeed.

20:30 gfredericks: You remind me a lot of me when I get to be your age.

20:32 hyPiRion: Raynes: Where are you hiding that time machine of yours

20:36 gfredericks: That was an interesting way of looking at prime generation. I'm just a low-level person who sacrifice memory and readability for locks and cache hits.

20:37 gfredericks: I don't know that mine is very readable

20:37 I tried to explain it to a clojure study group once and ended up just hanging my head in shame

20:38 Raynes: I'm working on the dang css thing but it can haz a bug

20:39 now it doesn't have a bug

20:40 `arrdem: now you see it now you don't, the heisenbug uncertainty principal remains.

20:40 hyPiRion: gfredericks: Well, I understood it fine. Then again, it's not unlikely that I've actually made a similar version, considering all those project euler problems I've tried to solve

20:40 callenbot: gfredericks: what?

20:42 gfredericks: callenbot: what?

20:43 callenbot: gfredericks: what did you fail to explain to a clojure study group?

20:43 gfredericks: where was this study group?

20:44 hyPiRion: callenbot: a lazy iterative prime number generator

20:44 gfredericks: callenbot: at Groupon

20:45 Raynes: https://gist.github.com/fredericksgary/5282642

20:46 hyPiRion: I expect it's not usefully fast; it just satisfied all my idealisms

20:46 * gfredericks pretends that prime-sequence generators are ever useful in general

20:46 callenbot: gfredericks: are you in the Yay?

20:47 hyPiRion: gfredericks: hey, we need one for Swearjure mister

20:47 They're pretty darn important

20:47 gfredericks: callenbot: http://en.wikipedia.org/wiki/Yay

20:47 callenbot: gfredericks: bay area.

20:47 gfredericks: hyPiRion: well that's factoring which is slightly different

20:47 callenbot: no, chicago

21:05 dribnet: having trouble understanding how to extend the reader with a tagged literal in cljs

21:05 anyone have any experience with this?

21:08 callenbot: hyPiRion: Swearjure makes the baby jesus cry.

21:18 ivaraasen: mikera: ping

21:21 bytechunky: ,(list? (cons 1 ()))

21:21 clojurebot: false

21:22 bytechunky: ^^ this really got me by surprise

21:33 dribnet: so, like, data_readers.clj doesn't work for clojurescript...

21:35 cljs.reader/register-tag-parser! seems to work fine, but not so much for the data reader used by the compiler...

21:37 dean: Hi, I'm working on solving the sum product problem with core.logic. I've got the first two steps sort of working (http://pastebin.com/Txaz5e5B). At the minute I've restricted the domain to 17 to keep things fast and it does work but it returns 17 8 times. Anyone have any ideas why that is happening?

21:41 dribnet: is the cljs compiler data reader in clj or cljs space?

21:52 bbloom: dribnet: the compiler's reader is the clj reader written in Java

21:52 dribnet: the runtime reader is written in cljs and only reads EDN, not source code

21:53 dribnet: cljs may move to tools.reader, now part of contrib, which is written in clojure, but should be cross-compilable as cljs

21:53 dribnet: thx. do you know in clj I could hook into *cljs-data-readers*?

21:54 eg: (alter-var-root #'*cljs-data-readers* assoc ...)

21:55 when I throw that into a clj file, I get runtime exception: Unable to resolve var.

21:56 gfredericks: why does (.printStackTrace *e) print nothing in nrepl? o_O

21:56 bbloom: dribnet: ignoring for a moment that this implies a shortcoming in cljs that you might want to file a bug on....

21:56 * gfredericks just figured out that pst takes a depth argument

21:56 bbloom: dribnet: you need to reference the namespace that the var is in

21:57 dribnet: try requiring cljs.tagged-literals

21:57 dribnet: the fully qualified var is #'cljs.tagged-literals/*cljs-data-readers*

21:59 dribnet: right, thanks. that worked.

22:00 i guess the function i provide in this context needs to be a clj function and not a cljs one. that's too bad.

22:00 tomoj: it's basically a reader macro :P

22:00 dribnet: cljs.reader/register-tag-parser! of course works with a cljs function...

22:00 bbloom: dribnet: you're modifying the read table for your SOURCE CODE, the source code is interpreted by a clojure, not clojurescript

22:02 dribnet: right. whereas when I call reader/read-string in cljs, that is interpreted by cljs and not clj.

22:08 hmmm. still not able to modify the read table for my source code as hoped...

22:08 (ns tags

22:08 (:require [cljs.tagged-literals :as t]))

22:08 (alter-var-root #'t/*cljs-data-readers* assoc "js" identity)

22:11 dribnet_: hey bodil. what do you think of a cljs tagged literal for javascript?

22:12 so instead of the runtime (def jso (clj->js {:a 1 :b 2 :c [1 2 3]}))

22:12 there would be the more concise compile time option

22:13 (def jso #js {:a 1 :b 2 :c [1 2 3]})

22:13 tieTYT2: what's the difference between "(def ^:dynamic x 1)" and "(def ^{:dynamic true} x 1)"?

22:14 amalloy: &(binding [*print-meta* true] '(def ^:dynamic x 1))

22:14 lazybot: java.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!

22:14 amalloy: feh. anyway, the point is they're the same

22:15 tieTYT2: ok

22:15 thanks

22:15 theophilusx: Returning to play with clojure again and I find the emacs environment has moved from slime to nrepl - is that correct?

22:15 ivan: man do I hate bindings+laziness

22:15 amalloy: &(binding [*print-meta* true] (pr-str (read-string "(def ^:dynamic x 1)")))

22:15 lazybot: java.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!

22:16 amalloy: ,(binding [*print-meta* true] (pr-str (read-string "(def ^:dynamic x 1)")))

22:16 clojurebot: "(def ^{:dynamic true} x 1)"

22:16 callenbot: theophilusx: yes

22:17 theophilusx: callenbot: thanks.

22:17 callenbot: theophilusx: nrepl + nrepl.el is the standard way of going about this. Moved to that so that other environments could take advantage of the REPL server.

22:19 theophilusx: callenbot: OK, the repl server was just getting going when I was last using clojure. Had to go off on some other work for a while, now back and finding a few changes. Nrepl + clojure-mode seems good. Running from elpa packages. Much easier than getting things working with slime etc

22:19 callenbot: theophilusx: it is easier to get rolling for noobies. I'm still using my dotfiles repo on github, so these sorts of things aren't a "problem" for me.

22:20 theophilusx: I just integrate the code into my pharaonically constructed emacs lisp pile of code and then I'm off to the races.

22:21 theophilusx: callenbot: yes. I still love how easy it is with lein and emacs elpa - after not doing this for a while, took me about 15 minuts to be back up and running and coding. Can't think of another environment that easy and fast!

22:21 callenbot: theophilusx: well - mine. I just clone my git repo and my entire work environment is installed.

22:22 I don't recommend that you use it, just learn from it: https://github.com/bitemyapp/dotfiles/

22:22 theophilusx: callengot: yes, must sort out my git setup better. Obviously an easy way to get things working - especially with mutiple environments etc.

22:23 callenbot: theophilusx: I use a single git-managed environment across like 6 machines.

22:25 theophilusx: Has anyone been using java.jdbc with Oracle 11g databases and if so, how reliable have they found it? I notice it is not one of the officially tested environments. I've got it working, but have run into a couple of 'oddities' (probably me not jdbc!)

22:29 gfredericks: Raynes: I'm having trouble figuring out how to take a fragment of html and add it as content to a full document

22:30 oh wait there is a whole section in the guide on "Documents and fragments" I shall read this using my eyes

22:30 Raynes: gfredericks: Show me your broken codeses?

22:30 lol

22:30 gfredericks: I always expect I will endear myself to library authors by poking them repeatedly while ignoring their documentation

22:32 * gfredericks grumbles about github not having the "Your Fork" button anymore

22:35 amalloy: gfredericks: i just push "Fork" and follow the link to whichever fork i wanted to. this has the nice advantage that i can follow the same steps to go to a fork belonging to an organization i'm a member of

22:38 tieTYT2: http://stackoverflow.com/questions/15736960/what-does-dynamic-do-in-clojure

22:42 gfrederi1ks: Raynes: I think my problem was assuming the to-html function was a reasonable thing to use

22:44 amalloy: recommended change: remove to-html so nobody ever makes that mistake

22:45 gfrederi1ks: I take it back I still have no idea what I'm doing

22:46 mostly I am trying to get the transformation functionality of laser/document without the converting-to-a-string part

22:47 neither laser/at nor laser/fragment seem to do that

22:47 tieTYT2: i'm thinking about buying a clojure book. Is the joy of clojure for someone who already knows clojure but wants to write idiomatically or is it for beginners like me?

22:49 i think I can write a program in clojure, but I'm struggling with topics like meta-data, java interop, etc.

22:49 actually I can't figure out if I'm a beginner or not

22:49 callenbot: tieTYT2: get the cemerick book, not the JoC

22:50 tieTYT2: why's that?

22:50 theophilusx: tieTYT2: I think the Joy of Clojure is an excellent book for both beginner and for someone looking for a book to go back to as they learn and understand more. It is one of my two favorite clojure books - the other being Clojure Programming.

22:51 tieTYT2: are either of these viewable online?

22:52 ah i can

22:52 theophilusx: tieTYT2: both are available as ebooks and both are available inside safari if your a member. I think both publishers offer sample chapters if you just want to see what the style is like.

22:53 tieTYT2: cool man, thanks

23:01 Raynes: gfrederi1ks: I needs to sees some codes.

23:18 callenbot: http://blog.joda.org/2011/11/scala-feels-like-ejb-2-and-other.html

Logging service provided by n01se.net