#clojure log - Jul 01 2013

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

2:36 kyled: Hello all, quick question about design patter. I'm writing some clojurescript to draw some stuff on the canvas element. I find myself having to pass around the canvas ctx to a lot of functions. This seems a bit repetitive and unnecessary...would it better to use def-type, pass in the canvas element, and then add the functions to the new type?

2:37 seems more like OOP that way, but ..again state isn't being preserved since drawing to an element does produce side effects

2:40 noidi: maybe instead of directly manipulating the canvas you could collect all your operations into a data structure, and then perform them once on the canvas e.g. using doseq?

2:41 e.g. you'd have a seq of operations such as [:line :red [10 10] [100 100]]

2:43 then your drawing functions would not need to know about the canvas object

2:43 kyled: noidie: i started to go that route, and works fine in some places. but in others it breaks. To sum up the project I am working on it's a lisp-like syntax for creating flowcharts quickly

2:44 so i broke it up where i have "boxes" and w/e text is in them

2:44 at some point though, i need to draw connecting lines. To keep things simple I have a function that when given text to create a box, you supply it with a canvas element, and the text you want in the box, and the box type

2:45 in that function it calculates the required dimensions of thie box

2:46 noidi: to you read the canvas' dimensions from the canvas object to perform the calculation?

2:46 kyled: noidis: not quite, i interact with the canvas to get the text height for example at one part, then later on in the code i use the calls to the canvas to do the drawings..but mabey you are right there is abit of code smell going on

2:47 before drawing i really should just have a collection of hashmaps or what have you,without dimension information

2:47 since dimension information can only be determined by accessing the canvas element (ie, getting the font height0 then figuring out how much spacing the lines will take up)

2:49 but anyways im at the point of drawing, and i have functions that look like this

2:49 noidi: nowadays I try to push all interaction with the world (i.e. side-effects) near the entry point of the system and keep as much of the system pure as possible

2:50 kyled: (defn drawLine [ctx ...]) (defn drawRect [ctx ..]) (defn drawNode [ctx ...])

2:50 so mainly , my question is for all my draw functions, since they operate on the same canvas context

2:51 does it make sense to remove the 1st parameter?

2:52 i think it will clean up my code a bit, since im not having to pass the same thing around to a whole bunch of functions

2:55 noidi: you could use a dynamically bound var *ctx* to eliminate the parameter, but I believe that style of API design is generally frowned upon in the Clojure world

2:55 kyled: noidi: exactly...

2:55 thats why i was thinking about using closure scope or something

2:56 again, all this canvas stuff isn't really functional..i think of the canvas as IO bound stuff with side effects

2:57 anyways i have to leave for the night, thanks for your input. i will leave the window open incase you would like to add something.

2:58 noidi: quick q though, do you think defprotocl would be fitting though?

2:58 i mean, deftype? im not sure if that is the right instruction, im still new to clsure

2:59 but i thought you can supply an argument, and w/e method is in the deftype arguments is accessible by all the functions defined in the type

3:06 noidi: kyled, you'll still have to pass in the "this" parameter manually with protocols

3:09 I have no idea about your problem domain, but I think you could separate the drawing to three phases: 1) form an abstract model of the graph (e.g. "a box with text 'foo'"), 2) build a sequence of drawing operations required to render the model (e.g. [:line [10 10] [5 100]]), 3) perform the operations on the canvas

3:10 (1) would not need the canvas at all, (2) would need only some data obtained from the canvas (e.g. the text height), (3) would need the canvas, but there would only be a small number of primitive drawing commands that would need the canvas as an argument

3:11 if you feel like half your functions need the canvas as an argument, I suspect you might be conflating calculations about the chart with rendering the chart

3:18 amalloy: i like noidi's approach. but instead of a sequence that has to be "interpreted" by your drawing code, i'd suggest instead building up a lambda that eventually wants to be called with the canvas

3:19 you would probably also learn a lot from watching the SICP lecture (or reading the chapter) on the importance of abstraction barriers, since they use drawing as an example case study

3:20 really it applies to any domain, but it will feel extra-topical at the moment, kyled

3:43 noidi: kyled, another presentation that you might find helpful is Stuart Sierra's Thinkin in Data http://www.infoq.com/presentations/Thinking-in-Data

3:43 it has a bit about separating side effects from the code that calculates which side effects should occur

