#clojure log - Apr 16 2012

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

0:00 yoklov: i mean, every deterministic state machine is still an non-deterministic one, so i don't think that you're too pressed to do that

0:10 pipeline: kovasb: that's the joke, isn't it. They were doing well, but it's an order of magnitude problem. Real estate speculation is the devil.

0:13 zenlike: pipeline: how so?

0:35 kovasb: ibdknox: i figured out the problem

0:35 ibdknox: but the solution hits a bug in noir-cljs

0:35 ibdknox: noir.cljs.watcher/build does not respect the :src-dir in the options

0:43 ibdknox: kovasb: are you using an older version?

0:44 kovasb: I'm looking at the source on github right now

0:44 ibdknox: hm

0:44 it seems to respect src-dir?

0:44 where doesn't it

0:44 kovasb: compile-options its busted

0:44 (@options m)

0:45 should probably be just @options

0:45 ibdknox: no

0:45 options are keyed by mode now

0:45 :advanced { ...}

0:46 so you can have different options based on what mode you're in

0:46 that likely isn't documented

0:46 kovasb: ok, let me try that

0:46 ibdknox: ah no it is, hah

0:46 kovasb: :)

0:48 whew ok

0:48 anyway the issue is that any clj code that calls himera cannot be on the path for the cljsbuild command

0:48 no idea why its not ignoring the clj files automatically, but that seems to be the problem

0:51 (cljsbuild also has problems with its options; in this case i literally copied the examples and modified them with no luck)

0:54 laurus: Will the "ratio" type ever exist in clojure-py?

1:14 yoklov: laurus: i wouldn't bet on it.

1:15 clojure-py isn't official, it's basically a reworked version of clojurescript's innards, and since javascript can't have a ratio (no integer type…) i wouldn't bet on it.

1:15 oh you aren't even here anymore.

1:15 ibdknox: actually clojure-py is based on JVM Clojure I think

1:16 I looked at the source and it looked much more java-y :)

1:16 which is unfortunate :(

1:30 yoklov: yeah?

1:30 weird, i had thought it was the same sorta deal as clojure-scheme

1:30 ibdknox: nope

1:30 lots of cool, but duplicated work there :/

1:31 yoklov: yeah

1:31 septomin_: ibdknox: so maybe an announce-only mailing list

1:31 ibdknox: yeah...

1:31 yoklov: i saw one that was to actionscript which was the same sort of deal. basically an enormous port of all of clojure

1:32 ibdknox: septomin_: it's only the first day. I'll give it a couple days to settle

1:32 if it remains ridiculous, I'll close it down

1:33 kovasb: i think the deal with clj-py is

1:33 implementing the core functions in rpython gives you the benefits of the jit'ing compiler

1:34 though i could be wrong

1:34 (as opposed to implementing the minimal pieces of clojure which then allows you to bootstrap the rest of the definitions)

1:39 afoolsuchasi: anyone have any recommendations on where to host clojure/noir backed by some kind of elastic setup?

1:39 Scriptor: I think you can host clojure projects on heroku, since they have jvm support now

1:40 http://blog.heroku.com/archives/2011/7/5/clojure_on_heroku/

1:40 ibdknox: clojure support on heroku is awesome

1:40 and if you created the project with lein noir new

1:40 all you need to do is heroku create --stack cedar

1:40 git push heroku master

1:40 and done.

1:41 afoolsuchasi: thanks, ill check it out. ive been trying unsuccessfully to get beanstalk working so it may be time to give heroku a shot if ppl here have found success with it

1:41 Scriptor: kovasb: you'd still get JIT benefits for any clojure code running on the interpeter wouldn't you?

1:42 if you wrote the core functions in RPython, the advantage would be that they would be compiled to C, not that they would be JIT'd

1:42 laurus: Any clojure-py users here?

1:42 kovasb: the are one and the same

1:42 if it compiles to c then it also builds a tracing jit for that bit

1:43 Scriptor: really? It can JIT the C code?

1:43 kovasb: hold on lemme find u the link

1:43 eggsby: does clojure-py run on pypy yet?

1:44 Scriptor: it generates a JIT, but I don't think it's for the C code

1:44 kovasb: http://tratt.net/laurie/tech_articles/articles/fast_enough_vms_in_fast_enough_time

1:45 laurus: eggsby, I'm not sure. Probably!

1:45 eggsby, hey, I'll try it, just a sec.

1:45 kovasb: great post explaining all this stuff

1:46 Scriptor: kovasb: where's it say it JITs the C?

1:46 eggsby: laurus: I see there's a clj-py repo on github

1:46 laurus: eggsby, yes, it works on pypy :)

1:46 Scriptor: kovasb: it can't literally just-in-time compile the C code...since it's already compiled as far as I know

1:46 kovasb: read the "JITs for free" section

1:47 laurus: eggsby, what is clj-py?

1:47 kovasb: right, it doesn't git the C per say, it overlays instrumentation on top of the C

1:47 Scriptor: it JITs the code that is being run on top of the VM

1:48 kovasb: "As said earlier, RPython automatically layers alongside C code a second representation of the interpreter (the tracing interpreter). "

1:48 Scriptor: yes, that's the JIT

1:48 laurus: eggsby, the official repository is https://github.com/halgari/clojure-py .

1:49 kovasb: though its not obvious to me if simply writing rpython gives you this benefit

1:49 eggsby: sorry https://github.com/halgari/clj-pypy laurus

1:49 Scriptor: if you write some core Clojure functions in RPython, I don't think the JIT will be involved

1:49 kovasb: particularly since clojure-py is already living inside of pypy, which is already a vm implementation

1:49 Scriptor: you can't trace code that is already compiled...

1:49 laurus: eggsby, well, the normal clojure-py works with pypy anyways.

1:50 kovasb: i don't understand how these things stack on top of each other..

1:50 eggsby: heh, must be an earlier version

1:50 will pypy is python written in python so doesn't it just use the python instructions for whatever the compiled c is?

1:51 * eggsby doesn't know how it works either

1:51 Scriptor: kovasb: the tracing jit looks for loops run frequently by the regular VM, when it detects one it JITs that loop

1:51 laurus: eggsby, I don't know the details of pypy, sorry.

1:51 Scriptor: so that next time the VM can execute the machine code that the JIT just generated for that loop

1:51 arohner: I have a fn I want to implement, insert-before. inserts item into a seq, at the position before (f x) returns true. Is it possible to do lazily?

1:52 I can do (lazy-cat (take-while #(not f)) [item] (drop ???))

1:52 Scriptor: I'm not an expert on JITs or even VMs but that's a basic idea of how a tracing jit works

1:53 arohner: I guess I can use an atom to count...

1:53 eggsby: thanks Scriptor :)

1:53 amalloy: arohner: ew, no atom

1:54 arohner: amalloy: what does my drop clause look like then?

1:54 amalloy: just write it by hand with lazy-seq - i don't think any of the HOFs help a lot

1:54 septomin_: maybe split-with?

1:55 amalloy: arohner: what do you want to happen if f is never satisfied? i'm writing it up

1:55 arohner: return the unmodified seq then

1:56 yeah, I guess I'll use lazy-seq

1:57 amalloy: arohner: https://gist.github.com/2396569

1:58 arohner: amalloy: why the fn? why not just return lazy-seq?

1:59 amalloy: if you recur to insert-before you have to keep passing pred and item, even though they don't change

1:59 hsteak: hello. I'm new in the clojure world and i would like to implement an tokenizer. Usually i would use a finite state machine but is it the right way in clojure? If not, what would it be? (pointers?)

2:00 arohner: oh, missed the recur

2:00 amalloy: there's probably no particular efficiency gain from my ((fn ... (lazy-seq))) compared to just lazy-seq - i'm probably creating a closure and passing it pred and item behind the scenes

2:01 but i like the ((fn )) pattern, since it works anywhere, not just exactly at the head of a named function

2:01 yoklov: heh, made a dent in a 3d game in clojurescript: http://thomcc.github.com/Argh/ . very unfinished, but is somewhat neat.

2:01 basically served as a test run for game development in cljs, with the real deal being ludum dare next weekend

2:01 amalloy: arohner: i like the pattern so much i pulled it out into a nice little macro at https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L105

2:02 arohner: amalloy: nice

2:02 ibdknox: yoklov: nice!

2:02 yoklov: code on github?

2:03 amalloy: arohner: updated the gist to include what it looks like with lazy-loop, if you're interested

2:03 yoklov: ibdknox: thanks, it is! https://github.com/thomcc/Argh

2:09 the source is messy. i found that doing things elegantly would lead to… very poor frame rates. or in the case of the level generator, a 5-second lag between the page loading and anything happening

2:10 ibdknox: very cool :)

2:11 laurus: How do I "subsume" a list into another? I.e, turn (1 (2 3)) into (1 2 3)?

2:12 yoklov: laurus: list* works if your list is at the end.

2:12 arohner: laurus: there's flatten, but that's a big hammer

2:12 yoklov: otherwise you want flatten probably

2:13 or maybe something like 'apply concat'

2:13 laurus: I could swear there was an easier way to do this :)

2:13 yoklov: ibdknox: thanks, really it ended up being much harder to do than i thought it would be, but i think i have the tricks down so that i'll be able to make something neat next weekend

2:14 amalloy: laurus: i think the first step is to start with a more thorough definition of what you want to do in various cases. list*, cons, apply concat, and even (god help us) flatten might be right, so far

2:14 kovasb: yoklov: once you figure out the tricks, please share with the mailing list :)

2:14 yoklov: ,(list* 1 2 3 '(4 5 6))

2:14 clojurebot: (1 2 3 4 5 ...)

2:14 kovasb: yoklob: also I'm sure the core devs would be interested in the stumbling blocks

2:16 laurus: amalloy, I am trying to turn this Python example, http://networkx.lanl.gov/tutorial/tutorial.html#edges , into clojure-py.

2:16 So the equivalent code is (.add_edge G '(2 3))

2:16 yoklov: kovasb: yeah, most of them are known (e.g. don't use nice data structures in the middle of a big loop), and some weird things are annoying but seem like they might just stay that way regardless (for example, (str) is painfully slow)

2:16 laurus: But I wondered how to put in the variable e from (def e '(2 3)) there.

2:17 kovasb: str being slow is a concern

2:17 are you using the new optimizations branch?

2:17 yoklov: yeah

2:17 kovasb: early days in clojurescript...

2:18 I've been debugging this clojurescript compiler thing for the last 3 hours

2:18 yoklov: str being slow is due partially to checking type, and partially due to using gclosure's stringbuilder.

2:18 kovasb: painful

2:18 amalloy: well, surely it's [2 3] - quoted lists are pretty uncommon and vectors are a much more normal way to represent tuples

2:19 kovasb: what does stringbuilder get you?

2:19 yoklov: kovasb: what compiler thing

2:19 i have no clue

2:19 kovasb: my personal issue

2:19 yoklov: hah, bummer

2:19 amalloy: but if you want to do python interop, i dunno man. if it were a real clojure function you'd just want apply; if it were jvm interop you'd have to pull the list apart yourself and then call (.addEdges g x y)

2:19 kovasb: i just set up this complicated state inside the compiler namespace

2:20 and now the repl went bust

2:20 FML

2:20 yoklov: whenever ive had an issue with str its been totally replacable with (.join (array …) "")

2:20 kovasb: you mean for speed?

2:20 yoklov: yeah.

2:20 kovasb: cool. can probably macro that

2:21 yoklov: i was originally rendering by moving around a bunch of divs and setting their css.

2:21 or just a function, the overhead isn't the function call its the other parts of str

2:22 kovasb: right, i mean instead of having to type (.join (array ..) "") every time

2:22 so what was faster than setting the css?

2:22 yoklov: canvas

2:22 and rewriting everything.

2:22 kovasb: i c

2:23 yeah i want to do relatively large visualizations in cljs

2:23 so I'm interested in all this stuff

2:24 yoklov: https://github.com/thomcc/Argh/blob/63d9864742083155ef4069ab3920bafd05dd7450/src/argh/core.cljs#L212-230

2:24 and that was rendering around 60fps but it was very limited in what i could do with it

2:24 e.g. no shadows

2:25 and even if i was just (str some-num "px") it would end up being about 25% of the time spent overall.

2:25 kovasb: yeah canvas is the way to go for that sort of thing

2:25 wow

2:25 yoklov: yeah, when i was doing more it was over 60%

2:25 ibdknox: you should mention that to dnolen, see what he has to say

2:25 kovasb: well thats something to keep in mind for DOM manipulation libs

2:25 ibdknox: maybe we should dump google.string

2:26 kovasb: how do you profile that?

2:26 yoklov: yeah, i was goiing to

2:26 google chrome profiler

2:26 * profiles tab in webkit inspector

2:27 kovasb: cool

2:27 yoklov: but google.string is probably not really built for that also

2:28 that = performance critical string manipulation, as both java and javascript allow you to just use +

2:31 annnnnnd i'm out.

2:31 night al

2:31 *all

2:31 kovasb: later

2:40 laurus: I have a seq of objects. Is there a way to print them all out in a nice way?

2:41 (just typing (seq things) prints out a list of what the type of object is)

2:42 Oh, (map seq (seq things)) did it.

2:42 Raynes: I'm not sure what the goal is.

2:43 What are these objects?

2:43 And what is 'a nice way'?

2:43 laurus: Raynes, sorry, I am using clojure-py, and it was a list of "tuples".

2:43 Raynes: Oh, yeah. No idea about clojure-py.

2:43 laurus: So typing (seq mylistoftuples) just printed out a list of "builtin_tuple".

2:43 Well the same kind of thing happens with Java objects.

2:44 amalloy: most of the java builtins have mostly-non-dumb toString representations

2:44 except arrays

2:44 Raynes: Well, what you're doing isn't actually printing anything. The REPL is printing the result of the code you're executing.

2:45 laurus: Raynes, right, good point.

2:45 Raynes: But yeah, what you see when you print is whatever .toString returns for that object.

2:45 And most of them are pretty worthless.

2:45 laurus: :)

2:46 Raynes: At least in JVM Clojure.

2:46 Not sure about clojure-py or how it works.

2:46 laurus: Very similar, I think

2:46 :)

2:47 I am still not sure how each of the data types of Python compare to the Clojure or JVM equivalents and how clojure-py deals with that.

2:47 But just plowing through and fudging things seems to be working well so far.

2:48 Raynes: I'm kinda weirded out by how clojure-py is going to have to do Erlangish concurrency.

2:48 But I guess it's kinda irrelevant since it'll probably be a library thing.

2:49 It pretty much blows away any chance of compatibility though, I'd think. It'd be like a whole new dialect of Clojure at this point.

2:49 laurus: Raynes, the thing I am concerned about is the difference in numeric types... for example, I don't think clojure-py supports ratio.

2:50 amalloy: i don't think so, Raynes. you can easily write future in terms of processes instead of threads, right?

2:50 Raynes: amalloy: Yeah, probably. But this would pretty much make refs, atoms, etc, pointless, wouldn't it?

2:51 So anything using STM for important things would suffer.

2:51 Is there even an implementation of those things at all in clojure-py? I haven't checked.

2:53 amalloy: python probably has some kind of shared-memory library, like mmaping a file or something. so it doesn't have to be super-slow

2:54 laurus: Raynes, only clojure.core has been ported, I think.

2:55 amalloy: well, clojure.core has all the hard stuff. so i'm inclined to think clojure.core isn't actually all ported

3:04 laurus: How do I make a function that takes a list and puts (map seq ) around it? Is that a "macro"?

3:05 Licenser: I'd make that a function - at least I don't see a reason to make it a macro out of the box

3:06 amalloy: that just sounds like...(defn f [x] (map seq x))...?

3:06 laurus: amalloy, yes, I just figured that out :) Thanks.

3:06 Null-A: (def f (partial map seq))

3:06 laurus: I just remembered hearing about macros so I figured this might be one.

3:08 bsteuber: laurus: first rule of macro club - don't use macros :)

3:09 of course there are very useful cases, but they are so rare you can neglect that until more experienced

3:10 laurus: Thanks Licenser, bsteuber :)

