#clojure log - Jan 23 2013

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

0:07 Frozenlock: Ahhh lazyness... you hurt me once more.

0:07 * Frozenlock should stop using `map'

0:55 brainproxy: i'm comfortable prog'ing with clojure, javascript, some python and ruby, shell... i need to whip something together in C# (maybe toss in some clojurecljr), but I feel lost don't even know where to start

0:56 anyone have a favorite .net/c# crash course w/ some examples of how to just start doing some basic things?

0:57 I'm just not even sure how to layout a project, compile or whatever, etc.

0:57 xumingmingv: Have you ever used Java?

0:57 They are similar

0:58 brainproxy: tbh, not really, i got into clojure from working w/ other dynamic languages

0:58 and have been learning little bits of java as i go along

0:58 I have absolutely no idea what I'm doing with eclipse, netbeans, etc. when I fire those up and tinker w/ stuff

0:58 though I have managed to get java classes to compile and run as application

0:59 brehaut: brainproxy: personally id skip C# and go straight to F#

0:59 its got a better non-visual studio experience

0:59 brainproxy: brehaut: can't do it ... it really needs to be c#

0:59 brehaut: thats unfortunate

1:00 brainproxy: i'm a quick study, and have been looking at c# code and get the basic ideas, I just feel totally lost with the tooling

1:00 brehaut: brainproxy: the tooling basically all asumes visual studio and msbuild fiels (managed by VS)

1:01 Raynes: Visual Studio is a raging heap of steaming cow dung just for the installation procedure.

1:01 brainproxy: yeah, well I can get the 30-day version of VS, should be enough to get done what I need to get done

1:01 brehaut: brainproxy: or perhaps monodevelop

1:01 though i have no idea what state its C# support is at

1:02 (version number wise)

1:02 brainproxy: brehaut: thanks! that might do the trick

1:02 there are some get-up-and-running examples on the site

1:02 brehaut: sweet

1:03 Raynes: brehaut: We should write something in F# together.

1:03 Maybe a Lisp.

1:03 ;)

1:03 brehaut: lols

1:03 i do quite like F#

1:03 and mono 3 supports F#3

1:08 brainproxy: keep in mind the version of C# any tutorial talks about BTW; C#4 is drastically different to C#2

1:11 (local type inference, lambdas and block lambdas, linq (which is not just an SQL thing), covariance and contravariance, async…)

1:20 tomoj: hmm, ring.util.codec uses URLEncoder

1:20 I mean, ring.util.codec/form-encode

1:20 which it also uses for cookies

1:21 but that encodes spaces as +

1:21 where javascript's urldecoding wants %20

1:22 amalloy: then, uh, javascript's url decoder is no good? last i checked both of those are allowed

1:22 tomoj: http://stackoverflow.com/questions/2678551/when-to-encode-space-to-plus-and-when-to-20

1:23 hmm

1:23 brainproxy: brehaut: thanks for the tip

1:24 Raynes: amalloy: In my experience, most URL encoder/decoders are wrong. I went through 4 different Erlang libs before just writing that URI lib in Elixir.

1:24 bbloom: amalloy: javascript is doing url encoding which is different (but similar to) form encoding

1:24 Raynes: amalloy: The thing that most people don't account for are unicode characters. They encode a single byte.

1:25 bbloom: there's also URI "component" encoding

1:25 tomoj: and angular.js and ring BOTH make that choice deep inside

1:25 oi

1:25 incompatible choices I mean :)

1:26 bbloom: the web is broken.

1:26 brehaut: derp

1:26 amalloy: tomoj: that seems like an unambiguously correct choice for ring.util.codec/form, since it's presumably being used to encode forms, not uri path components, although making the other choice would also have been fine.

1:26 bbloom: it's impossible complex, but b/c it's all plain text, it works out more or less right modulo some major security bugs

1:27 that's the unix way!

1:27 tomoj: amalloy: and wrap-cookies too?

1:27 brehaut: bbloom: nothing some more poorly considered regexen wont solve!

1:27 Raynes: amalloy: https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/uri.ex The URL decoding stuff wasn't me, but the encoding stuff is. Lots of blame in that file now, since people have mucked with it over time.

1:28 bbloom: form encoding makes sense as the default for post data, but i'm pretty sure cookies are supposed to be URL encoding, not form encoded

1:28 tomoj: so that might be a bug in ring, but it would be backwards incompatible to fix... however, you may want to report it anyway

1:28 amalloy: tomoj: cookie values don't have to be url encoded at all

1:29 tomoj: then ring should let you choose?

1:29 amalloy: i think so

1:29 bbloom: yes

1:29 url-encoding is just the most common choice

1:30 tomoj: how the heck do you even do url-encoding on the jvm if URLEncoder does form encoding?

1:30 bbloom: spec says: The VALUE is opaque to the user agent and may be anything the

1:30 origin server chooses to send, possibly in a server-selected

1:30 printable ASCII encoding.

1:30 so it has to be printable ASCII

1:30 amalloy: bbloom: your summary is the exact opposite of what you're summarizing

1:31 bbloom: and since javascript makes urlEncode readily available (but oddly, no way to get form encoding) most client side code uses url encoding

1:31 amalloy: the value may be anything; the server may, if it chooses, encode it some way into ascii

1:31 cbp`: hello

1:31 bbloom: amalloy: yes, but in practice, browsers suck lol

1:31 cbp`: for a friend just starting out what would be the best way

1:31 with like no programming experience

1:32 bbloom: amalloy: http://stackoverflow.com/questions/1969232/allowed-characters-in-cookies

1:32 the money shot: "so in practice you cannot use non-ASCII characters in cookies at all. "

1:32 tomoj: I guess I can with-redefs ring.middleware.cookies for now

1:32 bbloom: "Most popular is UTF-8-inside-URL-encoding (as produced by JavaScript's encodeURIComponent)."

1:33 tomoj: that or make another copy of a bunch of middleware-related code :(

1:33 bbloom: tomoj: i think you should report a bug in ring if it's using form encoding

1:33 it should, at minimum, be pluggable

1:33 tomoj: will do, but I also want to make it work tonight

1:34 bbloom: for sure :-)

1:34 point to http://stackoverflow.com/questions/1969232/allowed-characters-in-cookies

1:36 tomoj: ok, alter-var-root time

1:37 cbp`: anyone used catnip? :P

1:37 seems like newbie friendly

1:42 tomoj: oh, ring.util.codec has url-encode too, didn't notice

1:43 (->> (.getBytes unencoded (or encoding "UTF-8")) (map (partial format "%%%02X")) (str/join))

1:46 amalloy: hah, the least efficient way imaginable

1:47 bbloom: surprising that they wouldn't delegate to some well tested and performing apache module...

1:50 tomoj: especially since that ns imports base64 from commons-codec

1:51 bbloom: tomoj: lol

1:51 i guess base-64 is a bit trickier

1:52 probably implemetned url encoding & then was like "oh, shit." and went to find commons-codec

2:14 mich2: Hi there! I'm new to clojure and now using data.xml to process some XML data, I have a problem though

2:15 The data.xml API gives you the content of an XML element with :content , this returns a l: LayzSeq but I want a string

2:15 So how do I convert a lazySeq to a string?

2:15 bbloom: mich2: what's it a lazy seq of? (take 5 the-seq)

2:16 or even just (first the-seq)

2:16 mich2: (Str lazySeq) seem not to work

2:16 bbloom: try (apply str the-seq)

2:16 mich2: First or take, hmm

2:16 Apply! Ok I try that thanks!

2:17 jballanc: hmm...so apparantly recur doesn't work with apply :(

2:17 Raynes: jballanc: apply only works with functions.

2:18 jballanc: what do I do, then, if I have a func that returns an array of two items, and I want to recur while "exploding" the array

2:18 Raynes: recur isn't even a macro, much less a function.

2:18 jballanc: yeah, I'm not surprised it didn't work

2:18 just not sure what to do...

2:18 bbloom: jballanc: use a vector or a seq

2:18 if you need to alter the signature you want to recur to, use a loop

2:18 Raynes: Don't explode the 'array', probably.

2:19 jballanc: ah

2:19 bbloom: it's very common to see (fn [...] (loop [...] ... (recur ...)))

2:19 Raynes: It's hard to answer specifically without code to look at.

2:19 jballanc: ok...one sec

2:22 this is a trivial example: https://gist.github.com/4602823

2:22 SegFaultAX: Is it common to have a server like nginx or apache serve static content directly instead of letting tomcat or whatever serve it in the Java world?

2:22 amalloy: jballanc: just call foo

2:22 bbloom: SegFaultAX: i put nginx in front of everything as a matter of principle

2:22 jballanc: yeah, that's what I was going to do...

2:22 amalloy: and don't wrap it in []s

2:23 jballanc: right

2:23 well, the [] is coming from another function

2:23 SegFaultAX: jballanc: You can't recur across function clauses like that.

2:23 bbloom: jballanc: i assume you know the number of elements in the vector? use a let to destructure right before your loop

2:23 or, just change the loop target to take the vector itself

2:24 SegFaultAX: bbloom: I'm really shaky on how to actually deploy Clojure web applications in a production environment. I haven't found many tutorials on the subject, either.

2:24 bbloom: And how to handle things like redeploys, etc.

2:25 bbloom: SegFaultAX: i've never done it, but my assumption is that you just use the ring jetty container and do exactly like you would do for any other java app

2:26 ro_st: we have a ring app in production on ec2

2:26 jballanc: bbloom: ah, yeah...that's not a bad idea :)

2:27 SegFaultAX: ro_st: Can you tell me a little about your stack?

2:28 michaelr525: hello

2:28 ro_st: we use "lein trampoline run" to start our server, and use apache to proxy to it (and take care of stuff like mime types, cache + expiry, etc)

2:28 SegFaultAX: ro_st: What application server do you use?

2:28 tomoj: ring-refresh checks for "Content-Type" specifically :)

2:28 clj-http downcases all headers due to the ring spec

2:29 ro_st: jetty, i believe

2:30 for deploys, we rsync from our build vps, which only happens once our build vps has done a 'lein check' and run the tests

2:30 SegFaultAX: ro_st: Do you use jetty to serve static content?

2:30 ro_st: no. S3

2:30 tomoj: relatedly, I kind of expect (re-find #"foo" nil) to be nil

2:30 SegFaultAX: ro_st: But aren't static resources in the webapp tree?

2:31 ro_st: actually, i might be wrong about that. we serve our content from s3, and our static assets (js, css, ui stuff) from jetty

2:32 tomoj: weird

2:32 ro_st: the intent is to move everything to s3, though

2:32 SegFaultAX: ro_st: I see. So is jetty a pretty capable web server, then? I've been using nginx as a proxy for my application servers for so long, /not/ using it feels wrong.

2:32 ro_st: you could still use nginx

2:33 jetty is perfectly capable. it's just that you don't want your contended app server process serving something that S3 or the proxying webserver can serve instead. prefer 100% of jetty's requests to be dynamic

2:34 amalloy: SegFaultAX: nginx in front of jetty is pretty popular for clojure

2:34 SegFaultAX: Is there a tutorial or blog post on this?

2:34 ro_st: we went with apache because of all the goodness the html5boilerplate .htaccess gives us

2:34 SegFaultAX: I've never really deployed a Java application into production.

2:34 Only local development stuff. Toys, really.

2:34 bbloom: SegFaultAX: just leave "clojure" out of your searches

2:34 ro_st: SegFaultAX: our production server does exactly the same thing that our dev server does

2:34 "lein run"

2:35 we use env vars to configure the process

2:35 so if you can start a jetty server and proxy to it from nginx locally, you have your solution

2:36 SegFaultAX: ro_st: Do you use the auto-generated web.xml?

2:36 ro_st: we don't use jars or wars

2:37 we rsync the loose clj files over from the build box (which gets it from github) once it's been checked and tested

2:37 that way, when we connect to our nrepl server in production, we can reload files from disk if need be

2:38 SegFaultAX: ro_st: That sounds awesome. I wish I knew how to set all that up. :/

2:38 ro_st: feel free to PM me and ask more :-)

2:38 amalloy: it's a lot easier to set up than anything involving web.xml files

2:38 ro_st: yep

2:39 apache vhost proxies to localhost:9991. configure ring server to start on port 9991. lein run. done

2:39 SegFaultAX: ro_st: Does deploying a new version require downtime for your site?

2:39 ro_st: yes, about a minute's worth, at this point

2:39 amalloy: i hope you don't mind my poking a bit of fun, but asking if he uses the autogenerated web.xml after hearing he just does lein run made me think of the introduction of cars: "a horseless carriage!" "sounds great, what kind of horse feed do i have to buy for it?"

2:40 ro_st: as our startup does several important things; connect to datomic, transact datomic schema, connect to rabbitmq, connect to memcached

2:40 SegFaultAX: amalloy: I don't. But like I said, I don't really have much experience deploying production Java applications and all the tutorials I've found start with configuring the web.xml file.

2:41 ro_st: Does the long pause between versions dissuade you from deploying very often?

2:41 ro_st: as we're using ec2, we won't bother trying to shorten that time. once we have load, we'll add another ec2 web node and lean on the the load balancer to direct traffic properly while we cycle each node one at a time

2:42 yes. it does cause us to think carefully about whether we need or want to deploy the changes we have

2:42 SegFaultAX: Bummer.

2:42 ro_st: once we have two nodes, though, we'll deploy as much as we like, because then we'll always be up

2:43 SegFaultAX: True.

2:43 amalloy: if two nodes is really all it would take, you could just run two of them on the same machine with a load balancer or something in between

2:43 SegFaultAX: ro_st: Are you using pallet for automation? Cap? Fab? Other?

2:43 ro_st: thanks to memcached, rabbitmq, and datomic, the web processes don't have any state to shepherd. so we don't lose sessions or datomic peer cache

2:43 pallet

2:44 amalloy: true. but we'd be trading a day's developer time to get that working robustly just to throw it away in a couple weeks. we can live with a minute's downtime for now

2:44 SegFaultAX: ro_st: A day? nginx can load balance in 1 line ;)

2:44 ro_st: -grin-

2:45 we use upstart for our java process management

2:45 it's a tradeoff, we've chosen to wait out the short-term niggle, keep complexity down and get some features built instead :-)

2:47 you could probably do a loadbalanced solution on a single server, and keep jumping back and forth between two jvms every time you deploy

2:47 we also have to factor in the fact that we have a limited number of datomic processes available