3:44 turtil: [M ?M/quit

3:46 ddellacosta: hmm…is there a way to ensure that you use the same version of CLJS across everything (libs/plugins) you have loaded in your project.clj?

7:37 jtoy_: is clostache or stencil the recommended choice for a mustache implementation?

7:47 dark_element: jtoy_ i use stencil. Works flawlessly and follows mustache spec pretty well

7:54 jtoy_: dark_element: thanks

9:12 BeLucid_: Hello all, I have a macro question. What's the right way to share something a macro "learns" at runtime with the body? As a simplified example: https://gist.github.com/belucid/5900560

9:13 Obviously in the real world case, I have something more interesting to share with the body than [let foo "bar"], but this example is sufficient to capture my dilemma.

9:13 What's the right way to let the body code take advantage of something that's been calculated by the macro code.

9:14 ucb: BeLucid_: normally I'd use autogen'ed symbols like foo#, however your body doesn't know these names beforehand :/

9:14 BeLucid_: right... I tried that path

9:14 and the macro is then generating the right thing with a let

9:15 but the body has no way of knowing what the symbol is going to be

9:15 ucb: indeed

9:16 BeLucid_: my real world use, in case it spurs any ideas, is a macro with-collection. It takes a collection name... does a bunch of DB look ups and checks and things, and if everything is all good, it needs to provide the collection id to the body.

9:18 need the macro so all the cruft about finding and validating a collection goes away and isn't duplicated, but everything that needs the macro only has the name but needs an id

9:19 here's a (non-working) start at the real thing: https://gist.github.com/belucid/5900620

9:20 coll-id# is autogen'ed, so then body doesn't know what it is, or coll-id gets qualified by the macro and is then not a valid form for the let.

9:21 Either way, no love. Seems that this would be a not so incredibly uncommon case. But so far I haven't found anything that addresses how to do it.

9:34 ahh... it seems that def, thereby creating a var that's local to the macro (I presume) works: https://gist.github.com/belucid/5900746

9:35 thanks for being a sounding board everyone, if anyone has any commentary on how idiomatic or not that is, I'm all ears

9:36 hyPiRion: BeLucid_: It's a silent time now, too early/late for Americans

9:37 You may want to post it on the google group or come back in some hours

9:37 (And I'm a bit busy, so I haven't time to look at it now, sorry)

9:37 BeLucid_: I'm an (unconscionably early rising) East Coast American. I guess that makes me a singleton.

9:38 No worries, I'll post it to the group, thanks.

9:39 hyPiRion: oh, it's later than I thought it was

9:41 BeLucid_: yeah... turns out the def doesn't work in the real world case, only worked in the REPL cause the macro and it's use were in the same ns.

9:41 In the real world case, I get: CompilerException java.lang.RuntimeException: Can't create defs outside of current ns

10:46 dnolen_: timer coalescing in core.async is kinda genious

10:51 bbloom: github really needs to fix their shitty news feeds

10:52 literally one solid page of "$user starred brandonbloom/asyncx"

10:52 surely that should be like retweets or favorites on twitter

10:52 compressed down to "22 people starred brandonbloom/asyncx"

10:56 drewolson: quick question about core.async. I'm using map with <! in go blocks and i'm seeing an error. am i doing something wrong? https://gist.github.com/drewolson/5212fcb3ae46f4c58bd6

10:57 pjstadig: drewolson: map is lazy so you probably need to wrap your map call in (doall ...)

10:57 drewolson: pjstadig: ah :) that maps perfect sense, thanks

10:58 it also explains why it works if the function passed to make makes its own go block

10:58 s/make/map/g

10:58 hyPiRion: mapv perhaps

10:59 gfredericks: man I've been doing (.printStackTrace *e) in my repl for months thinking it was a bug that it wasn't working

10:59 time to start using pst

10:59 bbloom: you can't use <! in a higher order fasion anyway

10:59 drewolson: bbloom: interesting. seemed to work for me to use <!! in a map

10:59 bbloom: <!! works

10:59 not <!

10:59 https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L77-L81

11:00 go blocks have lexical, not dynamic extent

11:00 drewolson: ok, that's a big help, thanks

11:01 bbloom: i dunno what the main core.async people would say, but you should try to use the double bang operations only at the "edges"

11:01 prefer go and single bang operations everywhere in the middle, since those will be portable to cljs (where there are no blocking threads) and will be multiplexed onto os threads

11:01 drewolson: bbloom: that was my intuition as well. basically only to block the "main" thread when waiting on work

11:02 bbloom: yup

11:02 drewolson: here's what i came up with for a higher order, non-blocking map: https://github.com/brandonbloom/asyncx/blob/master/src/asyncx/core.clj#L291-L305

11:03 drewolson: bbloom: here

11:03 here's my pmap implementation from last week: https://gist.github.com/drewolson/5888365

11:04 bbloom: cool

11:05 heh, so many channels haha

11:05 it feels kinda weird at first, being used to working w/ sockets and the like where you have like ONE or TWO of them

11:06 jtoy_: i hate the name go blocks

11:06 it sounds like it means its coming from go the language

11:06 bbloom: having cheap first class channels takes some getting used to

11:06 jtoy_: bbloom: are you using them already for projects?

11:06 bbloom: not beyond my little learning experiments

11:07 i don't have a strong need for them yet

11:07 drewolson: bbloom: yes. i've been experimenting with go for a while so i'm a bit more used to it. but i'm not a fan of go's type system at all, so this is a breath of fresh air

11:08 hyPiRion: drewolson: haha, the type system is funny

11:08 drewolson: bbloom: i think if you only implement it using a single channel, you'd at least need to make it buffered so that the computation was actually parallel. otherwise it would just be lazy, which it already is

11:22 bbloom: drewolson: my library isn't concerned with parallelism. only concurrency

