#clojure log - Apr 12 2013

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

0:01 brehaut: https://github.com/pufuwozu/fantasy-land/

0:14 ivan: too much interop will put the object adaptation industry out of business

1:01 asumu: Hi. Quick question. Anyone know why the "thrush" operators are called that? Google didn't help much.

1:03 Oh, maybe it's a reference to Smullyan's "To Mock a Mockingbird"?

1:04 technomancy: asumu: that's correct

1:09 asumu: technomancy: Thanks, that makes sense, given thrush := lambda a b. b a

1:10 technomancy: asumu: it's not quite the same since thrush in the book is a function and thrush in clojure is a macro, but that's getting pedantic.

1:11 that said if you want to be pedantic you can read http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

1:17 mullr: fogus/bacwn or martintrojer/datalog for in-memory catalog?

1:18 s/catalog/datalog/

3:22 `arrdem: is there a naming convention for lurking tmux/screen connections?

3:41 MrHus: Hi I'm using Cheshire for my json encoding and decoding. No I want to add a custom encoding for a Postgresql array. I have the following code:

3:41 (add-encoder org.postgresql.jdbc4.Jdbc4Array

3:41 (fn [array jsonGenerator]

3:41 (let [sequence (seq (.getArray array))]

3:41 (do

3:41 (println sequence)

3:41 (encode-seq sequence jsonGenerator)))))

3:42 https://gist.github.com/MrHus/d3c385433943a7d57f6c

3:43 However I get the following error: clojure.lang.ArityException: Wrong number of args (4) passed to: generate$generate

3:44 I've used this as a reference: https://github.com/dakrone/cheshire#custom-encoders

3:44 but don't understand what I'm doing wrong.

3:48 jjido: where is generate$generate defined? How many args does it expect?

3:48 MrHus: https://github.com/dakrone/cheshire/blob/master/src/cheshire/generate.clj#L111

3:49 It expects 4 arguments

3:49 https://github.com/dakrone/cheshire/blob/master/src/cheshire/generate.clj#L182

3:49 encode-seq expects 2

3:49 which calls generate

3:50 but I don't know where *date-format* comes from

4:28 clgv: what do I do wrong if I have no autocompletion in the buffer with the sourcecode file in emacs? slime is running

4:42 rodnaph_: has anyone used lein-rpm with success? got any example projects you can link?

4:46 iartarisi: hi! is anyone using clojure-test-mode for emacs? How do I see the whole output of a failed test? (I only see the highlight in my code)

4:53 ah, stupid question, it's in the *nrepl* buffer

4:57 thm_prover: Is there any java library that will let me produce TeX style graphics?

4:57 (without calling TeX)

4:57 I want to create techncal illustrations in Java.

4:59 AimHere: I dunno what TeX graphics consist of; but batik will turn SVG into graphics

5:25 clgv: thm_prover: why not shell out to TeX? because of deployment?

5:26 thm_prover: I want animation

5:26 clgv: so?

5:27 thm_prover: calling tex to create 30fps seems rather unreasonable

5:27 unless you're implying that Tex supports animation itself

5:27 which would e awesome

5:28 clgv: thm_prover: your setup does not allow a pre-calculation of the animation graphics?

5:28 arrdem-lurkin: Computer says no, try "!bot help".

5:28 Computer says no, try "!bot help".

5:28 Computer says no, try "!bot help".

5:28 Computer says no, try "!bot help".

5:28 Computer says no, try "!bot help".

5:28 thm_prover: clgv: I want rela time animation.

5:42 nonuby: in the ns macro :require coupled with :refer is the same as :use with :only right?

5:42 arrdem-lurkin: Computer says no, try "!bot help".

5:56 gkunno: Is there a way to manage project dependencies like: [compojure "1.1.*"] or [compojure ">1.1.0"] so that i would always have the updated version

5:57 weavejester: gkunno: Not really. There's "[1.1.0,)" which will always get the latest version, but that includes snapshots.

5:57 gkunno: ok

5:57 weavejester: There's been some plans about having two clojar repos; one for snapshots and one for release versions

5:58 But that hasn't happened yet to my knowledge

5:58 gkunno: that would be cool

5:58 weavejester: Maven's version range handling is pretty limited unfortunately, and Leiningen uses that behind the scenes.

5:59 gkunno: i been using composer for dependency management and its a really good tool

6:00 (in php :/)

6:00 well, leiningen seem really good too

6:00 so much more included

6:02 CookedGryphon: Does anybody know of a decent clojure library for easily using the java 7 watcher service?

6:03 I want to check for file updates without polling, I found an awesome gist, but it doesn't seem to be packaged up anywhere

6:03 https://gist.github.com/moonranger/4023683

6:18 GR: Hiya. I've recently written a library of data structures that includes a 'vector' implementation similar to Clojure's and I've added a pair of new algorithms. Does that sound interesting to anyone?

6:19 I'm not entirely sure it will work for other implementations, but it is very likely.

6:32 naeg: does (first lazy-seq) consume the whole lazy seq?

6:34 nbeloglazov: naeg: no, it consumes first chunk - 32 elements

6:36 naeg: so (first lazy-seq) == (take 1 lazy-seq) ?

6:38 nbeloglazov: no, (first lazy-seq) returns first element while (take 1 lazy-seq) returns sequence that contains first element. I think they both realize chunk of 32 elements from lazy-seq.

6:40 naeg: why is (first (drop-while ...)) much slower than (take 1 (drop-while ...)) then?

6:43 nbeloglazov: How do you compare them?

6:43 Actually (take ...) also returns lazy seq. So unless you realize it initial collection won't be realized.

6:45 naeg: nbeloglazov: with (time ...). (first ...) takes about 1msec whereas (take 1 ...) takes ~0.4msec

6:47 nbeloglazov: naeg: try (time (doall (take 1 ...))) so that sequence returned by take is realized

6:49 naeg: nbeloglazov: then it's the same, but I get the same result back with and without (doall ...)

6:52 is the time not correctly measured if I just do (time (take 1 lazy-seq))? like only the time to create the lazy seq and it is realized after the measurement and then I get the result?

6:52 nbeloglazov: Yes, exactly

6:52 naeg: I see, thanks

6:58 necronian: I have a function that uses (eval (symbol database)) to turn a string into my korma database object. It works when I call it from inside the namespace the function is defined in. But not from another namespace.

6:58 I don't understand why.

7:05 hyPiRion: ,((-> $ #(* % (({(*) {(+) (*)}} % $) (- % (*))))) 10) ;; new factorial in swearjure

7:05 clojurebot: 3628800

7:05 hyPiRion: A shorter variant, which is amazing

7:17 otfrom: morning all

7:17 does anyone have any suggestions for parsing *very* large json arrays?

7:18 cheshire's parse-seq is a bit too greedy and I'm wondering if I'm missing something before I start coding up something myself

7:21 CookedGryphon: otfrom: depending on the data, quite how large it is and what you want to do with it, have you considered importing it into mongo? That can read json directly, and you could then do advanced queries on the data contained

7:22 i don't know how you'd keep the insertion order trivially though

7:22 but if you didn't care about the order, you could then pull things out lazily through congomongo

7:22 otfrom: not too fussed about the insertion order

7:23 I'd thought about mongo as a possibility. It feels a bit like just relying on mongoloader or similar to do the lazy parsing of the json array.

7:24 CookedGryphon: yeah, it depends what you want to do with it really, if you're only going to scan through and read this array once, then mongo would be a bit of a ridiculous way to do it,

7:24 but if it's a dataset you're going to look at a few times, it might be a more convenient way of storing it

7:26 otfrom: I'm just going to scan it once, but I am going to get a new array each day

7:27 CookedGryphon: hmm, yeah you don't want to be doing a manual import every day

7:27 i take it there's no way to get a stream instead, parse the data as it comes in?

7:28 and use storm or something to set up a pipeline

7:28 robewald: Hello, I am trying to use the clojurescript js->clj function on an domina event object and I just get back the js object instead of a map.

7:29 CookedGryphon: otfrom: anyway, i gtg, good luck

7:29 robewald: the culprit seems to be that line in core/js->clj: (indentical? (type x) js/Object) which is false although I would expect it to be true.

7:30 Any clues?

7:46 cmdrdats: hey guys, in compojure, I'm trying to see from middleware what route matches.. is that even possible?

7:56 Glenjamin: cmdrdats: i don't think so, unless the app, records that in the response

7:56 cmdrdats: ok - I'm putting together a workaround, using clout the same way as compojure.. was hoping there would be a more direct way :/

7:57 Anderkent: Hey, how can I avoid a lot of quote-unquote when writing an anaphoric macro? Example: https://www.refheap.com/paste/13552

7:57 cmdrdats: hating the fact that compojure returns black-box functions instead of data structures from POST / GET and defroutes

7:57 Anderkent: i.e. I don't like how I have to quote-unquote the argument symbols all the time

7:58 Glenjamin: cmdrdats: why do you need this info in the middleware?

7:58 cmdrdats: I need to do authentication based on the matching route

7:58 hyPiRion: ,(let [it 'it] `(+ ~it 4))