2:48 amalloy: i'm not saying you're wrong and should spend time on no-downtime deploys, just saying it's silly to blame it on having only one node

2:49 ro_st: sure

2:57 SegFaultAX: ro_st: PM?

2:59 amalloy: You mentioned earlier that nginx -> jetty is a pretty common configuration for clojure. Are you aware of any sample apps I can take a look at?

3:01 amalloy: sure, 4clojure is open source, and the nginx configuration is just https://gist.github.com/02f0ccf609e8d3d5db34

3:03 SegFaultAX: amalloy: Does 4clojure also use lein run? Or wars?

3:03 amalloy: lein run

3:05 michaelr525: cljs-kickoff is great, now how can I clojurescript to an existing compojure site?

3:06 add cs

3:06 ro_st: from the perspective of a compojure site, the output of the cljsbuild is is just a static js file

3:06 treat it accordingly :-)

3:07 our cljs app is in a separate git repo to our server code. we use symlinks between the two in development to test the one on the other, and deployment copies the js etc into place for production

3:09 michaelr525: ro_st: why do you separate the projects?

3:10 ro_st: so that we can build the cljs and deploy it without also causing a server reboot

3:11 michaelr525: ok

3:11 ro_st: what's your startup?

3:11 btw

3:11 ro_st: www.cognician.com

3:11 yunfan: so how to use regex for replacing? i can only found those funcs for finding/matching

3:11 ro_st: clojure.string/replace

3:12 yunfan: it support regex?

3:12 ro_st: (doc clojure.string/replace)

3:12 clojurebot: "([s match replacement]); Replaces all instance of match with replacement in s. match/replacement can be: string / string char / char pattern / (string or function of match). See also replace-first."

3:13 yunfan: it didnt said it support regex. is char pattern the alias of regex?

3:14 ro_st: match is a regex or a string

3:15 michaelr525: ro_st: how do you access the web services?

3:15 ro_st: ,(clojure.string/replace "aBc" #"[A-Z]" "!")

3:15 clojurebot: "a!c"

3:15 ro_st: michaelr525: we don't currently have content for the general public to use, sorry. we only went live last week :-)

3:16 yunfan: ro_st: ok thanks

3:16 michaelr525: ro_st: heh, sorry. I was asking using what method do you call the web services from clojurescript code.. :)

3:16 ro_st: ohh :-)

3:16 we use shoreleave-remote

3:17 and shoreleave-remote-noir

3:17 cljs/clj respectively

3:17 michaelr525: clojure datastructures over the wire or json?

3:18 ro_st: edn :-)

3:18 michaelr525: cool

3:18 yunfan: why not just push clojure express as a alternative for jsonp?

3:18 ro_st: never heard of that before

3:19 yunfan: i know some one agree that using s-exp to instead json

3:19 SegFaultAX: edn is probably best if you're a) using datomic and b) using clojure throughout your entire stack.

3:19 ro_st: check, check.

3:19 SegFaultAX: yunfan: We've been doing it for years, it's called XML.

3:19 yunfan: SegFaultAX: oops, hell xml

3:21 SegFaultAX: how much cost of you using datomic per month?

3:23 SegFaultAX: yunfan: ro_st uses datomic, ask him.

3:24 yunfan: ro_st: ?

3:24 ro_st: yunfan: we have 8 processes. we use a normal m1.medium with postgres for storage, right now

3:24 spjt: Finally finished my first clojure program? a prime number generator.

3:24 yunfan: i am also want to use clojure for my website idea, but i am worry about the cost

3:25 spjt: Generates all prime numbers between 2 and 10^7 in 120ms.

3:25 yunfan: ro_st: how many PV per page of your site?

3:25 ro_st: datomic is expensive, but in our particular case, it's saved us many hours of development time, and, going forward, code maintenance time

3:26 yunfan: sorry, not sure what that means

3:26 yunfan: ro_st: how many page view of your website in a day?

3:26 in average

3:28 ro_st: in the hundreds. when we switch off our old stack in feb, in the thousands

3:28 can't wait for that day. no more php!

3:29 yunfan: oop, that must be horrible while you using php

3:29 ro_st: not long now.

3:29 yunfan: i have those experience in the earlytime

3:29 now i live on python, less horrible but still have

3:30 ro_st: py is far better'n php, i believe. can't say personally, never used py.

3:31 yunfan: i have a question, if i made a rss subscribe service like GR but with more customizing services , and need you pay $5 per month, would it be expensive?

3:32 ro_st: another great thing is no more IE8-

3:32 p_l: ro_st: lucky you

3:33 * p_l looks at "IE7 support" bit on requirements

3:33 ro_st: our rationale is, install one of the other 4, or install google chromeframe

3:33 which can be done sans admin rights

3:34 MUCH rather put that time into feature dev

3:34 we even have some folks carrying Chrome Portable to use on university networks

3:36 yunfan: ro_st: can i have a look of your site?

3:36 ro_st: www.cognician.com

3:36 yunfan: ok

3:37 p_l: ro_st: and our requirements were written few years ago and can't be changed. Fun.

3:38 ro_st: i feel for you. not fun

3:45 p_l: that must be a big project

3:52 p_l: it is

3:52 and it was done by foreign company first and we were supposed ony to integrate

3:54 yunfan: foreign company , is it indian one or a chinese company in shenyang :]

3:56 p_l: yunfan: worse - american

4:07 cinvoke: can someone point me to a good source that would help me decide the benefits of clojure vs nodejs?

4:10 ChongLi: cinvoke: with clojurescript you don't have to choose

4:10 cinvoke: ChongLi: but they would run on 2 diff platforms correct? jre vs v8?

4:11 ChongLi: cinvoke: clojurescript compiles to javascript so it'd be running on v8

4:16 amalloy: don't run cljs on node

4:16 ChongLi: why not?

4:18 cinvoke: so no benefit to use one over the other ChongLi?

4:18 amalloy: it's a mess, and even if it worked you might as well use the well-tested, performant clojure environment. cljs is (and this part is just my opinion) for letting you write clojure on the client; if you're on the server you get to choose, and there's no reason to do all the extra hoops to get cljs->node interaction going

4:18 cinvoke: just lang flow?

4:19 ChongLi: cinvoke: I didn't say that

4:19 cinvoke: clojure (and clojurescript) has many advantages

4:20 it's an extremely beautiful language with some really nice abstractions

4:20 so much of it was designed based on a ton of experience and it shows

4:21 javascript, on the other hand, is the result of a rushjob with many deep flaws

4:21 cinvoke: ok so more zen, more principle..

4:22 ChongLi: javascript makes it easy to do the wrong thing; it has quite a few language features that experts would recommend you never use

4:23 clojure's language features make it easier to write better code

4:23 with persistent data structures and clean abstractions

4:23 cinvoke: like eval :)

4:24 augustl: ChongLi: out of curiousity, since you can choose VM on the server, why choose V8/Node, instead of the JVM?

4:24 ChongLi: augustl: no idea, I'm not all that familiar with node

4:25 augustl: ah, cinvoke was the one asking

4:26 cinvoke: but i would have access to most java libs on jvm, and wouldnt it also be more stable, application-wise?

4:27 ChongLi: cinvoke: in jvm you have access to java libs

4:27 cinvoke: nice

4:27 ChongLi: on v8 you have access to js libs

4:28 clojure (and its variants) aim to nestle themselves within their host platform

4:28 so interop syntax is very simple

5:09 Bodil: cinvoke: The biggest problem with Cljs on Node is that you can't use any Clojure libraries - you're limited to what's been ported to Cljs, which on the server side is practically nothing.

5:10 cinvoke: Bodil: makes sense. i didnt see the point in cljs unless i just wanted that lang flow.

5:11 noidi: and with CLJS you also get all the JavaScript's problematic semantics

5:11 (defn foo [x] x) (foo no such symbols defined in this ns)

5:11 will work

5:12 passing extra arguments to a function is fine in JS, and undefined names evaluate to, well, undefined :P

5:12 on the JVM both are errors caught at runtime

5:16 clgv: noidi: no the unknown symbols are detected on compile time

5:17 noidi: oh?

5:17 clgv: noidi: wrong function arity will throw at runtime

5:17 noidi: that wasn't the case when I last used CLJS

5:17 clgv: noidi: oh, I picked up your last sentence, so on the JVM I meant

5:20 &(do something with unknown symbols)

5:20 lazybot: java.lang.RuntimeException: Unable to resolve symbol: something in this context

5:20 bozhidar: Bodil: the availability of libraries on node is problematic even if you're using JS :-). The platform is simply too young at this point...

5:44 AWizzArd: Is Java’s „Sizeof.FLOAT” in Clojure „Float/SIZE”?

5:48 bozhidar: AWizzArd: Java's Sizeof.FLOAT? I don't recall the existance of such a class

5:50 AWizzArd: bozhidar: good, thanks for the info. Then this is a JCuda class.

5:50 That guy imported jcuda.* and so I wasn’t sure if Sizeof is Java or JCuda. Thanks :)

5:50 bozhidar: AWizzArd: You're welcome.

6:00 clgv: &Float/SIZE

6:00 lazybot: ⇒ 32

6:07 AWizzArd: ,(.clone (float-array 5))

6:07 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: clone for class [F>

6:07 AWizzArd: But I found this Java code: float h_C[] = createRandomFloatData(10); float h_C_ref[] = h_C.clone();

6:07 createRandomFloatData obviously returns a float array.

6:14 xumingmingv: AWizzArd: you wonder why the IllegalArgumentException is thrown?

6:15 AWizzArd: Yes.

6:16 To me it seems from that Java code that .close can be called on float arrays.

6:16 clone even

6:17 xumingmingv: java.lang.Object.clone is a protected method

6:18 It is only callable in Java class's definition file itself. (Unless you define your clone public clone method)

6:20 &(.clone (java.util.Date.))

6:20 lazybot: ⇒ #inst "2013-01-23T11:20:22.952-00:00"

6:20 xumingmingv: java.util.Date defines its public clone method

6:28 clgv: AWizzArd: you probably have to use reflection for that since arrays are no objects on JVM level

6:31 AWizzArd: try java.util.Arrays/copyOf like ##(java.util.Arrays/copyOf (float 5) 5)

6:31 lazybot: java.lang.IllegalArgumentException: No matching method found: copyOf

6:31 clgv: &(java.util.Arrays/copyOf (float-array 5) 5)

6:31 lazybot: ⇒ #<float[] [F@a494b>

6:32 AWizzArd: clgv: yes, I already use that.

6:32 clgv: good :)

6:34 AWizzArd: Very nice performance difference. Two 800x800 matrices multiplied in Clojure with quad core at 100%: 25000 msecs. The same task on my Nvidia: 63 msecs. Holy goodness :)

6:34 clgv: yeah thats what these GPUs are good at ^^

6:34 AWizzArd: Nice that 98% of my program runtime is about exactly this :)

6:52 noidi: AWizzArd, cool :)

7:12 fantasticsid: as

7:52 mattyw: in core.logic I'm trying to say something should be in list a but not in list b. Seems like I need (membero q vec-A) (not-membero q vec-B) but there doesn't seem to be an official implementation of not-membero.

8:14 clgv: mattyw: you can look up the source of `membero` and implement `not-membero` analogous

8:14 mattyw: clgv, just started looking into that

8:17 Morgawr: question time... I am using ClojureScript to output to javascript into a web page, it's some small silly javascript game (just for the hell of it) and the game runs starting from an "init()" function called from the html page.. using the :advanced flag for the clo_s_ure compiler it doesn't detect such function called from my html hence it prunes everything and removes it

8:17 how can I specify which functions I want to stay in my code even when using :advanced?

8:25 no7hing: shouldn't ^export do the trick?

8:25 ^:export

8:26 Morgawr: doesn't seem to be working

8:26 ChongLi: sometimes you need to do a clean and recompile

8:28 Morgawr: okay... looks like I was wrong, the problem isn't with the init() function

8:28 I call it with "testjs.core.init();" in my html code (inside a <script>)

8:28 and it says "referenceerror testjs is not defined"

8:28 in advanced mode

8:28 testjs is the name of my namespace

8:28 in simple mode it works

8:29 ChongLi: try searching for testjs in the text of the advanced output

8:30 Morgawr: there's a few instances

8:30 ChongLi: hmm

8:30 Morgawr: stuff like

8:30 ("testjs.core.init",function()..

8:30 etc tec

8:30 also the output says "TypeError: jQuery.Uf is not a function" maybe that's related?

8:30 ChongLi: is there any reason you need to put the init call inline in the html file?

8:30 Morgawr: no real reason, I am just trying it out and it made sense, what other option do I have?

8:31 ChongLi: just put (init) at the bottom of your source file

8:31 Morgawr: mmm yes that might work, lemme try

8:32 okay, reference error is gone, now I get a jQuery error so I guess that makes for half of the problem solved

8:33 ChongLi: have you read up on calling externs from google closure?

8:33 https://developers.google.com/closure/compiler/docs/api-tutorial3#externs

8:34 Morgawr: I'll give it a read

8:34 ChongLi: why are you using jquery btw?

8:34 as far as I know it doesn't work too well with the closure compiler

8:35 and a lot of its functionality already exists in the closure library

8:35 I take it you're probably experienced with jquery

8:35 Morgawr: because I was following (and translating along the way) a jQuery javascript tutorial and wanted to see how it worked with clojurescript

8:35 clgv: ChongLi: huh? it should. there is the jayq lib

8:35 Morgawr: I don't really know much about jQuery, I don't care which library I use

8:35 and yeah, jayq is working fine with jquery

8:35 ChongLi: ah ok

8:36 the core idea of advanced mode compilation is to get rid extra scripts so you can take advantage of whole program optimization

8:36 Morgawr: http://corfield.org/blog/post.cfm/getting-started-with-clojurescript-and-jquery-and-fw-1 reding from this

8:37 ChongLi: if you're also loading jquery on the side you're losing a lot of the benefit

8:37 Morgawr: reading*

8:37 it seems I need ":externs ["externs/jquery.js"]" in my project.clj

8:37 let's try

8:37 but yeah, I'm just using jquery now because I'm following this example tutorial (in javascript), I'll move on to better stuff after I'm done

8:38 I'm satisfied I managed to learn how to do all this stuff and properly translate clojure code into javascript

8:38 ChongLi: here's a tutorial on clojurescript

8:38 https://github.com/magomimmo/modern-cljs

8:38 it uses the domina library

8:38 Morgawr: yeah, I saw that

8:39 ChongLi: it's a native library which is functional and idiomatic clojure

8:39 Morgawr: I read the basics from that but I was more curious on working out some game programming in html5 so I read a tutorial related to that and translated it to clojurescript

8:39 but that tutorial used jquery so that's why

8:39 not a big deal either way, I'm learning how it works :)

8:39 ChongLi: the real key is to learn the underlying ideas

8:39 of what you want to do with the dom

8:39 then you can use any library to get the job done

8:40 Morgawr: yeah exactly

8:40 anyhow, thanks for the help, gotta go now :)