11:23 drewolson: makes sense

11:23 supersym: using positions instead of .indexOf, positions is a lot faster. When I use it to lookup nth, its exactly the other way around

11:23 does that make any sense?

11:26 oh well..guess I care less about the 'how' now :)

11:36 timvisher: i'm trying to view a matrix in incanter and having trouble. i figured i'd simplify and go for getting something directly out of the docs to work and that also fails. i get an exception stating that there is no multimethod dispatch value for clatrix.core.Matrix. https://gist.github.com/timvisher/5901834

11:36 am i doing something wrong or are the docs out of date?

11:50 supersym: timvisher: I recall having that somewhere as well, don't think I found the solution tho...definitly clatrix as well

11:57 timvisher: supersym: good to know i'm not alone. :)

12:01 SegFaultAX: It's gonna be a good day: BART is went on strike + an excessive heat warning in the east bay (100+ everywhere). Yay Mondays!

12:01 BART went*

12:01 bbloom: SegFaultAX: meanwhile, here in NYC, there was a flash flood warning

12:01 weeeee

12:01 SegFaultAX: bbloom: I'm sorry :(

12:02 bbloom: not nearly as bad as being unable to get to work

12:02 WFH day!

12:02 enjoy

12:04 SegFaultAX: Haha, yea.

12:05 gfredericks: does anybody know if org-babel and nrepl.el have any chance of working with each other?

12:06 the org-babel docs for clojure talk about version 1.1.0-alpha-SNAPSHOT and swank and similarly ancient concepts

12:06 kmicu: gfreII RC yes

12:07 gfredericks: IIRC yes, it works

12:08 gfredericks: good to know

12:11 kmicu: You can find an example config in Stuart Sierra's dotfiles and in google ;]

12:12 hiredman: gfredericks: yes

12:14 gfredericks: https://gist.github.com/5902187 is what I found somewhere on the internet that makes it use nrepl

12:15 gfredericks: hiredman: yeah, same thing stuartsierra has I think; thanks

12:18 holy crap it just worked

12:19 kmicu: gfredericks: https://www.refheap.com/16234 this is my last config, but I did not use it for a time

12:25 kovas: let the hacking commence

12:29 alandipert: kovas: rage

12:29 kovas: alandipert: f to the yea

12:31 manutter: mental block time: there's a technical term for things like "this" (in Java), where it's just defined for you. What's that term?

12:33 you can build them in Clojure using macros but that may or may not be a good idea

12:33 technomancy: manutter: anaphora, I think

12:33 manutter: that's it!

12:33 been on the tip of my tongue all day

12:33 thanks

12:39 dnolen_: OK some subtle core.async bugs around alts! CLJS support fixed in master

12:41 bbloom: dnolen_: nice

12:42 dnolen_: yeah, going to port the Go example to CLJS now :D

12:43 mrb_bk: baller

12:46 bbloom: kovas: (Math/pow f yea)

12:47 kovas: lol

12:48 kmicu: Why second example prints, but first not? https://www.refheap.com/16235

12:49 devn: big ballin'

12:50 technomancy: AC/DC reference?

12:50 devn: sure, why not?

12:53 pbostrom: or Fat Pat

13:17 atyz: Aside from korma, are there any good ORM's worth looking at?

13:18 seancorfield: ORM sort of implies Objects...

13:31 enquora: just watched a video of dnolen talk on clojurescript with browser wired up to repl for live demonstration. what is the simplest way to configure something like that?

13:32 bbloom: it's not super simple at all… lein cljsbuild is your best bet, but the browser repl is a bit tricky to configure

13:32 enquora: am starting a project to create PDF generator that must run on server, in browser, an iOS, and am trying to find a starting point

13:32 nDuff: won't Light Table pretty much automate that (for its built-in browser)?

13:32 enquora: I'm not religious about the coding environment

13:33 perhaps I'm better serializing results to file and using Preview on OS X for testing then?

13:34 and worrying about the cljs part once the PDF generation code is working somewhat

13:37 pbostrom: enquora: piggieback is also an option to use with nREPL https://github.com/cemerick/piggieback

13:37 enquora: Is Light Table generally usable for real work in current state?

13:39 nDuff: enquora: My inclination is to say "no". Last time I did cljs, I did the work to set up a proper browser repl with emacs (which wasn't really very much work).

13:39 enquora: pbostrom: what does 'clojurescript repl' mean in this context?

13:39 nDuff: enquora: ...but it's been long enough that I'm not able to recount the steps.

13:39 enquora: sorry for being dense - have had *very* long last week and am having trouble grokking at the moment

13:40 need to interactively test results of PDFs I'm building as they will be viewed in web browser

13:40 pbostrom: enquora: it supports Rhino and browser REPL

13:41 enquora: pbostrom: so one might enter cljs in browser console and have it execute?

13:42 pbostrom: enquora: no, enter cljs in your normal REPL process, whether that's running in your terminal, or inside emacs

13:42 nDuff: enquora: ...so you want to enter cljs in _your browser_, rather than enter it in _your editor_ and have it executed in your browser?

13:42 enquora: no, want to code on desktop with keyboard, transparently generate PDF and send to browser

13:43 want to code in normal environment

13:43 devn: enquora want code in normal environment!

13:43 :)