3:12 Licenser: bsteuber is right the better you know macros the less you use them :P

3:14 bsteuber: laurus: btw, the main reason not to use macros is less composability, like with higher-order-functions

3:24 kral: morning

3:26 laurus: bsteuber, thanks.

3:29 Licenser: morning kral

4:58 kral: i know it's ot, but is there anyone that would like to come to italy for some java programming?

4:58 it's a steady job offer

4:58 query me if interested

4:59 * vijaykiran thinks - damn just came back from tuscany :)

4:59 kral: vijaykiran: we are near venice

4:59 vijaykiran: kral: :) nice place too ... but unfortunately I can't move :(

5:15 kral: may be you should post on clojure mailing list as well

5:30 wei_: this example from joy of clojure (https://gist.github.com/2397225) transforms a callback-based function to a blocking call. how would I add a 5-second timeout to the blocking call?

5:31 kral: vijaykiran: not sure if it's clojure related... we may have some side projects that may involve clojure, but we mainly search for a java programmer.

5:31 wei_: i was thinking of using another thread that sleeps for 5 seconds and calls deliver, since calling deliver twice seems to work ok in my repl

5:58 _KY_: Does "let" evaluate arguments sequentially?

6:00 Yes it does..

6:14 laurus: How do I see the exceptions in the SLIME repl?

6:20 vijaykiran: laurus: *e

6:24 laurus: vijaykiran, thanks!

6:44 neotyk: Good morning everyone!

6:44 clojurebot: Pardon?

6:44 neotyk: clojurebot: are you talking to me?

6:44 clojurebot: Gabh mo leithscéal?

7:12 * angerman feels like nodejs doesn't want to work with him. Back to clojure.

7:14 _KY_: Is there a convenient way to store in-memory data for quick look-up?

7:14 I'm thinking something similar to Erlang's ETS (Erlang term storage)

7:15 angerman: neotyk: that async client is yours right?

7:16 vijaykiran: _KY_: what type of data ?

7:16 _KY_: Perhaps key-value

7:17 vijaykiran: simple map won't work ?

7:18 _KY_: Ah... that's what I'm asking... =)

7:18 Can they be relatively big?

7:18 vijaykiran: but ETS claims - "very large quantities" :)

7:19 depends on what you mean by "big"

7:19 _KY_: Well.. almost takes up all main memory

7:19 Potentially, I mean

7:20 vijaykiran: may be start with a map - and later switch to redis or something

7:20 _KY_: I see...

7:20 Redis can be automatically distributed?

7:21 vijaykiran: "At the same time Redis Cluster, an automatically distributed and fault tolerant implementation of a Redis subset, is a work in progress, and may be a good solution for many use cases."

7:21 http://redis.io/topics/faq

7:21 I'm not a redis expert :)

7:21 neotyk: angerman: yes, indeed

7:21 angerman: what about it?

7:22 angerman: do you have a connection pool for it?

7:22 neotyk: yes

7:23 angerman: e.g. call c/GET client url 1000 times, but have them worked down in at most 5 concurrent calls?

7:23 _KY_: I see...=)

7:23 neotyk: angerman: http://neotyk.github.com/http.async.client/doc/http.async.client.html#var-create-client

7:24 and examine max-conns-...

7:24 angerman: thanks, will take a look

7:24 neotyk: but what you are asking is queueing, I guess

7:24 not connection pool

7:25 angerman: if you allow max 5 conns to host and issue too many requests, they will get rejected

7:25 angerman: neotyk: you are right. Though what happens if I throw that 1000 urls at one client with :max-cons-tital 5 ?

7:26 urgs.

7:26 _KY_: What if I need a map with possibly duplicate keys?

7:26 Derander: _KY_: that doesn't sound like a map :-)

7:26 neotyk: angerman: let me check, I had custom queue for it somewhere

7:27 Derander: _KY_: how do you want that case to behave?

7:27 vijaykiran: _KY_: use multimap - google collections

7:27 angerman: neotyk: that would be great

7:29 neotyk: angerman: my implementation for it was based on PriorityBlockingQueue and FixedTdreadPool

7:29 angerman: neotyk: mind sharing?

7:30 neotyk: angerman: this is code for one of my clients, can't

7:30 angerman: alright, no worries :)

7:31 neotyk: would you like to see this feature in http.async.client itself?

7:33 angerman: yes, I guess it would be great if you could just throw urls at the client, and tell it how many to execute at most in parallel.

7:33 waiting for the promises would do the rest.

7:36 neotyk: angerman: can you create a ticket for autoqueueing? I guess it would be nice feature to have

7:36 angerman: will do

7:36 neotyk: thanks

7:48 angerman: didn't `lein deps` just download the dependencies, that were not there alread?

8:01 O_o what am I doing wrong now? Have i been too long away from clojure?

8:01 java.io.FileNotFoundException: Could not locate http/async/client__init.class or http/async/client.clj on classpath:

8:02 neotyk: angerman: can you gist your project.clj and file that is invoking h.a.c?

8:02 angerman: neotyk: I just copied the sample code from the website...

8:02 neotyk: oh my

8:03 which sample, the basic one?

8:03 angerman: yep that one from the README.md

8:03 (ns sample ...)

8:03 (with-open …)

8:03 neotyk: let me check

8:03 angerman: and I added the :dependencies [[org.clojure/clojure "1.3.0"] [http.async.client "0.4.3"]]

8:04 ran $ lein deps

8:04 and since then every lein command crashes. that's very strange!

8:04 hmm

8:04 neotyk: maybe… it's a stale line install somewhere.

8:05 I'll just clear out everything, and start anew :D

8:05 neotyk: how lein is crashing?

8:06 angerman: with?!

8:07 neotyk: you said: and since then every lein command crashes. that's very strange!

8:08 angerman: just recreated sample from scratch, works here

8:09 angerman: wasn't there a tool to see what's in a jar?

8:09 neotyk: yeah, jar -tf

8:10 angerman: OOOOkay!

8:11 otfrom: Hi

8:11 angerman: it says it doesn't find the file. But the file is there. And the jar is on the class path… wth is leiningen doing?

8:12 neotyk: what version you have, and what plugins you installed

8:12 Hi otfrom

8:12 vijaykiran: angerman: it would be better if you paste the output from lein command somewhere

8:12 angerman: neotyk: lein 1.7.1

8:15 neotyk: angerman: I was at 1.6.2, upgraded to 1.7.1 rm lib and works

8:16 it must be plugins

8:16 but vijaykiran is righ, post your output

8:16 s/righ/right/

8:28 angerman: hmm. completely purging leiningen and reinstallng, did the trick...

8:42 neotyk: angerman: good that it worked

8:45 angerman: just reviewing docs for next http.async.clinet release, connections will not get rejected above max-conns-... limit, they will be created but will not be kept avlive.

9:05 angerman: how do I turn :foo into "foo"?

9:05 ,(name :foo)

9:06 clojurebot: "foo"

9:06 angerman: ic

9:06 oskarth: http://clojuredocs.org/clojure_core/clojure.core/name

9:21 _KY_: How can I test for number type?

9:21 gtrak: ,(number? 5)

9:21 clojurebot: true

9:22 gtrak: ,(number? (/ 5 3))

9:22 clojurebot: true

9:22 _KY_: But not float...

9:22 ,(number? 0.9)

9:22 clojurebot: true

9:22 _KY_: ,(number? .9)

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

9:22 _KY_: I see...

9:23 gtrak: . is java interop to the reader i think

9:23 hmm, well at any rate it treats it as a symbol, which isn't what you want

9:24 ,.9

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

9:24 gtrak: ,0.9

9:24 clojurebot: 0.9

9:24 gtrak: .x

9:24 ,x

9:24 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0)>

9:30 angerman: how do I turn "2012-04-16T06:20:22-07:00" into a date object in clojure?

9:31 raek: angerman: use clj-time (or joda-time through interop)

9:33 with joda-time: (DateTime/parse s)

9:33 vijaykiran: angerman: or use Clojure 1.4 Instant Literals :)

9:33 https://github.com/clojure/clojure/blob/master/changes.md

9:34 raek: that method accepts the ISO 8601 format your string uses

9:37 gtrak: reader literals look awesome

9:39 angerman: raek thanks. :)

9:49 _KY_: I need to do "return-from" as in Lisp, what should I do?

9:50 S11001001: _KY_: use raise from slingshot

9:50 Licenser: restructure the code

9:50 S11001001: _KY_: you cannot do a lexical non-local return in the JVM

9:51 also Licenser is right

9:51 Licenser: of cause I am :)

9:51 ;)

9:51 * Licenser runs for cover

9:51 _KY_: It's very hard to restructure

9:51 S11001001: except when spelling :)

9:52 _KY_: Licenser is still right, and restructuring will probably make you a better clojure programmer, but if you really must do it the non-clojure way, use slingshot

9:52 _KY_: http://pastebin.com/PBV9pCnj

9:53 The code doesn't work yet...

9:53 Licenser: _KY_ we only look at refheap pasts :P

9:53 j/k

9:53 gtrak: is return-from like the goto joke?

9:54 _KY_: I don't know how to break out of the doseq when 0.9 is found

9:54 S11001001: _KY_: I would suggest, instead of doseq, you use a HOF that gives you intermediate results from consuming fetch-rules. iterate and reductions are good choices

9:54 Licenser: something like take-while also comes to mind

9:54 S11001001: doseq is for non-functional code, and you are intending to write functional code

9:55 Licenser: something like <metacode> (take-while #(not= % 0.8) (map evaluate-rule rules))</metacode>

9:55 or drop-while < 0.8 might be even better

9:56 _KY_: I see...

9:56 Licenser: it's just a idea from a first glance at your code

9:56 when I see it right you want to get the first result that hits 0.9?

9:57 _KY_: That code is messed up...

9:57 Licenser: a bit yes :)

9:57 but that's fine :)

9:57 _KY_: Let me rethink and if it's not solved I'll repost

9:58 gtrak: http://en.wikipedia.org/wiki/COMEFROM

9:58 angerman: if I have a list of maps ({…}, {…}, …) how could I add a :rank i keyword to all? interleave, partioin, assoc? or is there a simpler solution?

9:58 Licenser: angerman I think there is reduce-kv now

9:58 S11001001: gtrak: no, return-from is like break to a lexical label, but it escapes any number of stack frames, and passes a result to be the result of the return-from form

9:59 Licenser: or even map-kv

9:59 that'd be greater

9:59 S11001001: (the block form, that is)

9:59 angerman: Licenser: map-indexed … whoa

9:59 gtrak: S11001001, ah, so like an exception

10:00 S11001001: gtrak: except there's no dynamic capture

10:00 Licenser: angerman you could also just reduce it

10:00 angerman: ,(map-indexed #(assoc %2 :rank (inc %1)) (list {:o :a} {:o :b})))

10:00 S11001001: (block blah (lambda () (return-from blah 42))), that lambda will *always* refer to the exact block-blah it was created in, even if you recursively enter block-blah again

10:00 clojurebot: ({:rank 1, :o :a} {:rank 2, :o :b})

10:00 angerman: Licenser: I don't see that reduce there, right now. Mind to explain?!

10:00 _KY_: Ok... it's still not solved:

10:01 http://pastebin.com/QYGTHAXF

10:01 The "result" is not defined in my code, but that's what I want to do

10:01 Licenser: angerman sorry I did not udnerstand what you mean with rank\

10:02 angerman: Licenser: ahh, ok… I just though I was missing something :)

10:02 S11001001: _KY_: that's the code you pasted before

10:02 Licenser: well you can reduce but it get's more complicated

10:02 so it's not a good solution ^^

10:03 S11001001: reduce consumes the whole seq, which I assume is not what's desired; reductions is a good general alternative that won't

10:03 but take-while may indeed be easier

10:03 _KY_: Slightly corrected...

10:03 How does take-while work?

10:03 S11001001: ,(doc take-while)

10:03 clojurebot: "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects."

10:04 _KY_: So if there is an empty item... the pred fails...

10:04 Licenser: S11001001 reduce was for angerman not _KY_

10:04 S11001001: Licenser: ah, sorry

10:05 Licenser: but also there it wasn't the best answer :) I just didn't understand his problem

10:05 _KY_: The problem is quite complicated actually

10:05 If the 0.9 point is reached, I want to return with 0.9

10:06 Otherwise, I want to do the last line

10:06 The last line should be performed after the whole sequence is processed

10:06 S11001001: so do a first filter, turn the body of doseq into a map, and there you have it

10:06 ,(doc filter)

10:06 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

10:08 S11001001: ,(doc split-with)

10:08 clojurebot: "([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"

10:08 S11001001: then you can submit the first of that result, then check the (seq (second result)) to see whether you ran into 0.9

10:08 _KY_: Ok... I see... but it's more work... =(

10:09 S11001001: it's not; it's just more thinking about doing things in a way you're not used to

10:09 _KY_: It seems slower too

10:10 More computation, I mean

10:10 S11001001: something about premature optimization here...

10:12 _KY_: So I just need to test if a sequence contains [] in it, how to do that?

10:14 S11001001: seq or empty?

10:14 _KY_: I see... "some" will do

10:15 (some #(= % []) sequence)

10:16 tomoj: #{[]}

10:16 S11001001: empty?

10:16 clojurebot: empty is amalloy: therfor I return [previous] if rest

10:16 S11001001: heh

10:16 ,(doc empty?)

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

10:17 _KY_: Ah right...

10:18 S11001001: if you wish to only submit those jobs *preceding* the empty, then split-with seq will help you

10:19 _KY_: No.. any empty will cause 0.9 and abort

10:20 S11001001: hmm, your original code invariably submits every job until encountering an empty

10:22 _KY_: Yes but that's not intended

10:22 Now it's better=)

10:35 mega: anny one know of a lib for json to clojure data that works in cljs?

10:35 goodieboy: anyone using the sublime text editor with leiningen and a repl?

10:40 Licenser: _KY_ how about write metacode first

10:43 werg: goodieboy, yes it works ok, not quite as nice as an emacs setup i guess

10:44 goodieboy: werg: good to know. Do you know where I can find instructions to get it working? When I try to connect to SublimtRepl I get "OSError(2, 'No such file or directory')"

10:45 _KY_: Licenser: I think I've got that part right now...

10:45 But it has another problem

10:45 wkmanire: Howdy folks.

10:46 _KY_: http://pastebin.com/xpsMjBUA

10:46 werg: none beyond the official docs

10:46 _KY_: ^^ this is the entire code

10:46 Gets an error: "Cannot cast java.language.Double to java.util.concurrent.Callable"

10:47 That "if" statement seems problematic

10:48 S11001001: _KY_: stick a # before (solve-rule

10:49 _KY_: Really?

10:49 S11001001: you forgot the lambda :)