8:40 ChongLi: good luck :)

8:46 michaelr525: Ctrl-C'ing 'lein run' on cygwin windows leaves a java process still running in the background.. is this a known problem?

9:10 no7hing: if i'am not mistaken, adding "-Djava.awt.headless=true" to the :jvm-opts in your project file should solve the issue

9:11 one of my deps had a dependency on AWT...

9:11 can't write proper sentences today apparently

9:12 can't read them properly either, as i replaced process with window in my head

9:13 rasputnik: is there some trick to accessing a var in another namespace?

9:13 michaelr525: no7hing: you're writing to me?

9:13 rasputnik: have an atom in one namespace, just want to read it from another

9:14 no7hing: yes, but i gave you the wrong answer

9:14 michaelr525: rasputnik: you can use the fully qualified name i think, like this my-namespace.myatom

9:14 rasputnik: rephrase that: functions via (defn….) and vars (def….) defined in a namespace thingy.whatever should both be accessible as thingy.whatever/name right?

9:15 michaelr525: i think so

9:15 rasputnik: probably a brain fart this end

9:16 michaelr525: you can also (:require ... :refer...

9:16 rasputnik: do i need a require to be able to see the namespace at all?

9:16 clgv: rasputnik: you need to require the other namespace at least

9:17 rasputnik: clgv: there we are, that's my problem. I'll do the require/refer bit to limit the exposure

9:17 clgv: rasputnik: yes, require does load the namespace

9:17 rasputnik: thanks both

9:17 Thallasios_Xelon: hello :))

9:17 clgv: rasputnik: you can use :require :as

9:17 and should^^

9:18 rasputnik: this would be easier but I'm building an uberjar so have to go round the houses to get an error

9:18 Thallasios_Xelon: (let [f1 lazyseq1

9:18 f2 (fun f1) ]

9:18 this will work?

9:18 rasputnik: clgv: actually I just want to reach this one atom, and it's only at atom because I need somewhere to keep a config map for the app

9:19 clgv: rasputnik: hmm for encapsulation you should not expose that atom. expose operations on the atom as functions

9:21 rasputnik: clgv: it's a read-once , "turn this configfile into a map" kind affair. [-main] needs to set it up as it's a command line argument, but it's used later to wire up connection pools

9:21 probably doesn't even need to be an atom, a 'global' would do. and i'd rather it were immutable

9:22 shared state bad, i know :)

9:22 s/shared//

9:22 clgv: rasputnik: functions might prove more handy. since the using namespaces do not need to know how the configuration is organized. so changes to that affect only that one namepsace

9:23 rasputnik: clgv: point taken. one of those situations where im' balancing the Right Way with Pragmatism

9:26 no shit

9:26 clgv: rasputnik: what does it save you to expose the global and have every consumer knowing how to access it? I'd say just using the function that gives me the desired result and encapsulates the config access is the pragmatic one^^

9:26 rasputnik: it's just a map of JDBC setup info

9:27 sorry, the 'no shit' was to my mate in another window

9:27 clgv: how many namespaces use that map`

9:27 rasputnik: he lives in the welsh mountains and says it's snowy :)

9:28 clgv: 3, one where main lives (reads the jetty port) , one for the DB layer (reads the jdbc bits), one for the utility function that turns the config.clj into a map

9:28 firefux: is clojure better than java?

9:29 ro_st: YES

9:29 ohpauleez: that was an easy answer

9:29 tiled: why does this not work? it always returns nil (http://pastebin.com/HnmSdCfA)

9:32 clgv: rasputnik: well thats 3 namespaces that are affected with changes when you change the config organization^^

9:32 ro_st: ohpauleez: :-)

9:32 bpr: tiled: i'm not sure what (to-vect ...) actually returns, but you may want to try (flatten (to-vect ...))

9:32 rasputnik: clgv: seriously, this is around 30 lines of clojure code total and I'm replacing 500+ of Dropwizard with it. :)

9:33 bpr: tiled: that will find the 2 if (to-vect ...) returns a vector of vectors

9:33 rasputnik: clgv: if it gets any bigger i'll refactor but seems like overkill for something so teeny

9:35 clgv: rasputnik: your choice after all. but I did not see the tradeoff from your arguments, thats why I asked^^

9:35 rasputnik: clgv: hey i come here for the voice of experience, thanks for the advice.

9:35 bpr: tiled: oh.. i read that wrong, you are doing nested iteration on that.

9:37 tiled: but i guess it is easier to use flatten?

9:37 bpr: well, i believe flatten is eager, so you'll loose the benefits of lasziness

9:38 rasputnik: arg, require loop : [ /tyrekick/core ]->/tyrekick/db->[ /tyrekick/core ]

9:39 firefux: rasputnik: dropwizard, the java web framework?

9:40 rasputnik: firefux: yup

9:40 can I use refer inside a (ns … ) ? or a let binding ?

9:41 bpr: refer needs to be in a require form

9:41 Thallasios_Xelon: (let [f1 (parse_replace '(=> a (<=> b c)) () del=>)

9:41 f2 (parse_replace f1 () del<=>)]

9:41 f2)

9:41 parse_replace return a lazyseq

9:42 do you know why only f1 is evaluated?

9:42 rasputnik: bpr: you sure? the samples on http://clojuredocs.org/clojure_core/clojure.core/refer don't make it look that way

9:42 maybe that's a repl thing?

9:42 bpr: rasputnik: lol. nope that's new to me

9:42 rasputnik: (nope, i'm not sure)

9:43 firefux: rasputnik: do you use dropwizard-views?

9:46 rasputnik: firefux: no

9:47 hum, bit stuck here now then. wanted to set a 'global' config map, but can't see it from other namespaces (since can't require them to reach it).

9:47 *that feeling when you're fighting the language*

9:48 Thallasios_Xelon: is there a way to make a clojure.lang.lazyseq to sequence?

9:49 rasputnik: Thallasios_Xelon: do you mean like (doall ...)

9:49 Thallasios_Xelon: maybe i got stuck...

9:49 augustl: weavejester: hey, I'm using clout outside of ring, in fact outside of http in general. Using message queues to do RPC, and the commands are HTTP-like, but not HTTP. Does it make sense to decomplect clout from ring, you think?

9:50 Thallasios_Xelon: (let [f1 (parse_replace f () del=>)

9:50 f2 (parse_replace f1 () del<=>)] f2 ) ; parse return lazyseq,f2 is never calculated dont know why

9:50 augustl: I currently have to construct a ring-like request even though I'm not in ring or http

9:50 weavejester: augustl: You should be able to use strings too.

9:51 Thallasios_Xelon: is there anything to think before you pass a lazyseq as argument?

9:51 weavejester: augustl: Oh, wait, my mistake - I think it needs to be a request.

9:52 rasputnik: is there any way to let 2 namespaces access things in each other without causing a require loop then?

9:53 weavejester: augustl: I think it would be hard to pull the HTTP out of Clout. It's designed to match against HTTP, with information spread throughout the request map.

9:54 jballanc: style question..."if" with "do" clauses: ugly? or acceptable?

9:54 for example: https://gist.github.com/4607286

9:55 alternatively, what would be a good way to branch, but also report based on which side of the branch is taken?

9:55 augustl: weavejester: I guess there's not much point in splitting it

9:55 weavejester: jballanc: Sometimes necessary, but to be avoided in favor of more functional code when possible.

9:55 jballanc: weavejester: yeah, that's what I was thinking

9:55 augustl: weavejester: perhaps it would make sense if it took strings, though

9:57 jballanc: in this case, I have 3 methods that are all returning bools, and I'm using an "and" clause to report their collective success/failure

9:57 augustl: weavejester: but passing {:path-info "/my-path"} works fine :)

9:57 jballanc: but for one method, I'd like to have a guard, and report + return false if the gaurd fails

9:58 clgv: rasputnik: no. you cannot make circle-require-statements.

9:59 rasputnik: usually you have to extract those functions both namespaces want to use in a third which does not depend on the other too

10:00 xumingmi`: A question about Clojure CA: http://clojure.org/file/view/ca.pdf

10:04 xumingmingv: A question about Clojure CA: http://clojure.org/file/view/ca.pdf

10:05 It asks me which projects I'd want to contribute

10:05 Is it enough to just put Clojure(https://github.com/clojure/clojure) in it?

10:07 gfredericks: xumingmingv: I've never heard that field mentioned

10:08 hyPiRion: xumingmingv: I added Clojure core and Clojure contrib

10:08 I think that should cover all of it

10:08 xumingmingv: gfredericks: So I dont need to fill in that field, only Contact information is Ok?

10:09 TimMc: Well, put Clojure in, for sure.

10:09 All they ever care about is "did you sign the CA?"

10:10 xumingmingv: ok, thanks you guys

10:13 ohpauleez: Raynes: ping

10:16 Anderkent: Is it possible to make dosync *always* start a new transaction, even if it's already contained in one?

10:16 rasputnik: clgv: good call, i'll merge the tyrekick.config and tyrekick.utils and keep the atom in there

10:17 TimMc: Anderkent: Why?

10:17 hyPiRion: Anderkent: Doesn't sound like you want transactions then.

10:18 Anderkent: It's more that I don't control whether my transaction is nested in one or not, but I want to persist the result if my transaction succeeds

10:18 hyPiRion: If you start a new transaction, then that transaction may run multiple times.

10:18 Anderkent: that's fine, it's idempotent

10:18 basically I have a code coverage 'store' that keeps track whether a form was executed

10:18 since I may have multiple threads executing I update it in a transaction

10:19 hyPiRion: Anderkent: The thing is, (dosync (dosync (commute a + 10)) (commute a + 20)) may increment a by more than 30

10:19 *IF* the inner dosync started a new transaction

10:19 Anderkent: right, I'm not saying it should be the default, I'm just asking whether there is a way to do it

10:19 think like this: (dosync (dosync (mark-visited :here)) (throw Exception.))

10:20 I want the coverage state to be updated even if the outer transaction fails

10:20 hm. I suppose I want an atom instead?

10:21 clgv: Anderkent: huh. I thought (dosync (dosync ...)) would result in only one transaction

10:21 hyPiRion: clgv: It does

10:21 Anderkent: clgv: it does. That's exactly the opposite of what I want

10:21 and I undestand why it does

10:22 hyPiRion: Anderkent: So you want to know how far into a transaction you get before it errors out?

10:22 clgv: ah ok. I inspected the code once, and saw a check for the enclosing transaction...

10:22 Anderkent: hyPiRion: something like that. It's a code coverage library.

10:23 currently I can't properly cover transactions that fail

10:23 because it rolls back my 'forms that were visited' store

10:23 are atoms also reverted if an outer transaction fails?

10:24 hyPiRion: Anderkent: Try it out

10:25 clgv: Anderkent: no atoms take no part in transactions

10:25 gfredericks: how do protocols enable dynamicity but still stay low-level enough to be fast? e.g., what happens when you (extend-protocol ...)?

10:26 hiredman: gfredericks: inline callsite caching is the big one, outside of extending the protocol directly when you create the type

10:27 Anderkent: okay. That sounds like a solution here, but it means I have to change some other code.. Anyway, thanks

10:27 gfredericks: hiredman: so is extending protocols to existing types always a bit slower?

10:27 TimMc: Anderkent: You can *prevent* your code from running inside a transaction. :-)

10:27 hiredman: gfredericks: I cannot see how it would not be

10:27 Anderkent: TimMc: that doesn't help - I want to be able to cover transaction expressions, just breaking would be worse than current state :P

10:28 gfredericks: hiredman: okay, that's what I suspected

10:28 TimMc: Anderkent: Oh, I see -- this is code you're injecting into the code to be analyzed.

10:28 Anderkent: yes

10:28 TimMc: Ew, tricky.

10:28 Anderkent: :P

10:28 gfredericks: hiredman: is it better than doing a long list of type-checks?

10:28 or maybe a map of classes to functions...

10:29 TimMc: Yeah, tell an atom. It's an idempotent action, yeah?

10:29 hiredman: gfredericks: I think inline caching should be, yes

10:29 Anderkent: yes, that's what I'm changing it to

10:29 have to update some initialization code, but it shouldnt be that hard

10:30 gfredericks: I need some reason to dig into the compiler details :/

10:31 hiredman: gfredericks: pjstadig has a library that pulls out the protocol dispatching code out in to a regular function (no protocol grouping functions), I doubt it has the inline caching that protocols have, so comparing the two would be one way to isolate performance

10:32 https://github.com/pjstadig/polyfn

10:33 gfredericks: hiredman: cool, thanks

10:35 hiredman: the callsite caching and constant pool entry kind of stuff would be interesting to expose to macros somehow

10:37 e.g. so a macro could tell the compile that then function it emits needs an extra callsite cache or constant pool entry that the macro will futz with

10:37 not sure how that would work though

10:47 tiled: how can I test whether two floats have the same value? since its value varies (0.2 becomes 0.20000000298023224)

10:48 firefux: that's why you don't test them

10:48 bpr: tiled: define an acceptable epsilon and see if they are within epsilon of each other: (< (- float1 float2) epsilon)

10:49 hyPiRion: Weren't there an approx= in numeric-tower?

10:49 hiteki`: bpr .. some abs is missing I guess

10:49 bpr: tiled: well, you'd want to wrap that subtraction in a Math/abs

10:49 hiteki`: yup

10:50 TimMc: ,(< (Math/abs (- 0.1 (/ 10.0))) 1e6)

10:50 clojurebot: true

10:50 TimMc: ,(< (Math/abs (- 0.1 (/ 10.0))) 1e-6) ; rather

10:50 clojurebot: true

10:51 bpr: TimMc: I was like, "Wow! He must be doing cosmology... or economics"

10:51 :-p

10:51 TimMc: :-)

10:51 tiled: ok thank you

10:53 TimMc: bpr: What's a few orders of magnitude among friends, anyway.

10:54 hyPiRion: As long the sign is correct

10:55 let epsilon be less than zero