13:43 enquora: sorry

13:43 brain not working

13:43 devn: lol im just messing with you

13:43 pbostrom: enquora: what do you use for normal Clojure editing and REPL development

13:43 enquora: am in Calgary, have been working in flood zone for last week

13:44 Raynes: sorry cant brane today

13:44 i got the dums

13:44 enquora: brain not working normally yet

13:44 pbostrom: having done anything serious in clojure yet

13:44 normally I'm a vim person

13:45 but am happy to use emacs, evil mode or not

13:45 have lisp experience from decades ago, but no real clojure experience

13:46 have need to create bit-identical PDFs in web browser, on server, and in native iOS app. Am now tackling library to do so

13:46 pbostrom: ok, well, lein has a nice REPL, nREPL, built in, you can run piggieback on top of that, another nice option is the lein cljsbuild plugin which also has a REPL

13:48 enquora: piggieback creates some sort of local http server then?

13:50 pbostrom: yes, on port 9000, although I think the actual work of creating the server is done by the core cljs libs, piggieback just sets up the plumbing between nREPL and the core cljs REPL

13:59 enquora: thks

13:59 dnolen_: Rob Pike's Go multi search timeout example now works in core.async CLJS http://gist.github.com/swannodette/5903001

14:00 kmicu: nice

14:01 edbond: dnolen_, can you add a link to original?

14:03 dnolen_: edbond: to the Go code?

14:03 edbond: dnolen_, yes, where can I see "Rob Pike's Go multi search timeout example"?

14:03 bbloom: w00t. i'm glad i ported that little snippet. it's seeing a lot of milage :-)

14:05 edbond: dnolen_, ok, I found slides and presentation, anyway.

14:05 dnolen_: edbond: updated

14:05 with direct link to slide

14:05 edbond: dnolen_, yknow, for famous LOC comparision :)

14:06 dnolen_, great, thanks.

14:08 bbloom: i really want ><! :-)

14:08 or <>!

14:09 or something that somehow makes the order of arguments not ambiguous :-P

14:09 edbond: :-D put-or-take

14:10 bbloom: no, i want take-then-put

14:14 go func() { … } () feels so heavy weight now :-)

14:15 edbond: in go, what i want is basically "<- <-"

14:16 http://play.golang.org/p/LKM85cobjd

14:17 kovas: i prefer words over symbols for everything but the very most common ops

14:17 so move! or route! or something

14:17 bbloom: sure, my biggest concern is the extra parens :-)

14:17 kovas: i agree

14:17 bbloom: i like move!, but i can never decide if i want (f src dest) or (f dest src)

14:17 technomancy: a little perl now and then is good for the constitution

14:18 bbloom: whut

14:18 who puts the destination first?

14:18 kovas: oh god, flashbacks of ln -s

14:18 bbloom: technomancy: assignment operators.

14:18 (set! x 1)

14:19 it also depends on whether you want variadic sources or variadic destinations

14:19 kovas: i think "from here to there" is the easiest to remember

14:19 a la mv

14:19 bbloom: mv some list of source files to here

14:19 link this-file to each of these locations

14:19 technomancy: kovas: unless you're in an RTL language =)

14:20 bbloom: the real problem with ln is that the docs are ambiguous

14:20 it says: ln [options] source_file … target_dir

14:21 enquora: pbostrom: I hope I'm not putting the cart before the horse worrying about setting up a repl to test PDF out in browser first. Final code will be packaged as javascript and jvm library - I'm naively assuming that there are no particular problems generating/packing the code once it is complete? The actual generation of the PDFs is dauntingly difficult and I'm anxious to get going on development of that, which will involve learning which p

14:21 of Clojure I need, too.

14:21 bbloom: but it's referring to the source and target OF THE LINK

14:21 not the action of creating the link

14:21 *d'oh*

14:21 kovas: technomancy: never seen that before, cool

14:22 TimMc: bbloom: Ugh, yeah. alias ln='ln -n' has saved my butt a few times.

14:22 kovas: the docs are terrible

14:22 i can never remember

14:25 MrGarlic: what are the advantages of clojure over lisp and/or scheme

14:26 bbloom: MrGarlic: http://clojure.org/rationale

14:26 awwaiid: MrGarlic: running on the jvm means accessing a bunch of libs, to start with. After that the first thing that comes to mind is having just a touch of extra syntax for hashes and vectors and sets and such

14:26 technomancy: MrGarlic: clojure is lisp

14:27 awwaiid: bbloom++ # thanks

14:27 bbloom: technomancy: presumably he means common lisp

14:27 MrGarlic: technomancy: a type of lisp?

14:27 nDuff: MrGarlic: A member of the LISP family of languages.

14:27 MrGarlic: Common LISP is a specific language. LISP is not.