10:49 _KY_: What would that do?

10:49 S11001001: what do you give submit?

10:50 _KY_: Ahh... I see

10:51 Works now... thanks! =)

10:52 mmarczyk: dnolen: ping?

11:26 Frozenlock: I'm experiencing some difficulties with java interop: I can use the class without any problem, even import them... but I get an error each time I try to do the same with a nested class. How can I use a nested class?

11:28 Bronsa: class$nested

11:28 instead of class.nested

11:28 Frozenlock: With the dollar sign?

11:28 Bronsa: yes

11:28 Frozenlock: Thank you so much!

11:33 Lajla: &(quote #(+ %1 %2))

11:33 lazybot: ⇒ (fn* [p1__7230# p2__7231#] (+ p1__7230# p2__7231#))

11:34 Lajla: Okido

11:34 &(quote #(+ %1 %2))

11:34 lazybot: ⇒ (fn* [p1__7239# p2__7240#] (+ p1__7239# p2__7240#))

11:34 Lajla: &(quote #(+ %1 %2))

11:34 lazybot: ⇒ (fn* [p1__7248# p2__7249#] (+ p1__7248# p2__7249#))

11:34 Lajla: Hmm

11:41 angerman: neotyk does h.a.c. support compression?

11:42 neotyk: angerman: yes

11:42 check create-client

11:44 angerman: neotyk: thanks. what are the defaults?

11:44 kurtharriger: Is this a bug - seems lazy sequences don't are written as function calls by printer:

11:44 (read-string (binding [*print-dup* true] (prn {:propertes (range 0 2)} )))

11:45 (prn {:propertes (range 0 2)} )) => {:propertes (0 1)}

11:46 with print-dup #=(clojure.lang.PersistentArrayMap/create {:propertes (0 1)})

11:47 Chousuke: that looks correct to me

11:47 kurtharriger: try reading it back you get a null pointer exception

11:47 Frozenlock: Another java question: My example code "cast" a class to another object--> (some-class)object.method(argument1 argument2) . In clojure: (method. object argument1 argument2 and...?

11:48 kurtharriger: wouldn't {:properties (0 1)} imply apply the function 0 to 1 and save the result to :properties in the map

11:48 Chousuke: Frozenlock: you shouldn't need a cast.

11:48 kurtharriger: no, if it's only read

11:48 if it's evaluated, then yes

11:48 neotyk: angerman: compression is disabled by default

11:48 kurtharriger: yes, thats what *print-dup* is supposed to do?

11:49 Chousuke: yeah

11:49 I mean, it's supposed to give you a form that is okay when you read it

11:49 kurtharriger: to me it seems that lazy-seq should be serialized by the reader as vectors

11:49 angerman: neotyk: what I mean is: I guess it would be helpful if http://neotyk.github.com/http.async.client/doc/http.async.client.html#var-create-client would list the defaults.

11:49 e.g. what' the default connection timeout, request timeout, ...

11:49 kurtharriger: but it currently doesn't do that, it gives me a form that throws an exception when I read it back

11:49 Chousuke: kurtharriger: if you do (read-string "(0 1)") you get the correct output

11:50 kurtharriger: how are you reading it back?

11:50 neotyk: angerman: indeed that would be helpful, I agree

11:50 kurtharriger: (read-string (binding [*print-dup* true] (prn {:propertes (range 0 2)} )))

11:51 doh sorry shouldn't be prn

11:51 thats probably my problem

11:51 Chousuke: kurtharriger: prn returns nil :P

11:52 LauJensen: Evening gents

11:52 Lajla: Chousuke, miksi on: ##(symbol? (symbol "EESTILAISET ON TULEVAT, MIEHITÄ TYKIT"))?

11:52 lazybot: ⇒ true

11:52 Frozenlock: Chousuke: ... I don't understand what you mean :( I'm interested to use the methods associated with the 'some-class' casted to the object in my java example.

11:53 Lajla: Ei ole true, symboleissa ei voi olla spacejä

11:54 fmw: what is the path I can access files in my ring uberwar with? I put a directory called database-views in my resources directory, which is included in the uberwar archive (e.g. WEB-INF/classes/database-views/map_user_by_username.js). However, e.g. (slurp "database-views/map_document_by_feed.js") returns a file not found exception.

11:56 locally (i.e. when not running from the .war on tomcat, but with jetty through lein ring server) it works fine, through a symbolic link I created with database-views/ in my main project directory, so this only concerns the .war deployment.

11:58 kurtharriger: Chousuke: is there an easy way to make pr-str print lists as vecotrs? I would like to take a datastructure and copy and paste it into a test, but I have to replace lists with vectors otherwise the tests tries to evaluate them as functions

12:00 I could probably use clojure.walk... but I'm not sure yet how to do that

12:00 angerman: If I have multiple threads calling one function, but I want that function to be executed in sequence, can clojure help me here?

12:02 zamaterian: fmw, look at http://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/servlets/DefaultServlet.html

12:04 tomoj: angerman: if I understand what you mean, https://gist.github.com/0a0f95c07b16fcc6f358 is one way

12:05 fmw: zamaterian: thanks, but I'm not sure if I described what I'm intending to do clearly enough. I'm not trying to serve files, but I want to read a file from my clojure application. This works fine with full, hardcoded paths (see https://github.com/fmw/vix/blob/master/src/vix/db.clj for this exact same code, but with hardcoded paths). However, I'm trying to get rid of the hardcoded paths and include the files in the .war instead.

12:05 angerman: tomoj: so agents have a work queue?

12:06 Chousuke: kurtharriger: no, but you can quote the lists

12:06 fmw: zamaterian: I think your link concerns serving files? I just want to bundle them (which works) and access them (which does not, because I get a file not found exception).

12:06 kurtharriger: Chousuke: automatically or manually after pasting it into my test?

12:06 Chousuke: manually

12:06 tomoj: angerman: yeah

12:06 angerman: tomoj: but I don't get a promis back, for which I could wait, no?

12:06 Chousuke: it's just a single '

12:07 angerman: tomoj: ohh, maybe I can create a promos, and have it delivers by the agent.

12:07 tomoj: also if one of the fns throws an error, agents may not do what you want

12:07 kurtharriger: Chousuke: yeah easier perhaps but I think vectors are easier to read in the tests

12:07 angerman: tomoj: ?

12:08 zamaterian: fmw, 2 sec, then i have something you can use

12:09 tomoj: angerman: you want each thread to be able to get back the return value of the fn they scheduled? or do you just need the latest return value at any point?

12:10 if the former, agents don't seem right

12:10 oh, well, yeah, you could just have the send-off'd fn deliver the promise

12:11 still seems strange to use agents just to synchronize

12:11 zamaterian: fmw, https://refheap.com/paste/2150

12:13 technomancy: ibdknox: have you ported lein-noir over to lein-newnew yet?

12:14 ibdknox: technomancy: I have a pull request for it, need to clean it up a bit though. Just haven't had time :(

12:14 mmarczyk: does anybody have any experience testing ClojureScript @ jsPerf ? I'm running some test cases for the port of PersistentHashMap I'm working on and getting completely crazy results

12:15 fmw: zamaterian: let me have a look at that, thanks

12:15 technomancy: ibdknox: we made the newnew stuff nicer in preview3; if you have a link to the pull req I can put a pointer there to make sure it matches our convention.

12:16 the old style of adding it to the :user profile will still work, but the new style can be used without messing about with profiles

12:16 ibdknox: technomancy: https://github.com/ibdknox/lein-noir/pull/6

12:16 wkmanire: Is there a library function that will compare two numbers and return negative, zero or positive based on their relation? example: (compare 25 50) .1, (compare 50 25)

12:16 -oops

12:16 premature return

12:17 technomancy: cool

12:17 wkmanire: (compare 25 50) -> -1, (compare 50 25) -> 1, (compare 50 50) 0

12:17 that's what I'm looking for.

12:17 * technomancy can't believe mapv got added before map-map

12:17 rplevy: when using lein 2 I miss being able to see my transitive dependencies by looking in libs. Maybe this would be a good feature to add to lein-pprint?

12:17 technomancy: rplevy: try `lein deps :tree`

12:17 rplevy: oh neat

12:18 technomancy: thanks!

12:18 technomancy: brought to you by cemerick and xeqi

12:18 mmarczyk: wkmanire: yes, it's called compare (in clojure.core)

12:18 wkmanire: mmarczyk: Seriously?

12:18 _phil: is there a way to refer to symbols in single-segment namespaces in clojurescript?

12:18 mmarczyk: wkmanire: totally

12:18 :-)

12:18 _phil: i.e. i can write com.bla.f/symbol

12:18 but not com/symbol

12:19 wkmanire: &(doc compare)

12:19 lazybot: ⇒ "([x y]); Comparator. Returns a negative number, zero, or a positive number when x is logically 'less than', 'equal to', or 'greater than' y. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable"

12:19 wkmanire: :D

12:20 _phil: specifically, im trying to write a macro that invokes a domina function without requiring the client code to explicitly :require domina

12:21 seancorfield: _phil: your macro could include a (require ..) call on domina?

12:21 _phil: so what i would like to do is something like (domina/add-class! ...)

12:21 seancorfield: i thought clojrescipt didnt support require? only ns?

12:21 wkmanire: cemerick: I really liked the two code snippets you gave for negated-sum-str where you illustrate a usage of comp.

12:22 cemerick: I was already more or less understanding the concept, but the example made it crystal clear.

12:22 seancorfield: _phil: hmm, haven't done enough cljs to know, sorry

12:22 cemerick: wkmanire: excellent :-)

12:23 dnolen: _phil: not possible far as I know.

12:24 _phil: dnolen: thx a lot

12:25 mmarczyk: dnolen: hi

12:25 dnolen: I've put up some tests for phm on jsPerf, but the results are crazy :-(

12:26 angerman: tomoj: I just need the thread to block until that piece of code has been processed

12:26 don't care about the result actually

12:26 tomoj: oh

12:26 then (locking 42 ...) should work

12:26 angerman: ?

12:26 tomoj: though maybe using something other than 42 would be better..

12:27 dnolen: mmarczyk: thx, I suspected that - I've done some benchmarking - PHMs are way slower than ObjMap.

12:27 mmarczyk: link?

12:27 mmarczyk: especially access times

12:27 mmarczyk: dnolen: actually these results are the opposite sort of crazy

12:27 tomoj: just have a lock object (e.g. (Object.)) that all the threads have in scope, and wrap the code that should be synchronous in (locking lock-object ...)

12:27 mmarczyk: dnolen: link posted at the ticket's page

12:27 links, rather

12:28 dnolen: the branch with the transient stuff attempts to do some switching

12:29 dnolen: mmarczyk: ooh, actually that looks really good :)

12:29 mmarczyk: dnolen: there's definitely some conceptual work left to be done, since e.g. TransientObjMap (obviously) trounces everything for updates, but if all of a sudden a non-string key turns up @ 5000 entries, the cost of conversion to PHM will be noticeable

12:29 dnolen: do you mean you actually believe that? :-D

12:30 dnolen: mmarczyk: it's possible, I need to try the patch out myself.

12:31 fmw: zamaterian: thank you, this solves it. I didn't realize I needed to open files from the classpath directly in this case, instead of through conventional means like slurp.

12:32 mmarczyk: dnolen: great, looking forward to your feedback

12:32 dnolen: mmarczyk: http://jsperf.com/cljs-persistent-hash-map-tiny-assoc

12:32 mmarczyk: updated with Safari and FF Nightly

12:32 mmarczyk: basically V8 is insane.

12:33 mmarczyk: other browser looks good and reasonable.

12:33 mmarczyk: dnolen: wow, thanks

12:33 ibdknox: slashdot is a depressing place

12:33 autodidakto: Does the clojure community have strong opinions about code formatting? Particularly column width

12:33 mmarczyk: dnolen: about V8 -- yeah -- I can't believe it

12:34 dnolen: mmarczyk: haha yeah, for large maps PHM destroys.

12:34 autodidakto: ibdknox: I'll make some hot cocoa. tell me everything

12:34 mmarczyk: dnolen: :-)

12:34 ibdknox: autodidakto: lol

12:34 autodidakto: kids can be so cruel :)

12:34 angerman: tomoj: so, i could basically wrap the body of the function i want to be executed synchronized into (locking o body), right?

12:34 where o is (def o (Object.))

12:35 mmarczyk: dnolen: I like the flat bars on the comparison chart

12:35 technomancy: clojurebot: style guide?

12:35 clojurebot: Titim gan éirí ort.

12:35 technomancy: clojurebot: style?

12:35 clojurebot: style is http://paste.lisp.org/display/81021

12:35 autodidakto: technomancy: thx

12:35 technomancy: hm... not quite what I was looking for

12:35 autodidakto: htm

12:35 hrm

12:35 technomancy: http://mumble.net/~campbell/scheme/style.txt

12:35 mostly applicable to Clojure

12:35 autodidakto: Gotcha

12:35 tomoj: angerman: think that should work, yeah

12:36 technomancy: I think the prevailing opinion is that if you have super-wide lines you will annoy people who split their screens into multiple panes; said people may mock you for it

12:36 autodidakto: oh right I saw this one. they lost me when they started calling ()'s "round brackets"...

12:37 dnolen: mmarczyk: OK this is looking promising PHM looks nearly always better. so we can probably just replace. I'll do more testing later tonight and if it looks good, apply the patch.

12:37 mmarczyk: thanks a lot!

12:37 mmarczyk: dnolen: fantastic, thanks!

12:38 angerman: node.js 0, clojure: 1

12:38 zamaterian: fmw, your welcome :-)

12:39 wkmanire: Does #clojure have a preferred paste?

12:39 mmarczyk: wkmanire: http://refheap.com :-)

12:40 RickInGA: I am trying to translate a simple example from js to cljs, drawing an image on a canvas.. here is both the js and the cljs https://refheap.com/paste/2151

12:40 fmw: zamaterian: it seems that clojure.java.io/resource does the same thing, though?

12:41 RickInGA: I am able to draw rectangles and text, but the image isn't working. not sure if it is because of the "new Image()" or the callback

12:41 wkmanire: I'm building a guessing game for the terminal. I want to branch a function four different ways based on some user input. https://refheap.com/paste/2152

12:42 Should I nest (if) a bunch of times or is there a better way?

12:42 clojurebot: Gabh mo leithscéal?

12:44 technomancy: wkmanire: cond is typically used for that

12:44 zamaterian: fmw, thx

12:45 mk: is there anything that clojure is missing out on by not having currying?

12:45 wkmanire: &(doc cond)

12:45 lazybot: ⇒ "Macro ([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil."

12:45 RickInGA: mk: I think partial does most of what currying does

12:45 wkmanire: technomancy: Thank you.

12:46 technomancy: np

12:47 mk: currying is more concise than partial, but it doesn't support var-args

12:47 mk: wkmanire: are you doing the typical if ... else if ... else if thing? or are you doing if(..){if(..){ ... }}?

12:48 wkmanire: if elif elif else

12:48 mk ^

12:49 mk: wkmanire: yep, definitely what technomancy said then. You can express the other one using an and, and you can express guards using an or (in case you ever run into that)

12:49 wkmanire: mk: Yo ulost me with "the other one" and "guards"

12:49 You*

12:50 autodidakto: VimClojure users: There's a new nailgun server plugin. Supports Lein 2; standalone repl connected to server -> https://github.com/sattvik/lein-tarsier

12:51 technomancy: isn't nailgun about to be deprecated by nrepl?

12:51 mk: wkmanire: the if(test) { if (test){...}} -> use and. A "guard" is when you have a sequence of "fallback" values - if (a==null) a=foo; if (a==null) a=bar; is (or a foo bar)

12:52 autodidakto: technomancy: the creator of vimclojure wants to move to nrepl, but he's struggling with the "backend"

12:52 link incoming..

12:52 technomancy: I thought nrepl was the backend

12:52 mk: wkmanire: you can safely ignore what I'm saying though, your immediate problem is solved :)

12:52 autodidakto: https://groups.google.com/forum/?fromgroups#!topic/vimclojure/WezVKn5eucQ

12:53 Meikel: "Currently only the nrepl client is done. The backend needs serious adaption to nrepl from nailgun. This not done, yet. I don't recommend its use unless you want to help migrating things. Any help is appreciated."

12:53 wkmanire: mk: Okeydokey :)

12:54 mk: technomancy: hmm. Currying is also harder to understand than partial, which seems to outweigh the fact that it's concise. Was there anything else special about it?

12:55 RickInGA: would js: var SomeImage = new Image(); translate to (def SomeImage (. Image)) in cljs?

12:56 wkmanire: mk: I'm just starting out with clojure. I've read through the first couple of chapters of cemerick's book and I'm trying to write my first simple app just to burn-in the concepts I've learned so far. Unfortunately with this little sample app I don't need to map, comp or destructure anything. But it's still nice to get used to the syntax and such.

12:56 Raynes: technomancy: Yeah, I'm not going to bother with interactive Vim stuff until the nrepl support is done. I don't want to figure that crap out unless I get to use it for a year.

12:56 pelleb: This probably comes under the department of schoolboy error, but when I run "lein jar" in my project https://github.com/pelle/clauth it packages up all the dependencies within it. What am I doing wrong? I'm using lein-1.7.1.

12:57 autodidakto: wkmanire: map, comp, and desutrcture anyway :)

12:58 wkmanire: autodidakto: Where there's a will there's a way I suppose.

12:58 Ah, and I aughta use reduce too. Although to be honest, I'm already familiar with the premise of map and reduce from the the underscore.js library.

12:58 autodidakto: wkmanire: yeah, it's a throwaway project to learn the first few concepts. It's going to be contrived anyway, might as well shove in as much learning as you can

12:59 mk: wkmanire: yeah, definitely. And like autodidakto said, you can mess around with those things. You might find that there actually is a good reason to use advanced-seeming functions instead of something you're doing. You might check out 4clojure.com, they have nice exercises for starting out

12:59 wkmanire: mk: Crap! I meant to do that for this.

12:59 mk: But somehow I completely forgot about 4closure.

13:00 I'll just finish this as it is and then tomorrow I'll do a 4clojure problem.

13:01 mk: wkmanire: yep. Feel free to ask here if you run into any problems, or are wondering if there's an easier way to do something. The early 4clojure problems are very short.

13:02 wkmanire: mk: Oh I've been feeling free alright. I pester these poor guys almost constantly.

13:02 ha ha ha ha

13:02 mk: Thank you.

13:02 mk: wkmanire: no problem, have fun :)