10:56 gfredericks: emacs' trailing whitespace removal feature is quite annoying when editing other peoples' projects :/

10:57 minimal134: gfredericks: use ethan whitespace

10:57 hyPiRion: turn it off then

10:57 gfredericks: but I wants it on otherwise :/

10:58 hyPiRion: I'm sure there's a hook which enable features based on what the git's origin links to

10:58 minimal134: ehan-wspace only auto cleans files that were opened clean

11:00 gfredericks: minimal134: that does sound useful.

11:00 yedi: is the clojure log at n01se relatively complete?

11:01 or a better q, does it tend to miss messages at all / often

11:02 gfredericks: whoever suggested ethan, thanks for the tip; I just borked my irssi and lost the history :/

11:03 hyPiRion: gfredericks: that would be minimal134.

11:04 gfredericks: minimal134: thanks

11:04 hyPiRion: thanks

11:04 (inc everybody)

11:04 lazybot: ⇒ 1

11:04 minimal134: gfredericks: thanks. blame ethan

11:06 gfredericks: it's weird that extending a protocol to Object doesn't cover the nil case

11:06 is that a jvm detail or a clojure detail?

11:07 hyPiRion: gfredericks: nil/null isn't an object

11:07 null instanceof Object returns false

11:07 gfredericks: wat

11:07 my whole world is falling apart

11:07 I guess this makes sense

11:07 creese: gfredericks: re: whitespace: because you can't find the changes you actually made?

11:07 gfredericks: creese: I can it just takes lots of paging

11:07 hyPiRion: gfredericks: how can nothing me something? :)

11:08 creese: gfredericks: in a diff?

11:08 gfredericks: hyPiRion: I was thinking of the fact that in java "int x = null;" is bad but "Integer x = null;" is okay

11:08 creese: gfredericks: seems like there ought to be a way to tell git to ignore whitespace changes

11:08 gfredericks: that fact mislead my expectations

11:08 creese: in `git add -p`

11:08 yazirian: git diff --ignore-space-at-eol

11:08 hyPiRion: gfredericks: oh right.

11:09 gfredericks: so at compile time null is an Object; but I can see why instanceof would disagree

11:11 * gfredericks has another whitespace issue and kicks himself

11:11 hyPiRion: gfredericks: null is only void, null is just the lack of an Object

11:12 But I agree that it is strange

11:12 Just like you'd think "((Math)null).abs(1+2);" would fail, yet it compiles and runs perfectly.

11:12 gfredericks: O_O

11:13 what the hell is that

11:13 hyPiRion: Makes sense compile-wise

11:13 gfredericks: it looks like an instance method call though

11:14 hyPiRion: gfredericks: static method, can be inferred that it's just a call to that method

11:14 No need for the object to find the specified method

11:14 gfredericks: oh you can call static methods on objects

11:14 I forgot that weird little flexibility

11:15 okay; now it makes sense

11:16 hyPiRion: This one has always bothered me though: https://www.refheap.com/paste/8894

11:17 Man, those edge cases

11:17 Well, "always bothered" is a bit of a stretch, but it's gotten to me once.

11:17 gfredericks: does it crash?

11:17 is that an implicit cast?

11:18 hyPiRion: It crashes with an arraystore exception

11:19 gfredericks: would the equivalent code with generics do the same thing?

11:19 hyPiRion: And yeah, since String isa Object, casting an array to Object[] is valid somehow.

11:20 gfredericks: List<Object> x = (Some List of String) fails

11:22 yedi: if clojure wasn't tied to the jvm, do you think it would be as popular?

11:23 bawr: It's hardly "tied" to the JVM as it is.

11:23 hyPiRion: yedi: Depends.

11:23 Most likely not due to lack of libraries.

11:25 gfredericks: Hmm, you can cast generics if you don't define them before given.

11:25 https://www.refheap.com/paste/8896

11:28 TimMc: hyPiRion: Whee, covariant types...

11:30 hyPiRion: What is this syntax? {{add(1); add(-2); add(3);}}

11:30 Some sort of initializer?

11:30 Anderkent: TimMc: static initializer

11:30 TimMc: How long has that been there? :-/

11:30 Anderkent: it's basically a hack

11:31 TimMc: Anonymous class?

11:31 Anderkent: you're creating an anonymous inner class

11:31 yep

11:31 TimMc: nasty

11:33 Anderkent: anyone knows how to check if an element has children in clj-webdriver? no? thought so :(

11:35 Morgawr: I've got a fairly basic clojure question... let's say I have a vec made like [1 2 3 4 5 6 7] and I want to "update" one of its element based on the position (update = return a new vector that looks like that just with an element changed), how do I do that?

11:35 I mean, I want a new vector with the nth element changed into something else

11:36 I know how to use map/reduce/whatever but I have no idea how to specify an index to change

11:36 Anderkent: ,(assoc [1 2 3 4 5 6] 0 0)

11:36 clojurebot: [0 2 3 4 5 ...]

11:36 Anderkent: uh, bad values chosen..

11:36 ,(assoc [1 2 3 4 5 6] 0 123)

11:36 clojurebot: [123 2 3 4 5 ...]

11:36 Anderkent: there :P

11:36 Morgawr: oh that's great

11:36 thanks

11:36 :)

11:37 TimMc: Anderkent: I wasn't aware you could do a non-static initializer. o_o

11:40 Morgawr: You can also append an element that way, since vecs will accept an index one beyond the end when assoc'ing.

11:41 Anderkent: TimMc: I shouldnt have said static. It's not a static initializer, it's an instance initializer. static {} run on class init, not instance init

11:41 Morgawr: neat, good to know

11:41 TimMc: It can be a little confusing to the reader, though.

11:41 Anderkent: So do those run before the constructor chain?

11:42 Anderkent: yes, they run when the class is being loaded

11:42 'those' -> static initializers

11:42 not double brace initializers

11:42 TimMc: No, the instance initializers.

11:42 Anderkent: oh. Instance initializers run before the actual constructor

11:43 TimMc: And before the super constructor?

11:43 Anderkent: yeah

11:43 TimMc: Freaky.

11:43 Anderkent: they run in literal order together with other static initializations

11:43 TimMc: No wonder I've never seen them used.

11:43 Anderkent: i.e. you have class { my_field = 1; { my_field += 1 }; constructor() }

11:43 in weird pseudocode

11:44 then the myfield will be set to one first, then the initialization block will run

11:44 hyPiRion: Morgawr: You should also check out ##(update-in [0 1 2 3] [1] + 10) if you're using the previous value

11:44 lazybot: ⇒ [0 11 2 3]

11:44 Anderkent: I don't like explaining java because writing example code is so much pain :P

11:45 hyPiRion: I don't really mind Java when it comes to its verbosity, it's more its lack of expressiveness.

11:45 Morgawr: hyPiRion: nice, thanks

11:45 hyPiRion: And its default mutability.

11:45 craigbro: i always thought of it as tinker toys

11:45 i felt like I was building stuff from tinker toys

11:45 mutability doesn't bother me

12:01 brainproxy: anybody here using the jnbridge pro product in conjunction with their clojure apps?

12:01 experiences? good, bad?

12:13 tomoj: &(into {} [(list (clojure.lang.MapEntry. 1 2) (clojure.lang.MapEntry. 3 4))])

12:13 lazybot: ⇒ {1 2, 3 4}

12:13 tomoj: (into {} [[1 2] [3 4]])

12:14 oh right

12:14 &(conj {} (seq {1 2 3 4}))

12:14 lazybot: ⇒ {3 4, 1 2}

12:16 tomoj: &(apply conj {} (seq {1 2 3 4}))

12:16 lazybot: ⇒ {3 4, 1 2}

12:45 muhoo: i could swear there was a let-fn in clojure somewhere, but i can't find it. or was i imagining it?

12:45 egghead: muhoo: letfns

12:45 muhoo: thanks

12:45 egghead: oops

12:45 -s

12:45 muhoo: yep, no dash

12:55 ohpauleez: Does anyone know of an example illustrating loop unrolling via Clojure macros?

12:58 gfredericks: ohpauleez: what's a loop? something like dotimes?

12:58 ohpauleez: yeah, essentially a doseq that I want to force to unroll

12:58 gfredericks: or I guess you include not a full unroll (which requires iteration count to be known at compile-time) but also unrolling every 2 or 3?

12:58 hyPiRion: ohpauleez: That requires knowledge of the seq at compile-time

12:59 ohpauleez: hyPiRion: totally, I have that

12:59 gfredericks: ohpauleez: so it's (doseq [x <some vector literal>] ...)?

13:00 ohpauleez: yeah, (doseq [x <A seq of objects created at compile time>] )

13:00 hyPiRion: Well, then it's rather straightforward I believe. Just do a `(do ~@(map clojure.walk/some-fn-replacing-stuff the-seq))

13:01 It won't give you any speed improvement though.

13:01 Or barely any.

13:01 ohpauleez: hyPiRion: definitely, I already wrote basically that, but I wanted to make sure I wasn't duplicating something tucked away in core

13:01 oh, not for speed

13:01 native library needs things done upfront

13:02 hyPiRion: oh, okay

13:02 gfredericks: (defmacro unrolled-doseq [[name elems] & body] (let [names (repeatedly (count elems) gensym)] (list* 'let [(vec names) elems] (for [name' names] (list* 'let [name name'] body)))))

13:02 hyPiRion: ohpauleez: I can see at least immediate bugs with it though

13:02 two immediate*

13:03 * gfredericks runs off to a meeting having no idea if that code works

13:03 hyPiRion: erroneous return value and improper handling of multiple body elements

13:03 So just be aware of that.

13:06 Frozenlock: ohpauleez: Ping. What's the status with shoreleave?

13:07 ohpauleez: Frozenlock: As in, what's left?

13:07 warz: i see that maven stores downloaded repos into ~/.m2. i have a maven repo that's not available on the sites that leiningen checks though. whats the best way to get this repo into that m2 directory that lein checks?

13:08 copy and paste it in there? or is there a way to tell lein to check other online repos

13:08 technomancy: warz: just add it to :repositories in project.clj; see `lein help sample`

13:08 Frozenlock: As in: last time IIRC you were almost ready to release a major updrage

13:08 upgrade even.

13:08 warz: ok ill check that out

13:09 ohpauleez: Frozenlock: Just smoothing stuff out, building up the example. Swamped at day job recently, so it's been a little slow going

13:11 warz: technomancy, oh i see. awesome! thanks.

13:15 ibdknox: ohpauleez: what's the day job for you at this point? :)

13:15 ohpauleez: ibdknox: I'm not sure I can say in #clojure haha

13:19 hyPiRion: ohpauleez: Oh, I didn't knew you were programming stateful programs with locks, mutexes and hairballs.

13:19 /s/knew/know/

13:20 ohpauleez: hyPiRion: It's all in really bad, STL C++

13:20 :)

13:20 ibdknox: which has been macro'd so far that you can't even tell it's C++

13:21 ohpauleez: ibdknox: Turn off the VNC viewer - stop looking at my code

13:21 haha

13:21 If I every publicly interview Rich, I want to know the worse abuse of C++ he ever wrote

13:21 but I want it documented for everyone else

13:23 technomancy: if you asked me that I'd only answer on condition of anonymity

13:23 ohpauleez: haha

13:23 ibdknox: technomancy: you do much C++ work in the past?

13:23 technomancy: ibdknox: about a year's worth at university

13:24 mercifully all but forgotten

13:24 hyPiRion: ohpauleez: Have you seen the Java he's written?

13:25 ohpauleez: All the more reason to want to see the C++ - he bends Java SO far, it's incredible

13:25 hyPiRion: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L802

13:25 ohpauleez: I imagine Guy Steele and James Gosling look at Clojure's Java code and nod in approval

13:25 hyPiRion: For some strange reason I always laugh when I see it.

13:26 ohpauleez: and then Steele says something about phantom types

13:27 `fogus: "Callbacks in C++ using template functors" a paper by Rich Hickey (1994) http://www.tutok.sk/fastgl/callback.html

13:27 S11001001: hyPiRion: set tab-width 4

13:27 clojurebot: hyPiRion: Probably because it is using the IRC protocol directly -- the equivalent of you putting /say in front of your messages.

13:27 ohpauleez: `fogus: I've read it. It's gruesome

13:27 (in a good way)

13:27 for a long time, Hickey Callbacks were the "it" thing i C++

13:27 in*

13:28 `fogus: I remember the technique from back in the day. :-O

13:28 hyPiRion: S11001001: Ahh, that explains everything. I've never bothered to check the tabs etc.

13:29 technomancy: http://www.emacswiki.org/emacs/TabsSpacesBoth

13:29 ChongLi: haha

13:30 hyPiRion: `C-x h M-x untabify`

13:30 ChongLi: you could do the same thing with the "K&R style vs one true brace style" debate

13:31 technomancy: ChongLi: so glad we don't have those discussions in clojure

13:31 ChongLi: yeah haha

13:31 technomancy: if anyone puts parens on their own line, everyone just tells them they're wrong and gets on with it

13:39 ChongLi: I'd like to see Crockford style context coloring

13:39 seems like it'd work pretty well in a lisp

13:40 it makes it easy to follow the scope of free variables in a deeply nested function

13:41 what I don't get is why Crockford hates on S-expressions

13:42 he actually likes writing crap like this: (function (a, b) {return a + b;}());

13:43 technomancy: heh; statements

13:43 ChongLi: that's actually a "function expression"

13:43 technomancy: I mean explicit returns

13:43 ChongLi: it becomes a statement if the f in the reserved word function is in the first column

13:43 oh, yeah

13:45 I like his story about how somebody told him jslint should warn about switch cases falling through due to missing breaks

13:45 he told the person "sometimes you actually want them to fall through"

13:46 the next day that person sent him a bug report; the bug was caused by a case falling through

13:46 in jslint!

13:46 cbp`: I got this email: Dear LispWorks user,

13:46

13:46 LispWorks 6.1.1 Personal Edition is now available, free of charge

13:46 Bronsa: lol