14:27 pbostrom: enquora: actually, I was going to mention that, it might be better to start with the lein cljsbuild plugin to first compile your cljs as a static js file. Once you get that loaded in your browser and get a feel for the development cycle, then you can add the browser repl, you can certainly be ver productive just autocompiling your cljs and reloading your browser window

14:28 MrGarlic: nDuff: It's not a dialect?

14:29 nDuff: *shrug*.

14:29 enquora: pbostrom: am going to sleep on this. it's a national holiday here and I need a break. I've been procrastinating on this for ages though, and wanted to force myself to get going

14:29 another part of the problem I didn't mention is that the PDFs contain many html-style tables, and will need constraint management

14:30 need to brush up on my prolog

14:30 err, core.logic

14:31 constraint satisfaction, I should say

14:31 gfredericks: so I have, a couple times, somehow or another by playing with core.async gotten my machine into a state where all cores are running at 100% doing nothing in particular

14:32 enquora: MrGarlic: clojure is *a* lisp

14:32 in my case, the advantage is that I need lisp-level chops to generate PDFs on server and in web browser without plugins

14:33 Clojure has a nice javascript target called Clojurescript

14:33 such things exist for Scheme too (Gambit, Chicken), but Clojure has the traction

14:34 technomancy: chicken targets JS?

14:36 enquora: I might be forgetting, but I think emscripten is your friend there

14:37 At one time I was planning to meet out need for native iOS execution by using the Scheme target for Clojure, then compiling to native, so I may be crossing wires

14:38 Not necessary now in any case, with iOS 7 and public API for JavascriptCore independent of browser context

14:38 makes me sad that I can't just use Quartz to generate the PDFs though :-(

14:40 technomancy: I've never heard of anyone generating PDFs in the browser

14:40 enquora: that's because it's never been done on this scale

14:40 technomancy: seems very unlikely you could get pixel-for-pixel fidelity across any two runtimes

14:40 enquora: technomancy: use data url to deliver the file

14:41 not with existing PDF libraries

14:41 but by writing at the core PDF primitive level it's easy

14:41 for some definition of 'easy'

14:42 the real problem is that these PDFs are mostly tabular, and need some serious attention to typesetting principles

14:42 so constraint satisfaction is a big issue too - column widths, font sizes and kerning for type placement

14:42 white-space management

14:43 Haven't begun to get my head around representing the Carousel Object System in clojure yet, either

14:44 which is the basis for the PDF format

14:44 all of which is to say, if anyone else has this problem, the line for volunteers forms here

14:47 technomancy: here's the one instance that's tried it: http://jspdf.com

14:47 It's only useful for trivial stuff though, and has no concept of real typesetting

14:59 gfredericks: seancorfield: ping

15:07 murphy607: hi

15:08 i have a problem to get clojurescript running

15:08 jcromartie: murphy607: go ahead!

15:08 murphy607: I have just done this, myself, so I hope i can help

15:08 murphy607: the repl-browser

15:08 creates problems

15:08 (require '[cljs.repl :as repl])

15:08 (require '[cljs.repl.browser :as browser])

15:08 (def env (browser/repl-env))

15:09 if i do this i get the followig errtor:

15:09 java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.LazySeq

15:09 i use clojure in version 1.5.1

15:10 jcromartie: running that exact code?

15:10 murphy607: yes

15:10 this was cut and paste

15:10 jcromartie: have you tried them one at at ime?

15:10 one at a time

15:11 murphy607: yes

15:11 Cho4: hi

15:11 jcromartie: murphy607: and it's (def env (browser/repl-env)) that throws the error

15:11 murphy607: yes

15:11 Bronsa: murphy607: which version of cljs are you using?

15:12 jcromartie: murphy607: using the repl script that comes with ClojureScript, (which uses Clojure 1.5.1), I have no problem evaluating your code

15:12 murphy607: are you in a REPL?

15:12 murphy607: [org.clojars.bartonj/clojurescript "1.0.1-SNAPSHOT"]

15:12 Bronsa: that's not the official clojurescript

15:12 and it's probably an outdated one

15:13 murphy607: ahhh ok...

15:13 Cho4: https://www.refheap.com/16239 how can i make it work?

15:13 murphy607: Bronsa: thats the one i found... but you are probably right

15:13 Cho4: basicly i need to acess dynamic segment :id from context b-routes.

15:14 Bronsa: murphy607: [org.clojure/clojurescript "0.0-971"]

15:14 murphy607: Bronsa: i guessed that it is a problem with tthe clojure versions...

15:14 Bronsa: err

15:14 murphy607: Bronsa: thx

15:14 Bronsa: murphy607: [org.clojure/clojurescript "0.0-1835"]

15:14 murphy607: k

15:15 Cho4: weais it even possible?

15:15 murphy607: Bronsa: it works! thanks

15:16 jcromartie: thanks too :)

15:18 Cho4: https://github.com/weavejester/compojure/blob/1.1.3/src/compojure/core.clj#L180 not sure what happens with args

15:26 supersym: enquora: thats pretty sweet! ...didn't know it either

15:26 Cho4: help

15:42 amalloy: Cho4: that looks to me vaguely like it ought to work. instead of periodically crying "help" with no clarification, why don't you tell someone what happened instead?

15:47 CapnKernul: Are (:use [foo :only [bar]]) and (:require [foo :refer [bar]]) the same? Is one more idiomatic than the other?

15:49 Cho4: amalloy: it just doesn't sees id from b-routes.

15:51 supersym: CapnKernul: http://stackoverflow.com/a/872049/2508931

15:52 pbostrom: supersym: CapnKernul: that SO answer is a bit dated, I think :use is considered deprecated in favor for :require :refer, although you will still see quite a bit of references to :use in new code/blog posts, so I doubt it will ever go away

15:52 Raynes: muhoo: ninjudd requests a sound sample of your fretless guitar.

15:57 CapnKernul: great, thanks. :)