13:05 pelleb: I can see that running lein compile unpacks all dependencies into my classess directory. Is this right?

13:12 wkmanire: https://refheap.com/paste/2153, For the :else of this conditional expression what is the correct way to recurse?

13:12 Should I use recur or just call query again?

13:15 cemerick: Just (recur n) should be fine

13:15 Chousuke: branches of cond are in tail position

13:24 technomancy: pelleb: that's just an unintentional side-effect of the clojure compiler being transitive

13:24 if you don't require your dependencies at compile-time, they won't end up in classes/

13:25 pelleb: in your case it looks like :main is triggering AOT; you want to either remove it or do :main ^{:skip-aot true} clauth.demo

13:25 you really don't want to distribute a library jar with AOT unless you need gen-class or something

13:27 pelleb: technomancy: Thanks. Don't quite understand what AOT is, but I did notice the jar's were huge. I'll try adding that skip-aot

13:29 technomancy: or just remove :main; you can have people use `lein run -m clauth.demo` instead

13:30 pelleb: technomancy: adding the skip-aot worked a charm. Is there a particular reason to prefer removing the :main ?

13:31 tomoj: when you do need to gen-class something, is there no easy way yet to avoid putting too much in the jar?

13:31 wkmanire: cemerick, Chousuke: Thanks. Sorry for the delayed response. I was instructed by commander girlfriend to take a break and eat my lunch

13:31 Which was delicious.

13:32 technomancy: pelleb: just tidiness I guess

13:32 tomoj: in some cases you can perform require calls at runtime

13:32 TimMc: pelleb: Ahead-Of-Time compilation (conversion into .class files)

13:33 pelleb: technomancy: thanks for your help.

13:33 technomancy: tomoj: if you just want an uberjar, use lein-otf

13:33 but other gen-class uses are trickier

13:33 pelleb: TimMc: thanks. I'll read up on it.

13:39 mwillhite: is there a way to bring a dependency in as source in leiningen? I'm having issues with a ring middleware, but unable to determine what is going on

13:39 I'd like to bring in the source and stick a debugger in the function I'm calling

13:39 technomancy: mwillhite: most ring middlewares come with source

13:40 hopefully all, actually

13:40 mwillhite: technomancy: where can I find it?

13:40 its not under lib…

13:40 technomancy: it should be

13:40 mwillhite: the .jar is

13:40 technomancy: inside the corresponding jar

13:40 mwillhite: oh

13:40 sorry, new to .jars

13:40 Raynes: They're just zip files.

13:41 mwillhite: hm okay

13:41 so whats the best way to access that code then? Do I have to re-jar it with every change I make?

13:41 technomancy: in Emacs you just press M-. on the name of a function and it finds the source for you; many other editors have similar functionality

13:42 mwillhite: okay

13:42 technomancy: depends on the extent of the change. if you're just debugging, you can probably get away with editing straight out of the jar file

13:42 if you're making improvements you want to submit upstream you should use checkout dependencies

13:43 mwillhite: okay, yeah I just want to stick a trace in there so I can get some insight as to whats going on

13:43 thanks for your help

13:44 goodieboy: I'm having a hard time deciding on whether i should test a private function or not. One the one hand, it'll make the tests brittle (refactoring etc.) but on the other, I'll feel more confident that my app is working properly. Any advice here?

13:45 TimMc: Ask 3 different CLJers and you'll get 5 different opinions.

13:45 goodieboy: TimMc: I figured :)

13:45 ibdknox|away: don't have private functions! :p

13:45 technomancy: wat

13:46 ibdknox|away: :D

13:46 technomancy: ibdknox|away: spoken as someone who hasn't had to maintain a library for over a year yet, I see =)

13:46 goodieboy: ibdknox|away: ha, well that was easy :)

13:46 ibdknox|away: technomancy: you have no idea :p

13:46 TimMc: technomancy: Weren't you marking fns as ^:internal?

13:46 ibdknox|away: Though I was only half joking

13:47 dnolen: technomancy: I think it would be nicer if ^:private was just documentation and didn't actually mean anything.

13:47 ibdknox|away: don't make them actually private

13:47 was my only statement

13:47 tmciver_: my $0.02: I feel better testing private fns

13:47 drewr: does emezeske hang out in here?

13:47 dnolen: drewr: yes

13:47 technomancy: dnolen: maybe if completion functions filtered them out

13:47 goodieboy: tmciver_: that's the direction i'm leaning

13:47 drewr: having an issue with lein-cljsbuild building js that doesn't find goog.string

13:48 TimMc: dnolen: But that would interfere with :use without :only... oh. :-P

13:48 ibdknox|away: drewr: nodejs?

13:48 dnolen: drewr: in what context, Node?

13:48 ibdknox|away: drewr: use optimizations :simple

13:48 drewr: ibdknox|away, dnolen: jesss

13:48 technomancy: even without considering testing it's common to have defs that are internal to the library but not limited to a single namespace.

13:48 which is why I like ^:internal

13:48 dnolen: drewr: :whitespace optimization won't work, you need to use at least :simple

13:48 tmciver_: goodieboy: I was recently discussing this with TimMc. I discovered how to use @#' to good effect.

13:48 angerman: neotyk: would a.h.c. tell me when the connection is reset?

13:48 drewr: dnolen: will :advanced work ok too

13:48 dnolen: drewr: yes, that too

13:49 drewr: kthx

13:49 goodieboy: technomancy: what is ^:internal?

13:49 * ibdknox|away goes away for realz

13:49 TimMc: goodieboy: By "brittle", you mean implementation-specific? I test implementation details all the time.

13:49 technomancy: goodieboy: just a way to communicate intent via metadata

13:49 it doesn't mean anything special to the compiler

13:49 autodidakto: goodieboy: if you're worried about it breaking. test it. if you're worried about worrying too much, read books and articles about testing :)

13:50 goodieboy: TimMc: well, i might see that my code can be optimized, but requires a either a rewrite, or new functions etc.. Making those changes would then break my tests

13:50 technomancy: ahh ok

13:50 drewr: ibdknox|away, dnolen: thanks that worked

13:50 technomancy: I don't think ^:internal is necessarily the right thing here, but it's good for other cases where you can't make things private but still need to give a strong "hands off" message

13:51 drewr: I'm getting a node warning about the sys module being renamed to util... is that something that gclosure has to fix or is that cljsc-emitted code?

13:51 dnolen: drewr: the issue is that :whitespace optimizations emits goog.provides which don't work in Node.js. The other optimization modes remove them.

13:51 drewr: that's something to fix in the CLJS Node support I think.

13:52 RickInGA: Is it possible to have a catch block that doesnt do anthing? (catch Exception e) is not making Chrome happy

13:53 dnolen: RickInGA: are you talking about CLJS?

13:53 RickInGA: dnolen yes

13:53 dnolen: RickInGA: you want Error

13:53 js/Error

13:53 RickInGA: (catch js/Error e) ?

13:54 dnolen: RickInGA: yes

13:54 RickInGA: dnolen beautiful! thanks!

13:54 dnolen: RickInGA: np

13:55 * RickInGA needs to stop reading books about other programming languages to learn Clojure!

13:58 jamii: This took an awful lot of coding for so few lines - https://gist.github.com/2400297

13:58 dnolen: jamii: neat!

13:58 RickInGA: wow

13:59 jamii: I will comment it when I recover

13:59 TimMc: THat's what they all say. :-P

13:59 mdeboard: jamii: nice

14:00 technomancy: huh; first time I've seen with-local-vars used

14:00 jamii: I need it so that the lazy recursion in is-fact* work properly

14:00 If it was at the top-level I could just use declare

14:00 Time to go home

14:02 RickInGA: I am a complete github newb... if someone forks your repository, it means they have made their own branch?

14:02 neotyk: angerman: what do you mean by connection reset, like dropped?

14:02 dnolen: jamii: minor edit https://gist.github.com/2400319

14:03 neotyk: angerman: anyway, if there is problem with underlying conn while executing request you will get error

14:03 angerman: neotyk: when I run a connection logging application, I see some connections as "reset by peer", but (client/error resp) seems not to hold any value. I guess i should assume no problem, then?

14:04 neotyk: angerman: it might be that connection was idle

14:05 angerman: keep-alive, and when you don't run any request on it, there is no problem for you

14:05 amalloy: RickInGA: close enough

14:06 RickInGA: amalloy: thx. I was looking at the wrong graphic. Created my first ever project on github and I had watchers, not forks, which makes more sense to me :)

14:06 angerman: neotyk: I'll keep a close eye on it… :)

14:07 neotyk: angerman: if you would find an issue with it, do let me know :)

14:07 angerman: neotyk: :) sure will...

14:12 sadger: dnolen and other that helped I got vim working with clojure, so thanks in the end lein nailgun seems to maintain my dependencies

14:13 dnolen: sadger: excellent

14:14 sadger: the thing with the lein nailgun is that it needs to be started with a particular project but as you know you can add some packages for all projects so it works just fine

14:14 in particular some of the repl tools and trace which I couldnt get working

14:14 but all is well

14:15 Now all that remains is to learn clojure!

14:15 I bought the joy of clojure just out of interest to be honest would you recommend any other books/resources for entry level clojure (just experiance with java really and some haskell)

14:17 dnolen: sadger: been hearing good things about the new O'Reilly book

14:17 technomancy: sadger: yeah, another vote for the O'Reilly one

14:17 sadger: hmm interesting I saw that on "beta" release

14:17 I will have a look i think thanks

14:18 cemerick: sadger: The ebook is available; shipping in dead-tree style in a couple of days http://www.clojurebook.com/

14:18 sadger: cemerick: dead tree! ha ha

14:18 TimMc: pbook

14:20 sadger: i really should just get the e-versions as I have a android tablet but I find books easier to read

14:21 mostly for navigation purposes

14:21 technomancy: depends on whether you want an introductory read or a reference

14:21 deech: Hi all, is there anything similar to dynaspring (http://code.google.com/p/dynaspring/) in clojure? Dynaspring is a Spring integration library for ABCL.

14:21 sadger: going to the index of an ebook and back and forward between chaptesr us a stress

14:22 cemerick: deech: wow, what a tech combo! o.0

14:23 sadger: deech: this? https://github.com/lprefontaine/Boing

14:23 cemerick: I don't think Boing has anything spring-specific to it IIRC.

14:23 deech: cemerick: What do you mean :)

14:23 sadger: that's just from a google search so usure if it fit your critera

14:24 technomancy: why do you think you need spring for Clojure?

14:24 cemerick: deech: I've used spring (actually, just spring-security) with Clojure, so the two interop just fine. I don't think anyone's built a spring context DSL for Clojure, though.

14:25 deech: technomancy: Bunch of legacy code that needs to be able use Spring modules etc.