13:46 cbp`: :D

13:46 iwillig: ChongLi: yeah that was a good story

13:49 ChongLi: it really seems to fly in the face of his argument that "syntax is good"

13:49 syntax is bad if it leads to silent errors

13:52 Ember-: even though Javascript *does* have it's good points (or parts) I'd like to see even one person who thinks that the *syntax* of javascript is good and relevant to the actual language beneath

13:52 ChongLi: didn't brandon eich want to write a scheme interpreter originally?

13:52 akhudek: Switch cases falling through has been used forever in other languages to support grouped cases.

13:53 Ember-: ChongLi: yes and he did I think

13:53 ChongLi: oh it's brendan

13:53 Ember-: then management wanted to make it more "java like" since java was new and cool and hip

13:53 and Eich got like 3 weeks to turn the scheme-like language to java-like

13:53 and we got what we got

13:53 thank you management

13:54 ChongLi: and he decided to add some crazy prototype inheritance based on an obscure language called self

13:54 Ember-: well, that isn't actually crazy

13:54 prototypical inheritance is quite a good concept

13:54 technomancy: ChongLi: hadn't heard that story before; that's great

13:54 Ember-: but the syntax in javascript does not support that pardigm

13:54 paradigm

13:54 ChongLi: well, it was crazy considering his bosses wanted him to make it javalike

13:55 Ember-: the whole birth story of Javascript is kinda sad

13:55 especially since we still have to live with it

13:55 muhoo: "Doing the right thing was not possible at Netscape. That's why there's not a Netscape anymore" -- Douglas Crockford

13:55 technomancy: nearly rivaled in craziness by the birth story of Java/Oak though

13:55 ChongLi: I'd like to know whose idea it was to have so many contradictions in the equality operator

13:55 Ember-: but then again, if I'd have modules in javascript I could live with most of the stuff in it

13:55 technomancy: the whole "we have to find someone who would actually want this OO technology for set-top boxes, fast!"

13:56 Ember-: technomancy: hehe, yeah

13:56 ChongLi: modules are coming in ES7, no?

13:56 muhoo: how would i go about type-hinting a reduce?

13:56 Ember-: ChongLi: ES6 I think actually

13:56 or was it 7, don't remember

13:56 but come on, when can we actually *use* those?

13:57 muhoo: ,(reduce #(+ %2 (* 58 %1)) [0 9 15 21 33 0 4 32 23 30 9 32 27 39 14 41 48 17 1 41 6 32 1 12 22 27 1 17 5 40 29 5 1 41])

13:57 clojurebot: #<ArithmeticException java.lang.ArithmeticException: integer overflow>

13:57 ChongLi: they seem to abandon even-numbered releases

13:57 we'll be good to go once IE9 is obsolete

13:57 Ember-: it's like 5-6 years at minimum before you can use those

13:57 tomoj: &(update-in {} [:foo] identity)

13:57 lazybot: ⇒ {:foo nil}

13:57 Ember-: 5-6 years is a bit too much for my taste

13:58 I'm looking at dart, it's looking better and better each day

13:58 ChongLi: clojurescript targets es3 right?

13:58 Ember-: yeah

13:58 Ithink

13:58 ChongLi: why not target the intersection between es3 and es5/strict?

13:58 Ember-: (chatting via ssh screen in a moving train, might be missing a character or two)

13:58 technomancy: really bizarre story worth a read if you have some time: http://www.blinkenlights.com/classiccmp/javaorigin.html

13:59 ChongLi: seems like that'd get a bit more performance on strict compliant browsers

13:59 while gracefully falling back to es3 on non-compliants

13:59 Ember-: ChongLi: I'm hoping we'll see a clojurescript compiler for dart vm

13:59 and that dart vm get's implemented into other browsers than chrome too

13:59 ChongLi: is mozilla gonna ship dart in firefox?

13:59 Ember-: dunno

14:00 ChongLi: I doubt microsoft will even touch it

14:00 microsoft still wants to stand in the way of the web

14:00 hyPiRion: ChongLi: They may make their own proprietary version.

14:00 With special semantics

14:00 Ember-: dart vm is completely open source and google is pushing it for the other browsers too

14:00 I wouldn't be too sure about it

14:00 Microsoft wouldn't lose anyting with dart really

14:00 ChongLi: why else would they vote to ratify es5/strict and then not implement it in IE?

14:01 microsoft loses whenever the open web grows

14:01 Ember-: but let's see what happens

14:01 too early to tell if dart lives or dies

14:01 ChongLi: is dart a better candidate host for cljs?

14:01 Ember-: but in any case, it's already many multiples better than javascript in all possible aspects

14:01 ChongLi: dart vm is already faster than v8

14:02 and has support for lot's of stuff

14:02 ChongLi: I see that it has classes

14:02 Ember-: it's a full blown vm, not a script interpreter

14:02 WAY closer to JVM

14:03 ChongLi: "So, I've thought for a long time ... if I could take a clean sheet of paper and write [a new language] that retains all the goodness of [Javascript] ... I would not have come up with anything like Dart."

14:03 technomancy: how is V8 not a VM?

14:03 ChongLi: -- Douglas Crockford

14:03 Ember-: technomancy: in a way it is, it's a JIT compiler and VM

14:03 with a bunch of pretty crazy optimization magic

14:04 but dart vm runs bytecode

14:05 many good things about that, if anyone is interested then there's a ton of information in the g+ dart feed

14:07 ChongLi: Ember-: so the browser downloads bytecode archives from the server?

14:08 Ember-: ChongLi: that's the main way to run dart, not the only one though

14:08 there's dart2js compiler and stuff like that

14:08 but yeah, with dart vm you run compiled bytecode

14:09 allows a LOT faster startup times, smaller files, better optimization, real remote debugging and so on

14:09 ChongLi: so we could target that with clojurescript (or something similar)

14:09 technomancy: might be interesting to finally have a bytecode-based VM where the authors actually care about startup time

14:09 Ember-: current dart ide allows debugging running code directly from the browser

14:09 ChongLi: I'd like to know what douglas crockford really thinks about it

14:10 that quote is a frustrating non-answer

14:10 Ember-: or run the code without the browser, it's a separate VM afterall

14:10 ChongLi: dart has bigints

14:10 nice

14:10 Ember-: technomancy: dart developers are reporting over 10 times faster startup times even in early versions of dart vm compared to similar javascript

14:11 I think it's in RC2 currently

14:11 so closing on 1.0 final

14:12 ChongLi: everybody from the other browsers is angry about dart

14:12 dnolen_: Ember-: I don't see Dart going anywhere beyond Chrome.

14:12 ChongLi: angry? they don't care

14:12 Ember-: dnolen_: I know, it's a risk

14:12 but then again, you always have dart2js then

14:13 ChongLi: I'm not really interested in dart2js

14:13 Ember-: then it's in a similar position as clojure script with the exception that you can run native dart if dart vm is available

14:13 ChongLi: I'm more interested in a better host and browser API for cljs

14:13 Ember-: but I'm more excited about dart vm than about the dart language

14:14 dnolen_: Ember-: I don't know why you would wan to use the dart vm outside of the browser - in Clojure's case you have the JVM.

14:14 Ember-: I *really* want an efficient bytecode Vm into browsers to host several different languages

14:14 ChongLi: jvm is too slow to start up

14:14 dnolen_: ChongLi: for server applications who cares

14:14 for scripts you can target JS

14:14 ChongLi: we're talking about in the browser

14:14 Ember-: js script startuptime is slow

14:15 it really is

14:15 dnolen_: ChongLi: I understand - I was simply saying that Dart VM outside of Chrome is uninteresting

14:15 ChongLi: specifically: making the browser a faster and better host for cljs

14:15 Ember-: or any other language for that matter

14:15 the more the merrier

14:15 ChongLi: yeah

14:15 dnolen_: and so Dart VM's chance for success is quite small

14:15 ChongLi: probably zero

14:15 Ember-: let's wait and see

14:16 dnolen_: and don't forget it's not like JS engines are continuing to push ahead performance wise

14:16 Ember-: I'm not keeping my hopes too high, but one can hope, right?

14:16 dnolen_: are not continuing

14:16 Dart ... massive meh

14:16 Ember-: well actually, google engineers (and others too) have said that the current js interpreters are closing the limit what can be done with javascript

14:16 that's the reason dart vm is almost twice as fast as v8 already

14:17 dnolen_: Ember-: I guess that's why JSC 64bit is surpassing V8 on it's it's benchmark suite?

14:17 cause there's no more progress to be made ...

14:17 Ember-: well, it's about what kind of language javascript is

14:18 if you've ever studied what for example v8 does to achieve it's performance it's what one could call a one huge hack :)

14:18 dnolen_: Ember-: otherwise known as engineering?

14:19 Ember-: propably the best performance boost v8 does is to make it possible to turn object property references into constant time operations

14:19 hyPiRion: Same reasoning can be applied on Intel's processors

14:19 Or any CPU for that matter.

14:19 ChongLi: oh god

14:19 intel's in particular

14:19 frankenCPUs

14:19 Ember-: hehe

14:19 ChongLi: and it's what is killing them in mobile

14:20 hyPiRion: I'm happy ARM is around and kicking.

14:20 technomancy: it's not really interesting whether JS engines can make JS in general fast; the interesting question is how fast they can make that subset of JS which the closure compiler emits.

14:20 ChongLi: technomancy: it comes down to the assumptions they're allowed to make

14:21 technomancy: course if I spent any amount of time in that runtime I'd probably be cheering for it to be replaced by something that did arity checks by default and actually had integers, but whatever

14:21 nie moj cyrk, nie moje malpy.

14:21 Ember-: yeah, the fact that javascript has only floats is... mindboggling

14:22 dnolen_: Ember-: the list of thing that are mind boggling about JS is not short

14:22 Ember-: indeed

14:22 but that is among the top of my list

14:22 hyPiRion: Well, javascript has booleans

14:23 So you know... In theory

14:23 Ember-: hyPiRion: lol, you don't mean what I'm thinking? :D

14:23 hyPiRion: I'm just saying you can represent integers as boolean arrays, nothing more.

14:23 Ember-: custom made binary calculus based integers? :)

14:23 yeah, that

14:23 I wonder how fast that would be

14:24 not fast

14:24 ChongLi: profoundly slow

14:24 you might as well use strings

14:24 Ember-: ChongLi: most likely would be faster

14:24 aaelony: I'm writing a usage function for a clojure command line app where I'd like to say, Usage: $0 <arg1> <arg2> and have $0 resolve to the name of the executable. I found this http://stackoverflow.com/questions/41894/0-program-name-in-java-discover-main-class, but it's not great. Is there anything more clojure-like for $0 that I can use?

14:25 Ember-: hyPiRion: but I do like that idea even if it is perverse

14:25 might actually implement that for fun :)

14:25 technomancy: aaelony: pretending to be unix-like is not one of the JVM's strong suits unfortunately

14:26 Ember-: I've already implemented a purely functional immutable list for javascript :P

14:26 JasonSmith1: Each bit would be represented in memory as a 32 bit integer.

14:26 aaelony: technomancy: that's what I thought. I don't want to be too clever and call the system to tell me $0 but i might...

14:26 Ember-: that would be a good thing to do next for my "cool but totally useless pieces of code" -series

14:26 ChongLi: I seem to recall some guy wrote a DSL for those usage messages

14:27 technomancy: aaelony: depending on how you're distributing it you might find https://github.com/dekellum/hashdot useful

14:27 aaelony: ChongLi: sounds promising links pls ;)

14:27 hyPiRion: ChongLi: clojure.tools.cli?

14:27 aaelony: cool, all good ideas :)

14:27 ChongLi: I'm trying to find it again

14:30 aaelony: technomancy: it will be pretty much linux or mac os bsd for dekellum looks interesting

14:30 s/for/so/

14:31 ChongLi: gah

14:31 it's so hard to find because the word "usage" is totally generic

14:31 aaelony: haha, no worries

14:32 ChongLi: I think there's actually an ISO standard for those usage messages

14:32 if I could figure out what that is

14:32 I'd have better luck finding it

14:32 aaelony: Siri doesn't know? lol

14:35 ChongLi: here it is!

14:35 aaelony: :)

14:36 ChongLi: http://docopt.org/

14:36 it's not a clojure thing, I hope I wasn't getting your hopes up

14:36 aaelony: that's okay, will read what its about. thanks :)

14:36 ChongLi: no reason it couldn't be implemented in clojure however

14:37 at the bottom they list a bunch of different implementations

14:38 aaelony: hyPiRion: thanks for the link to clojure.tools.cli

14:47 technomancy: would it be a nice idea to be able to specify the name of a CLI executable in the project.clj for leiningen to faciliate? I'm thinking that maybe a config file of sorts could be read by the clojure program to tell it what the name is… or something...

14:48 technomancy: aaelony: I don't think that's a good fit for project.clj

14:49 aaelony: yeah, probably not a great idea

14:52 gfredericks: so protocol extensions can't be retracted in the same manner as remove-method, right?

14:52 (or overridden)

14:53 amalloy: gfredericks: welllllll, you could probably hack it

14:53 definitely not recommended

14:53 gfredericks: I've been pondering https://github.com/fredericksgary/java.jdbc/commit/c5ea0ac2b8a0fedc383b985c90c3f69956b1f287

14:53 and the fact that I had to put in the Object and nil extensions to get it to work

14:54 it's hard to imagine a user wanting to define those to do something else, but seems kind of icky that I had to rule it out

14:54 I imagine the only alternative is to remove the extension but wrap the call in an (if (satisfies? ...) ...)

14:54 amalloy: i think so, yes

14:55 gfredericks: should I expect worse performance for that?

14:55 the not-calling case would be the common one

14:55 amalloy: obviously it won't perform exactly as well

14:55 gfredericks: so is it faster to do a protocol dispatch that doesn't do anything, or check satisfies?

14:56 not too hard to do a hasty benchmark I guess

14:56 amalloy: looks to me like they're basically the same

14:57 gfredericks: based on? your knowledge of impl?

14:57 amalloy: a quick scan of the impl

14:58 gfredericks: man I don't even know what file in the source to look in for that

14:58 amalloy: core_deftype

14:58 ChongLi: jeez the applause is loud in that video

15:04 dnolen_: gfredericks: satisfies? is crazy slow in the failing case

15:05 gfredericks: in core.logic I've removed it, I just check for the interface behind the protocol, which may or may not work for you.

15:05 amalloy: dnolen_: really? is it slower than just calling the protocol method?

15:05 dnolen_: amalloy: yes, it traverses the inheritance hierarchy and doesn't cache

15:05 hiredman: ^-

15:08 ohpauleez: technomancy: Is there any specific doc I should look at for packaging native deps with my project?

15:08 gfredericks: yeah haphazard tests at the repl suggests satisfies is a lot slower

15:09 ohpauleez: I'm not pulling them, I'm providing/packaging them with my jar

15:09 technomancy: ohpauleez: we were just lamenting the lack of such documentation in #leiningen

15:09 ohpauleez: I'll pop on over :)

15:09 technomancy: tl;dr: there is nothing

15:09 ohpauleez: ok

15:13 dnolen: gfredericks: satisfies? performance in CLJS is much nicer (about the same as instance?) since we just ride on JS prototypes

15:13 gfredericks: dnolen: nice

15:17 dnolen: gfredericks: oops, actually that's not true anymore. satisfies? is fast *because* we don't really handle the prototypal inheritance case. Should probably be fixed, but no ones complained much about it yet.

15:18 gfredericks: wouldn't matter unless you're using JS inheritance for some odd reason?

15:18 e.g., I might extend a protocol to Backbone.Model and expect my models to satisfy but they won't? or they'll work but satisfies? will return false anyways?

15:18 ibdknox: would matter for extending protocols to JS objects

15:19 dnolen: gfredericks: yes, which I think is why people haven't complained. Michal Marcyk proposed a solution at one point - prototype bit masks which would allow us to handle it.

15:19 ibdknox: yep

15:20 it's actually an relative ly easy fix for someone curious about how protocols are implemented in CLJS

15:20 ibdknox: I haven't run into that *yet*, but I'm pretty sure I will at some point in the not too distant future. So that may end up being me

15:21 tomoj: so we're going to make satisfies? slow?

15:21 dnolen: tomoj: no

15:21 ibdknox: bitmasks are pretty darn fast

15:21 lol

15:21 dnolen: prototype bitmasks would allows them to be fast

15:21 tomoj: oh, I see

15:21 dnolen: er allow them to be fast

15:21 while handling inheritance

15:21 amalloy: oh, i thought you guys had already done the bitmask thing

15:22 dnolen: amalloy: at the instance level, probably better to just move it to the prototype level - should have thought that when I did it but

15:22 oh well

15:23 ibdknox: ha

15:23 that is the source of the weirdness I was seeing. I don't know why I didn't think about that

15:24 dnolen: ibdknox: heh, I think in benchmarks, putting it on the instance had the perf edge. Going up the prototype chain had a measurable perf hit. So we should probably just do both.

15:24 instance fields if we can statically determine all protocols

15:25 and prototype bitmask for dynamic case

15:25 ibdknox: yeah

15:33 tomoj: I just patched my clojure-mode to do always-2-spaces indentation

15:34 it seems to work well when the first argument is distinguished

15:34 like map/reduce

15:35 not so good for namespaces or function calls where the arguments are similar (like, say, +), unless you put zero args in the first line

15:35 which looks weird but may be the best option..

15:37 I wish I could have this https://www.refheap.com/paste/9d76bcb0c36d084fe61b28130 but that's special casing :(

15:43 Raynes: tomoj: Get off my planet.

15:44 Frozenlock: Hmm.. is there a command to clear the inferior-lisp buffer?

15:44 tomoj: what I settle for now is extra linebreaks between each cond/expr pair

15:44 or, when you're lucky, just one line per pair

15:46 I just undid the patch

15:47 ibdknox: I thought people lined up condition and return in conds?

15:47 tomoj: the prospect of committing code written in that style scares me

15:47 'lined up' as in all the conditions and all the returns start in the same column?

15:48 ibdknox: no: https://www.refheap.com/paste/8902

15:49 tomoj: yeah, when you're lucky, one line per pair

15:49 what if the condition and/or return are bigger?

15:50 ibdknox: I still do it that way

15:50 let me find one

15:50 tomoj: even when it's the condition that's big? huh

15:50 never thought of that option

15:50 ibdknox: it's definitely uglier in the condition case

15:50 but I don't usually have multi-line conditions

15:50 tomoj: yeah

15:52 https://www.refheap.com/paste/fef7e4256e143b00b156b3208 guess I should factor things out and just make the cond simpler

15:54 ibdknox: I'm not sure why, but that style is very hard for me to read

15:54 lol

15:55 the cond isn't idented correctly, but here's one: https://www.refheap.com/paste/8904

15:55 amalloy: aw tomoj, that double assoc-in should really be an update-in with two assocs

15:56 ibdknox: really? neither of those ands should exist at all; doesn't cljs have multi-arity = and >=?

15:56 bbloom: amalloy: it can be a single assoc with additional args

15:56 amalloy: bbloom: yes, better

15:56 bbloom: amalloy: sometimes an and is a little clearer than using less-than to mean strictly-ascending

15:57 ibdknox: I acutally always forget about being able to do that

15:57 bbloom: in this case, i'd say that's true of the first and

15:57 amalloy: bbloom: that may be the case on occasion, but the first and was terrible for me to read

15:57 ibdknox: yeah, the second one should go away

15:57 amalloy: is line supposed to be in between the two properties of this thing, or not in between them? if it's just a single <=, it's easy

15:57 bbloom: the second one should definitely be 3-arity =

15:58 amalloy: sorry, i misread that first and, you're right, apparently my missreading it is proof that it would be better the other way haha

15:58 ibdknox: inbetween or equal to

15:58 amalloy: right, i figured it out

15:59 bbloom: as for how cond gets formatted, i prefer to line up a table when it's pretty small/clear & fits horizontally... but past that, i do something that i think others shun: i indent the consequences 2 spaces

15:59 amalloy: cond is just one of those things that no two people treat the same. we need style wars to cull the herd

15:59 ibdknox: lol

15:59 bbloom: it violates the unspoken rule of indentation only ever happening inside a braces nesting, but i really find it so much easier to read

15:59 tomoj: amalloy: https://www.refheap.com/paste/c37abca4581b75e87e1764294 ?

16:00 amalloy: tomoj: sure, although since req is such a small thing i probably wouldn't even bother with the ->

16:00 bbloom: tomoj: or you can keep the -> and move the app into it

16:00 amalloy: barf

16:00 tomoj: heh

16:01 I did that earlier for (-> req (update-in ...) app (update-in ...))

16:01 ..which seems cumbersomely common

16:01 amalloy: i think i must be the only one on the planet who would write that as (app); i never let un-parenthesized stuff into my ->s

16:02 ibdknox: I do that too

16:02 bbloom: amalloy: reduction of parens is one of the best features of ->

16:02 :-)

16:02 tomoj: I could go for that

16:02 bbloom: or at least touching parens

16:02 ibdknox: makes it more obvious that it's a function call

16:02 amalloy: bbloom: meh

16:03 tomoj: wait, except -> doesn't call app with zero args there

16:03 down with ->

16:03 amalloy: the best feature of -> IMO is that it lets me order my code however i want. i like to "emphasize" parts of a call by putting them on the left, and de-emphasize the boring parts by putting them on the right

16:04 yogthos: I find -> is nice because it flattens the tree out and it makes it really easy to reorder stuff and move it around

16:05 bbloom: i use the shit out of -> down in my (comment ... ) tests at the bottom for testing multi step processes. i generally put a bunch of intermediate debugging printing steps in there

16:05 yogthos: and it orders logic left to right

16:05 bbloom: it lets me centrally locate my tracing code

16:05 tomoj: it orders operations left to right

16:06 yogthos: tomoj: right, so if you're doing a series of transformations it reads more naturally I find

16:06 bbloom: tomoj: a very lovely property

16:06 tomoj: if you're working with operations

16:06 bbloom: it's particularly nice if you're threading some state through functions with side effects: side effect order matches the reading order

16:07 tomoj: but what's nice when you're working with pure functions and values?

16:07 well, -> is still pretty nice

16:10 but it's interesting that get-in and friends go 'right to left'

16:10 S11001001: tomoj: ->> with sequence ops

16:10 gfredericks: right to left?

16:10 tomoj: hmm, wait, they match, huh

16:11 just comp that's 'backwards'

16:12 gfredericks: does clojure.test guarantee tests in a ns run in the order they're declared?

16:12 hiredman: gfredericks: no

16:13 gfredericks: testing protocols is messy

16:21 Frozenlock: &(partition-by odd? [1 1 1 2 2 3 3])

16:21 lazybot: ⇒ ((1 1 1) (2 2) (3 3))

16:21 Frozenlock: What if I want to partition into only 2 seperate groups?

16:22 amalloy: ~separate

16:22 clojurebot: separate is in clojure.contrib.seq-utils, but just use (juxt filter remove) instead

16:22 Frozenlock: Thanks!

16:22 apwalk: &(split-with odd? [1 1 1 2 2 3 3])

16:22 lazybot: ⇒ [(1 1 1) (2 2 3 3)]

16:28 hugod: bbloom: I am wanting to do some transformation of clojure forms - looks like I could use the transduce functions in fipp to do this :)

16:29 bbloom: hugod: you need a stateful transformation?

16:29 hugod: yep

16:30 bbloom: hugod: do you need reducers or are lazy sequences sufficient?

16:30 i needed reducers in order to have strict handling of side effects (namely: printing)

16:31 hugod: bbloom: not sure - lazy sequences may suffice

16:31 bbloom: it's pretty easy to implement a lazy map-state or mapcat-state

16:31 hugod: I'm not sure I even need it to be lazy

16:31 bbloom: do you have any side effects? if so, you want the strict evaluation of reducers

16:32 do you want your transformation to be foldable? if so, you'd need reducers, but then the state doesn't make much sense, since it's a linear state updated over the seq

16:32 if you don't have side effects and want a state transducer, i suggest just porting my map-state and mapcat-state back to simple lazy-seq recursive functions

16:33 hugod: um, the state I need is probably scoped to forms, rather than linear

16:34 bbloom: as in you have a recursive transformation and you're accumulating state in each node?

16:35 hugod: yes, and the transformation depends on the accumulated state

16:35 bbloom: hmmmm

16:35 are you familiar with generators and "yield" ?

16:35 hugod: I was just about to read the paper

16:36 bbloom: have you ever used python? or c# ?

16:36 hugod: oh, yes

16:36 bbloom: so generators & yield are just like in those

16:36 in haskell land, they implement them using a monad that threads the yield state through all the operations

16:36 generators and yield are the strict (as opposed to lazy) equivilant of lazy-seqs

16:37 hugod: ok, thanks - I think you've helped clarify what I need

16:37 bbloom: if you need to pass data "up" the tree when doing your transformation, you're in a pretty tricky spot

16:38 you could use a zipper to let functions go up, edit, and then come back down, then resume traversing

16:38 hugod: I may need to pass state up

16:38 bbloom: can you do it in several passes? ie walk the tree once, collect some data, then walk it again using that state?

16:38 that's much simpler

16:39 you don't need to pass state up in that case, you just preserve it for the next pass

16:39 hugod: possibly - I could annotate forms with metadata

16:39 bbloom: hugod: probably best if you work with an AST like the one produced by clojurescript's analyzer or ambrose's Analyze

16:40 then you can just assoc in a ::key

16:40 hugod: also worth studying: http://en.wikipedia.org/wiki/Attribute_grammar

16:40 hugod: yeah - that was my original though

16:40 thought

16:40 I was looking for a clojure AST when I remembered fipp

16:41 bbloom: heh, i guess fipp's pretty print documents are *like* an AST for the outputted pretty printing

16:42 hugod: I'ld forgotten Ambrose' Analyze

16:43 bbloom: thanks again :)

16:44 bbloom: hugod: no problem. what are you making?

16:45 hyPiRion: Best check ever: Ran 1 tests containing 100008 assertions.

16:46 hugod: bbloom: I want clojure semantics for an embedded dsl, and can't achieve it any other way

16:46 bawr: hyPiRion: the hell. why would anyone do that.

16:46 bbloom: hugod: what's the dsl?

16:47 hugod: bbloom: pallet

16:48 bbloom: hugod: i really got to go study that at some point, but i'm terrified of pretty much all configuration management systems... i generally manage my servers with makefiles and that scaled pretty cleanly to 15+ servers, which is the most ive had to administer myself before :-P

16:48 hugod: pallet has targets with code attached to them, just like makefiles ;)

16:48 technomancy: pallet's feature list reads like a point-for-point "things that are wrong with chef" document

16:49 very different approach, which I'm glad of =)

16:49 hyPiRion: bawr: It's just to check if my prime generator works as intended. Them nasty bugs pop up when trying to implement fast and concurrent data structures

16:50 TimMc: classpath wat r u doing, stahp

16:50 bbloom: technomancy: that's good to hear

16:50 hugod: bbloom, technomancy: the problem is that plan-fn's generate a data structure which is executed in a separate phase, which affects how you have to write code. Too much cognitive overload still.

16:51 bbloom: hugod: i'm also exploring the world of declaration/plan/act cycles

16:51 technomancy: hugod: I didn't realize it at first, but now I see parallels to converge and eval-in-project

16:51 bbloom: hugod: but in the GUI context... so there is declare/plan/act/react/re-re-react :-)

16:52 hugod: bbloom: interesting - we generate an action plan, that is transformed and then executed. much like a compiler in some ways

16:52 technomancy: now that you mention it, yes

16:52 bbloom: hugod: that's precisely what i'm doing with the dom: i generate a script to permute the browser state

16:53 TimMc: permute? :-)

16:53 warz: is :filespecs only for additional clj files? im trying to include a yml file at the root of a jar, but specifying it with :filespecs causes a null pointer exception

16:53 bbloom: i like the word permute as opposed to the word "update"

16:53 update implies a place, it implies mutation

16:53 permute implies just a little reordering of things :-)

16:53 technomancy: warz: it should work for any file, but the docs are not very good

16:54 TimMc: Doesn't permute mean shuffle?

16:54 technomancy: warz: what are you trying?

16:54 bbloom: but i guess i am "update"-ing the dom

16:54 hyPiRion: TimMc: I thought that as well

16:54 TimMc: I like the idea of a DOM lib that only allows you to move things, not add/delete/modify.

16:54 bbloom: "A way, esp. one of several possible variations, in which a set or number of things can be ordered or arranged."

16:54 arrangement, shuffle, reorder, vary, etc

16:54 warz: technomancy, i just have :filespecs [{:type :path :path "plugin.yml"}]

16:55 TimMc: bbloom: Oh, that is in fact what you're doing? Carry on then.

16:55 bbloom: TimMc: surely you need to add and remove things lol

16:55 warz: if the file name doesn't exist, no exception is thrown and nothings included, but if the file name exists, it throws the exception.

16:55 so i can at least assume it's seeing the file there.

16:55 brehaut: I'd like an honest DOM library; every operation just throws (Exception. "This is going to end in tears; give up now")

16:56 TimMc: function doStuff() { throw new Boolean(false); }

16:56 hugod: bbloom: pallet's actions have return values representing values or results from operations on a remote node, and I want to be able to use clojure conditionals on these, even though their values aren't available until during the execution phase

16:56 amalloy: you could call it DOMinatrix: bringing you the pain you're begging for

16:56 bbloom: amalloy: which pain is that?

16:57 TimMc: The paradoxical boolean is just there to twist the knife.

16:57 technomancy: warz: works here on lein 2.0.0

16:57 bbloom: (there are just so many of them when the dom is involved)

16:57 technomancy: warz: can you put the stack trace on refheap or gist?

16:57 bbloom: hugod: are

16:57 hit return too soon

16:58 hugod: i'll assume you know what you're doing, but i worry that if you need anything more sophisticated than a result transformation function, you'd be better off with semantics that differ from a normal cond block

16:59 hugod: bbloom: we have pallet specific forms, but knowing when to use them is proving to require too much cognitive load

17:02 at the moment it's an exercise to see how it works out

17:07 warz: technomancy, ya ok. sorry i was heating up a hotdog. haha.

17:08 technomancy, im new to this so im probably doing something wrong. here is the stack trace: https://gist.github.com/4614501

17:08 i assumed it was looking for clojure code, because i saw the function EnumerateSeq and invoke and stuff

17:09 sshack: Did cemerick ever release any bays' network code after his talk on the subject?

17:09 brehaut: sshack: no; he discovered serious flaws

17:09 sshack: oh?

17:09 brehaut: sshack: i know nothing about bayes so im not qualified to comment on the flaws. i jsut know that there were there

17:10 amalloy: a pretty basic misunderstanding of the maths involved, from what i understand

17:10 sshack: Understood.

17:10 amalloy: he talks about it in one of his podcasts

17:10 sshack: ahh. Yeah, it is very tricky.

17:10 amalloy: the mostly lazy episode with chouser, if you're interested in finding it

17:11 technomancy: warz: hm; might be a windows-specific bug

17:11 warz: maybe open a github issue for it

17:13 sshack: amalloy: I will have a look.

17:15 amalloy: episode 6 sound right to you?

17:15 lpetit: Hi, what is the current state of marginalia ? Of literate programming in Clojure ?

17:15 amalloy: *shrug*

17:16 brehaut: lpetit: i think zkim has pretty much taken over maintainance? its slowed down considerably i believe

17:16 lpetit: I have a source code I'de like to share with others (essentially clojure newbies) so that they can learn by reading, so I want to decompose it intentionally in small pieces, explaining things as I go.

17:17 tomoj: bbloom: can't the state make sense with a fold if there's an identity state and a combine operation?

17:17 lpetit: brehaut: because it's stable, or because of lack of interest from most?

17:17 brehaut: lpetit: a bit of both i think

17:17 tomoj: hmm, I'm just thinking of the reduction state, I guess I still don't understand mapcat-state etc

17:18 bbloom: tomoj: for there to be a combine operation, you need composable state, which is tricky

17:18 lpetit: What would you suggest? Marginalia, some other lib I don't know about, or setting up a blog ?

17:18 brehaut: lpetit: well, its not exactly literate programming like you might expect with knuth's web or literate haskell

17:18 bbloom: tomoj: lots of folks studying that stuff, things like http://www.eecs.berkeley.edu/Pubs/TechRpts/2009/EECS-2009-173.html

17:18 tomoj: I didn't think the 'state' in map-state was about side effects

17:19 technomancy: lpetit: if you're just going to write it once and not re-publish the HTML for new versions I'd recommend a blog

17:19 bbloom: well in my case the printing is in fact linear

17:19 tomoj: the state isn't about side effects, the use of reducers was about side effects

17:19 brehaut: lpetit: you've seen http://fogus.github.com/marginalia/ i assume?

17:19 tomoj: yeah

17:19 brehaut: technomancy, lpetit: i second that.

17:19 lpetit: technomancy: yeah, I may well rewrite it more than once before it has stabilized, and the blog post may well come after the fact :-)

17:20 brehaut: yeah, saw the web page

17:20 technomancy: I use marginalia for publishing API reference for leiningen-core and it's fine, but I'm not an advanced user

17:20 brehaut: lpetit: thats pretty much the norm for marg projects

17:20 lpetit: technomancy: ok, so it's still in use :-)

17:20 technomancy: typically when reading code I prefer to do it in the editor, ironically because it's better at hyperlinking

17:20 TBH I'm not sure if anyone actually uses the API reference I generate

17:21 lpetit: technomancy: I can't expect people to install an editor, I want to catch their attention with just a browser :-)

17:21 technomancy: lpetit: yeah, it completely depends on the audience

17:21 lpetit: technomancy: Where is it located ? (Ok, I leave the room :-) )

17:21 technomancy: http://leiningen.org/reference.html

17:22 brehaut: lpetit: incidentally, the syntax highlighter that marg uses is a seperate JS project so its easy to stick into your HTML

17:22 lpetit: although the default colourscheme is angry fruit salad

17:23 lpetit: brehaut, technomancy : do you think marginalia could get help from IDE support, e.g. auto-regeneration, etc. ?

17:24 brehaut: lpetit: i'm the wrong person to ask, but i do forget to run marg for my own projects so maybe?

17:24 technomancy: lpetit: seems unlikely to me but I'm not a heavy user

17:25 lpetit: yeah, I knew that. I did great postponing this idea, then :)

17:27 brehaut: lpetit: one thing about marg im not sure about is the way comments and docstrings are merged in the 'textual' pane

17:28 lpetit: brehaut: will check this "live". But I've got to go now, thanks for the feedback

17:41 sshack: Ahh, found the note from cemerick https://github.com/cemerick/raposo

18:01 clojure-newb: hey guys, I've got a PersistentVector : [({:si ["14"]} {:si ["15"]}) ({:si ["16"]})] which I would like to turn into another PersistentVector : [(["14"] ["15"]) (["16"])], so just grabbing the :si key, any ideas ?

18:02 Bronsa: , (mapv #(map :si %) ' [({:si ["14"]} {:si ["15"]}) ({:si ["16"]})])

18:02 clojurebot: [(["14"] ["15"]) (["16"])]

18:03 AimHere: If the hash-keys vary, you might replace :si with 'vals'

18:04 clojure-newb: Bronsa: mapv, hmmm did not know about that one

18:04 Bronsa: it was added in clojure-1.4 afaik

18:04 AimHere: It was introduced in 1.4, just to clean up the (vec (map ... )) idiom

18:04 clojure-newb: cool, thx guys, I'll give it a go

18:14 aaelony: has anyone thought about Pentaho (http://community.pentaho.com/projects/bi_platform/) as a potential target for a Clojure DSL ?

18:21 muhoo: wha are you-all using for java profiling in clojure? visualvm? jprofiler?

18:28 sirvaliance: Any tips for copying a dir and its files specifically for running tests?

18:29 scottj: muhoo: yourkit

18:40 muhoo: thanks

18:41 sirvaliance: Are there any clojure libs that nicely wrap the java io functions?

18:42 dnolen: sirvaliance: clojure.java.io does the basic

18:43 s

18:43 sirvaliance: dnolen: Yeah, I just didn't know if anyone made a wrapper lib to simplify larger operations

19:06 muhoo: is there some way to get lein check to stop trying to run main?

19:07 amalloy: muhoo: bet you a dollar it's not running main

19:08 it's just compiling your namespace, which has side-effecty stuff at the top level (as opposed to in main where it belongs)

19:17 muhoo: there's sideeffecty stuff in (-main) for sure, but not floating about loose in the ns, at all

19:17 in fact, the side-effecty stuff that is running is most definitely inside (-main)

19:17 i can tell from the log

19:18 but this is so loaded with java interop stuff, it could be that too

19:19 https://www.refheap.com/paste/8911 .. start-everything is what is running at lein check time

19:21 amalloy: well, the code for lein check is very simple, and you can easily tell all it does is require your namespace

19:21 try requiring it yourself in a repl and see if start-everything is called there as well

19:23 muhoo: aha, i see

19:23 i've got an injetions

19:23 the injection runs the main, which i want it to do when i start the repl. but i do NOT want it to do when i run lein check. hmm.

19:23 :injections [(do (require 'spazcoin.server) (spazcoin.server/-main))] <-- there

19:38 ok, i'm lost now. i moved the injection to a profile, and naively tried "lein pdo cljsbuild auto, with-profile autorun repl :headless" with no success

19:42 * muhoo says screw it and just manually kills the jvm before running lein check

19:50 augustl: why is the ring-anti-forgery middleware only blocking POSTs? Why not PUT etc?

19:53 djwonk: what are some recommended ways to autorun clojure tests?

19:54 technomancy: djwonk: most people use something like clojure-test-mode; for some reason no one has extracted a generalized run-on-file-change higher-order Leiningen task

20:00 djwonk: technomancy: thanks

20:01 technomancy: np

20:09 augustl: weavejester: ping https://github.com/weavejester/ring-anti-forgery/pull/11 :)

20:11 weavejester: augustl: Why is CSRF-protection needed for XHR?

20:12 Surely the same-origin policy does the job of the anti-forgery token?

20:12 augustl: weavejester: it seems fishy/unsafe to try to detect whether an incoming request is an XHR

20:13 it's better to block any POST, xhr or not

20:13 ..for all I know

20:14 tomoj: did you figure out why not PUT?

20:14 augustl: tomoj: no, but I think it's because HTML forms can only POST

20:14 tomoj: ah

20:14 augustl: even chrome doesn't allow method="put" in the HTML iirc

20:15 technomancy: wow, is that still a thing?

20:15 amazing

20:16 augustl: xsrf, http methods, or something else? :)

20:16 technomancy: I mean method="PUT" not working

20:16 and by amazing I mean sad

20:16 warz: does that work on any browser?

20:16 brehaut: turns out the future is still the future :(

20:16 warz: i didnt think it did

20:16 weavejester: technomancy: Forms have no same-origin policy, which might be why people aren't in a rush to support PUTs etc.

20:17 augustl: I'm still not seeing what advantage using a token for XHR gives you

20:17 augustl: weavejester: the problem is on the server-side. I want to block any incoming request that doesn't contain the token.

20:17 it's not a client side issue, and the XHR block is only on the client side

20:18 s/XHR block/XHR same origin policy/

20:18 technomancy: weavejester: huh; hadn't considered that

20:18 augustl: weavejester: so, for some (most?) XHR requests, a header is more convenient, so my request body can be all JSON

20:19 instead of __anti-forgery-token=123abc&myjson=... and then use form params to parse the JSON, and not set content-type JSON on the request, and ...

20:19 weavejester: Hm… So the scenario is: what happens if a form from a remote page is used to send a POST to an XHR route?

20:19 augustl: there's no such thing as an XHR route, so it will be blocked since the forgery token isn't there

20:20 the route just blocks the POST if the correct token isn't in the form body or in the header

20:20 warz: technomancy, dang i must be doing something wrong. i just tried that :filespecs thing that i mentioned a few hours ago, on my linux machine at home. same error.

20:21 augustl: weavejester: also, I think it is possible for forms to POST raw json to a different origin

20:21 so simply checking for JSON in the body isn't enough

20:21 <input name="json here" type="hidden" /> will do that iirc

20:21 weavejester: augustl: You wouldn't necessarily need a random token though… any header being set would do it.

20:22 augustl: And the content-type would obviously stop it, too.

20:22 augustl: good point :)

20:22 technomancy: warz: if you can narrow it down to a simple case that works with a fresh `lein new` project please open a github issue

20:22 weavejester: Let me sleep on it… and read up on best practise :)

20:22 augustl: Rails requires the actual token so I didn't think about it (since I just stole this from Rails)

20:23 weavejester: goodnight

20:23 augustl: weavejester: great! I'll just disable forgery protection for now, won't be in production for a couple of weeks at least ;)

20:23 nn

20:25 auggierose: so, is leiningen a contextual or a composable tool?

20:25 augustl: regarding the method="xxx" on forms, I think pretty much every routing framework out there checks the method and the form param _method, which seems to be the convention for specifying the _actual_ method from a form

20:30 djanatyn: tomoj: happy birthday!

20:31 tomoj: who told? google?

20:32 ijeki'edo

20:33 warz: technomancy, ok i opened one. we'll see if anybody else can reproduce or if im just doing it wrong. :)

20:34 technomancy: warz: cool; I'll take a look tomorrow

20:34 :filespecs does kinda suck as it is

20:35 warz: i have to take your word for it. clojure as it is still looks alien to me, but im trying to get into it.

20:36 technomancy: it's just one of those places where I'm unhappy with the current implementation in Leiningen

20:36 djanatyn: tomoj: yep :)

20:46 gdev: anyone experiment with game programming in clojure?

20:49 Schaefer: hey folks... i've got two lists of maps. eg [{:name joe :age 10} {:name bob :age 12}] and [{:name joe: age 10} {:name bob :age 13}]. i want to find the records with names that match but ages don't. in this example, i'd find {:name bob}. i'm pretty new to clojure but this feels vaguely like a zipper problem. is there some canonical solution for this problem?

20:51 Raynes: Match what?

20:51 Oh, I think I see.

20:51 You want to find the records that have the same name but different ages?

20:51 Stuff like that

20:51 Schaefer: maybe not zipper. i was thinking

20:51 zipmap

20:51 brehaut: ,(for [a [{:name joe :age 10} {:name bob :age 12}] b [{:name joe: age 10} {:name bob :age 13}] :when (and (= (:name a) (:name b)) (not= (:age a) (:age b))] [a b])

20:51 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Invalid token: joe:>

20:51 Schaefer: Raynes: yes

20:51 Raynes: Yeah, I don't think zipper if what you're after here.

20:52 brehaut: ,(for [a '[{:name joe :age 10} {:name bob :age 12}] b '[{:name joe: age 10} {:name bob :age 13}] :when (and (= (:name a) (:name b)) (not= (:age a) (:age b))] [a b])

20:52 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Invalid token: joe:>

20:52 brehaut: well crap

20:52 something like that

20:52 Schaefer: let me try with quoting

20:52 Raynes: You probably want group-by.

20:52 Schaefer: ,(for [a '[{:name :joe :age 10} {:name :bob :age 12}] b '[{:name :joe: age 10} {:name :bob :age 13}] :when (and (= (:name a) (:name b)) (not= (:age a) (:age b))] [a b])

20:52 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Invalid token: :joe:>

20:52 brehaut: Schaefer: you probably dont want to use symbols for non code data

20:52 Schaefer: double crap

20:53 Raynes: You probably don't want group-by, actually.

20:53 Schaefer: brehaut: yep. that makes sense

20:53 brehaut: Schaefer: thats what keywords are for

20:53 Schaefer: i figure i could write the algo out longhand but i was hoping for some one-liner. seems like a pretty common problem

20:54 brehaut: keywords are basically symbols that refer to themselves, symbols are symbols that refer to something else

20:54 Schaefer: brehaut: thanks. i was just trying to do something quickly. i probably should have used 'joe and 'bob.

20:54 brehaut: ,(for [a [{:name :joe :age 10} {:name :bob :age 12}] b [{:name :joe :age 10} {:name :bob :age 13}] :when (and (= (:name a) (:name b)) (not= (:age a) (:age b)))] [a b])

20:54 clojurebot: ([{:age 12, :name :bob} {:age 13, :name :bob}])

20:55 brehaut: Schaefer: that for does the cross product of both lists though so it blows out pretty fast

20:56 Schaefer: its like SELECT * FROM a OUTER JOIN a WHERE a.name = b.name AND a.age != b.age

20:57 Schaefer: brehaut: thanks! that really helps me understand the algorithm

20:57 i find i have trouble understanding how laziness will affect the computation space

20:58 brehaut: Schaefer: its not laziness in this case, but the cross product

20:58 Schaefer: it has to compare every pair

20:58 Schaefer: brehaut: i understand the number of operations. would it be constant memory though?

20:59 brehaut: if you reformulated the problem so that you had {:joe 10, :bob 12} and {:joe 10 :bob13} for instance, you could take advantage of indexed lookup

20:59 Schaefer: yes it would

21:00 in any case for is a fantastic tool though

21:00 ibdknox: are you trying to find all of the ages of people with the same name?

21:00 Schaefer: brehaut: thanks for pointers! i'll have to think if i can restructure my data. seems plausible

21:01 rationalrevolt: Hi room, can someone help me understand why lein repl gives me cdoc on the user namespace, but using nrepl-jack-in in emacs does not? Is nrepl-jack-in and lein repl totally separate implementations of nrepl protocol? I was thinking nrepl-jack-in uses lein repl underneath... but i'm not understanding

21:01 brehaut: the repl implicitly uses clojure.repl, jack-in does not

21:02 you can use the emacs to access stuff instead

21:03 Schaefer: ibdknox: actually, i'm playing with datomic. i'm protoyping a reactive query system. right now, the queries are stored in datomic along with their results. i have a list of queries whose results *could* be changed by the most recent transaction. i want to determine the queries whose values actually changed so i can write the results back into the db

21:03 ibdknox: sounds like you should be using sets

21:03 rationalrevolt: do you mean the lein repl does an implicit require of clojure.repl before giving me the prompt?

21:04 brehaut: yes

21:04 ibdknox: Schaefer: if you do a set difference between before and after you'd get what you want, wouldn't you? :)

21:04 Schaefer: a set of maps? well, duh. of course that would work. <slap forehead>

21:04 make that two sets of maps....

21:05 rationalrevolt: brehaut: what would I do if i wanted jack-in to do that as well? do i have to change nrepl.el in order to do that?

21:05 Schaefer: ibdknox: thanks!

21:05 ibdknox: Schaefer: np :)

21:05 brehaut: rationalrevolt: you'd be better served by learning the emacs mode ;) otherwise i dont know

21:06 rationalrevolt: brehaut: sorry, din't get you - learning the emacs mode?

21:07 tomoj: it seems rather odd to store query results in datomic

21:08 brehaut: rationalrevolt: all the features of the repl namespaces are available in emacs as emacs commands

21:08 rationalrevolt: mostly with chord keys

21:10 rationalrevolt: brehaut: you mean like C-c-k to load the current buffer into the repl?

21:10 brehaut: etc

21:13 rationalrevolt: https://github.com/kingtim/nrepl.el#keys

21:13 rationalrevolt: C-c C-d and C-c C-j for clojure docs and javadocs respectively

21:14 rationalrevolt: it works in your source and the repl

21:21 ttimvisher: what's the state of swank/nrepl support for clojurescript?

21:25 rationalrevolt: brehaut: but i guess if i wanted nrepl-jack-in to auto 'use' clojure.repl when it gives me the prompt, instead of me having to load a buffer containing the (use 'clojure.repl) form or having to type it in - i would have to either make myself some key combination that will execute that form into the repl or some such?

21:26 Schaefer: tomoj: just saw your comment. yes, it's a little odd and i may not keep this design. the current approach is convenient because of dependencies. suppose one query depends on the results of another. my algorithm for computing the new results is pretty simple: take the current transaction, find all affected queries, compute their results. for the queries whose values have changed, write...

21:26 ...them back to the database. repeat the algorithm until the transaction queue is empty

21:26 brehaut: rationalrevolt: im not sure i understand the point of using nrepl from clojure if you are just going to use it like the command line repl

21:28 rationalrevolt: brehaut: hmm, i frequently use cdoc and i was looking for some way to automatically have it available when nrepl-jack-in gives me the prompt.. I do use the mode commands (such as C-c-k etc), so i do want to use emacs + nrepl-jack-in.. I'm quite new to clojure/emacs, so i might be coming across confusing

21:29 brehaut: wait, cdoc? what is that?

21:29 rationalrevolt: brehaut: clojuredoc, the command that fetches examples from clojuredocs.org

21:30 just like source or doc, but pulls examples of using command

21:30 like i can say (cdoc list) and it will give me examples on how to use list

21:30 brehaut: ah. thats part of reply not clojure.repl

21:31 clojuredocs.org is getting pretty out of date too; the last version it claims ot support is 1.3.0

21:32 rationalrevolt: brehaut: oh, ur right - i though it was part of clojure.repl - what did you say it was part of? reply?

21:33 brehaut: repl-y the new reply by tprtcolin; its the 'lein repl" nrepl client

21:33 https://github.com/trptcolin/reply

21:34 looks like its using https://github.com/dakrone/clojuredocs-client

21:35 raylu: woah, nice

21:35 rationalrevolt: ahh - so, i can accomplish what i wanted by just includng clojuredocs-client as a dependancy in my project.clj, is that right?

21:35 brehaut: i hope you mean as a dev dependancy ;)

21:36 rationalrevolt: yup

21:37 brehaut: thank you :)

21:54 tomoj: Schaefer: I see. curious, how do you store the queries themselves?

21:54 serialized as bytes?

21:54 or like reified with e.g. an entity per where clause, or what?

21:55 Schaefer: tomoj: right now, queries are datomic entities with three fields: a matching entity query, a value function and the current value

21:56 the matchin entity query and value function are both strings. i use read-string when i read them out of datomic

21:56 tomoj: ah, cool

21:57 Schaefer: obviously not very efficient at the moment but i figure i can cache them since i don't expect the queries to change very often

22:04 ttimvisher: What am I doing wrong here? https://github.com/timvisher/clojurescript-up-and-running/tree/master/keybord-events

22:04 I'm `:require`ing `goog.events`, which is the provide that KeyHandler should be under according to http://closure-library.googlecode.com/svn/docs/class_goog_events_KeyHandler.html

22:05 but I'm getting `undefined is not a function` when trying to use it from the browser

22:05 I also see it nowhere in the generated source

22:05 but I didn't think I needed to do anything special to get any of the closure libraries to be available to me to require

22:07 changing my require to a namespace that doesn't exist also triggers an error so `goog.events` is definitely being found.

22:17 i can construct a keyhandler now but it requires me to require `goog.events.KeyHandler`

22:17 what does the `:as` do in that case?

22:19 TimMc: It gives you a short alias.

22:19 Frozenlock: I'm not sure aliases work when dealing with goog libraries.

22:20 I always had to require it and still refer to it by its full (or almost full) name.

22:20 ttimvisher: TimMc: that's what i thought, but it `key-handler.` errored out

22:20 bbloom: Frozenlock: they generally do/should. i had an issue with some stuff in third_party like the dom query stuff, but if it's not working, it's definitely a bug

22:20 TimMc: Oh, CLJS? No idea on the differences from CLJ there.

22:20 ttimvisher: (- it)

22:20 bbloom: please report such issues

22:21 Frozenlock: bbloom: Oh great, perhaps it's been fixed then... it was many months ago

22:21 ttimvisher: bbloom: issues where `:as` doesn't produce a working alias?

22:22 bbloom: ttimvisher: none that i know of, the issue i had had to do with classpaths & loading files that weren't in in src/third_party instead of src/goog

22:22 Frozenlock: ttimvisher: if you are playing with key handler, you might want to look at https://github.com/Frozenlock/zyzanie

22:22 Not the prettiest, but it works.

22:23 ttimvisher: Frozenlock: fun! :)

22:23 this is my first foray into clojurescript so I'm more just playing around

22:23 Frozenlock: ttimvisher: huge fan of your emacs vim-golf btw :)

22:23 ttimvisher: will definitely look into that

22:23 thanks!

22:23 i wish i still had time to do them

22:23 there are downsides to working at a start up, i suppose ;)

22:27 This is what I ended up with. Seems like `:as` has no real effect for `goog` libraries. I get `goog.events` for free because `KeyHandler` requires it for itself. https://github.com/timvisher/clojurescript-up-and-running/blob/master/keybord-events/src/keybord_events/core.cljs

22:28 Frozenlock: ttimvisher: That was my experience as well; never been able to alias a goog library.

22:29 Also, you might want to look at domina https://github.com/levand/domina or enfocus https://github.com/ckirkendall/enfocus to deal easily with events.

22:31 tomoj: I've aliased goog.string as gstring

22:31 clojure.string in cljs does the same

22:32 probably issues referring to types using the alias

22:32 clojure.string also does [goog.string.StringBuffer :as gstringbuf]

22:33 j0ni: is there an obvious choice for standard crypto operations in clojure - stuff like sha digests and the like?

22:34 a cursory inspection shows nothing in core or listed in contrib on clojure.org

22:34 Frozenlock: [goog.fx.DragDrop :as dd] ---> (dd. some-element) ----> #<TypeError: undefined is not a function> :(

22:35 tomoj: well you can at least (:import goog.fx.DragDrop) I believe

22:35 Frozenlock: Perhaps... but I think `require' already does it, even if the alias doesn't work.