16:03 dnolen_: core.async + core.match is tasty http://gist.github.com/swannodette/5903968

16:03 core.match + core.async is tasty http://gist.github.com/swannodette/5903968

16:04 ro_st: dnolen_: howdy

16:04 kmicu: double logic all the way

16:04 bbloom: dnolen_: YOU'VE GOT YOUR ERLANG IN MY CLJS

16:04 awesome.

16:05 can you match on multiple channels w/ alts?

16:05 ro_st: is there somewhere i can read up on this channel malarky?

16:05 bbloom: ro_st: 2 places, the clojure blog & the go community

16:05 ro_st: i've never encountered it before. and i want to understand it

16:05 bbloom: clojure.com/blog/2013/06/28/clojure-core-async-channels.html

16:05 talks.golang.org/2012/concurrency.slide

16:06 ro_st: awesome, thanks Brandon

16:06 enjoyed your talk in Oslo, dnolen_

16:07 bbloom: dnolen_: presumably matching is a read-only operation. so could i match on a "channel group" or something & get multiplexing?

16:07 (this is just a random though, no idea if it's a good idea)

16:08 ro_st: so in that latest gist from dnolen_, we have two independent channels that cause the handler to fire whenever they are written to with >!

16:09 so the go macro is like callback retardant

16:09 dnolen_: core.match and core.async together are tasty http://gist.github.com/swannodette/5903968

16:09 bbloom: …. you said that already… twice… lol

16:09 ro_st: "callback retardant", while entertaining, is putting it very simply :-)

16:09 kmicu: triple logic all the way

16:09 hyPiRion: dnolen_ is broken D=

16:10 ro_st: i smell an emacs lisp keybinding

16:10 hyPiRion: he just repeats himself!

16:10 bbloom: I KNEW IT! of course he had to be a robot!

16:10 somebody reboot him

16:10 hyPiRion: $reload

16:10 lazybot: hyPiRion: It is not the case that you don't not unhave insufficient privileges to do this.

16:10 hyPiRion: whoops, wrong bot.

16:11 bbloom: heh

16:11 ro_st: bbloom: so i'm right about the other bits?

16:12 bbloom: ro_st: yeah, you pretty much got it

16:12 ro_st: wicked

16:12 bbloom: but there are some other interesting things going on worth noting

16:12 for example, the sliding-buffer calls

16:12 dnolen: amalloy: seqable article is history is there something you want to know from it?

16:12 bbloom: if multiple mouse move messages come in while the handler is busy doing other stuff, only the last message will be delivered

16:13 amalloy: dnolen: someone had asked a question on SO about how to do something similar, and i was hoping to link them to your implementation

16:13 bbloom: much more sophisticated (and pleasant!) than callbacks

16:13 dnolen: sorry for the double post earlier, IRCCloud client was effed up

16:14 ro_st: bbloom: and that's controlled by the buffer size?

16:14 dnolen: bbloom: hmm maybe, re: multiplexing

16:14 bbloom: dnolen: good cover up…. BOT.

16:14 dnolen: hehe

16:14 amalloy: yeah, it's a simple idea, I should probably repost that

16:15 bbloom: ro_st: you can have buffered or unbuffered channels. and if you have a buffer, then you can have one of 3 (currently) policies: drop newest, drop oldest, and block on full

16:15 dnolen: and you can of course provide your own buffer

16:16 ro_st: gotcha

16:17 dnolen: ro_st: thanks

16:17 ro_st: so in this case, on each pass in the while at the bottom, alts! is completing one of the two buffered channels and returning the map for the handler's match to destructure

16:18 dnolen: ro_st: yeah, one thing I realized - keep your go blocks small and call out as soon as possible

16:18 putting a match expression in a go block is a recipe for disaster

16:18 ro_st: and if we made the buffer size bigger, alts! would consume the subsequent 'queued' ops on the channel on subsequent passes

16:19 that makes sense. i should think you'd want to keep just your channel interactions inside go

16:19 dnolen: yeah

16:20 gfredericks: should creating 10000 go blocks be relatively cheap?

16:20 it maxes out all 4 of my cores for ~10 seconds

16:21 ro_st: would it make sense to wire network interactions up with channels? ie, (go (let [result (ajax action)] (do something with result)))

16:21 bbloom: gfredericks: can you share your benchmark?