7:58 clojurebot: (clojure.core/+ it 4)

7:58 hyPiRion: like that, Anderkent?

7:59 Anderkent: hm, guess that is better, thanks

7:59 weavejester: cmdrdats: That's the disadvantage of function composition; it's very black-box. I've been meaning to write another routing library based on a data structure; less flexible, but more transparent

7:59 Glenjamin: cmdrdats: there are some patterns for wrapping up groups of routes behind authentication middleware

7:59 weavejester: cmdrdats: However, if you need to do authentication on the matching route, why not apply the authentication directly to the route itself?

8:00 So some routes have the authentication middleware on them, and other routes don't.

8:00 cmdrdats: weavejester: you mean, inside the actual endpoint function? I'm kinda wanting to keep those clean from authentication logic

8:00 so that I can't get it wrong in the future

8:00 weavejester: cmdrdats: No, I mean, divide up your routes into those that need authentication and those that don't.

8:01 Glenjamin: (require-auth (defroutes admin ...)) and (defroutes public ...)

8:01 weavejester: The disadvantage of using functions is that they're more opaque, but the advantage is that you can arbitrarily nest middleware.

8:01 cmdrdats: weavejester: oh, no - mine requirement is more finegrained- one user can have access to one route, but not another user

8:02 weavejester: wouldn't it be feasible to return data structures from the defroutes, POST, GET, et al macro's

8:02 weavejester: cmdrdats: Ohh, okay, and there's no way of grouping that? e.g. Friend allows you to label certain routes as needing certain access roles.

8:02 cmdrdats: Well, no, because then you couldn't apply middleware to routes.

8:02 cmdrdats: and then just make handler/site build the black-box functions

8:03 weavejester: cmdrdats: That would mean you could only apply middleware at the top, and you couldn't use higher-level functions to generate routes.

8:03 There's a big advantage to using functions

8:03 cmdrdats: ah, ok

8:03 weavejester: But it trades off against transparency

8:04 cmdrdats: what I've done is write a wrapper macro for my routes now

8:04 weavejester: Ideally we need two libraries; one for routing via a data structure, with all the limitations that has, and one for routing via functions.

8:04 Glenjamin: i wonder if you could get somewhere by just using compojure.core/routes

8:04 wei_: (??? [1 2 3 4 5 6 7] [true false false false true false true]) => [1 5 7]

8:04 cmdrdats: which I can then eval to create the actual compojure routes

8:04 Glenjamin: wait no, thats reutrns a function, ignore me

8:04 snrmwg: does anyone here know and/or use sqlkorma?

8:04 weavejester: But it kinda seems strange that you're doing authentication directly against the routes

8:05 And not assigning roles to sets of routes.

8:05 cmdrdats: weavejester: I'm exposing an API, the API key gets assigned a set of routes

8:06 I can later on put grouping on top of it, but for simplicity, I'd rather leave that seperate

8:06 Glenjamin: can you just tie the auth to URLs in the middleware layer?

8:06 like with http://yogthos.github.io/lib-noir/noir.util.middleware.html#var-wrap-access-rules

8:07 cmdrdats: ye, that's what I'm doing

8:07 Glenjamin: but directly with things like "/item/:id"

8:07 that doesn't match the url "/item/123", unless you run the routing through the same logic as compojure

8:08 tomoj: you can implement a mind reader with nominal logic https://www.refheap.com/paste/ae34df589f4d62e47d771591e

8:08 cmdrdats: which, incidentally, I've just finished doing :P I just compiled all the routes myself using clout like compojure does

8:09 Glenjamin: right, i'm with you now - you want to check auth after the route's been composed, but before the function is evaled

8:10 snrmwg: how can i write a query with sqlkorma where i have different limits dependent on my query parameters? i.e. without any parameter i want max 100 rows, with parameters i want max 20 rows

8:10 cmdrdats: Glenjamin: yep

8:16 Glenjamin, weavejester: https://www.refheap.com/paste/13554 - the pieces I needed to get it to work :)

8:17 not including the actual middleware, but that should be fairly obvious

8:26 Glenjamin: heh, that's really hard to follow!

8:28 cmdrdats: xD - I'm just creating a list of symbols out of my routes, then compiling that with clout into 'compiled', into a route => compiled map

8:28 Glenjamin: yeah

8:28 you still end up searching the routes twice per request

8:28 cmdrdats: ye, totally

8:28 Glenjamin: it might be easier to just add an assert-style form in each route

8:28 maybe hide that behind a macro

8:29 cmdrdats: you mean, route it through an implicit function

8:30 Glenjamin: (authed-route GET "/blah/:id" [id] body) => (GET "/blah/:id" [id] (check-auth "/blah/:id" [id] body)

8:30 cmdrdats: ye, that's a good idea

8:31 and not use strict 'middleware' for the auth

8:32 Glenjamin: especially if you end up looking up the :id against the DB for the auth

8:32 cmdrdats: ye - it also addresses mixing auth'd and non-auth'd functions properly

8:32 routes*

8:34 Glenjamin: aha, there's a generalised version of this concept in express

8:34 http://expressjs.com/api.html#app.VERB

8:35 hrm, it's actually just ->

8:36 cmdrdats: haha

8:37 Glenjamin: (GET "/blah/:id" req (-> req check-auth normal-handler))

8:37 except you lose the compojure sugar for route param destructuring

8:38 or maybe it's more like http://expressjs.com/api.html#app.param - which compojure doesn't have an equivalent of afaik

8:38 anyway, gotta go - good luck!

8:39 cmdrdats: thanks :)

8:47 Anderkent: Idiomatic way to check if a map has given keys and they have truthy values? I came up with (every? true? (juxt :key1 :key2 :key3) map) ...

8:48 (missed parens around juxt and map there)