22:35 tomoj: it lets you do (DragDrop. some-element) ?

22:36 that seems like a bug

22:36 Frozenlock: No, it let's me (goog.fx.DragDrop. some-element)

22:37 Once I've tried to alias it in a require.

22:37 tomoj: right, that's because it's required. if you import you'll be able to (DragDrop. some-element)

22:37 Frozenlock: Oh God no... not another ns tweek to learn... :(

22:37 tomoj: I wouldn't expect (dd. some-element) to work

22:38 :require :as is for namespaces

22:39 :import is for importing classes so they can be referred to without the package

22:40 I wonder if (:require [goog.fx :as fx]) (fx/DragDrop. some-element) works

22:40 presumably not?

22:40 Frozenlock: I'll try.

22:41 Oh that works!

22:41 Interesting

22:41 tomoj: but I wonder if it doesn't really require DragDrop

22:42 ttimvisher: tomoj: good tip!

22:42 i'm still thinking of anything that is `provide`d as a namespace

22:42 but it can totally be a class as well.

22:43 Frozenlock: tomoj: you mean it might have worked because I have already required DragDrop?

22:43 tomoj: that's my worry

22:44 or that it'll suddenly break in advanced comp or something

22:44 Frozenlock: Well it works in another namespace. should I reset the repl?

22:44 tomoj: but I dunno

22:44 don't really understand goog.provide/require or how cljs deals with it

22:44 s/really/at all/

22:44 Frozenlock: Neither do I :P

22:44 bbloom: tomoj: did you read the docs on the gclosure site?

22:48 skelternet: anyone used your own reader literals to get something useful done?

22:50 tomoj: bbloom: nope

22:50 bbloom: tomoj: that's why you don't understand it :-)