16:21 gfredericks: bbloom: yeah one sec

16:23 bbloom: https://www.refheap.com/16243

16:23 bbloom: heh… are you sure the printing isn't what's killing you? :-P

16:23 gfredericks: me?

16:23 bbloom: yeah

16:23 gfredericks: oh that

16:23 I forgot I printed; but no that should just be a few times

16:24 only once for each eval of line 10, no?

16:24 dnolen: gfredericks: I think you're going to create a lot of contention to read of that channel?

16:24 channel ends points are locked

16:24 gfredericks: okay, if this is expected that's fine; just wanted to understand what I was doing that was unorthodox

16:25 so 30,000 go blocks listening on 1 channel is a bad idea?

16:25 atyz: Does anyone know if its possible to pass in a connection string like this: jdbc:mysql://localhost:3306/content_vu?user=root to korma? Or will I have to parse it for the different components?

16:26 bbloom: lol just discovered i had a zombie vim instance trying to eval some async code sucking up one of my cores

16:26 dnolen: gfredericks: it seems like a weird design to me, but I dunno

16:26 bbloom: my computer didn't feel any slower haha

16:27 gfredericks: dnolen: certainly weird; I'm just trying to understand the boundaries

16:27 ro_st: yay multi-core. shows you how much of your software isn't multi-core :-)

16:28 bbloom: dnolen: that region inference thing is sweeeet

16:28 dammit too much cool stuff

16:28 how will i ever get any actual work done?

17:13 kmicu: I C-g nrepl-toggle-trace and killed my emacs :(

17:14 clojurenewb: hi… I'm looking for the 'rest' equivalent of 'nnext'… but can't seem to find it… wondering if I am missing something ?

17:15 bbloom: clojurenewb: i don't think there is one. just define one (def rrest (comp rest rest))

17:16 * technomancy coughs *method-missing*

17:17 clojurenewb: bbloom: yeah thought that might be the case, just checking :-)

17:18 * technomancy idly gestures towards https://github.com/technomancy/bus-scheme/blob/master/lib/bus_scheme/cons.rb#L103

17:19 technomancy: huh, the guards must be off-duty today

17:19 probably on strike to show solidarity with BART

17:21 amalloy: technomancy: https://groups.google.com/d/msg/clojure/CanBrJPJ4aI/S7wMNqmj_Q0J - who says only ruby can have confusing features like method-missing?

17:21 technomancy: ~guards

17:21 clojurebot: SEIZE HIM!

17:23 iwo: hey, does anyone know what the best/simplest way to get clj-http to send a map as json (in the body of a request) is?

17:24 is there no other option than to serialize the map into a string representation of json before sending to clj-http?

17:24 bbloom: amalloy: surely the problem with method-missing is the context sensitive nature of it

17:24 amalloy: if vars were generated to created to back symbols resolved at module load time, that wouldn't be so bad

17:25 and module load time ~= macro expansion time

17:25 so what could go wrong? :-)

17:26 also, this reminds me of swizzling in shader languages, which is a great feature

17:27 ie you can have some vector and do things like v.xxyy

17:27 or v.zyx

17:27 or whatever you want

17:28 pbostrom: iwo: the cheshire lib by dakrone will serialize your map, it's probably outside the scope of what an http client should do

17:33 iwo: pbostrom: so, are you suggesting calling 'encode' from cheshire before adding the contents to under the :body key?

17:34 it's strange because clj-http will perform 'coercion' (parsing json data to a map) on a response body, but not a request body

17:37 brehaut: iwo: you may need to set the content type header on the request before clj-http will encode it

17:38 iwo: brehaut: this doesn't seem to make any difference :(

17:38 seangrove: Should we be able to map over a javascript array in clojurescript?

17:38 I'm getting and error "Uncaught Error: is not ISeqable"

17:39 iwo: it looks like the only way to do this is: set all properties as form-params, set :content-type :json in the request map, use the wrap-form-params middleware

17:39 easier to call 'encode' i think

17:40 brehaut: iwo: and you have the appropriate middleware?

17:40 dakrone: iwo: you should be able to do (http/post "http://aoeu.com" {:body (encode {:my :thing})})

17:40 SegFaultAX: callen: Ping.

17:41 iwo: darkrone: yes, i think i'll just call encode, it seems simpler than the middleware+form params route

17:41 dnolen: seangrove: it's working for me here

17:41 technomancy: seangrove: looks like clojure accidentally an error message

17:42 bbloom: blah. probably a (print nil)

17:42 er str nil, i mean

17:42 iwo: darkrone: what do you think about the following change to clj-http: if json-enabled? and :content-type :json, and :body contains a collection, then use 'encode' on the body automatically (?)

17:45 dakrone: that would make the case when sending a string body kind of confusing, I'd personally rather have the encoding be explicit, especially because it's pretty easy to do right before sending

17:48 iwo: dakrone: i think it would be really nice to have something similar to :as :json, but for the request

17:49 seangrove: Ah, I think it may be mistaking null/strings for arrays...

17:55 gt``: hi looking for some help on clojure and odbc