14:25 technomancy: oh, ok

14:25 deech: cemerick: It's kinda nice, you can inspect what's been loaded (and create/load beans dynamically) at runtime. No more guessing what the XML file does.

14:26 cemerick: Yeah, I can see the attraction if you're knee-deep there.

14:26 I've managed to dig myself out of ever using spring anymore, though.

14:27 deech: cemerick: Trying to make the best out of a conservative development environment.

14:27 cemerick: Sure. I totally appreciate that. :-)

14:27 deech: Thank you all for your help.

14:38 wkmanire: Alright, who wants to play my extremely awesome number guessing game?

14:38 https://refheap.com/paste/2155

14:38 I finished my exercise for the day.

14:39 mfex: cemerick, thanks for the friend lib, indeed the missing piece for clojure web apps

14:39 cemerick: mfex: well, one of many, perhaps :-)

14:40 angerman: hmm… I have the feeling that sqlite ist hitting a wall. Does anyone know how to see what time queries take?

14:40 mfex: everything else can be done with interop, authentication was is in need of a clojure lib to play nice with ring

14:41 0.0.6-SNAPSHOT works great with leiningen 1.7.1 so world domination is next

14:46 cemerick: mfex: Thanks for the confirmation; 0.0.6 is now released.

14:50 mfex: cemerick, for open id friend requires a post to /openid with the endpoint, is this required by the openid protocol to not allow get links to start the openid workflow?