22:52 tomoj: yeah

22:54 ttimvisher: bbloom: have a link to these docs?

22:59 Frozenlock: just pushed up some changes that i think follow a better approach. Not sure what the difference between import and require is in those cases but that certainly makes the calling code cleaner.

23:02 Frozenlock: Indeed. I'll do the same in my own code now that I'm aware of that :)

23:03 tomoj: s3-wagon-private's output makes me appreciate how good we had it when it was just maven uncontrollably spitting out garbage

23:05 yedi: #clojure is so awesome

23:05 Raynes: yedi: I know I am

23:15 akhudek: j0ni: I would suggest using a java library: built in pbkdf2, jbcrypt, or jasypt

23:16 tomoj: if all you want is a sha digest, I don't think you need a library

23:17 example (and a library, though I won't claim it's an obvious choice): https://github.com/tebeka/clj-digest/blob/master/src/digest.clj

23:18 j0ni: well for now i just used java.security.* directly

23:18 i'll take a look at clj-digest though

23:19 thanks

23:20 adu: clojure is so awsome

23:24 Rich_Morin: I' trying our the Community editions of IntelliJ - are there any plugins other then Leiningen and La Clojure that I should grab?

23:24 akhudek: tomoj: does clj-digest iterate the sha? If so, then it should be fine.