18:49 onceUponATime: I have $CLASSPATH set to ".:/usr/local/clojure-1.5.1/target:/usr/local/clojure-1.5.1" and "jline-0.9.94.jar" under "/usr/local/clojure-1.5.1/target" and when I run the command: "java -cp jline-0.9.94.jar:clojure-1.5.1.jar jline.ConsoleRunner clojure.main" I get the error message: "Error: Could not find or load main class jline.ConsoleRunner"

18:49 Any idea??

18:49 lazybot: onceUponATime: What are you, crazy? Of course not!

18:50 technomancy: onceUponATime: don't set $CLASSPATH, and try using absolute paths

18:50 (assuming you have a good reason to be constructing `java` invocations by hand)

18:50 amalloy: also -cp overrides $CLASSPATH anyway

18:50 technomancy: oh, also jline 0.x is pretty terrible

18:50 onceUponATime_: I tried that and got the same thing

18:51 well do we have a choice?

18:51 amalloy: onceUponATime_: why is clojure in /usr/local anyway? a system-wide install of clojure is a pretty bad idea; use lein instead if you have any choice at all

18:51 onceUponATime_: it runs only if I go to target directory and run from their

18:52 why bad?

18:53 technomancy: onceUponATime_: it assumes you're only going to use one version of clojure at a time

18:54 onceUponATime_: yes correct, am I missing something? do I need multiple clojures?

18:54 yes correct, am I missing something? do I need multiple clojure versions that is?

18:55 technomancy: typically each codebase you work on will declare which version of clojure it's designed to work with

18:56 onceUponATime_: Oh, I like that, didn't think of that. But then this assumes the language may change a lot down the road?

18:56 nDuff: onceUponATime_: It doesn't necessarily change _a lot_, but you'll still have libraries that require a given version.

18:56 onceUponATime_: mm

18:57 technomancy: onceUponATime_: it assumes you can't depend on backwards-compatibility between various versions of a library, and it treats clojure as just another library.

18:57 nDuff: onceUponATime_: ...and letting leiningen take care of starting the version you need takes the effort out of your hair.

18:57 onceUponATime_: mM

18:57 nDuff: onceUponATime_: ...you'll be using leiningen to manage your libraries' versions anyhow, so why not let in manage your language runtime too?

18:57 onceUponATime_: yea

18:57 i c

18:58 nDuff: s/let in/let it/

18:58 onceUponATime_: where does leiningen install clojure?

18:58 nDuff: onceUponATime_: Into your Maven cache (~/.m2), where all your other libraries live.

18:58 ...or maybe it's your Ivy cache. Doesn't really matter.

18:59 onceUponATime_: mm

18:59 ye

18:59 * nDuff glances askew at the two-character lines

18:59 onceUponATime_: alright thanks for the advice

19:00 amalloy: nDuff: character rationing

19:00 this way if the NSA has an equal likelihoof of looking at each character, they're less likely to notice him

19:01 seangrove: dnolen: seems to specifically happen with clojurescript 0.0-1835, not sure why. Something weird about map.

19:02 dnolen: seangrove: hrm, I just tried against master there's not much difference

19:02 seangrove: Ah, bummer, because piggieback depends on that version

19:02 dnolen: seangrove: are you sure you don't have an older version somehow?

19:02 1835 works as far as I know

19:02 seangrove: did you try (seq (array 1 2 3)) ?

19:02 seangrove: Is there a runtime var available that I can check in the browser console?

19:03 dnolen: no there was a patch lying around for that, should probably get around to actually applying to make this easier

19:03 seangrove: I'll try it that line

19:03 dnolen: I think it doesn't apply any is why I haven't done it yet

19:03 onceUponATime_: does clojurescript support concurrency?

19:04 dnolen: onceUponATime_: not really but there's some sweet process coordination now with core.async

19:04 onceUponATime_: aha

19:08 technomancy: any heroku users around interested in testing out some clojure buildpack changes before I roll them out to everyone?

19:13 Raynes: technomancy: Do I have to sell my soul?

19:13 technomancy: I can give it a shot for tryclojure if you'd like, since it is super simple.

19:13 (and the only thing I still run on Heroku)

19:13 technomancy: cool, I'll msg you

19:24 seangrove: dnolen: I've tracked it down to arrays that come from a different context, map does something strange with them

19:30 Yeah, looks like this is probably the problem: https://github.com/clojure/clojurescript/commit/46eb8627627a3b027cd0758ea73da50216a42fd2

19:34 Since cljs doesn't supprt objects coming from another context, I modified js->clj in my own utils that I use when I can guarantee that it's just basic types: https://www.refheap.com/6830dbd541df305be517d9eca

19:34 Now even this is failing though from that commit

19:35 How can I convert an array from another context to a clj object? I could do some janky thing where I eval javascript that reads through the keys and builds up a value-identical array in the local context, but that wouldn't be super fast

19:36 Fast, super, or pleasant, really

19:38 Definitely going to be happy when we can find a way to stop dealing with objects created in another context

Logging service provided by n01se.net