14:53 cemerick: mfex: You can set the openid workflow URI to anything you want, but yes, it requires a POST with an identifier param to start. If you want to give the user a button-array or field to enter their own openid endpoint, you can put those on a form accessible to anon users (e.g. @ /login) that POSTs to /openid (or whatever you configure as :openid-uri in (openid/workflow).

14:54 mfex: yeah, I use the form as a button/link now, just wondering why the post was enforced, a get can work as well right?

14:54 cemerick: Not at the moment.

14:54 The POST requirement is mine. GET doesn't make sense to start the openid workflow AFAICT; that, and it makes the workflow itself simpler (i.e. no need to support configuring multiple URIs).

14:55 mfex: ok, makes sense. Just wondering

14:58 amalloy: wkmanire: you forgot a reason the computer can lose the game: i choose a fraction, since the rules don't forbid it

15:02 TimMc: amalloy: I'm thinking of a real number, can you guess it in 20 tries? I'll tell you high/low.

15:03 ibdknox|away: TimMc: your number is e.

15:03 amalloy: 0, 1, 2, pi, e. if i haven't gotten it yet your number is dumb

15:03 TimMc: ibdknox|away: high

15:03 amalloy: low low high high high

15:04 You all lose, it was phi.

15:04 cemerick: I figured tau.

15:04 TimMc: I would have accepted tau just on principle.

15:04 ibdknox|away: lol

15:05 TimMc: Note: You can do "binary search" on an unbounded range, such as the integers.

15:07 amalloy: i select n+1 as my number, TimMc

15:07 technomancy: http://en.wikipedia.org/wiki/Aleph_number

15:07 amalloy: echo "yes 'too low'" > guess-my-number.sh

15:08 technomancy: echo "exit 1" >> guess-my-number.sh

15:09 wkmanire: amalloy: You chose a fraction?

15:09 amalloy: You bastard!

15:09 amalloy: well i didn't actually play. but i read the code

15:10 TimMc: haha

15:11 wkmanire: I guess I need to fix the directions.

15:11 Choose a real positive integer that is greater than 0 and less than 101.

15:11 It would be hard to pick a negative integer in that range.

15:11 but you get the idea.

15:12 TimMc: choose n such that (and (integer? n) (< 0 n 101))

15:13 wkmanire: TimMc: Nice.

15:14 amalloy: c'mon, everyone is gonna prefer <=

15:14 wkmanire: I never even thought about passing more than 2 args to < or >.

15:14 TimMc: true

15:14 wkmanire: &(doc <)

15:14 lazybot: ⇒ "([x] [x y] [x y & more]); Returns non-nil if nums are in monotonically increasing order, otherwise false."

15:15 wkmanire: Cool

15:15 TimMc: &(apply < [1 2 3 4 5])

15:15 lazybot: ⇒ true

15:15 TimMc: &(apply < [1 2 300 4 5])

15:15 lazybot: ⇒ false

15:15 wkmanire: &(apply < [1 2 3 "a fraction" 5])

15:15 lazybot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

15:15 * wkmanire shrugs.

15:16 amalloy: you can do cool bounds-checking of 2d (or whatever) "points" with that feature. (every? true? (map <= [minx miny] the-point [maxx maxy]))

15:16 TimMc: &(< 0.1 2/3 4)

15:16 lazybot: ⇒ true

15:19 autodidakto: ibdknox|away: Any thoughts on my pull request? -> https://github.com/ibdknox/cljs-template/pull/5

15:19 wkmanire: amalloy: That is definitely nicer than the way I've done that in a few other languages.

15:19 amalloy: Usually involves 4 explicit comparisons in a for loop.

15:20 technomancy: autodidakto: if you adhere to a specific group-id convention you don't need to add it to the user profile as of preview3

15:20 https://github.com/Raynes/lein-newnew/issues/12

15:21 wkmanire: Time to start cranking out some VB.Net imperativeness. :( Later folks.

15:22 angerman: how do i run an ubarjar?

15:22 TimMc: angerman: kava -jar

15:22 java, even

15:22 autodidakto: technomancy: Ok i see. Will incoporate that info.

15:22 angerman: hmm. says: Exception in thread "main" java.lang.NoClassDefFoundError:

15:22 I must have doe something wrong :/

15:25 TimMc: if $ lein run, works flawlessly. that -standalone.jar should as well, no?

15:25 TimMc: angerman: It's looking for a .class file in that jar.

15:25 angerman: TimMc: there's only a __init.class and a .clj file in there

15:26 tmciver_: angerman: jars in lib must be on classpath

15:26 /lib

15:26 angerman: tmciver_: it's actually complaining about my project/core class

15:27 tmciver_: and I though that an uberjar actually contained all lib jars.

15:27 tmciver_: angerman: ah, yes, uberjar does

15:28 angerman: i do have core__init.class and cor$_main.class but no core.class in the classes folder? did I do something wrong?

15:28 TimMc: angerman: :gen-class in core.clj?

15:28 angerman: no. ahh. I should, I guess due to the -main, eh?

15:28 TimMc: yep

15:29 angerman: If you want to avoid all this AOT compilation nonsense, I would recommend my lein-otf plugin. :-)

15:29 gf3: ibdknox: If you don't have one already, and providing you like it, I'd like to donate this icon to Light Table → http://dribbble.com/shots/186884-Editor-Icon

15:30 angerman: TimMc: link?

15:30 gf3: ibdknox: It needs some cleaning up, but I think it could work

15:30 TimMc: https://github.com/timmc/lein-otf

15:31 angerman: FYI, I haven't tried it with lein 2.x yet.

15:31 ibdknox: gf3: dude, very pretty

15:32 gf3: ibdknox: I won't be offended if you have something else in mind

15:32 ibdknox: gf3: haven't gotten that far yet, to be honest :) Gotta remember I was doing something completely different 3 days ago haha

15:32 gf3: ibdknox: Absolutely

15:35 autodidakto: ibdknox: pull request updated -> https://github.com/ibdknox/cljs-template/pull/6

15:37 ibdknox: autodidakto: I think you're missing a "need" in there

15:37 autodidakto: doh *checking*

15:37 ibdknox: autodidakto: past that, looks like it's clearer :) I'll happily take it

15:38 angerman: so, now I need to figure out how to create a cronjob...

15:38 autodidakto: extra "need". I originally said "when you need it", but then it sounds clunky when you later reused the word to say "nothing more is needed"... :P Ok let me fix that

15:39 er. Best git practice to commit/rebase/whutcha-mo-call it a pull request? (or do I have to close and reopen?

15:39 *practice to update/

15:42 amalloy: autodidakto: just...add commits to whatever branch your pull request is attached to

15:42 autodidakto: ah, google says github updates it automatically. nvm

15:43 amalloy: thanks

15:43 amalloy: but it's entirely a github best practice, not a git best practice. pull requests are a github thing

15:43 autodidakto: gotcha

15:45 cduffy: ...well, the general practice behind "pull requests" existed long before github existed

15:46 heck, before _git_ existed -- sending an email to the mailing list asking for pull+review+merge was common practice in the GNU Arch community

15:46 (not Arch Linux the distro, GNU Arch the DSCM)

15:47 autodidakto: The bad-old-days of version control?

15:47 cduffy: Wouldn't say that, necessarily. Some of Arch's features almost nobody has today

15:48 ie. history-sensitive merge

15:48 now, from a usability perspective, granted, it was awful

15:49 autodidakto: something about VC and UI/UX... they can't seem to mix

15:50 * cduffy thinks the bzr folks do a decent job of that, at least in terms of building a DSCM that's comfortable to users familiar with centralized workflows.

15:50 cduffy: (...OTOH, making bzr comfortable to users coming from _git_ is something they're only now starting to address, ie. with first-class colocated branch support)

15:51 zzach: With (aleph.tcp/tcp-client {:host "" :port 3335})) , it is possible to open a connection to a TCP server running at port 3335. If there is no server running, a Java exception is thrown (SEVERE: Unhandled error in Netty pipeline. ... java.net.ConnectException: Connection refused ... ). Is it possible to somehow catch or suppress this exception? I would like to silently retry connection

15:51 attempts until the server is running (like with the "socat" option "forever").

15:51 autodidakto: cduffy: what I wish is that VC would work for non-programmers... project gutenberg should be using it

16:00 Wild_Cat: zzach: wrap it in a try-catch block

16:00 (although I've never managed to get aleph working up to the point where stuff actually gets sent to the server)

16:10 zzach: @Wild_Cat: within a try-catch block, the exception still appears

16:13 sattvik: technomancy: Do you know why a console-interactive lein plug-in would work fine in Lein 2.x, but has issues with getting input in 1.x?

16:23 mwillhite: I'm looking at using the checkouts dir to bring in some source code

16:23 the way I understand it is I should just be able to create a "checkouts" directory at the root level of my lein app

16:23 then it should take the place of the specified dependency…

16:23 am I missing a step?

16:24 It doesn't appear to be using the checkouts version

16:24 cduffy: zzach: if you wrap your tcp-client in wait-for-result inside the try-catch, the exception should then be caught properly.

16:25 mwillhite: I also updated the dependency version to that of the checkout version, but then running lein ring server went and pulled down another version

16:25 cduffy: zzach: ...the issue is that, being async, it isn't otherwise actually getting thrown until after construction is done.

16:29 strax: is there an idiomatic way to call a single function for multiple arguments?

16:29 instead of doing (close a) (close b)

16:29 amalloy: map?

16:29 clojurebot: map is an evil genius.

16:29 strax: sure, but I'm talking about variable arguments here

16:29 amalloy: so far you aren't

16:30 strax: _single function for multiple arguments_ :)

16:30 not a seq

16:31 like a reverse todo

16:32 tomoj: (doseq [x [a b]] (close x))

16:34 strax: tomoj: aight, that's probably the way to go, thanks

16:34 so there's not a "cleaner" way

16:34 tomoj: of course (dorun (map close [a b])) would work too

16:35 I don't think of anything like what you're thinking of, no

16:35 strax: is dorun really needed there?

16:35 tomoj: well, if you have 32 or less things in the vector, it shouldn't make a difference...

16:35 s/less/fewer/

16:36 strax: yeah, it's just two or three

16:36 tomoj: but it is odd to rely on the chunked implementation detail here

16:36 semantically you really want dorun

16:37 dnolen: tomoj: I think doseq is better.

16:37 strax: well, assuming I have some locals and I need to apply f to all of them

16:37 amalloy: i doubt that chunkiness matters. if he's not realizing them all, he's probably not realizing any of them

16:37 tomoj: right

16:39 (do (map println [1 2]) nil) prints nothing

16:40 kurtharriger: tomoj: map is lazy you need to force evaluation

16:40 try do all instead of do

16:41 TimMc: kurtharriger: tomoj was telling strax that.

16:41 strax: I guess doseq is better then

16:42 kurtharriger: ah sorry, I fade in and out

16:43 technomancy: mwillhite: checkout dependencies do not replace normal dependencies, they augment them

16:45 ((juxt (map (partial comp k) [:a :b :c])) [function1 function2])

16:45 oops, that should be s, not k

16:45 jamii: slightly less crude - https://gist.github.com/2400297

16:46 dnolen: jamii: very cool, are you just experimenting?

16:47 jamii: dnolen: I want to port http://www.bloom-lang.net/

16:47 I will eventually write a proper datalog interpreter and test it against this one

16:48 dnolen: jamii: sweet!

16:49 jamii: I have their papers (none of which I've really read in depth) but I just watched the Lang.NEXT panel w/ one of the BLOOM guys in it, very interesting stuff.

16:49 jamii: there's actually an old contrib datalog implementation, but it's crazy slow.

16:50 jamii: dnolen: I've been following the papers for ages (since 2007ish) and just never got around to playing with it

16:51 dnolen: But now I have 2 months without much work

16:52 dnolen: jamii: definitely interested in seeing where your work goes - I'm assuming you've looked a bit at Datomic as well?

16:53 jamii: dnolen: Yeah. I'm thinking (based on http://db.cs.berkeley.edu/papers/cidr11-bloom.pdf) that it should be possible to provide a similar data model and query power (minus consistency) in a flooded p2p gossip db

16:53 Which would be fun

16:54 Although a bit ambitious for 2 months.

16:54 I'll stick to porting bud for now

16:55 dnolen: jamii: exciting stuff

16:55 jamii: do you work on tele-hash?

16:56 jamii: dnolen: yeah, I wrote the erlang version and I'm vaguely porting it to clojure. I redesigned it a bit (https://gist.github.com/1910754). I think the original design had some issues

16:57 dnolen: Right now there are bits of kademlia that are bothering me so I'm working on this while I think it over

16:58 strax: tomoj: (defmacro apply-all [f & args] `(doseq [x# ~args] (f x#))) does the trick

16:58 dnolen: jamil: I'll be following your progress with much anticipation :)

16:59 jamii: dnolen: don't hold your breath, I am phenomenally distractable :)

16:59 dnolen: jamii: haha, if you have something like a prototype that will be very interesting.

16:59 jamii: I was thinking about trying to do a mini-datalog w/ core.logic - you beat me to it.

17:00 jamii: dnolen: that version still needs stratification/negation if you're bored :)

17:00 dnolen: jamii: haha sadly I've got enough free time Clojure project as is.

17:00 amalloy: strax: there's no reason to make that a macro

17:00 dnolen: projects

17:01 strax: amalloy: hmm, true

17:01 hiredman: is there a good paper somewhere that summarizes "this is the features datalog has" and "for these inputs you get these outputs" I've been fiddling around a little with what might be datalog

17:02 just not a lot of experience with datalog so hard to say

17:03 strax: i'm surprised something like this doesn't exist in core

17:03 hiredman: there was a contrib datalog

17:03 jamii: hiredman: http://en.wikipedia.org/wiki/Datalog

17:03 hiredman: in old contrib, dunno how much work it saw

17:04 amalloy: strax: it's just an eager version of map. clojure encourages statelessness

17:04 jamii: basically somewhere between sql and prolog

17:04 hiredman: jamii: "datalog is like proglog without feature X and Y"

17:04 technomancy: hiredman: the author of the contrib datalog didn't seem too excited about it

17:04 hiredman: thats not really helpful for specing something out

17:04 technomancy: right

17:05 strax: amalloy: sure, but the target is not seq - rather a fixed set of locals

17:05 amalloy: so what. it costs two characters to wrap those in a vector

17:05 (map f [x y z])

17:05 jamii: hiredman: see the bullet points near the top of the wikipedia page

17:05 hiredman: "In contrast to prolog, it:..."

17:06 The main tradeoff is you can't do relational programming but your queries are guaranteed to terminate

17:06 hiredman: jamii: right, which, unless someone knows prolog and is familiar with terms like "stratification" in the context of prolog that definition is not helpful

17:06 jamii: hiredman: stratification is about termination. basically...

17:07 hiredman: if you have a prolog program like do(X) :- do-not(X), do-not(X) :- not(do(X)) it will never terminate

17:08 strax: amalloy: then again, doseq is preferred for side-effects and that has bindings, which is _not_ 2 characters

17:08 jamii: hiredman: stratification means that any time you use 'not' create a new layer. rules in lower layers cannot reference rules in higher layers. that prevents infinite loops like the above forming but it means some loss of power

17:08 s/create/you create/

17:09 hiredman: thats the next thing I need to add to the toy version above

17:09 hiredman: ah, interesting

17:18 arohner: ok, cyclic load dependencies really suck

17:18 jconnolly: working some of the clojure koans now to familiarize myself a bit with clojure. this is wrong, but I'm not sure why: (= '(:a :b :c :d :e 0) (conj '(:a :b :c :d :e) 0))

17:19 anyone have pointers?

17:19 a rtfm is also appreciated, if you've got a url to a m to rtf

17:19 Raynes: &(conj '(1 2) 3)

17:19 lazybot: ⇒ (3 1 2)

17:19 jconnolly: ah

17:19 prepend

17:19 Raynes: conj adds to the front of lists.

17:19 jconnolly: much obliged!

17:19 thanks Raynes

17:19 Raynes: No problem. :)

17:26 septomin_: i wonder if the clojure koans should even teach lists

17:28 Raynes: septomin_: This is actually a good reason why they should.

17:29 &(conj [1 2] 3)

17:29 lazybot: ⇒ [1 2 3]

17:29 jconnolly: ;D

17:29 Raynes: conj does something completely different for these two data structures.

17:29 If you don't hit that early on, I expect it could cause some nasty trouble in real code.

17:30 cduffy: jconnolly: ...re: the "M to RTF", (doc conj) touches on it.

17:31 septomin_: well, it's something you need to know sometime

17:32 i just don't like language introductions that spend equal time on each feature of the language

17:33 jconnolly: cduffy: thanks, that's great. just dipping my toe into the clojure pool now, that's helpful

17:33 cduffy: jconnolly: *nod*. The general rule with conj is that it does whatever is fast/efficient for the data structure in question, rather than having a specific semantic re: location.

17:37 jconnolly: ...incidentally, Clojure's PersistentQueue implementation uses both a list and a vector, thereby leveraging the most efficient behavior of each (vectors being cheap to add onto the end of, lists being cheap to pop from the top of).

17:38 jtoy: what file format do clojure people typically use for a project config?

17:38 app config I mean

17:39 Raynes: jtoy: Most people use Clojure data structures for configuration. Particularly maps.

17:40 amalloy: well, it uses a seq and a vector, jconnolly. not really a list

17:41 i guess i meant to send that to cduffy

17:41 hagna: how do I get a random element from a set?

17:42 jtoy: which json library do you guys normally use?

17:42 I've been using clj-json, but i just found chesire which seems to be better

17:42 gfredericks: hagna: that is a good question

17:42 technomancy: clj-json is deprecated

17:43 dakrone: jtoy: use cheshire

17:43 jtoy: dakrone: shah, that is yours, but ok

17:43 technomancy: though it doesn't say so in the readme; what the heck

17:43 I better heckle mmcgrana about that next time I see him =)

17:43 hagna: gfredericks: maybe change it to a vector first and then use (nth v (rand-int (count v)))

17:44 technomancy: (comp rand-nth vec)

17:44 gfredericks: hagna: yeah that's one of several non-performant options

17:44 I don't think you could do it performantly without built-in support

17:45 hiredman: ,(doc rand-nth)

17:45 clojurebot: "([coll]); Return a random element of the (sequential) collection. Will have the same performance characteristics as nth for the given collection."

17:46 zzach: @cduffy: Exception is caught using wait-for-result inside the try-catch block. The only thing I would still like to remove are remaining messages in the stdout of the lein repl like SEVERE: Unhandled error in Netty pipeline.... (before the exception is caught).

17:46 gfredericks: so still O(n)

17:47 Raynes: technomancy: lancepantz maintains it. I'll mention it to him when he comes back into the room.

17:47 hagna: gfredericks: well it doesn't work on a sorted-set so I still have to convert to vector

17:47 (rand-nth (into [] #{"a" "b" "c"}))

17:47 technomancy: Raynes: like maintains maintains or he has push access

17:47 Raynes: technomancy: Both?

17:48 gfredericks: well hopefully not the former but not the latter

17:48 technomancy: oh, I thought Mark told everyone to quit using it; maybe I'm getting it confused with clj-http

17:48 Raynes: technomancy: Well, clj-http isn't deprecated.

17:49 dakrone took that one over.

17:49 technomancy: yeah, just mark's fork

17:54 Raynes: technomancy: Yeah, he just hasn't updated the README. There are a couple of things he wants to make sure cheshire can do first and he wants to ask Mark first before making it as officially deprecated.

17:55 technomancy: Raynes: good to know; thanks

17:55 dakrone: Raynes: it should be able to do anything he'd like

17:55 Raynes: dakrone: He just wants to make sure coercions work the way we need them to.

17:56 dakrone: Raynes: okay, lemme know if anything doesn't behave

17:56 Raynes: dakrone: Will do.

18:00 cduffy: zzach: hmm; SEVERE sounds like a standard log4j / commons-logging level; I'd guess you could configure filtering through whichever of those mechanisms is actually in place.

18:14 jtoy: what library is usually used to join a dir with a file name to get a full path?

18:14 technomancy: jtoy: clojure.java.io/file

18:14 jtoy: cool,txh

18:14 Raynes: &(clojure.java.io/file "foo" "bar.clj")

18:14 lazybot: ⇒ #<File foo/bar.clj>

18:15 Raynes: If you need the actual path (which you probably don't), ##(.getPath (clojure.java.io/file "foo" "bar.clj"))

18:15 lazybot: ⇒ "foo/bar.clj"

18:16 jtoy: hm, I would have thought (clojure.java.io/file "" "config.json") would be ./config.json buts its /config.json

18:17 Raynes: I'm not sure I would have expected that.

18:18 amalloy: why would "" be "."?

18:18 i mean, "/config.json" is clearly a bit silly, but you gave it a silly input

18:18 jtoy: amalloy: its better then /config.json

18:19 if not /config.json then what?

18:20 technomancy: how else would you specify the root of the filesystem in a portable way?

18:20 amalloy: smart man

18:24 wkmanire: I'm back for a short break :)

18:26 jtoy: technomancy: is that to deal ith windows because it uses \? i don't even know if it uses \

18:28 amalloy: jtoy: well it does use \ as a directory separator, but his point is (or is at least related to) that the windows fs has multiple roots

18:30 jtoy: I see

18:46 dnolen: anybody have CLJS code that makes heavy use of maps?

18:46 ibdknox|away: I do!

18:46 lol

18:47 dnolen: ibdknox: http://dev.clojure.org/jira/browse/CLJS-178 mind applying this patch and letting me know whether you see a dramatic perf difference?

18:48 ibdknox: I'm more interested in not slowing things down - rather than whether there's a speed improvement or not.

18:48 ibdknox: might take me a day or two :/ I'm still responding to stuff

18:48 but I would be happy to when I get a minute

18:48 emezeske: haha ibdknox DDoS'ed himself with light table

18:48 ibdknox: emezeske: that's actually a really good description

18:48 lol

18:49 emezeske: ^_^

18:49 ibdknox: emails from all sorts of people

18:49 MIT emailed me about an hour ago

18:49 emezeske: dayyum

18:49 dnolen: ibdknox: wowzers

18:54 TimMc: ibdknox: The whole MIT?

18:55 ibdknox: MITx specifically ;)

18:56 dnolen: ibdknox: what did I tell you? online learning folks want Light Table yesterday.

18:57 ibdknox: yeah, the more I've explored the idea, the more I've realized it has a lot of applications. One of the most important most interesting is in education I think

18:57 and most interesting*

19:32 devn: ibdknox: im so glad you're a part of our community

19:32 TimMc: awwwww

19:32 mdeboard: +1

19:33 Kowboy: second

19:33 TimMc: (and I agree)

19:33 mdeboard: I already said +1 you bandwagoneers

19:33 Find a new messiah, he's MINE

19:33 ibdknox: it's funny how things work

19:34 devn: seriously, talk about a boon for this community -- the popularity of light table and your association with this language and community make it *ever better* than it would have been had you released that from scala-land

19:34 ibdknox: I don't really remember how I started using Clojure

19:34 lol

19:34 devn: or any-language-other-than-clojure-land

19:34 emezeske: ibdknox: I was just thinking about that the other day, and I don't remember how I got started either

19:34 ibdknox: Which kind of bugs me...

19:35 ibdknox: I know roughly that it was because I kept seeing it on HN

19:35 and I'd never done a lisp

19:35 Raynes: I got started by coding.

19:35 Stop being silly.

19:35 Kowboy: I got started on clojure.org

19:35 emezeske: Yeah, HN was certainly involved for me too :P

19:35 devn: ibdknox: i also have to say im incredibly annoyed in some respects, because ive been brain-jamming on an interactive environment that is repl-driven

19:35 and here you come and blow my mind

19:35 ibdknox: but in retrospect, I have no clue why it attracted me, I wasn't doing anything that clojure was particularly good at, at the time

19:35 devn: but it seems just...i dont know...right on time

19:35 Kowboy: I don't follow HN

19:35 jconnolly|away: actually, ibdknox unbeknownst to me, is the reason I'm learning clojure too ;D

19:35 ibdknox: jconnolly|away: oh?

19:35 jconnolly: indeed

19:36 Raynes: I

19:36 devn: we were talking the other day at work over lunch about smalltalk, and how the refactoring browsers and so on have just...never caught on in the way they could have

19:36 Raynes: I've met the guy in person. Seriously, he isn't that great.

19:36 ;)

19:36 jconnolly: http://www.chris-granger.com/2012/02/20/overtone-and-clojurescript/

19:36 devn: one week later...light table demo

19:36 ibdknox: pretty short actually

19:36 jconnolly: and light table

19:36 I thought it was time to jump in ;D

19:36 okay, back later

19:37 Kowboy: for me, it was Scala that led me to Clojure

19:37 ibdknox: holy shit, I didn't make the YC interview...

19:37 devn: ruby => chris wanstrath said "learn a lisp" => common lisp => haskell => clojure

19:37 frx: hello. what is the -> macro called? I can't google it, and I can't search for it in clojure.org either

19:37 devn: frx: thread first

19:38 ibdknox: frx: threading

19:38 ivan: ibdknox: "pg, your finger slipped"

19:38 ibdknox: I'm actually astounded

19:38 devn: frx: -> is "thread first", ->> is "thread last"

19:38 frx: thanks

19:38 devn: frx: it's also the "thrush combinator"

19:39 frx: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

19:39 frx: one more: https://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown

19:39 gfredericks: is it time to talk about swiss arrows?

19:40 ivan: ibdknox: Dropbox got rejected at first too

19:40 ibdknox: dropbox didn't just have the largest launch in HN's history

19:40 kovasb_: idbknox: Jordan got cut from his high school basketball team

19:40 frx: found it thanks. but what if I want to insert result or object as a non-first item?

19:41 ibdknox: plus several recommendations from YC founders

19:41 devn: ibdknox: i was thinking a bit about YC and your project. light table is sort of a funky area for YC, maybe?

19:41 the idea of it being open source, an editor

19:41 gfredericks: frx: there's a new library called swiss arrows with a generalized version

19:41 clojurebot: Excuse me?

19:41 ibdknox: no more so than Meteor is

19:41 ivan: ibdknox: did you have a cofounder?

19:41 ibdknox: ivan: yessir

19:41 ivan: oh wow

19:41 devn: ibdknox: fair enough

19:41 Raynes: ibdknox: Whoa.

19:41 TimMc: cofounder? I hardly even know 'er!

19:41 ibdknox: TimMc: haha

19:42 * devn *rimshot*

19:42 technomancy: I just updated the Leiningen plugins page to mark plugins which haven't been confirmed to work with lein2: https://github.com/technomancy/leiningen/wiki/Plugins

19:42 * TimMc looks guilty

19:42 technomancy: if you have a plugin that's been updated, could you please mark it?

19:42 eggsby: hey guys, say my noir/compojure app had a caching layer that circled around some api and said 'are there any new records? do I need to flush things?'

19:43 Raynes: ibdknox: Was this for that other company idea you had?

19:43 technomancy: or rather, remove the "hasn't been confirmed compatible" mark

19:43 frx: gfredericks: so nothing in standard lib I take it?

19:43 eggsby: could I integrate this with noir or compojure or would it need to be its own process?

19:43 ibdknox: Raynes: yes, though they claim this whole thing is about people

19:43 eggsby: stuff like 'lein ring server' not sure I can shove that sort of looping logic into a handler, can I?

19:43 clojurebot: excusez-moi

19:44 eggsby: ibdknox: :/

19:44 * devn listens to alan dipert on the thinkrelevance podcast

19:44 eggsby: just kickstarter it

19:44 * devn looks around the channel for adipert

19:44 * ibdknox is genuinely confused

19:44 ibdknox: eggsby: that's the plan

19:44 devn: ibdknox: same.

19:45 but that's nothing new for me

19:45 eggsby: YC is 'can I turn this into a money making machine'

19:45 that's all VC

19:45 Raynes: ibdknox: Yeah, luckily everybody wants to give you their wallets.

19:45 gfredericks: frx: not besides sticking an anonymous function literal in the middle of the thing

19:45 devn: ibdknox: i think keeping it open has the opportunity to make it a /revolution/

19:45 frx: ok thanks, will check that lib out

19:45 eggsby: stop looking for angels and take my money already damnit

19:45 devn: not just a product

19:45 ibdknox: devn: I agree :)

19:46 devn: change the way people program. that's bigger than just this rinky dink money making stuff.

19:46 ibdknox: eggsby: I'm just waiting on the damn kickstarter people

19:46 apparently they're slow ;)

19:46 eggsby: So, is it possible to run a polling/caching daemon as part of a noir/compojure app or should I just have it be a separate process operating on the same data?

19:47 xeqi: like a caching middleware?

19:48 TimMc: ibdknox: Are you sure Kickstarter is the right venue?

19:48 ibdknox: TimMc: ?

19:49 weavejester: eggsby: It depends on what you're caching, really.

19:49 TimMc: That Calyx ISP guy was rejected and went with IndieGogo or soemthing instead.

19:49 lancepantz: ibdknox: i would get the kickstarter up, show traction, then re-apply with light table on the app

19:49 ibdknox: for the summer session, as a late applicant

19:50 ibdknox: lancepantz: it wasn't late, we were in there a month or two early

19:50 lancepantz: no, i mean apply again for the same session

19:50 ibdknox: oh

19:50 lancepantz: but with light table

19:50 they will take applications up until the session starts

19:50 eggsby: My particular use case is: A system presents data to a user, the data is aggregated from n other systems, rather than having the web request issue the function that goes and asks what the state of the other systems are, I want to have a loop on a timer fetching the data, and then when a user requests a web page just present them with the most recent information

19:50 lancepantz: that's what i did

19:50 ibdknox: lancepantz: interesting

19:50 lancepantz: i got an interview, got rejected, turned around, re-applied

19:50 got rejected again

19:51 but whatever, didn't hurt

19:51 and yc is all into traction

19:51 septomin_: maybe lighttable is more than a business :)

19:51 devn: you're a better person for having gone through the process

19:51 septomin_: that's the key i think

19:51 it's not a business. it's a big idea.

19:51 it could be a business too

19:51 ibdknox: devn: been through it a couple times now haha :) Got an interview the first time

19:51 mmarczyk: dnolen: ping?

19:52 eggsby: So the way I see it I can have a project that just populates the db the compojure app is reading from, but what I'm wondering is whether or not this sort of infinite db populating loop is able to be run inside a compojure 'lein ring server' or whether it will need to be standalone

19:52 devn: ibdknox: i have some reading material you might be interested in.

19:52 ibdknox: mainly, white papers on refactoring browsers

19:52 and how, despite the productivity gains, people were still unwilling to give up grep and ack in favor of using a refactoring browser

19:52 dnolen: mmarczyk: hullo

19:52 lancepantz: ibdknox: if i was you, i would reapply, with lighttable, but you have to say you are focusing on making it a js ide

19:52 mmarczyk: dnolen: hi

19:53 dnolen: I just finished a comment on the phm ticket

19:53 devn: that's not damning, but it's good to be aware of similar previous attempts at changing the way people write programs

19:53 their upsides and downsides

19:53 mmarczyk: dnolen: re: -strobj, or lack thereof

19:53 weavejester: eggsby: I'm not sure I understand the purpose. Is what you have effectively a database-backed cache?

19:54 devn: ibdknox: you going to euroclojure?

19:54 ibdknox: nope, unfortunately the timing didn't work out well for me

19:54 devn: aww, bummer

19:54 ibdknox: lancepantz: on it.

19:54 dnolen: mmarczyk: but HashMap doesn't support strobj right?

19:54 mmarczyk: dnolen: right

19:54 eggsby: weavejester: the data I am presenting is formed by asking hard questions of remote systems. I want to ask those questions on a timer and then write the answers to a db, so then a user can read the data from the db instead of when the client makes a request

19:55 dnolen: mmarczyk: code relying on strobj is way broken.

19:55 mmarczyk: but yes we should deal with it.

19:55 mmarczyk: dnolen: agreed

19:55 devn: src/clj/cljs/compiler.clj | 557 ++++++++++++++++++++++++---------------------

19:56 eggsby: So, either a separate loop writing to the same db compojure app is reading from, or somehow shoving a loop to populate the db in the compojure handler

19:56 devn: dnolen and company killing it as usual-^

19:56 eggsby: I'm not sure if the latter is possible, or where to start looking for how to do it :)

19:56 weavejester: eggsby: Oh, I have something like that. I implemented the cache in the application itself, which gives me greater control over invalidation.

19:56 devn: keeping up with commits on cljs lately has been a hobby unto itself

19:57 mmarczyk: dnolen: I think the vararg js-obj could actually solve much of the problem

19:57 dnolen: most uses of -strobj I remember seeing where with small map literals

19:57 eggsby: weavejester: so I should just be studying compojure's caching? :p

19:57 mmarczyk: there was at least one funky reduce involving -strobj though... not sure where

19:58 weavejester: eggsby: Compojure is just a routing library. Caching is up to you.

19:59 dnolen: mmarczyk: yeah in net.cljs, but that's kinda silly, we just just use a mutable (js-obj) there.

19:59 we can just use, I mean.

20:01 eggsby: weavejester: I guess the hangup i'm having is how I would define an app handler that also handled that... (def app (handler/site my-routes)) <-- where is there room for 'caching' ?

20:01 do I drop down to ring for this problem?

20:01 (I apologize, I'm still learning clojure)

20:01 mmarczyk: dnolen: right

20:02 weavejester: eggsby: It depends where you want to cache, whether you want to cache the data directly, before it's returned as a response, or whether you want to cache the response, in which case you'd use some middleware.

20:02 eggsby: If the answer was before?

20:02 mmarczyk: dnolen: TwitterBuzz would be perfectly well served by a variadic js-obj

20:03 dnolen: mmarczyk: I think this should be a seperate ticket - remove .-strobj usage.

20:03 eggsby: I guess it's like a pre-cache or something

20:03 mmarczyk: dnolen: sure, and I can get that done

20:04 dnolen: mmarczyk: we can add a compiler warning for anyone trying to access that particular propertyto be nice.

20:04 mmarczyk: dnolen: cool

20:05 dnolen: do you want this in before PHM?

20:06 dnolen: mmarczyk: yeah ... I think trying to provide a alternate solution is not really a great idea.

20:07 mmarczyk: PHMs can hold arbitrary keys - those simply can't get converted.

20:07 mmarczyk: so people that were relying on .-strobj should just use a mutable js-obj like we will.

20:07 mmarczyk: dnolen: sure

20:08 eggsby: weavejester: should I just take the 'two separate projects' route ?

20:09 mmarczyk: dnolen: how about the variadic js-obj to make creating small objects easier?

20:10 dnolen: mmarczyk: a nice simple enhancement - but definitely separate ticket.

20:11 mmarczyk: dnolen: yeah, but that's the simplest way to remove the -strobj's from twitterbuzz.core :-)

20:11 dnolen: though (doto (js-obj) (aset ...) ...) will work fine too

20:13 dnolen: mmarczyk: hmm there's actually a note in there about strobj already

20:14 mmarczyk: dnolen: yeah, noticed that too; been there for a long time apparently, judging by the property access syntax

20:15 dnolen: mmarczyk: I think clj->js to complement js->clj is what we want.

20:15 gfredericks: I wrote one of those once

20:15 dnolen: mmarczyk: it should throw on maps with complex keys.

20:17 mmarczyk: dnolen: that's one oft-reinvented function, I believe

20:17 dnolen: and obviously solves this particular problem

20:17 dnolen: mmarczyk: yeah

20:19 devn: mmarczyk: dnolen: +1 on that -- i see it a lot

20:20 clj->js and vice versa

20:20 mmarczyk: right, I'm writing a version now

20:21 weavejester: eggsby: Well, it doesn't really matter. Middleware is effectively the same as a proxy. The only difference is whether it is local, or remote.

20:21 eggsby: It's also pretty easy to turn caching middleware into a caching proxy.

20:22 mmarczyk: dnolen: what do you think it should do to seqs?

20:23 dnolen: btw, if anyone has CLJS code that uses maps a lot, you should try mmarczyk's patch, we're looking for perf feedback - http://dev.clojure.org/jira/browse/CLJS-178

20:24 mmarczyk: I guess convert them into arrays.

20:24 devn: ^-that's what i was thinking

20:24 what about for lazy-seqs?

20:24 mmarczyk: right

20:24 arrays it is

20:25 ivan: can you use two different versions of the same jar/namespace in the same process?

20:25 dnolen: devn: it should realize them and put them into an array.

20:25 devn: if you give clj->js an infinte seq that's programmer error.

20:25 devn: dnolen: fair enough -- i was imagining it might hold onto the producer fn or something

20:25 but i agree

20:25 just didnt know if you had tricks up your sleeve

20:26 technomancy: ivan: yes, but you have to construct your own classloaders

20:26 ivan: technomancy: thanks, I guessed it would be something tricky like that

20:26 dnolen: devn: nah, this is just about interop.

20:27 ivan: technomancy: lein will just blow up if there's a version conflict, right?

20:27 dnolen: mmarczyk: it should probably handle fns, since that's so common in JS interop.

20:27 technomancy: ivan: it will refuse to resolve if there are non-overlapping ranges in the version tree

20:27 ivan: right. thanks.

20:27 mmarczyk: dnolen: handle as in pass through?

20:27 technomancy: ivan: but there's no problem with having multiple versions specified in and of itself

20:28 only one can "win"

20:28 dnolen: mmarczyk: yeah.

20:30 mmarczyk: but I think it should error on sets.

20:30 mmarczyk: dnolen: it could emit a wrapper function, but I'm not sure it's worthwhile

20:32 dnolen: mmarczyk: anything that doesn't have a sensible JS representation should not be allowed I think.

20:32 mmarczyk: dnolen: ok, so I'll have it throw on complex keys and stuff which looks too outlandish from JS perspective

20:33 dnolen: mmarczyk: cool.

20:33 mmarczyk: dnolen: except perhaps when passed an option to force stringification / pass-through ?

20:33 dnolen: or should we let those crazy enough to think they need that worry about it themselves

20:34 dnolen: mmarczyk: I think symbols and keywords should have name called on them.

20:35 mmarczyk: (goog/isString x) (name x)

20:36 mmarczyk: dnolen: right, I'm doing that

20:38 dnolen: alternatively we could have an option :stringify-keys causing that behaviour

20:38 dnolen: and default to throwing on symbols / keywords too

20:39 or maybe I'll just mention in the docstring that having strings/symbols/keywords with the same "name" in a map will result in information loss.

20:39 dnolen: mmarczyk: hmm, now that I think it - probably some legitimate uses for allowing them to pass through for event handling interop.

20:40 mmarczyk: perhaps leave them alone, and add :stringify-keys option.

20:40 mmarczyk: dnolen: ok

20:45 dnolen: first cut: https://github.com/michalmarczyk/clojurescript/tree/clj-to-js

20:45 dnolen: oops, wrong link -- https://github.com/michalmarczyk/clojurescript/commit/11734e71aae765cfb51b7f8cd1641af337bc7f73

20:46 that's on top of the transient stuff cause I forgot to switch branches.

20:48 ivan: turning maps into JavaScript objects is always dangerous business. things like toString can get set. you probably already know this.

20:48 dnolen: mmarczyk: I think clj->js should be properly recursive and handle the allowed types - i.e. string

20:50 ivan: and hasOwnProperty and valueOf

20:50 alexbaranosky: how do I use a library such as javax.speech or javax.speach.synthesis from my project?

20:51 just importing them doesn't work, is there something I need in my project file?

20:51 (ns gong.core

20:51 (:import [java.util Locale]

20:51 [javax.speech.synthesis SynthesizerModeDesc]

20:51 [javax.speech Central Synthesizer]))

20:52 there's no complaint about java,util Locale, but the others get a classNotFoundException

20:52 dnolen: mmarczyk: hmmm, this probably needs more thought and discussion ... which is probably why it wasn't done in the first place.

20:52 ivan: not an issue for CLJS - CLJS maps are real maps.

20:53 mmarczyk: dnolen: ahhhh well.

20:53 ivan: dnolen: well, presumably the user is going to do something with that object that they get from clj->js, and sometimes you'll have weird consequences, depending on how much untrusted input was used as keys

20:56 dnolen: mmarczyk: put the patch in a ticket and we can trigger a discussion.

20:56 ivan: I think you need a really well-defined spec that defines the lossiness

20:56 mmarczyk: dnolen: ok

20:56 dnolen: mmarczyk: I think PHM higher priority - we can warn and say build your js-objs yourself.

20:57 mmarczyk: dnolen: great

20:57 ivan: yay PHM

20:57 mmarczyk: dnolen: and yeah... clj->js in core should be able to be the "canonical" version

20:58 dnolen: ivan: i'm less concerned about the untrusted bit - but I agree that the lossiness problem is not something that can be decided on very quickly.

20:59 mmarczyk: dnolen: I'll prepare a quick fix for TwitterBuzz too, with a separate ticket

20:59 dnolen: we'll be able to prettify it if (a version of) clj->js lands someday

21:03 alexbaranosky: wish there was a clojars for java libraries - is there? I'm looking for whatever it is I need to paste into my project file to import javax.speech and javax.speech.synthesis

21:04 technomancy: alexbaranosky: tried search.maven.org or jarvana?

21:04 Raynes: technomancy: You can use clojars for Java libraries too.

21:04 *shrug*

21:05 technomancy: yeah, assuming he meant for search

21:05 mmarczyk: dnolen: ah, arrays should probably be traversed recursively, as should objects... I'll post the ticket with a somewhat more workable patch soon, though I'm beginning to feel super sleepy, so might need to wait until morning

21:05 Raynes: Oh, his question makes no sense then.

21:05 technomancy: though I guess clojars still doesn't let you search by class or namespace

21:05 Raynes: clojars search sucks worse than maven central's.

21:05 technomancy: but at least it doesn't take 20 minutes to download the indices! =)

21:05 Raynes: Trudat

21:05 technomancy: did you see we had someone investigating the search indices?

21:06 https://github.com/technomancy/leiningen/issues/243 <3

21:07 alexbaranosky: dang javax.speech gives zero results on both links

21:07 wtf

21:07 Raynes: technomancy: hot

21:09 alexbaranosky: going with plan B -- robokind speech :)

21:09 cmajor7: I see that clojure stream is in development. what is the standard way to consume a stream of data (e.g. a feed)?

21:12 seancorfield: clojure stream?

21:12 amalloy: cmajor7: you are probably reading some very old documentation

21:13 someone should take that stuff about streams replacing lazy sequences off of atlassian or wherever it is

21:13 alexbaranosky: if it's in Maven Central then leiningen should be able to find it with no customizations right?

21:15 cmajor7: amalloy: I see, so Streams are all cooked?

21:15 amalloy: whatever they were going to be, they're not. lazy-seq won

21:15 seancorfield: cmajor7: URL for the docs you are referring to?

21:15 amalloy: though if you link to whatever document made you think streams are relevant...

21:16 seancorfield: just in case we can fix it or prevail upon the author/owner to do so

21:16 cmajor7: or what is the (other/better) way to consume a feed?

21:16 amalloy: seancorfield: probably http://clojure.org/streams

21:17 cmajor7: seancorfield: yes, clojure streams.

21:18 amalloy: interesting, so you would consume a feed in a regular seq?

21:18 amalloy: cmajor7: "consume a feed" is so tremendously vague that i can't answer you

21:18 seancorfield: ugh! let's see if we can prevail upon clojure/core folks to remove that page...

21:18 amalloy: but most things in clojure are done with seqs, yes

21:20 alexbaranosky: cmajor7, you could use some kind of lazy sequence

21:23 cmajor7: amalloy: point taken. it is a vague desire.. let's say I'd like to consume a feed that comes in on a socket, where I read it with something like netty framing packets. I would like to be able to capture this data somewhere. can that "somewhere" be a lazy seq (data is streaming in)

21:23 amalloy: yes, absolutely you can create a lazy sequence out of the bytes coming in over a socket

21:26 cmajor7: internally though, the data is.. cached? by a lazy seq? since before actually getting the data from a seq (take 5), the data needs to be evaluated (looked at) as it comes in?

21:27 alexbaranosky: cmajor7, this might be useful http://clojuredocs.org/clojure_core/clojure.core/lazy-seq

21:30 * alexbaranosky is still not doing so hot trying to get a speech synthesis library imported

21:31 cmajor7: alexbaranosky: yep, I looked at it before, thx. the point that is still moot to me is where does the data actually go (from the socket) _before_ invoking an action on a lazy seq

21:35 alexbaranosky: I guess this is God punishing me for my laziness... I never wanted to wait the time to use ling search

21:35 lein search *

21:36 cmajor7: any thoughts?

21:36 alexbaranosky: lein search of course worked like a charm

21:36 cmajor7, I'm not sure I understand

21:36 the lazy part of the lazy seq would pull off a new chunk of data

21:37 seancorfield: in other words cmajor7 the data is consumed from the socket when the lazy-seq is consumed (if you've written it correctly)

21:38 cmajor7: but the socket is not lazy

21:38 seancorfield: for example, we use a lazy-seq around search results - our search engine returns results in pages... the second page is only requested when enough of the lazy-seq is consumed to go past the first page

21:38 but data is only consumed from the socket when you actually read it, yes?

21:39 cmajor7: no

21:39 seancorfield: so if you only read it when you need the data, the process is lazy

21:39 cmajor7: the data is always coming

21:39 other wise

21:40 an OS socket receive queue will over fill pretty quickly

21:40 gfredericks: oh man I didn't know about this stream stuff; fascinating bit of history

21:40 "SVN" in particular

21:40 cmajor7: so you need to constantly consume, it is streaming in

21:41 seancorfield: cmajor7: what is your interface to the socket? java's Socket class?

21:42 cmajor7: yes. I have regular and NIO implementations

21:42 seancorfield: using this as an example http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html you would call .readLine() when you wanted the next element of the sequence

21:43 assuming you wanted a lazy seq of lines from the socket

21:43 similarly with nio, you'd read bytes as you needed them

21:44 cmajor7: when you consuming a feed, you need to keep up at a certain rate e.g. 300,000 quotes a sec

21:44 seancorfield: that has nothing to do with laziness tho'

21:44 cmajor7: otherwise a producer will disconnect you

21:44 seancorfield: your code could still consume the lazy seq fast enough to satisfy that

21:45 cmajor7: so you consume _before_ you call on a lazy seq

21:45 bubba42: hi I need to do the equivalent of sum = sum + x in a recur ... do I use a let ? ... not clear how to do this ... would appreciate some help.

21:45 seancorfield: no, you consume as part of the process that satisfies consumption of the lazy seq

21:46 gfredericks: bubba42: like (recur (+ sum x))?

21:46 cmajor7: ok. in this case there is no point of a lazy seq

21:46 seancorfield: cmajor7: sure there is - a lazy seq can make your code much easier to write

21:47 the rest of your code doesn't need to care about buffering or chunks or anything inconvenient like that

21:47 cmajor7: sean, why is that?

21:47 gfredericks: bubba42: or if you haven't even gotten that far, try (loop [sum init-val] (let [x (... compute stuf ...)] (recur (+ sum x))))

21:47 or even better tell us what you're doing at a higher level and we can tell you why you probably don't need to use loop or recur at all

21:47 seancorfield: the search engine example i gave: our code just consumes search results... it doesn't care where they come from and it doesn't care about pagination or anything... only the lazy-seq wrapped code cares

21:50 bubba42: thx @gfredericks -- first few hours on clojure, it's just different enough that my old language skills don't carry forwards :-) ... let me look @ what you're proposed

21:51 @gfredericks ... (recur (+ sum x)) what I don't understand here is how does it know where to place the + sum x ... how does it know to place it in sum and not x

21:51 y3di: do you guys know of any webapps that use noir?

21:51 seancorfield: bubba42: recur says to re-bind the symbols in the loop binding

21:52 (loop [sum 0] ... (recur (+ sum x))) will re-bind sum to (+ sum x) next time

21:52 xeqi: y3di: looks like refheap uses noir

21:52 seancorfield: cmajor7: did i answer your question?

21:52 bubba42: ah

21:52 I think i c

21:52 so the order of the expressions in the recur statement is important ?

21:53 seancorfield: yes, they correspond to each element of the binding in (loop [...] ...)

21:53 bubba42: ah .... I'm glad I dropped on this channel ... I could have been stuck for weeks on this

21:54 seancorfield: so (loop [a 1 b 2] ... (recur (+ a b) (inc b))) binds a to (+ a b) and b to (inc b)

21:54 bubba42: got it thx

21:54 is it worth it to understand the *immutability* philosophy early on ?

21:55 seancorfield: if you're coming from OO, that's the hardest part, but yes you need to grok it early on

21:55 muhoo: is anyone using lein2 with trampoline repl?

21:55 seancorfield: that way you don't think in terms of sum := sum + x

21:56 bubba42: did fair bit of clos in grad school and some early on @ work .... so I'm excited about clojure :-) cool have to do some reading then

21:56 muhoo: "lein trampoline repl" times out even if i set :repl-options {:timeout 120000} in user profile

21:58 seancorfield: i love writing clojure every day at work... i'm excited about programming all over again!

22:00 zackzackzack: Any ideas about why the clojurescript one repl would freeze after firing an event?

22:01 emezeske: zackzackzack: Uncaught exception on the client-side?

22:01 cmajor7: seancorfield: buy if you have to always consume to meet the throughput reqs, what is the advantage of using a lazy seq?

22:04 zackzackzack: emezeske: that's what it looks like now. Opened up the console in chrome and found an error. Unable to reproduce again though.

22:04 gfredericks: cmajor7: being able to treat it like a normal data structure instead of a stateful thingy?

22:04 seancorfield: cmajor7: i already answered that - yes, what gfredericks said

22:05 gfredericks: and by "normal" I include "immutable"

22:05 seancorfield: from the program's p.o.v. it looks just like a regular immutable data structure

22:05 alexbaranosky: cmajor7, which means you can use all the great clojure.core functions on it

22:05 emezeske: zackzackzack: I've seen problems with uncaught exceptions not being logged when they were thrown from event handlers

22:06 zackzackzack: In chrome. not sure if it still does that, though

22:06 zackzackzack: No idea. Trying to understand clojurescript now. It's mostly just magic at this point to me.

22:07 cmajor7: but does it matter it is lazy or not if the data is constantly being evaluated..

22:08 I get that I can call all the map/reduce/filter on it, but would that be all?

22:08 emezeske: zackzackzack: ClojureScript One is an example of a fully-featured application stack

22:08 zackzackzack: There's no doc in clojurescript!

22:08 emezeske: zackzackzack: I'm not sure it's the best starting point to learn from

22:08 cmajor7: or there is an actual real advantage of it being lazy in this case

22:09 seancorfield: without laziness, you'd have to consume all the data upfront, then process it

22:09 emezeske: zackzackzack: Yeah :/

22:09 zackzackzack: emezeske: What would you recommend as a good place to start?

22:09 seancorfield: with laziness, you can process it as you consume it - so an infinite sequence is possible

22:09 emezeske: zackzackzack: That's a good question; I'm not really sure to be honest

22:09 seancorfield: and you'll only use as much memory as needed for the data on hand

22:09 emezeske: zackzackzack: I haven't looked at introductory examples in a while

22:10 zackzackzack: emezeske: That's pretty much why I am starting with clojurescript one

22:10 emezeske: zackzackzack: haha

22:10 zackzackzack: There isn't really a good introduction to actually using it as far as my google fu knows

22:11 emezeske: zackzackzack: Yeah, I know there's a book due out this summer, but none yet

22:11 gfredericks: cmajor7: it gives you separation of concerns in your code

22:11 zackzackzack: Time to use the source

22:11 gfredericks: your data code doesn't have to know whether the data comes from a socket or not

22:11 cmajor7: seancorfield: ok, let's take an example of a feed that streams in at 300,000 orders a second. You need to process all this data _as it comes in_ => there is always "data at hand", it is a streaming protocol (e.g. TCP/IP)

22:11 gfredericks: but for that I can use any other data structure e.g. a queue

22:12 emezeske: zackzackzack: I probably would recommend starting with https://github.com/emezeske/lein-cljsbuild/tree/master/example-projects/simple

22:12 zackzackzack: To build your own app

22:12 zackzackzack: But to keep using clojurescript one as a source of example code

22:12 zackzackzack: Neat! Thank you

22:12 emezeske: zackzackzack: It's the opposite of cljs one; it's the simplest thing possible, and does nothing

22:13 muhoo: what about cljs-template?

22:13 emezeske: Oh, yeah, zackzackzack ^

22:13 muhoo: I forgot about that, it's even better than my recommendation

22:14 zackzackzack: Great

22:14 Just got finished with the first one

22:15 Graduating quickly so far

22:15 gfredericks: cmajor7: so the difference between a lazy seq and a queue is mutability

22:16 if you don't see any benefit to immutability then you probably won't be convinced that lazy seqs are worth the trouble

22:17 cmajor7: gfredericks: I know what the difference is, and I always prefer immut/referential transparency/composition/etc.. this is not the question of theory

22:17 but of a concrete example

22:18 gfredericks: okay; well I guess we're done listing benefits then

22:19 muhoo: does nrepl even work with trampoline?

22:19 i'm starting to think that "lein2 trampoline repl" will never work because it can't ever work

22:20 TimMc: lein tasks do not *tend* to compose well, in my experience

22:20 I think that situation can improve, though.

22:21 seancorfield: cmajor7: sorry, i don't know how to explain it any more clearly

22:21 the speed of consumption has nothing to do with laziness

22:21 it's a matter of how the data is exposed to your application

22:22 as gfredericks said, we're about out of explanations and benefits - why don't you _try_ it?

22:23 cmajor7: seancorfield: right, I understand where you going to, and a lazy-seq is a nice abstraction around the socket (_generally_), but let's simplify, and say that you need to consume the data and persist it to a durable store (that's it). would you use a lazy seq in the middle?

22:25 xeqi: I would so I could use (doseq ..), until a profiler told me not to

22:27 arohner: has anyone had a good experience with a distributed messaging library?

22:28 muhoo: arohner: i haven't, but i have heard people raving abotu rabbitmq on clojure

22:31 seancorfield: cmajor7: it depends on how you would persist it - if you're persisting it piecemeal (say in records in RDBMS or document store) then a lazy seq of those chunks is still valuable

22:49 cmajor7: seancorfield: right, because it buffers, and can be replayed if needed.. but let's take an nio example where you don't really block on receive (e.g. event loop) => something is received and you provide a calllback.. how do you wrap that in a lazy-seq?

22:50 spoon16: anyone know how to get the clojurescript compiler to output a js file with goog.global.CLOSURE_NO_DEPS = true?

23:06 dnolen: mmarczyk: btw, are you planning on taking the strobj problem? or do you want me to fix that?

23:28 seancorfield: hmm, i don't actually know how to answer cmajor7's last Q but he's gone now... if the only way data is "read" is via a callback, then i guess the app has to put it in a queue and the lazy-seq can wrap the other end of the queue?

23:33 emezeske: spoon16: I don't think you can

23:33 spoon16: This is what I do: https://github.com/emezeske/lein-cljsbuild/blob/master/example-projects/simple/src-clj/example/views.clj#L11

23:38 spoon16: emezeske: I saw that and ended up doing something similar

23:38 thanks

23:40 amalloy: you need another thread, seancorfield. have the callback drop stuff into a blockingqueue, and your lazy-seq is reading from it and blocking as necessary

23:41 spoon16: using lein-cljsbuild I'm trying to require the cljs.repl namespace

23:41 https://gist.github.com/2403227

23:42 do I need to add a cljscript dependency in my project.clj?

23:42 other than the lein-cljsbuild plugin

23:42 wkmanire: muhoo: Do you use paredit?

23:43 emezeske: spoon16: Nope, that should always exist

23:44 spoon16: Wait, are you trying to start a cljs repl?

23:44 spoon16: wierd

23:44 emezeske: spoon16: Check this out: https://github.com/emezeske/lein-cljsbuild/blob/master/doc/REPL.md

23:44 drewr: emezeske: started using lein-cljsbuild and it really sped things up for me thanks!

23:45 emezeske: spoon16: I think my comment about that already existing is wrong, I was confused about what you were trying to do

23:45 drewr: That's great to hear!

23:45 drewr: had to drop back to lein1 and not use :whitespace but other than that it worked really well

23:45 any plans for lein2 support?

23:46 emezeske: drewr: It should be supported now; what version did you have trouble with?

23:46 drewr: version of lein-cljsbuild I mean

23:46 drewr: 0.1.7

23:46 emezeske: drewr: Huh, if that didn't work, it's a bug.

23:46 drewr: What went wrong?

23:47 drewr: emezeske: http://p.draines.com/133463402710643ce57ef.txt

23:48 emezeske: drewr: Interesting, let me look at that

23:49 drewr: gracias

23:49 emezeske: drewr: What version of lein2?

23:50 drewr: a sort-of recent 2.0.0-SNAPSHOT

23:50 emezeske: drewr: I think I released 0.1.7 just before the latest release

23:50 drewr: K

23:53 wkmanire: Yesterday in the mall I stopped in a tobacco shop. Not because I smoke, but because they cell all kinds of guy stuff, like cologne and knives and what not.

23:54 There I saw a Sudoku magazine and I remembered about representing data structures in Clojure.

23:54 How would you go about storing a Sudoku game board and passing it around as an argument?

23:55 You would need to be able to do all sorts of accessing on it to validate it.

23:55 they sell* bleh

23:56 emezeske: drewr: Unfortunately, the latest lein2 has more than one change that lein-cljsbuild has to support

23:57 drewr: I'll have to track things down and fix them

23:57 drewr: ok thanks

23:57 emezeske: wkmanire: Seems like a vector, or a vector of vectors would be fine

23:57 xeqi: I would use a vector of vectors

23:58 to start with

23:58 espeed: Will someone look at my multimethod attempt and let me know what I'm doing wrong: https://gist.github.com/2403336

Logging service provided by n01se.net