23:25 non-iterated sha digest is apparently too weak though

23:28 Rich_Morin: I'm signed into http://dev.clojure.org/display/doc/Getting+Started+with+La+Clojure+and+IntelliJ+IDEA and see a typo, but no way to edit the page.

23:39 amalloy: sometimes i think that's the desired experience for *.clojure.org: a community-maintained site the community isn't allowed to maintain

23:44 Rich_Morin: IntelliJ wants me to specify an SDK. Do I need one for Clojure?

23:47 akhudek: Rich_Morin: if you've install la clojure, then the way I always get started is to create a new project with "lein new" from the command line

23:47 issue "lein pom"

23:47 then import the project as a maven project in IntelliJ

23:48 you'll need to do lein pom every time you change project.clj though

23:48 or rather, change the dependencies in it

23:48 you shouldn't have to worry about the SDK business (though don't quote me on it)

23:53 Rich_Morin: I tried "Start Clojure Console" and got "Error: No jdk for module 'ii_1'"

23:57 akhudek: Rich_Morin: hmm. I've never encountered that. One thing I forgot, right click on the project itself in the project pane (default on the left) and select "add framework support"

23:57 not sure if it will solve that message though

23:58 Rich_Morin: I tried right-clicking on the project.clj file - is that what you mean?

23:59 nm

Logging service provided by n01se.net