8:50 arcatan: Anderkent: (every? map #{:key1 :key2 :key3})

8:51 AimHere: Note also that true? doesn't just pick truthy values, it demands actual truth

8:51 truthiness doesn't cut it for the likes of true?

8:51 ,(true? "true)

8:51 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

8:51 AimHere: ,(true? "true")

8:51 clojurebot: false

8:52 arcatan: ,(every? {:a 1, :b nil} #{:a})

8:52 clojurebot: true

8:52 arcatan: ,(every? {:a 1, :b nil} #{:a :b})

8:52 clojurebot: false

8:52 arcatan: ,(every? {:a 1, :b nil} #{:a :c})

8:52 clojurebot: false

8:52 arcatan: yay.

8:52 Anderkent: oups

8:52 thank's for that

8:53 dpathakj: re

8:53 Anderkent: ,(every? identity ((juxt :a :b :c) {:a 1 :b 2 :c 3}))

8:53 clojurebot: true

8:53 Anderkent: ... I created a monster

8:53 ,(every? identity ((juxt :a :b :c) {:a 1 :b 2 :c nil}))

8:53 clojurebot: false

9:01 auastro: hey all

9:02 any of the clojars maintainers around, I need to get my account name changed

9:02 ?

9:04 anyone alive down here?

9:13 Anderkent: auastro: I guess the clojars issue tracker is your best bet (that's what they want for deletion request or group name takeovers), though why not just make a new account and transfer your group names to that account?

9:15 auastro: Anderkent: thanks, I've emailed the contact email twice now, I'd prefer not to put it on the issue tracker, kind of embarrassing actually, put my password in the username field :/

9:15 Anderkent: Ah :P

9:15 auastro: Australian? or just up late?

9:15 Anderkent: European, ain't late here

9:16 anyway technomancy or xeqi might be able to help you

9:16 auastro: I see, we are something like +10 here so it's about lunch time where you are?

9:16 what tz are they in?

9:16 US probably

9:17 Anderkent: Afraid so

9:18 auastro: hmm, well let's hope they respond to my email this time.

9:18 I'm not quite sure why they don't just have a way to delete an account, isn't that like a reasonably important feature?

9:19 Anderkent: not really, and it could get quite confusing since your published artifacts would not get deleted

9:19 borkdude: auastro I tried to change something in clojars once, never got a reply

9:20 auastro: Anderkent: I don't have any published artefacts

9:20 borkdude: :(

9:22 llll: how do i apply modifier key on regexp?

9:23 auastro: llll: sorry don't understand the question

9:23 llll: eg. i want to use "g" for global

9:25 (re-find #"rabbit" "follow the white Rabbit")

9:26 or i for case insensitivity

9:28 Anderkent: you can embed flags with (?<flag>) : ,(re-find #"(?i)aabb" "AABB")

9:28 ,(re-find #"(?i)aabb" "AABB")

9:28 clojurebot: "AABB"

9:28 Anderkent: but not sure how to pass them in otherwise

9:29 llll: Anderkent: thank you

9:43 i am getting an error using cljs

9:43 I'm using ((re-find #"(?i)^.*?<body[^>]*>(.*?)<\/body>.*?$" html) 1)

9:44 Parse error. invalid flag after regular expression

9:44 here is the compilation of the code: cljs.core.re_find.call(null,/^.*?<body[^>]*>(.*?)<\\/body>.*?$/i,p1__24321_SHARP_)

9:45 the error marker is on the first / after null

9:46 Anderkent: Am I right in thinking that the \\/ makes the regex end prematurely and thus it tries to interpret /body as flags?

9:46 otherwise, sorry, I know nothing about clojurescript

9:50 llll: i should just run js in cljs

9:51 how do i eval js in cljs?

9:52 noidi: I know this is a bit unhelpful, but you shouldn't be parsing html using a regular expression in the first place :) http://stackoverflow.com/a/1732454/13340

9:53 llll: but then how do jquerymobile do it :/

9:54 hyPiRion: llll: You should try to parse stuff with instaparse

9:54 dsapala: llll: he didn't say it couldn't be done

9:54 hyPiRion: it's going to be vastly more readable, and you get more power

9:55 rbxbx: llll why don't you just use something like enfocus?

9:57 jjl`: one presumes they built a real parser

9:57 (which is the correct way to do it)

10:01 llll: rbxbx: its a jquery replacer?

10:02 rbxbx: llll no, there is https://github.com/ibdknox/jayq to that effect though.

10:03 AimHere: You should parse html by search/replacing angle brackets to round ones, then writing a macro and running 'eval' on it

10:06 hyPiRion: AimHere: read-string only, not eval

10:06 Eval is for evaluating data

10:06 AimHere: Fair point

10:07 Though why not just booked the string you're reading with "(eval " and ")", for added awesome

10:07 *bookend

10:08 ToBeReplaced: what do people use for logging inside of threading macros? something better than creating an anonymous function that takes in an arg, does logging based on that arg, and returns the arg?

10:09 silasdavis: I'm trying to require this: https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/request.clj

10:10 with this in my (ns ...) block: [ring.util.request :as req]

10:10 but it can't find it

10:10 rbxbx: ToBeReplaced you could use `doto`, I'm not sure if that's conventional though.

10:10 silasdavis: [ring.util.response :as resp] works fine

10:11 I've got [ring/ring "1.1.8"] dependency and lein-rint 0.8.2 plugin if that matters

10:12 ToBeReplaced: rbxbx: that's cute!

10:13 weavejester: silasdavis: You're using a Ring 1.2.0 namespace but your ring version is 1.1.8

10:13 bhenry: silasdavis: [ring/ring-core "1.1.8"]

10:13 rbxbx: ToBeReplaced remember, one should always write cute & clever code. It's the road to longevity.

10:13 bhenry: eehh...

10:14 ToBeReplaced: of course

10:14 bhenry: 1.2.0-beta2

10:15 silasdavis: weavejester, which part is the ring 1.2.0 bit?

10:16 weavejester: silasdavis: The namespace "ring.util.request" was only added in 1.2.0

10:16 silasdavis: You're using Ring 1.1.8, which doesn't have that namespace

10:17 bhenry: silasdavis: https://github.com/ring-clojure/ring/tree/1.1.8/ring-core/src/ring/util here's what you have available.

10:18 silasdavis: ahh, thanks. It seems that friend relies on 1.2 then

10:33 otfrom: in a repeat from earlier: does anyone know a good way to parse huge json arrays? (about 1.5gb)

10:34 cheshire.core/parsed-seq seems a bit too eager

10:34 dakrone: otfrom: how so?

10:35 otfrom: my json looks like this (ish): [{"foo" : 1}, {"foo" : 2}...]

10:35 so calling first on parsed-seq gives me the whole array

10:35 xeqi: borkdude: what did you need changed in clojars? I might have missed the request

10:36 zamaterian: otfrom, maybe https://github.com/mmcgrana/clj-json/blob/master/src/clj/clj_json/core.clj#L43 can do the trick ?

10:36 dakrone: otfrom: so, parsed-seq returns a sequence of objects, in your example you have only a single object

10:37 zamaterian: that's the same basic implementation

10:37 otfrom: dakrone: basically, yes

10:38 borkdude: xeqi https://www.refheap.com/paste/13560

10:38 xeqi november 2011 ;)

10:38 dakrone: otfrom: so in order to take advantage of laziness, you'll need to separate the one object into separate objects

10:39 xeqi: borkdude: ah, before my time then :p now I should only feel bad about missing auastro's

10:39 otfrom: dakrone: I'm guessing that is outside of what cheshire does

10:40 borkdude: xeqi deleted the message again

10:40 xeqi: borkdude: still want it removed?

10:40 borkdude: xeqi yes

10:40 xeqi nobody is using it anyway

10:40 xeqi: borkdude: done

10:40 borkdude: tnx

10:41 otfrom: zamaterian: thx. I'll look at that too

10:41 dakrone: otfrom: for example: (first (parsed-seq (StringReader. "{\"foo\":1}\n{\"bar\":2}"))) returns {"foo" 1}

10:42 otfrom: if you want recursive laziness, I don't know of any JSON parser that does that yet

10:42 borkdude: xeqi I thought it was better to just use org.clojars.borkdude

10:43 otfrom: dakrone: thx. That was what I was finding from reading and testing things and I was wondering if I was missing something.

10:44 dakrone: sounds like I need the json equivalent of a SAX parser.

10:46 dakrone: otfrom: it's a neat idea and would be cool to have a lazy-tree of json parsings

10:46 otfrom: dakrone: perhaps one of those new parser libraries... ;-)

10:47 zamaterian: otfrom, clj-json uses jackson for parsing. jackson does support stream parsing see : http://wiki.fasterxml.com/JacksonInFiveMinutes#A.22Raw.22_Data_Binding_Example

10:47 dakrone: zamaterian: cheshire uses jackson also, and cheshire's stream parsing is the same implementation

10:47 since it was originally based on clj-json

10:48 otfrom: yea, would have to be an optional thing though, since it would not perform as well (but would be better for memory usage)

10:53 otfrom: dakrone: yep

11:10 mklappstuhl: A few friends of mine and I would like to crunch some numbers and financial market seems to provide lots of room to get creative... whats the best datasource thats out there for this kind of stuff? I guess parsing CSVs from Yahoo isnt it

11:13 nDuff: mklappstuhl: Hrm. There's a startup here in Austin that specializes in just that kind of thing (assembling datastores, whether publicly available or otherwise), but their name escapes me at the moment.

11:16 gfredericks: w00h00, I think my ->/->> patch will get into 1.6

11:17 the-kenny: http://clojure.org/lisps says "In Clojure nil means 'nothing'. It signifies the absence of a value, of any type, and is not specific to lists or sequences.". (get {:a nil} :a 1) returns nil. Shouldn't the not-found value (1) kick in, as 'nothing' can obviously not be found (e.g. ":a doesn't map to anything")

11:17 bbloom: gfredericks: it sems like Rich is on JIRA duty today :-P

11:20 CookedGryphon: the-kenny: yeah, but they *key* exists and can be found, just the thing that's been put in that placeholder is nothing

11:20 gfredericks: ha

11:20 the-kenny: Hm

11:22 ppppaul: can someone give me pointers on making pretty walk functions

11:27 bbloom: ibdknox: damn you and your lighttable stealing some of my file associations!

11:28 mdeboard: ppppaul: Walk what? file paths?

11:38 TimMc: gfredericks: Oh no, we were gonna use that bug for Swearjure! I think.

11:40 gfredericks: I think clojure.template may help with the problem that caused me to want inner-macros.

11:41 (The #=(arity 3) thing.)

11:42 borkdude: ,(= 3 3.0) ;; nice

11:42 clojurebot: false

11:43 TimMc: ,(== 3 3.0)

11:43 clojurebot: true

11:44 borkdude: ah cool

11:45 $findfn 3 3.0 true

11:45 lazybot: [clojure.core/== clojure.core/not= clojure.core/distinct? clojure.core/>= clojure.core/<=]

11:49 clgv: http://starlogs.net/#clojure/clojure

11:53 TimMc: I tried using this autodoc thingy, but it doesn't seem to work! I guess I'll have to go back to writing my docstrings by hand.

11:53 False advertising, I tell you.

12:03 S11001001: too bad we can't infer core.typed toplevel term types

12:03 then could generate free theorems from them and call those autodocs

12:07 TimMc: S11001001: hyPiRion used your -> idea to come up with a factorial fn one-liner that can be passed around. Very cool.

12:08 S11001001: TimMc: great, one step closer to taking over all clojure dev

12:09 TimMc: The trick should work for all simple-recursive fns.

12:10 Still no closures.

12:10 ppppaul: mdeboard, clojure.walk/prewalk postwalk

12:11 wondering about idioms for those functions

12:17 DerGuteMoritz: what's a good way to have some dirty unsafe mutable place? currently I'm using an object-array with one slot which works but feels a bit clumsy :-)

12:17 ppppaul: huh?

12:17 DerGuteMoritz: huh!

12:18 ppppaul: DerGuteMoritz, you could use an atom

12:18 sometimes a var is ok

12:18 DerGuteMoritz: yeah well that's safe and clean :-)

12:18 I don't want any synchronization etc.

12:18 ppppaul: dynamic var is dirty

12:18 DerGuteMoritz: no thread-safety

12:18 ah, can I set! a dynamic var? I thought I couldn#t

12:19 ppppaul: (bindings [my-dirty-var new-value] my-fn)

12:19 DerGuteMoritz: ah no I need to mutate it

12:19 it's a variable I close over in a proxy

12:20 ppppaul: you can do with-redefs

12:20 DerGuteMoritz: unlike deftype, proxy doesn't provide a way to add attributes

12:20 ppppaul: maybe alter-var (though i haven't had success with that)

12:20 DerGuteMoritz: with-redefs also only affects the body

12:20 yeah, alter-var-root would work

12:20 ppppaul: you can do (def thing 1) (def thing 2)

12:21 DerGuteMoritz: ppppaul: it's a local variable I close over, not a global var

12:21 ppppaul: oh

12:21 DerGuteMoritz: I could perhaps instantiate clojure.lang.Var or something

12:21 ppppaul: lol

12:21 DerGuteMoritz: but that doesn't seem much better :-)

12:21 ppppaul: you are doing crazy things

12:22 DerGuteMoritz: yeah, just a little friday afternoon goofing around

12:22 ppppaul: alter-var-root ftw

12:23 DerGuteMoritz: well, alter-var-root involves a function call!

12:23 I mean one more than my current aset approach

12:25 ,(let [x (clojure.lang.Var/create 1)] @x)

12:25 clojurebot: 1

12:25 DerGuteMoritz: that even works heeh

12:25 ppppaul: ,(let [x (clojure.lang.Var/create 1)] x)

12:25 clojurebot: #<Var: --unnamed-->

12:26 DerGuteMoritz: yep! :-)

12:26 ppppaul: woah

12:26 this is new to me

12:26 * DerGuteMoritz spreads bad practice

12:27 ppppaul: time to make a blog and show people how to program in clojure just like they do in their language of choice

12:27 DerGuteMoritz: too bad it just was april first

12:28 ppppaul: going to have to wait a year

12:28 so, you should start writing and not release anything until next april first

12:29 they you can have lots of interesting topics, like clojure for c++ users, without any of the benefits of using clojure at all. hack in some text macros too

12:29 clojure preprocessor is best preprocessor

12:31 S11001001: ppppaul: When you bind a value, you have to supply an expression that "destroys" it for when it goes out of scope.

12:31 TimMc: ,(let [b (clojure.lang.Box. 5)] (set! (.val b) 42) (.val b))

12:31 clojurebot: 42

12:32 ppppaul: woah

12:32 this code is making my eyes hurt

12:35 TimMc: I'm having trouble writing a templating macro: https://gist.github.com/timmc/5373281

12:36 I want to write a deftype that has nearly the same body for each of its methods, but the bodies vary in what methods and arg names they use in interop calls.

12:36 I've taken a stab at writing what I think I want my source code to eventually look like, but even that isn't quite right.

12:37 A big part of the problem is that I want to splice-inject forms, not just inject them.

12:38 technomancy: TimMc: whoa, what?

12:38 Box, huh

12:39 ppppaul: ,(clojure.lang.Box. 5)

12:39 clojurebot: #<Box clojure.lang.Box@1501d0c>

12:39 ppppaul: i could use a Box

12:40 ,(seq (clojure.lang.Box. 5))

12:40 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Box>

12:40 technomancy: been around since 2006

12:41 DerGuteMoritz: TimMc: thanks a lot, Box clearly is the cleanest way to implement this dirty bit :-)

12:42 TimMc: It at least telegraphs your intention.

12:42 DerGuteMoritz: yep

12:43 TimMc: technomancy: I think every Java library of sufficient size has a Box class.

12:43 DerGuteMoritz: that is, my intention to cause trouble!

12:44 technomancy: TimMc: I think knowing you need a Box class requires a certain level of sophistication

12:45 TimMc: Actually, I do see one-element arrays used a lot in Java libs. It's a more opaque idiom.

12:46 The use-case is almost always for allowing a "closure" to send back some data.

12:46 ppppaul: ...

12:46 woah

12:46 TimMc: (because Java inline classes can only refer to final references)

12:47 technomancy: that's how Mirah implements closures IIRC

12:52 DerGuteMoritz: excellent, I now have a criminally offensive function to turn a (potentially lazy) seq of strings into an InputStream!

12:53 maybe I could have implemented it easier with gen-class rather than proxy though

12:54 wink: yogthos: did you do any performancetests with luminus or got any resources where to start looking?

12:54 yogthos: I'm basically a noob with JVM stuff in production, but it all felt really slow (just an enhanced guestbook app)

12:58 nDuff: wink: In terms of the JVM in general -- it's designed to maximize throughput after a long, slow spinup time, so the details of how benchmarking is done matter.

13:00 wink: nDuff: siege -c 10 -r 100 as a rough basic test

13:00 squidz: what would be the best way to write this in clojurescript with domina? https://www.refheap.com/paste/13569

13:01 nDuff: wink: *nod*; second instance of that run against a server should be fair. I'd throw away the first one.

13:01 wink: nDuff: yup. I'm playing aroudn witrh concurrency levels, but that one above only did 15 req/s on my c2d notebook

13:01 nDuff: wink: anyhow -- standard Java-centric tools, ie. YourKit, work well.

13:02 wink: nDuff: ah, thanks, I only know of visualvm

13:02 nDuff: wink: ...a lot of the time when you see really, really awful performance, it'll be related to garbage collection; tuning memory parameters can help a lot with that if it's not something with a clear code fix.

13:07 squidz: its jquery, but i dont know any jquery, so how could I do this with domina?

13:41 yogthos: wink: hey so for performance testing there's a few options

13:41 wink: siege is definitely a good one, but if you want to see what's happening in the code that makes it run slow you can use a profiler

13:42 the jvm ships with jvisualvm and if you run it and connect to a process you can see where the cycles are going

13:42 wink: yeah, probably a good idea :)

13:42 yogthos: wink: I've got a tutorial on that here http://yogthos.net/blog/24-Reflecting+on+performance

13:43 wink: yogthos: awesome, thanks

13:43 yogthos: I really like luminus so far, good job :)

13:44 yogthos: squidz: this should work

13:44 (->

13:44 (by-id "datetimepicker4")

13:44 (.-datetimepicker)

13:44 (.-pickTime false))

13:45 squidz: assuming datetimepicker is a property

13:45 wink: glad to hear it :)

14:02 DerGuteMoritz: thinking about it again ISTR seeing some library that turned seqs into InputStreams ... is anyone aware of something like it?

14:04 amalloy: seqs of what? you can't just turn an arbitrary seq into an input stream

14:05 DerGuteMoritz: well, based on a protocol to turn things into byte seqs

14:08 borkdude: what is the best intro to clojure philosophy talk out there?

14:12 stuartsierra: borkdude: Maybe "The Value of Values" http://www.infoq.com/presentations/Value-Values

14:12 borkdude: or if you will, best Rich Hickey talk to watch for someone new?

14:12 stuartsierra ok cool, thank you. I'm looking for something I can show in class next monday

14:13 stuartsierra: np

14:16 amalloy: DerGuteMoritz: it's not what you're asking for, but gloss may be what you want

14:17 ppppaul: anyone can give me their thoughts on this lib (testing) https://github.com/jaycfields/expectations

14:18 DerGuteMoritz: amalloy: ah yeah, gloss is cool :-) but no, in my case I am looking for something to turn a seq of strings into an OutputStream; I now have a working proxy based implementation and thinking of maybe packaging it up as a generic library

14:18 noidi: brudgers, I really like Simple Made Easy http://www.infoq.com/presentations/Simple-Made-Easy

14:19 oops

14:19 that was meant for borkdude :)

14:19 amalloy: into an output stream? surely you mean an input stream

14:19 borkdude: noidi thanks

14:19 DerGuteMoritz: amalloy: ah, yes, right

14:20 I am now trying a gen-class based implementation, I have a hunch that it might be less hacky

14:20 amalloy: anyway, that's sorta one unnecessarily monolithic problem: if you break it up into (1) turn a string into an input stream; and (2) turn a seq of input streams into another input stream, then you will find available easy solutions for both things

14:21 DerGuteMoritz: amalloy: (1) is easy, are you aware of an existing solution for (2)?

14:21 amalloy: https://github.com/flatland/io/blob/develop/src/flatland/io/core.clj#L30-L38

14:22 DerGuteMoritz: cool!

14:22 that library looks like what I had in mind :-)

14:22 thank you!

14:25 gfredericks: I did not know about SeqEnumeration

14:26 amalloy: gfredericks: i told you about it yesterday, but i think you had already gone

14:26 gfredericks: I implemented it myself in a thread-dangerous way

14:27 amalloy: well, enumerations are implicitly not threadsafe anyway, right?

14:27 ppppaul: anyone using expectations in clojure?

14:29 gfredericks: amalloy: well you'd hope two threads wouldn't call .nextElement and get the same result?

14:31 amalloy: gfredericks: in java, i wouldn't expect such a hope to be well-founded

14:32 for example, java.util.ArrayList produces an iterator which doesn't satisfy your hopes

14:33 and, in fact, clojure.lang.SeqEnumeration has exactly the same "problem"

14:33 you're just not supposed to use iterators or enumerations from multiple threads

14:35 DerGuteMoritz: amalloy: thanks for pointing me at java.io.SequenceInputStream and clojure.lang.SeqEnumeration, a beautiful solution!

14:48 gfredericks: amalloy: I mean if I was to go about implementing an Enumeration that might be something to aim for

14:49 but perhaps as you say it's not worth the overhead

14:49 if clients aren't expected to multithread it

14:50 curious -- if you're implementing it in clojure and have no need for thread-safety, are atoms still the most straightforward approach?

14:51 the only other option I know of is some kind of mutable field on a deftype

14:55 amalloy: gfredericks: you can use an atom and still be thread-safe. i don't understand the question

14:55 gfredericks: right but if you don't _need_ to be threadsafe and therefore don't _need_ to use an atom

14:56 might you do it anyways just because it's so easy?

14:56 amalloy: well, i'd probably use a ref

14:56 gfredericks: e.g., the java version of SeqEnumeration does not use an atom

14:56 amalloy: but yeah

14:56 gfredericks: because from java it would be much more of a hassle

14:57 amalloy: right

14:57 borkdude: a var? ;)

14:57 *ducks*

14:58 gfredericks: (java ISeq v = seq(coll))

15:00 lynaghk: ping: dakrone

15:00 dakrone: lynaghk: pong

15:00 DerGuteMoritz: gfredericks: haha, I asked exactly the same question a few hours ago

15:00 gfredericks: clojure.lang.Box is a good way

15:01 ,(let [x (clojure.lang.Box. 1)] (.val x))

15:01 clojurebot: 1

15:01 DerGuteMoritz: ,(let [x (clojure.lang.Box. 1)] (set! (.val x) 2) (.val x))

15:01 clojurebot: 2

15:01 DerGuteMoritz: alternatively, (object-array 1) with aset and aget

15:01 technomancy: looks like Box is used internally in some implementations of maps

15:01 lynaghk: dakrone: I think the generators in cheshire 5.1.0 got borked when the key-fn functionality was added

15:02 DerGuteMoritz: technomancy: ah, for transients I think

15:02 lynaghk: dakrone: I'm getting an arity exception when trying to call cheshire.generate/encode-map

15:02 gfredericks: man I just started using key-fn yesterday

15:02 DerGuteMoritz: at least in the cljs implementation of PersistentHashMap

15:02 gfredericks: it's been working fine for me though

15:02 dakrone: lynaghk: hrm, that's no good, can you gist an example?

15:03 lynaghk: dakrone: yeah, one sec; I'm also happy to submit a pull but wanted to ask you about it first

15:04 DerGuteMoritz: does lein repl :headless :port work for anyone? it doesn't seem to honor the port I'm passing

15:06 lynaghk: dakrone: https://gist.github.com/lynaghk/5374327

15:07 dakrone: lynaghk: thanks, I'll check it out

15:08 lynaghk: dakrone: here's the offending line: https://github.com/dakrone/cheshire/blob/master/src/cheshire/generate.clj#L219 I can either add an empty key-fn to the encode-* functions that call generate or add the 4-arity case to the generate fn.

15:11 dakrone: lynaghk: I see the issue, I'll send nil as the key-fn, looks like encode-seq needs to be fixed also

15:12 lynaghk: dakrone: okay, awesome. thanks dakrone. Do you have a rough ETA on an official release containing those fixes?

15:12 dakrone: lynaghk: less than 30 minutes maybe?

15:12 :)

15:12 lynaghk: dakrone: Make sure you get a few beers or coffees out of me if we're ever in the same place

15:22 ivan: &{Float/NaN 3 Float/NaN 4}

15:22 lazybot: java.lang.IllegalArgumentException: Duplicate key: Float/NaN

15:22 ivan: &(assoc {Float/NaN 3} Float/NaN 4)

15:22 lazybot: ⇒ {NaN 4, NaN 3}

15:22 Bronsa: huh

15:25 ivan: &(= Float/NaN Float/NaN) ; Bronsa

15:25 lazybot: ⇒ false

15:26 Bronsa: , (let [x Float/NaN] ({x 1} x))

15:26 clojurebot: nil

15:26 Bronsa: &(let [x Float/NaN] ({x 1} x))

15:26 lazybot: ⇒ nil

15:27 Bronsa: &(let [x {Float/NaN 1}] (map x (keys x)))

15:27 lazybot: ⇒ (1)

15:28 ivan: &(let [x {Float/NaN 3}] (= x x))

15:28 lazybot: ⇒ true

15:28 ivan: Python is similarly "broken"

15:28 borkdude: is def thread safe?

15:29 nDuff: borkdude: Setting atoms involves locking.

15:29 err, vars

15:29 Bronsa: ,(let [x {Float/NaN 1}] (map x (keys x)))

15:29 clojurebot: (nil)

15:29 Bronsa: &(let [x {Float/NaN 1}] (map x (keys x)))

15:29 lazybot: ⇒ (1)

15:29 Bronsa: wtf.

15:29 amalloy: ivan: it's a brokenness that is required by the IEEE floating-point spec

15:29 borkdude: I wonder what things could go wrong with this: http://stackoverflow.com/questions/15979151/can-i-refer-to-a-clojure-hashmap-value-from-another-value-in-the-same-map/15979322

15:29 nDuff: borkdude: so, you get more concurrency from using atoms

15:29 Bronsa: &*clojure-version*

15:29 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

15:29 Bronsa: ,*clojure-version*

15:29 clojurebot: {:major 1, :minor 5, :incremental 0, :qualifier "RC6"}

15:29 Bronsa: uh uh

15:31 amalloy: I understand why ({Float/NaN 1} Float/NaN) would return false, but it looks to me like (let [x {Float/NaN 1}] (map x (keys x))) should return 1 as it did in 1.40

15:31 1.4,0*

15:32 am I right or ..?

15:32 s/false/nil

15:33 dakrone: lynaghk: Cheshire 5.1.1 released, should be good to go. I also added a test using every one of the custom helpers, so hopefully it won't happen it the future

15:33 lynaghk: thanks for catching it and letting me know!

15:33 gfredericks: ,(= Float/NaN Float/NaN)

15:33 clojurebot: false

15:35 devn: Given: (foo (bar (baz qux))) id like to know how many layers deep it is. for instance (how-deep (foo (bar (baz qux)))) => 3

15:35 amalloy: Bronsa: probably not. getting NaN out of a map is something that should be impossible, since you should never be able to find an object that is equal to the key

15:36 Bronsa: ,(let [x Float/NaN] (= x x))

15:36 clojurebot: false

15:36 Bronsa: right

15:36 then it was broken back in 1.4.0

15:37 amalloy: i expect it changed when rich added EquivPred

15:37 Raynes: ibdknox: I don't like surprises. Tell me what the surprises are.

15:37 Bronsa: yeah

15:37 I wonder if NaN should be allowed at all as a key

15:37 amalloy: Bronsa: NaN isn't the only thing that behaves this way. you can't forbid them all

15:38 (you can advise against them all, of course, but you can't throw an exception)

15:38 devn: amalloy: in 4clojure where is the code to calculate the golf score?

15:38 amalloy: devn: it's just (count (remove whitespace? soln))

15:39 borkdude: Raynes IE6 support in LightTable?

15:39 devn: oh, okay.

15:39 amalloy: you can just write how-deep yourself; it's not a hard recursive function

15:39 Bronsa: meh. I guess you're right, thanks amalloy

15:39 devn: amalloy: yeah, you're right

15:39 thanks

15:40 ivan: I would guess no one thinks = should deep-descend everything to make (let [x {Float/NaN 3}] (= x x)) false

15:42 perhaps collections could taint themselves with a "I cannot possibly be equal to myself" flag

15:48 lynaghk: dakrone: awesome! thanks again for the quick fix.

15:53 TimMc: ,(let [x {Float/NaN 5}] (= x x))

15:53 clojurebot: true

15:54 TimMc: ,(let [x {Float/NaN 5}] (= x (into {} x)))

15:54 clojurebot: false

15:54 TimMc: Anyway, using numbers as keys is kind of sketchy.

15:54 Especially floats.

15:56 mefesto: ,(= Float/NaN Float/NaN)

15:56 clojurebot: false

15:56 mefesto: interesting

15:58 Okasu: mefesto: Nope.

15:59 ,(= 1.0 0.99999999999999999)

15:59 clojurebot: true

16:00 metellus: ,(- 1.0 0.99999999999999999)

16:00 clojurebot: 0.0

16:00 pjstadig: ,(.equals Float/NaN Float/NaN)

16:00 clojurebot: true

16:00 asteve: ,(= 1.0 0.9999

16:00 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

16:00 asteve: )

16:00 ,(= 1.0 0.9999)

16:00 clojurebot: false

16:01 asteve: how many 9's = repeating

16:01 ?

16:01 Okasu: ,(count "99999999999999999")

16:01 clojurebot: 17

16:01 asteve: (= 1.0 9999999999999999)

16:01 ,(= 1.0 9999999999999999)

16:01 clojurebot: false

16:01 asteve: ,(= 1.0 99999999999999999)

16:01 clojurebot: false

16:01 asteve: whoops

16:02 (= 1.0 0.9999999999999999)

16:02 ,(= 1.0 0.9999999999999999)

16:02 clojurebot: false

16:02 asteve: damnit

16:02 ,(= 1.0 0.99999999999999999)

16:02 clojurebot: true

16:02 mefesto: heh

16:02 asteve: that's what happens when you make a mistake in your irc history; you're bound to repeat it :)

16:03 AimHere: Those who do not log the past are condemned to repeat it

16:04 mishok13: are there any test coverage tools that work with Midje?

16:07 Okasu: ,(= 1.0 (reduce + (repeat 10 0.1)))

16:07 clojurebot: false

16:07 Okasu: ,(reduce + (repeat 1000 0.1))

16:07 clojurebot: 99.9999999999986

16:08 patchwork: lovely

16:08 alindeman: Does using clojure.xml require something other than just (:require [clojure.xml]) in my ns declaration? Getting a ClassNotFoundException when running `lein jar`

16:09 kanwei: [org.clojure/data.xml "0.0.7"]

16:09 what i use at least :)

16:10 MarcoPolo: ,(= 1.0M (reduce + (repeat 10 0.1M)))

16:10 clojurebot: true

16:10 alindeman: kanwei: Is clojure.xml gone in favor of clojure.data.xml?

16:10 kanwei: I'm finding it hard to figure out when things came in and out of clojure

16:11 The docs I have seem to say that clojure.xml is shipped with clojure?

16:11 kanwei: i just did (require 'clojure.xml)

16:12 technomancy: IIRC clojure.data.xml is better but requires an additional dependency

16:12 kanwei: both seem to work here

16:18 stuartsierra: To my knowledge, nothing has been *removed* from the Clojure language distribution.

16:27 technomancy: «As to why xml and zip are in Clojure: because I wrote them, and: zip is non-trivial and without it people would have wondered how to manage these immutable trees, and XML was simply to show, early on, how to "get into Clojure data structures ASAP", an important model for all libraries.» - https://groups.google.com/group/clojure/msg/58ec09f7de93f1d9 (rich)

16:29 dakrone: stuartsierra: seq-contains? was removed

16:29 Okasu: ,((juxt #(reduce + %) #(reduce - %)) [1 2 3])

16:29 clojurebot: [6 -4]

16:29 Okasu: ,((juxt (partial reduce +) (partial reduce -)) [1 2 3])

16:29 clojurebot: [6 -4]

16:30 dakrone: stream? was removed

16:31 technomancy: I thought stream? was only ever on a branch

16:31 TimMc: ,((apply juxt (map (partial partial apply) [+ -])) [1 2 3])

16:31 clojurebot: [6 -4]

16:31 TimMc: Okasu: ^

16:32 dakrone: technomancy: dunno, just doing a `git log | fgrep remove` and looking at what's been removed from clojure

16:34 technomancy: I think stuart was implying nothing that made it into a release was then removed

16:39 stuartsierra: yes

16:40 dakrone: removed at all, or removed without feature-parity workaround?

16:41 because add-watcher and remove-watcher were removed, although they can be implemented in terms of add-watch (but not exactly the same)

16:43 still, stuartsierra's point stands, and it's very difficult to find things that have been removed

16:49 kanwei: i really like that about clojure, coming from a python background where every release was different :)

16:50 we had to maintain a branch for 2.4, 2.5, 2.6, and 2.7

16:52 gfredericks: I think rich's plan is to leave deprecated features indefinitely

16:52 in the same way that j.u.Date is still around

16:53 Okasu: ,((apply juxt (map (partial partial apply) [+ -])) ((reduce (partial partial reduce) (repeat 1 partial)) [1 2 3]))

16:53 clojurebot: [6 -4]

16:53 Okasu: TimMc: ^

16:56 ,((comp + + + + + + - - - - - - - +) 1 1)

16:56 clojurebot: -2

16:57 Okasu: ,((comp = + + + + + + - - - - - - - +) 1 1)

16:57 clojurebot: true

17:01 pl6306: How do I use regex in clojure to find a line that starts with "TODAY=" in string?

17:02 SegFaultAX: pl6306: re-seq probably.

17:03 metellus: or re-find or re-matches, depending

17:03 something in that family

17:03 ToBeReplaced: ,(re-matches #"TODAY=." "TODAY=FRIDAY")

17:03 clojurebot: nil

17:03 ToBeReplaced: oops

17:04 #"TODAY=.*"

17:04 pl6306: thanks i got it (defn get-singleline-property "Extracts single line properties from  File." [field sss]  ((split (re-find (re-pattern (str field "=.*")) sss) #"=") 1))

17:04 Thanks

17:05 SegFaultAX: ,(re-seq #"^TODAY=(.*)" sss)

17:05 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sss in this context, compiling:(NO_SOURCE_PATH:0:0)>

17:06 SegFaultAX: ,(let [sss "TODAY=123\nNOT_TODAY=456\nTODAY=abc"] (doall (re-seq #"^TODAY=(.*)" sss)))

17:06 clojurebot: (["TODAY=123" "123"])

17:06 pl6306: How do something like skip lines (a seq) until I hit say "BEGIN" and stop after "END"?

17:07 ToBeReplaced: drop-while take-while

17:07 pl6306: Cool

17:07 thanks

17:08 wink: breaking news: as soon as you don't benchmark shitty hardware, the results aren't disapppointing anymore

17:15 SegFaultAX: Clojure's regex flags are weird.

17:18 pl6306: You can add a (?m) to the start of that regex snippet I gave you to enable multiline mode.

17:22 squidz: what needs to be done to make the compiled clojurescript smaller?

17:23 TimMc: SegFaultAX: s/Clojure/Java/

17:24 dnolen: squidz: I don't see much room for improvement unless you're talking about more trivial programs. We could probably do smarter things here and there.

17:24 SegFaultAX: TimMc: Are the inline flags available in plain old Java re?

17:25 squidz: dnolen: because I think I heard somewhere that clojure in clojure would reduce the size. Am I mistaken

17:25 SegFaultAX: dnolen: Does clojurescript compress well? Does closure do anything to help?

17:26 pl6306: How I split a string by say "\r\n" or "\n"?

17:26 dnolen: squidz: huh, not sure how C-in-C will help with that, it's still work that needs to be done.

17:26 SegFaultAX: it does compress well, we produce the kind of code that Closure was desgned to optimize.

17:27 squidz: dnolen: okay so the size probably isnt going to improve much?

17:27 dnolen: squidz: for trivial programs yes, for non-trivial programs we're already doing very well.

17:28 guns: pl6306: clojure.string/split-lines

17:28 squidz: by compressing are yall talking about using google closures optimization?

17:28 dnolen: http://blog.sethladd.com/2013/03/i-shrunk-my-dart-to-js-code-by-11x-and.html

17:29 we're doing about as well as Dart compression-wise, and Dart has way more engineers on it.

17:29 MarcoPolo: What's left to use sourcemaps with clojurescript, and how can I help?

17:29 dnolen: we get a lot for free from Closure

17:30 kanwei: dnolen: off top of your head, any idea what a "smallish" cljs gzipped total would be?

17:30 dnolen: MarcoPolo: read the code, we need to swap in tools.reader and fix emission

17:30 kanwei: i'm an angularjs developer and it's 80k gzipped

17:31 dnolen: kanwei: the smallest I've see is ~19k, I think 80k gzipped is about right for small applications.

17:31 kanwei: that's really good

17:31 squidz: awesome, i didnt know it was that good

17:32 kanwei: now if someone would port angularjs to cljs :)

17:32 dnolen: kanwei: hehe, people seem to be happy using angularjs from cljs

17:32 kanwei: angular supports advanced compilation no?

17:32 squidz: I havent had any luck turning closures optimizations on yet. What can be done to help make clojurescript code take advantage of closures optimizations?

17:33 dnolen: squidz: closure optimizations are all about code size, we do our own optimizations for perf (which kicks in if you used the advanced setting).

17:33 kanwei: dnolen: never tried advanced, i need jquery and some other stuff for my current project

17:33 dnolen: kanwei: gotcha

17:34 kanwei: dnolen: do futures work in cljs?

17:35 dnolen: kanwei: they do not

17:35 kanwei: dnolen: i've seen your talk on Oz, having read the book myself, i'm a big fan of dataflow vars

17:36 i think futures can "kind of" replace dataflow vars

17:38 scottj: dnolen: doesn't look like angular js works with advanced mode https://github.com/angular/angular.js/pull/1951

17:39 dnolen: kanwei: yes dataflow vars are cool. futures could probably be made to work w/ some compiler hacking - but I haven't looked at it much and people seem to be coming up w/ other solutions that work well enough.

17:39 TimMc: SegFaultAX: Yeah, Clojure regexes are just Java regexes, straight-up.

17:40 The Clojure reader provides some syntax that allows for fewer backslashes, that's all.

17:40 SegFaultAX: TimMc: TIL. I've never used the (?mix) style switches in Java. I just use the appropriate constants.

17:41 kanwei: sorry my internet died

17:41 dnolen: any thoughts on dataflow concurrency in cljs?

17:42 dnolen: kanwei: not really, beyond I think it would be cool, but I haven't looked into much myself.

17:46 TimMc: alexbaranosky: clj-schema's reporting for :or predicates can be really misleading. Are there plans to change this?

17:55 SegFaultAX: Eheh http://starlogs.net/#clojure/clojure

17:58 wink: SegFaultAX: htpt://starlogs.net/#s-t-a-r-w-a-r-s/episode-iv beats all

18:38 n_b: Anyone have experience using Scala within a clojure project?

18:40 technomancy: n_b: there's a lein-scalac plugin, but it's kind of a proof-of-concept more than anything else

18:41 callen: The next time I try to share some professional experience with somebody and the say, <nasal voice>"well that's anecdote"</nasal voice> I am going to go volcanic.

18:41 technomancy: sometimes I think Scala is design-by-checklist.

18:41 which is regrettable, because I find about 1/3 of the checklist intriguing.

18:41 technomancy: callen: that's how I imagine D

18:42 pokemon-oriented programming. gotta catch all the paradigms.

18:42 callen: technomancy: yep. Although I think half of that was Alexandrescu laughing in his evil lair exclaiming, "MORE POWER!"

18:42 n_b: callen: You'll just have to reply Comic Book Guy style; "Worst. Rebuttal. Ever."

18:43 technomancy: Thanks - I'll take a look at that.

18:44 callen: n_b: it's just annoying because it's that thing not-smart-enough-by-half people do to sound educated where they try to port the jargon and technique from scientific disciplines into something totally irrelevant like workplace interactions and meetings.

18:44 "This isn't a double-blind study, shuddup"

18:45 muhoo: is there a way to golf this up? (f1 x (f2 x))

18:45 callen: muhoo: comp?

18:45 muhoo: thrush?

18:45 amalloy: make it shorter than that? no

18:45 but you could avoid repetition if you want

18:46 muhoo: wow. if amalloy says there's no way to to it, then there's no way to do it. thanks.

18:46 n_b: (-> x f2 f1)

18:46 amalloy: if you don't mind making it three times longer :P

18:46 muhoo: amalloy: i'm curious

18:46 callen: n_b wrote what I had in mind.

18:46 muhoo: probably won't use it

18:46 amalloy: callen: because neither of you read the original request :P

18:46 callen: amalloy: I'm a write-only IRC daemon.

18:46 n_b: It's same # of chars, just moving them around a bit :p

18:47 muhoo: callen: n_b: nope, look, it's got x as the first arg to f1, and the resulst of f2 as the second arg to f1

18:47 amalloy: his code is (->> x f2 (f1 x)) or something

18:47 n_b: it also does something totally different

18:47 callen: muhoo: write APL if you want that much concision.

18:47 n_b: ohh. yes.

18:47 amalloy: (apply f1 ((juxt identity f2) x)), lol

18:48 muhoo: hahah

18:48 amalloy: anyway, as i said it's much longer but has no repetition

18:48 muhoo: well... i could write a function to do that

18:48 takes a vector of f's, and applies it in that pattern. but again, i'm rearranging deck chairs here

18:49 * muhoo eyes the yak warily

18:49 muhoo: the yak looks back worried. "i'm chilly, i don't *need* a shave!"

18:50 callen: muhoo: next step is skinning the yak.

18:55 muhoo: don't worry, i'm putting that on my to-do-when-bored list

18:56 it smells like reduce could be used, maybe. later.

19:04 maquina: hi guys, i had a question, i have created a function in clojure with defn, and in the function body I instantiate a java object, however the object is instantiated even if the function is not called

19:04 do you know why this happens?

19:06 actually, even if i do :import type-name, the type -init method is called

19:12 technomancy: maquina: yes, that gets called when the class is loaded

19:12 that's what -init is for

19:29 maquina: technomancy: thanks! is there anyway to prevent this? when i call the same clojure code from java, the -init method is not called until i call new, and i would like to replicate this behaviour

19:31 noonian: Hi, I just started messing around with dynamic vars and the binding form. If I want to bind (with binding) a var called foo for code I call from another namespace, do I have to declare (def ^dynamic foo) in each namespace? also if that is the case but there is a more idiomatic way to do something like that I would like to know.

19:38 technomancy: maquina: you can defer class loading to runtime with reflection

19:41 maquina: technomancy: mm.. ok, so this is just clojure behaviour? i am just surprised because in java if i import the class generated by clojure the method in -init is not called until i call new

19:44 nDuff: maquina: it's just like static initialization sections in Java.

19:44 maquina: those are invoked well before you call new.

19:44 maquina: ...so, a defn itself won't do that.

19:45 maquina: perhaps something in your namespace actually calls the function.

19:46 maquina: nDuff: its just that I am porting some legacy code from java, the java code was calling a clojure generated class, the code inside -init in the clojure class, was only called when i called new in java. however now that i ported to clojure, the code in -init gets called as soon as i do import

19:47 nDuff: maquina: Show me the code.

19:59 maquina: nDuff: its this class: https://github.com/nathanmarz/storm/blob/0.8.2/src/clj/backtype/storm/LocalCluster.clj

19:59 nDuff: LocalCluster, in clojure -init is called as soon as i import LocalCluster, in java it is called when i call new LocalCluster

20:04 nDuff: That's... surprising. Can you provide the code you use to reproduce or demonstrate that behavior?

20:05 (or, if not the exact code, a minimal reproducer which does so)?

20:20 jjttjj: f

20:49 Raynes: Does the Clojurscript book even mention compiling for node?

20:49 Or working with cljs on node?

20:51 chessguy: hidy-ho neighbors

21:05 rbxbx: Raynes breifly, yes.

21:05 briefly, also.

21:05 Raynes: So it doesn't actually discuss using it?

21:06 rbxbx: No, it just mentions that you're able to set it as a compilation target.

21:06 "Compiling ClojureScript for Node.js is still an experimental feature and not widely used, so we do not cover it in this book."

21:09 Raynes: Heh

21:09 I wish people cared more. At least we have ohpauleez and friends.

21:12 ttimvisher: is there any way to tell pr-str to strip out unreadable forms?

21:12 i.e. when there's a java object in there?

21:14 also, i'm probably misunderstanding something fundamental here but i thought i could reference a symbol from the surrounding expansion context in a macro. i.e. a let with a particular symbol and then a macro expanded in the let. doesn't seem to be working though. is that a thing?

21:15 callen: Raynes: cljs and caring don't mix.

21:15 Raynes: Burn.

21:16 * callen dances vaudeville-style exit stage right

22:23 romanandreg: hey, would it be possible at all have something like robert.hooke in clojurescript?

22:28 ping

22:28 VFe: It may not be practical or performant, but I'm trying to think of reasons that wouldn't be possible, but can't think of any.

22:29 jack_rabbit: I'm having a problem with aleph whenever I try 'lein run.' The code works fine in the repl, so I'm wondering what I'm doing wrong: http://pastebin.com/L7sEE7qq is the error, and https://github.com/Jack-Rabbit/clojirc/blob/master/src/clojirc/core.clj is the code.

22:54 sorry, I ducked out.

22:57 Huh. It seems that the line "(alter-var-root #'*read-eval* (constantly false))" is causing my problems. Any ideas?

23:01 amalloy: jack_rabbit: nothing obvious springs to mind; it looks like something in clojirc is trying to compile stuff at runtime

23:01 jack_rabbit: :/ shouldn't be. Could it be a macro expansion?

23:02 amalloy: nah

23:03 jack_rabbit: Do I need to compile it specially in order to run it? If I call start-freenode once it seems to "initialize" whatever it is that needs to be compiled.

23:04 After calling it, I can run -main fine.

23:06 amalloy: no. although i'd suggest getting rid of all the AOT in your app; it leads to exciting problems for no reason

23:06 jack_rabbit: AOT?

23:06 clojurebot: AOT genclass is http://paste.lisp.org/display/70665 and http://clojure-log.n01se.net/date/2008-11-18.html#14:19

23:06 amalloy: :gen-class

23:06 jack_rabbit: What exactly is that? leiningen put it there, so I just followed suit.

23:07 amalloy: well, in order to define a named -main entry point, you need to generate a named class, with gen-class

23:07 but clojure transitively compiles every namespace that your class depends on

23:07 jack_rabbit: So I'll need it in my core.clj file?

23:08 amalloy: my advice, if you don't need any other features of AOT, is to define a "dummy" main namespace that doesn't depend on anything, but requires the real main at runtime and delegates to it

23:09 jack_rabbit: Huh. It seems to run okay without :gen-class in my core file anyway.

23:10 amalloy: yeah. you only need to gen-class if you want to create runnable jar files, i think

23:11 and if you do need that, i recommend the technique i just outlined, like https://gist.github.com/amalloy/5376731

23:11 jack_rabbit: Cool. I'll probably do that, then.

23:12 My core.clj will have gen-class, and 'require' a separate namespace with my real "main"

23:12 hmm. It seems to be a problem with lamina.

23:14 amalloy: doubtful. lamina is pretty solid

23:14 but feel free to ask ztellman, if you find a minimal repro case

23:14 jack_rabbit: Is it really dangerous to allow code to compile at runtime? That always seemed like a cool feature of lisps to me. It also seems fairly difficult to get a

23:15 "read" prompt with which to compile arbitrary forms.

23:15 Unless that feature is directly built in.

23:18 I guess it's just odd that I don't see any of my functions on the callstack in these errors. I don't have a lot of experience debugging in the JVM. Do you have any suggestions?

23:21 amalloy: jack_rabbit: of course some of your functions are in the callback

23:22 jack_rabbit: what do you mean?

23:22 amalloy: but line 47 of your paste indicates that it's happening while compiling some clojure functions, rahter than running them, and i can't really see any reason why they aren't already compiled

23:22 search for clojirc in that paste, it comes up lots of times

23:23 well, okay, three times

23:23 jack_rabbit: oh, yeah. I see.

23:31 The only thing that could really cause compiling should be reading some form from a file or input or somesuch, right?

23:32 ttimvisher: is it possible to reference a symbol from the surrounding context from a macro?

23:32 i.e. i know symbol `r` will exist everywhere the macro is expanded

23:32 jack_rabbit: It's possible, but not good practice.

23:33 It makes your macro non-hygenic.

23:33 ttimvisher: jack_rabbit: i can definitely see why. i'm trying to write a very simple logging decorator to all my compojure routes

23:33 jack_rabbit: *hygienic

23:33 ttimvisher: and i have :as r at the end of each destructuring and i'm trying to simply omit that from the arguing

23:33 argument*

23:33 i can't seem to make it work though.

23:34 syntax quote leaves me with a fully-qualified symbol

23:34 and ~ and ~@ require that the symbol be passed as an argument as far as i can tell

23:42 amalloy: ttimvisher: why is this a macro at all? just make it a middleware like anything else

23:43 (defn wrap-logging [handler] (fn [req] (log req) (doto (handler req) log)))

23:44 ttimvisher: amalloy: lol. good point.

23:45 i'm always looking for an excuse to write a macro and then someone comes along and pushes me down. ^_^

Logging service provided by n01se.net