# #clojure log - Nov 27 2012

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

0:00 bbloom: clj_newb_2345: hm, might be just because all the hot spots have been inlined into your program

0:00 clj_newb_2345: my cojurescript code is so shitty that my laptop's fan audibly spins up when I run my code

0:00 bbloom: is it faster? heh

0:00 clj_newb_2345: it's interactive gui; don't have a nice test suite yet

0:00 bbloom: clj_newb_2345: you know what they say right? lisp is two languages: one for writing programs fast, and another for writing fast programs :-)

0:01 clj_newb_2345: why hasn't someone written macros for writing fast programs fast?

0:01 i'm sorely tempted to switch back to java grpahics 2d

0:01 dnolen: bbloom: source mapping is making me realize two things - it's insane that we don't have position information on symbols - and the CLJS compiler doesn't generate proper AST for many things.

0:02 bbloom: dnolen: yes, the AST is broken in a whole bunch of places

0:02 dnolen: clj_newb_2345: problem #1 for fast graphics - SVG

0:02 bbloom: dnolen: i had a core.logic idea: data validator!

0:02 clj_newb_2345: dnolen: oh, don't use svg?

0:02 dnolen: I was hoping to write something like mathjax, but interactive

0:02 dnolen: clj_newb_2345: it really depends

0:02 clj_newb_2345: dnolen: what should I use instead?

0:02 bbloom: dnolen: you should be able to describe a validator for a clojure data structure and poof have it run

0:02 dnolen: clj_newb_2345: but if you have a lot of entities - it sucks

0:02 clj_newb_2345: dnolen: I'm actually using svg inside of chrome, using javascript to dynamically create/delete nodes

0:02 dnolen: I do, I need a single svg group for each character

0:03 clj_newb_2345: currently, I have a torture test of simulating a 80x20 terminal, where instead of using a svg:text per line, it's a svg:text per character

0:03 and i'm manuappy placing the characters

0:03 dnolen: clj_newb_2345: yeah for intense drawing you gotta go low level w/ canvas

0:03 bbloom: you should work your cljs/logic magic and come up with a data validator library and then apply it to the ast :-) then we could have a "formal" ast spec too

0:03 clj_newb_2345: is canvas or graphics2d faster?

0:04 dnolen: clj_newb_2345: I'm not sure that comparison even makes sense

0:04 clj_newb_2345: but canvas is not bad

0:04 bbloom: well hugod and lynaghk are kinda blazing that trial - if not using it for validation specifically.

0:05 bbloom: dnolen: well lynaghk wants to use it for term rewriting, right?

0:05 dnolen: what is hugod using it for?

0:05 dnolen: bbloom: they both are

0:05 constraints and rewriting

0:05 bbloom: dnolen: what's hugod's use case?

0:05 dnolen: bbloom: configuration for pallet it looks like

0:05 clj_newb_2345: does java (not chrome/web) have a nice way to organize a scene graph of javagraphics2D objects?

0:06 bbloom: dnolen: neat.

0:06 dnolen: well i have a bunch of thoughts about the AST

0:06 dnolen: bbloom: I know

0:06 bbloom: dnolen: i really hate the :children property :-)

0:07 that and :env make printing the trees kinda annoying

0:07 dnolen: bbloom: the last big debate about CLJS AST, suggestion was to move into :children to avoid duplication.

0:07 and not have things outside.

0:08 bbloom: dnolen: i liked the children as a vector of keys approach, but it didn't play nice with bindings

0:08 dnolen: bbloom: :env makes AST pretty printing annoying, but it's pretty darn nice in the compiler itself.

0:08 bbloom: binding should become a proper AST node I think.

0:09 bbloom: dnolen: yup, let is currently a macro that compiles to let*, but i think there needs to be a let*-just-one-binding node… the issue is then that loop supports simultaneous bindings, so it's the odd man out again

0:10 dnolen: also, we need a root level AST node: :op :script or something

0:10 dnolen: root might be useful - skeptical about let*-just-one-binding

0:11 bbloom: dnolen: i understand the skepticism, i'd like to prototype it first

0:11 dnolen: but binding as an ast node is a similar idea

0:12 dnolen: fixes the interleaved ordering problem

0:13 dnolen: the biggest issue i ran into is that not every spot has a "body env" .. there needs to be some kind of synthetic empty blocks, so there is somewhere to hang an :env … as it is, if you have (let [x 1]) then there is no way to get the env at (let [x 1] THIS EMPTY SPOT)

0:13 dnolen: bbloom: yes I know you mentioned that was a problem in your CPS adventures

0:13 bbloom: dnolen: sorry if i'm repeating myself :-)

0:14 dnolen: just thinking aloud

0:14 dnolen: bbloom: heh I know, I'm mostly concerned atm w/ fixing the AST enough for good source mapping - that's a bit of work as it is.

0:14 bbloom: dnolen: i believe it

0:15 dnolen: do you know for sure what needs to change in the upstream reader?

0:15 dnolen: or maybe it's time to move to the self hosted reader? :-)

0:15 dnolen: yes, col and line info on all symbols

0:16 Bronsa's already pitched blind as a contrib - just waiting to here from the powers that be.

0:16 soon as it's I plan on switching to it - waiting on the Clojure reader is just crazy.

0:16 Sgeo__: blind?

0:17 dnolen: Sgeo__: Clojure (not Java) reader for Clojure source

0:17 krl_: ok, i guess this comes up a lot, and might be a slime issue, but is there a way to have printlns inside of functions being used as predicates for maps act in the same way as those outside?

0:18 Sgeo__: krl, the issue isn't println behaving different, it's a matter of whether or not println gets run

0:18 bbloom: dnolen: does blind reuse any of the code in the cljs reader?

0:18 dnolen: or it a THIRD reader?

0:18 Sgeo__: Erm, wait, by maps, do you mean like (map println [1 2 3])?

0:18 Or do you mean {} and I just have no idea what you're asking

0:18 dnolen: bbloom: no, it's a pure Clojure port of the Java version of the reader

0:18 bbloom: cljs reader is just EDN, doesn't count

0:19 bbloom: dnolen: oh

0:19 dnolen: you can't bootstrap a compiler w/ it

0:19 bbloom: dnolen: gotcha

0:19 Sgeo__: Ooh, so Clojure-in-Clojure is doing well?

0:19 leo2007: which jvm to use, 1.6 or 1.7?

0:19 krl: in emacs, using slime, this code (map #(println (format "hello %s" %)) ["world"]) works differently than just (println "hello world")

0:19 bbloom: dnolen: I'm peeking at the source now… i like my implementation of syntax-quote better ;-) heh

0:20 Sgeo__: krl, with the former, is it just not getting run?

0:20 krl: why would it not be getting run?

0:20 Sgeo__: map returns a so called "lazy seq"

0:20 dnolen: Sgeo__: a pure Clojure reader would be a big step. But to really know if we're doing well some one has to reuse these tools for something that's not JS.

0:21 Sgeo__: That is, it merely describes how to get the elements

0:21 bbloom: dnolen: we really should namespace all the special forms too :-)

0:21 Sgeo__: It won't actually do the println until needed in order to get at the elements

0:21 krl: Sgeo__: hmm. could be. it does print in the minibuffer though for some reason

0:21 Sgeo__: One way to force it is to call doall or dorun on it. doall returns all the elements, dorun returns nil, and uses less memory

0:21 Oh

0:22 dnolen: bbloom: heh you like to think about long-term improvements ;) The list of things worth fixing now for people actually using CLJS is not short.

0:22 krl: Sgeo__: but actually using doall made it print in the right place.

0:22 Sgeo__: bbloom, PLEASE namespacing of special forms in Clojure

0:22 bbloom: heh see dnolen Sgeo__ wants it :-)

0:22 dnolen: :P

0:23 bbloom: dnolen: I just like to set the bar high

0:23 dnolen: sometimes, i fail miserably

0:23 Sgeo__: ,(let [do concat] (do [1 2] [3 4]))

0:23 clojurebot: [3 4]

0:23 bbloom: dnolen: but sometimes i get way further than i expected :-)

0:23 Sgeo__: ,(let [-> concat] (-> [1 2] [3 4]))

0:23 clojurebot: (1 2 3 4)

0:23 Sgeo__: &(let [-> concat] (-> [1 2] [3 4])) ; wrong behavior

0:23 lazybot: java.lang.IllegalArgumentException: Key must be integer

0:24 Sgeo__: ,(-> [1 2] [3 4])

0:24 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

0:24 Sgeo__: ..I don't entirely get why that error in particular

0:24 dnolen: bbloom: I'm all for these kinds of improvements - but I think we have to addres some underlying issues first.

0:24 bbloom: dnolen: which ones?

0:24 dnolen: besides source maps, of course

0:24 and everything leading up to source maps haha

0:25 dnolen: bbloom: after source map it would be nice to do a sanity pass on the AST and acutally document it.

0:25 bbloom: whatever we come w/ should be able to accomodate CLJ JVM

0:25 bbloom: dnolen: yeah, i really think more formality with the AST would be good. hence the core.logic validation idea :-)

0:25 dnolen: then we can start having discussion about building cool stuff on top of that.

0:27 bbloom: that sounds like a fun (and useful) side project, yes. but I think just having a design, discussion, eyes, patches is a good start.

0:28 bbloom: dnolen: fair enough. should we just start a wiki page?

0:28 oh wait

0:29 dnolen: bbloom: yep, jonasen tho it would be nice to get that directly on the wiki page.

0:32 bbloom: dnolen: yeah here https://docs.google.com/document/d/1DRN-tBIqhqVVyoHIDs7CMkduBFk-vqd_958ojeIBLHQ/edit

0:34 dnolen: bbloom: right - should probably link to that from wiki

0:36 bbloom: dnolen: for now: http://dev.clojure.org/display/design/Formalize+AST

0:36 i gotta run, but i'll write up my thoughts neatly soon

0:37 dnolen: bbloom: cool thx

0:39 seangrove: Oh man, I can't figure out how to get a single reasonable test to run in cljs

0:39 wingy: i have a form-params map and want to return a response depending on what keys/values are present in the map using pattern matching instead of nested (if) forms .. how is this done in clj?

0:43 dnolen: seangrove: what are you trying to do?

0:43 seangrove: test at command line? in browser?

0:48 seangrove: I'd like to run "lein cljsbuild test" and have it run the cljs tests in an environment that has access to a dom.

0:49 I've been trying to figure out how to run a cljs test in phantomjs based on cljs-bootstrap, but it really seems like it's not all there

0:50 dnolen: seangrove: so is this something that lein cljsbuild test supports?

0:50 seangrove: And I can't seem to find any examples of how people are doing it elsewhere

0:51 Really not sure. I suppose "lein cljsbuild test" was incorrect, I meant "$<something>" and my cljs test suite runs and tells me what, if anything broken 0:51 Are you running any tests at all on any of your cljs projects? 0:52 dnolen: seangrove: in a very hacky way yes - just w/ a script and a CLJS test file of asserts 0:52 seangrove: Ok, and that's not in a browser, right? 0:52 dnolen: seangrove: for CLJS proper - it's somewhat necessary because we want to test at commandline against a variety of JS engines 0:52 seangrove: yeah not in browser 0:52 seangrove: Ah, I might have found something, let me give it a try 0:53 I'll commit to porting clojure.test to cljs once I have the bare minimum environment running 0:53 dnolen: seangrove: I guess you're following this and it's not working - http://github.com/emezeske/lein-cljsbuild/blob/0.2.9/doc/TESTING.md 0:53 seangrove: heh no need to commit - but I definitely think people would use it if were available. 0:54 seangrove: Yeah, exactly. I'll stepped away for 20 minutes though, and I'll give it another try now 0:54 Well, it'd be a good project, and I'd like to get more involved with cljs where possible to help out 0:56 dnolen: seangrove: emulating cljs.test would require some help from the compiler - we could use the namespaces atom (which holds all defs in the compiler) to figure what the tests are in a namespace and generate some CLJS that runs them all. 1:01 bbloom: seangrove: I'm about to run into the browser-level cljs testing issue myself 1:01 not sure what i'm gonna do about it yet 1:01 i've been manually running asserts on refresh 1:04 seangrove: bbloom: Would running the tests in phantomjs be acceptable, or do you need actual browsers? 1:04 * dnolen shakes his fist at munge in CLJS compiler 1:04 bbloom: seangrove: I haven't used phantomjs ever before, but my experience with DOM testing is that browser quirks are kinda important to fix 1:04 dnolen: what now? :-/ 1:05 seangrove: the strategy i've used to good effect is to write a little test runner page and then load tests in an iframe 1:05 dnolen: bbloom: just all these places where we don't have real ast nodes and call munge directly 1:05 bbloom: seangrove: this way test runs are manual-ish 1:05 dnolen: that should never happen - we want everything to go through emit :var so we can put source mapping logic in one place 1:05 bbloom: dnolen: at least all the munging is in the code generator now :-) 1:05 seangrove: bbloom: Used to work at Sauce Labs, I'd like everything to be automated as much as possible :) 1:06 bbloom: seangrove: heh. my experience with selenium was rather poor 1:06 seangrove: Yeah, it was a janky project. Web-driver seems like a better approach 1:06 bbloom: seangrove: ultimately what my startup did was use JUUUUST ENOUGH selenium to navigate to /test.html and wait for "finished" to appear and then extract the number of tests/asserts/passes/fails and print that 1:07 seangrove: that let us test everything except for some more subtle platform things, like file pickers 1:07 seangrove: so we just tested those by hands 1:07 all the actual tests were pure javascript, no browser driver 1:07 seangrove: Ah, ok 1:07 So you could potentially have just run it in v8? 1:07 bbloom: v8 doesn't include a dom 1:08 seangrove: Heh, so not pure js ;) 1:08 js + dom 1:08 bbloom: sorry, i mean pure js in the sense that it wasn't external browser automatino 1:08 it ran IN a *real* browser 1:08 seangrove: Ok, got it 1:08 bbloom: much faster than selenium tho 1:08 i've been meaning to get skrenzel to open source that damn test library. it was amazing :-) 1:09 seangrove: I think with phantomjs it should still be very fast, can have it run on commit hook, and have cross-browser tests run in CI 1:09 What startup was it, by the way? 1:09 bbloom: thinkfuse 1:10 seangrove: Wow, great - you still at Salesforce then? 1:10 bbloom: nope 1:11 seangrove: Well, let me see if I can put together a reasonable package for running automated tests with DOM access via phantomjs 1:11 Feels like it could fill a need 1:11 bbloom: seangrove: would be nice if you can contribute it to cljs-build 1:12 seangrove: Feels like it should be a separate project that can work with cljs-build. Early projects always tend to be pretty bad, and are supersceded by someone who knows what they hell they're doing later. 1:12 bbloom: haha fair enough 1:31 tomoj: hmm.. (range a (inc b)) 1:32 that sometimes bothers me, but if I read it as a little flag that says "inclusive", great! 1:35 bbloom: tomoj: heh, great mnemonic 1:38 seangrove: Heh, nice 1:42 mpan: is there an equivalent to proxy for a superclass known at runtime? 1:42 or perhaps I may be trying to do something wrong here 1:49 what I would have liked was to do something along the lines of this: (let [o Object] (proxy [o] [])) 1:49 but perhaps that's a sign I'm going about it the wrong way 1:50 tomoj: what are you actually trying to do? 1:51 mpan: this weird framework has multiple interfaces which for my purposes are the same 1:52 although I need to double check this now that I think about it because it sounds very wrong in my head 1:52 seangrove: Ok, so in the advanced lein-cljsbuild project, it has a build section :test 1:52 mpan: I have no idea why it seems to be OK with me leaving out a method that the interface specifies 1:53 granted, the interface says the method returns void, but interop seems happy to let me just leave it out entirely 1:53 seangrove: That outputs to resources/private/js/unit-test.js. In it, it has code included from the compiled tests, but also from the main cljs as well - the cljs test ns does a (use :main.project.ns) 1:53 SegFaultAX: Re: lein-ring, when is it appropriate to use an uberwar over a normal war? 1:54 seangrove: I can't get that same output in my project - the compiled unit-test.js *only* has my unit-test.cljs in it, it doesn't seem to be including the other cljs source at all 1:57 mpan: quite strange, the proxy is willing to lie about implementing an interface and then when used at runtime complains otherwise 1:57 seangrove: I can't tell if there's some magic that knows to include the source cljs in the unit-test, or I'm just configuring things incorrectly 2:00 leo2007: has nrepl completely replaced slime+swank? 2:05 seangrove: leo2007: Yes, swank-clojure has been deprecated 2:05 tomoj: mpan: why do you only know the interfaces at runtime? 2:06 leo2007: seangrove: nrepl is a strict superset of swank-clojure? 2:06 mpan: tomoj: it's one from a list, but which one depended on some runtime into, which I figured I should probably restructure because that sounded wrong 2:06 seangrove: leo2007: Not really, no, but is there anything you're looking for in particular? 2:07 leo2007: Nothing in particular. I already have swank-clojure running from months ago. 2:07 Just want to know the community's opinion on the new tool. 2:08 seangrove: I switched form swank-clojure to nrepl.el about a week or so ago, no complaints 2:08 tomoj: I switched and had to switch back, but don't remember why :/ 2:08 seangrove: M-. and friends all work :) 2:08 tomoj: I use slime-inspector quite often 2:09 Raynes: tomoj: Inspector need somebody who cares about it to get it working with nrepl. 2:10 leo2007: I guess I will get it running to test out! 2:12 tomoj: Raynes: you mean get slime-inspect working? or write a new inspector? either way, I still use swank-clojure for work right now. since I haven't figured out how to get them to play nice in one emacs, I guess I should start another emacs and do scratch work in it with nrepl 2:17 echo-area: I use ritz + swank. But the java process uses more and more memory. Does anyone know why? 2:19 unic0rn: the memory allocation strategy of java can be described in 3 words. 2:19 nom nom nom. 2:19 mpan: where is the correct place to put the equivalent of "static initializers" i.e. stuff that needs to be run exactly once and before other stuff 2:20 my current example is loading a table of values into a def'd atom 2:20 nightfly_: defonce is useful :) 2:20 mpan: er, rather, my current process is to def it as an atom to nil and then initialize it 2:22 should I switch to defonce and just move that call into the defonce? 2:29 nightfly_: Not sure really. I'm working on something right now that uses a global ref that is defonced and then is populated my a function that is called in main. I'd be interested in the best way of handling this too. 2:30 mpan: I suppose part of my problem is I don't currently have a single "main" 2:57 jondavidjohn: how would I go about reducing a vector of vectors? 2:57 making this.. [[1 2] [3 4]] into .. [1 2 3 4] 2:58 tomoj: you already said it :) 2:58 &(reduce into [[1 2] [3 4]]) 2:58 lazybot: ⇒ [1 2 3 4] 2:59 Raynes: tomoj: Well, the existing inspector is written in Clojure. It just needs to be changed to work with nrepl. 2:59 tomoj: slime-inspector is certainly not written in clojure - are we talking about the same thing? 3:01 hmm 3:01 is it? 3:02 I mean certainly parts of what make slime-inspect work are in slime 3:07 I meant one would want to get that working with nrepl. Might require a whole rewrite. *shrug* 3:08 I don't really know how it all works because I've never used nor cared about the inspecotr. 3:14 jondavidjohn: tomoj: I ended up using (flatten [[1 2] [3 4]]) 3:14 is that ok? any reason to use the reduce method? 3:16 jyu: hello, any distribution library in clojure? 3:17 tomoj: flatten is overkill 3:17 and it doesn't give you a vector back 3:18 Raynes: ah right. biggest problem for me is the elisp involved.. 3:18 jondavidjohn: right, i had to do (vec (flatten ...) ) 3:18 cool, I'll use reduce, thanks! 3:19 tomoj: unless you really want to flatten 3:19 &(flatten [[[1 2 3] [4]] [5 6] [7]]) 3:19 lazybot: ⇒ (1 2 3 4 5 6 7) 3:19 tomoj: &(reduce into [[[1 2 3] [4]] [5 6] [7]]) 3:19 lazybot: ⇒ [[1 2 3] [4] 5 6 7] 3:20 jondavidjohn: gotcha, so if i was working with deeper data structures, flatten might be a better idea, but since I'm only ever working with one deep, reduce is more performant? 3:29 foodoo: &(apply concat [[1 2] [3 4]]) 3:29 lazybot: ⇒ (1 2 3 4) 4:02 * Bergle_2 finds instarepl in LighTable alpha 0.2.0 useful for learning 4:52 tomoj: simplify: (map (partial map f) coll) 4:53 hmm 4:54 unnali: non-trivial? 4:54 Sgeo__: So coll is a collection of collections? 4:55 unnali: if we go all Haskelly 4:55 f :: a -> b 4:55 partial map f :: [a] -> b 4:55 [a] -> [b]* 4:55 typo 4:55 map (partial map f) :: [[a]] -> [[b]] 4:55 so coll is [[a]] 4:55 where a is the input of f 4:56 * Sgeo__ winces at that partial in the pseudohaskell 4:56 tomoj: (fmap.fmap) 4:56 unnali: Sgeo__: yeah, I know ;-) 4:56 tomoj: I expected (comp r/map r/map) to work 4:56 it sort of does I think 4:56 unnali: it should. 4:57 Sgeo__: It's because fmap takes a function and returns another function, whereas map takes two arguments.. maybe? 4:57 * Sgeo__ isn't sure 4:57 tomoj: you must supply the final collection curried, though 4:57 Sgeo__: Why r/map and not map? 4:57 What's r? 4:58 tomoj: (((comp r/map r/map) inc) [[1 2 3] [4] [5 6 7]]) seems to work 4:58 ((comp r/map r/map) inc [[1 2 3] [4] [5 6 7]]) blows up 4:58 r is clojure.core.reducers 4:59 Sgeo__: tomoj, well, that 4:59 well, that's not necessarily unexpected 4:59 tomoj: yeah 4:59 I didn't expect it because all my functions are curried here 5:00 the functor is never passed with the, uh, functand? 5:02 s/sort of // 5:05 hmm 5:18 borkdude: functions that are evaluated in the REPL are just as compiled as any others right? how does this work again? where does clojure emit a .class file for a function defined in the REPL? 5:19 p_l: borkdude: you can generate the bytecode and load it without creating a file 5:19 borkdude: ah 6:06 p_l: gah. Forgot how memory-hungry java is 6:11 * p_l started nrepl-ritz, computer grinds to halt due to sudden shuffling of half a gig into swap 6:13 echo-area: p_l: I use nrepl + swank, and have kind of the same issue. 6:13 Bergle_2: get more ram :) 6:14 p_l: Bergle_2: 6G here 6:14 Bergle_2: if its swapping :) its not enough. 6:14 echo-area: But that becomes ridiculous for running a REPL 6:14 Bergle_2: i bought 16GB recently for like$80 lol

6:14 p_l: Bergle_2: work machine

6:15 Bergle_2: that sucks, but at least your using clojure at work :)

6:15 p_l: (also, unclear if it doesn't require rare FB-DIMM)

6:15 Bergle_2: only by own initiative, which is waning right now

6:15 Bergle_2: i usually amazed how many companies dont make sure the devs have good performance machines.

6:15 p_l: Bergle_2: it's good enough performance for most

6:16 Bergle_2: first thing i did at last company was get 3 ssd's for dev's and more ram.

6:16 p_l: also, government procurement is slow

6:16 Bergle_2: ahha double whammy - work + govt :) heh

6:26 p_l: eh, maybe I'll manage to ease the memory pressure by modding OS params

6:39 wingy: what middleware should i add to get a stacktrace on the web browser when ring is encountering an error: https://www.refheap.com/paste/7016

6:43 borkdude: why is the news info gone from clojure.org?

6:49 wingy: xeqi: why can't i find it in https://github.com/ring-clojure/ring/tree/master/ring-core/src/ring/middleware

6:49 its under ring/ring-devel

6:51 wingy: xeqi: thx

6:51 worked great

6:58 borkdude: what is the recent stabile clojure version, still 1.4?

7:00 foodoo: borkdude: yes

7:00 borkdude: although 1.3 is also marked as "stable" http://clojure.github.com/clojure/

7:19 wingy: the difference between def and atom is that atom can be changed later on while def vars cannot be changed?

7:21 HolyJak: Well, you can redefine a variable (unless you used defonce) but I feel it is kind of evil :)

7:21 atom is better if you actually want to share state between threads safely

7:24 borkdude: redefining vars is only allowed for REPL-purposes I think

7:24 wingy: HolyJak: but i can't redefine a variable from a fn right?

7:24 i can't use (def) inside a fn

7:24 yeah

7:24 so atom it is

7:24 borkdude: wingy you can, but it's not "idiomatic"

7:24 wingy: yeah .. looks weird

7:26 HolyJak: not idiomatic - or, in other words, evil :)

7:28 wingy: it's even forbidden

7:28 judge dredd will come after you

7:30 borkdude: you can however use def in a macro (like defn)

7:33 wingy: i c

7:37 josteink_: Im trying to create a "self-aware" object in clojure, but I cant get it right

7:37 Im trying something akin to

7:37 anyone have any leads on what Im doing wrong?

7:37 the compiler basically says that "me" cannot reference "me"...'

7:39 rodnaph_: josteink: i know it's not the answer you want, but why are you trying to do that? is there a better solution (clojure is complaining because the second "me" doesn't exist until the first "me" is created)

7:39 madsy: josteink: Because "me" isn't bound yet when you call the function. What you probably want is let* instead of let

7:39 josteink: rodnaph_: Im trying to create a system where components can distribute messages, and every message needs to have a caller to avoid causing endless loops

7:40 josteink: Im trying to -implement- something like that myself

7:41 not reuse others implementation

7:41 educational stuff ;)

7:41 * josteink is at SICP's chapter about constraint-based programming

7:41 josteink: madsy: let me look into that

7:43 examples?

7:43 clojurebot: examples is api examples

7:44 madsy: josteink: Hm.. maybe Clojure didn't have let*. I'm puzzled now.

7:44 josteink: so in clojure a thing cannot reference itself ever?

7:44 that sounds like a odd limitation

7:45 madsy: ,(let [a 1] [b (+ a 2)] b)

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

7:45 josteink: ,(let [a 1 b (+ a 2)] b)

7:45 clojurebot: 3

7:45 josteink: but this is a no go

7:46 ,(def x (let* [boo { :self boo :hoo "zoo" }] boo))

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

7:46 josteink: ,(let* [boo { :self boo :hoo "zoo" }] boo)

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

7:46 rodnaph_: josteink: the let macro is really just sugar over the identity monad.

7:46 josteink: so

7:46 in clojere no entity can know its own identity?

7:47 how do you auto-establish callers in messaging scenarios then?

7:47 "you dont" sounds like a pretty odd limitaion :P

7:48 mpan: josteink: how do you propose to evaluate that self reference? I'm confused

7:48 rodnaph_: i'm afraid i don't really understand what you're trying to do, but i doubt there is any limitation.

7:49 (no limitation on achieving your goal i mean)

7:49 mpan: you want a circular reference? I thought they tried hard not to let you do that directly

7:49 josteink: rodnaph_: I want a function to have equivalent of "this" in java or C#

7:50 mpan: I want a self-reference

7:50 so I can make "signed calls" from an object to another

7:50 Im trying to cheat with atoms here

7:50 mpan: with regards to interop, the interop calls have special features for "this"

7:50 with regard to outside of interop, I think I recall hearing that it's intentionally not allowed directly

7:51 you can use e.g. an atom to do it but that would be stylistically very strange

7:51 may I ask, why do you want "this"?

7:51 rodnaph_: if you want objects i think unless you use interop you're out of luck. you probably need to rethink your problem with FP in mind.

7:51 Ill try something like this then

7:51 I need to be able to identify myself as a caller

7:51 or else the system will have those circular loops you're not supposed to have :P

7:51 mpan: can you use some concept of "names" instead?

7:52 rather than references?

7:52 josteink: I like self-contained ID systems

7:52 otehrwise I would need a mutable name-caller structure

7:52 with global scope

7:52 and that is even worse

7:52 ChongLi: does calling reify on protocols count as interop?

7:53 josteink: I just want component A to be able to call component B saying (hey , Im compont A) so that component B can authorize the messager

7:53 I dont want a framework

7:53 I want simple inter-function identity :)

7:53 mpan: why can't A send some concept of a name?

7:53 josteink: because component B should be able to call back to component A

7:53 and names is misdirection

7:53 mpan: put something to dispatch

7:54 josteink: instead of compoent B going straight at A, it needs to look up As identity in a table

7:54 and then call it

7:54 instead of just passing it along directly

7:54 thats inefficient, obscures the code, and doesnt add any value

7:54 mpan: if you want to directly be able to have that sort of reference then you need something like e.g. an atom

7:54 josteink: like I said

7:54 Ill try something like this

7:54 mpan: was just trying to clarify what it was you wanted

7:55 josteink: yeah

7:55 I want a object to know its own identity

7:55 I find it strange that is should be so much work

7:55 :)

7:55 mpan: maybe I shouldn't be suggesting this because stylistically it would be strange, but have you considered e.g. an atom containing another one?

7:56 I guess that doesn't help much either though :/

7:56 josteink: example?

7:56 clojurebot: api examples is examples

7:56 mpan: never mind actually, it wouldn't work how I initially thought it might

7:56 sorry to confuse you there

7:59 josteink: hehe

7:59 np

7:59 mpan: josteink: this is an alternative idea you might want to try

7:59 josteink: w00

7:59 it compiles :)

7:59 mpan: every action you take on something, you could pass itself in

8:00 josteink: mpan: that is what Im trying to do

8:00 but to do so, I need to know my own identity

8:01 mpan: if you pass the value in, then in the function the value is known? why does the value need to be special beyond just an atom?

8:01 sorry I don't follow why you need the extra layer if you're doing that

8:01 josteink: because Im using message-passing style objects

8:02 I want to pass an object in to another object

8:02 and I want the object to be able to act on that

8:02 solussd: josteink: I'm not sure what you're trying to accomplish, but you can declare a var before it is bound, e.g. (declare selfaware) (defn selfaware [] selfaware)

8:02 si14: how would you guys do a cross-platform app on Clojure with sub-100ms startup time?

8:02 josteink: solussd: that is global scope

8:02 solussd: I want function-local

8:02 solussd: ah

8:02 mpan: si14: is prestarting jvms an option for you by any chance?

8:03 josteink: mpan: I want a object A, to be able to call object B's method "somethin" with itself as a parameter, so that object B can call back to ibject A's "some-other" function

8:03 solussd: si14: clojurescript + node.js?

8:03 josteink: using message-passing style object calls

8:03 mpan: I'm gonna try to write up an example of what I was trying to say

8:03 si14: mpan: it's definitely an option, but the question is how do you talk to Clojure server from shell in cross-platform way

8:03 josteink: thats as simple as I can explain it

8:03 si14: solussd: it's an option, but full-blown Clojure is nicer IMO

8:03 mpan: si14: there was a project which did this but I don't remember the name at the moment :(

8:04 josteink: si14: "drip"

8:04 works on unixes, not windows AFAIK

8:04 solussd: yeah, if "full-blown" = java interop, prestarting is the way to go

8:05 si14: it's definitely the way, but how to talk with JVM is a question :)

8:05 preferrably without binaries at all

8:05 not sure that's not doable on plain shell

8:05 not know how to do it either :)

8:06 josteink: I need Windows too, unfortunately

8:06 solussd: josteink: is this acceptable? (let [self (defn self [] self)]) :)

8:06 josteink: solussd: no

8:06 solussd: :(

8:06 josteink: solussd: the (defn inside the let binding WILL create a global scope binding

8:07 like I said

8:07 Ive settled with a construct like this

8:07 dirty but it works, and is pretty obvious

8:07 solussd: well so will your original example

8:07 josteink: no

8:07 anyway, I was wondering if there was a simple way to create a self-referencing entity in clojure

8:08 solussd: you mean you dont want a global binding for self?

8:08 josteink: no

8:08 never

8:08 solussd: something common lisp is bubbling yup to the surface in my head

8:08 josteink: I want each and every tiny little object I create of the million objects I create to each have their own "self", which refers to themselves

8:08 anyway, I was wondering if there was a simple way to create a self-referencing entity in clojure

8:08 a simple yes no question

8:08 I guess the answer is "no"

8:08 :P

8:08 mpan: josteink: I think I've got an example of "explicitly passing in self"

8:08 josteink: got any code to share?

8:09 to compare with what ive already done?

8:09 mpan: let me make it correct first

8:09 =p

8:10 clojure-newb: hey guys, I'm currently doing (ffirst (reverse (sort on a collection to get the item with the latest date in a hash set… its a bit newb.. whats the idiomatic way to do this ?

8:10 mpan: josteink: ok I meant something like https://www.refheap.com/paste/7020

8:11 you have functions and atoms, and you pass the atoms into the functions, specifically that the functions take an explicit "this"-equivalent as first arg

8:11 alexnixon: clojure-newb: something along the lines of (apply max-key :date [coll])

8:11 mpan: note that if you wanted the fn to know the caller, the caller can explicitly pass its atom

8:12 clojure-newb: alexnixon: thx I'll have a look

8:12 josteink: mpan: "def" is evil

8:12 mpan: like foo could have taken an extra arg that's "the atom of who it's from"

8:12 mpan: josteink: but you could do the same thing locally

8:12 josteink: def bleeds to the global scope

8:12 mpan: as in, a didn't need to be def'd

8:12 you could just as well have created an atom in local scope and done the same things to it

8:13 as in, my example could be entirely rewritten with a let

8:13 and they're just plain atoms, so you could hand them around as you like

8:14 josteink: mpan: I think youve missed my two pastes so far

8:14 which shows you that Ive already solved this using an atom :P

8:14 mpan: it's very similar

8:14 and I was saying, you can use an atom

8:15 but you didn't need to go and make something special to "get this"

8:15 josteink: anyway

8:15 thanks for the help

8:15 mpan: is the point I was trying to make

8:15 josteink: but you can stop

8:15 mpan: ok

8:15 hope it was useful for you

8:15 josteink: I see that to reference yourself you need to trick around with atoms

8:15 yes yes

8:15 absolutely

8:15 but you went on far beyond what was needed ;)

8:16 mpan: I hope you get my bigger point, though, which is that sometimes it's not very clean/nice to try to convert java verbatim

8:16 anyway have a nice day then

8:16 josteink: funny how clojure which makes so many things so short and conssce, makes a simple "this" into voodoo :P

8:16 mpan: scheme vebratim actually

8:16 * josteink is translating scheme-code into clojure while reading SICP

8:17 mpan: now you've got me curious

8:17 what are you doing in scheme?

8:17 josteink: read SICP, chapter on constraint-based programming

8:17 Foxboron: SICP contains Scheme examples

8:17 mpan: ok thanks

8:17 I was just wondering specifically which feature of scheme you were using for this

8:18 josteink: I was using scheme's ability to reference anything

8:18 even things which doesnt exist yet, like one-self

8:18 mpan: we messed around with the language briefly for school but I didn't go very deeply into it

8:18 josteink: (define (test x) (define boo '(x boo)) boo)

8:18 is valid scheme code

8:19 mpan: that's quite interesting to see that done with arbitrary values

8:19 solussd: josteink: how about alambda (from on lisp)? from my repl: https://www.refheap.com/paste/7022

8:21 josteink: thanks but no thanks

8:21 I got what I need sorted out

8:21 solussd: k

9:10 gfredericks: are there yet good enough CLJS libraries that using jquery is not the best way to get stuff done?

9:11 abp: gfredericks, I like jayq and mpenet is working on it.

9:11 $google jayq 9:11 lazybot: [ibdknox/jayq · GitHub] https://github.com/ibdknox/jayq 9:11 mpenet: jaq is fine, and you are likely to use jquery plugins anyway, so why not use it. 9:12 gfredericks: I think I considered that equivalent with jquery; what does it do that isn't a thin jquery wrapper? 9:12 mpenet: jayq* 9:12 plays well with compilation mostly 9:12 and add some sugar here and there 9:12 but being thin is kind of the point I think. 9:12 abp: gfredericks, not much, but it's a neat wrapper and I consider jquerys event-handling stuff quite usable. 9:12 gfredericks: does it include an externs file? 9:13 mpenet: no but there is a link to externs in the readme 9:13 gfredericks: ah cool; k thanks 9:13 mpenet: angular is also an option but it all depends on what you need to do really 9:13 abp: mpenet, do you maintain jayq or are you just filling some gaps for your needs? 9:14 mpenet: I maintain it. And try to improve it where I can 9:14 abp: mpenet, cool, glad to hear that. Theres much of Chris work laying around. 9:14 mpenet: I have been fairly active on it lately, PR are also very welcomed! 9:16 gfredericks: man I load up the github page and the last commit message makes me think of monads 9:16 mpenet: abp: I am trying to get chris to create a github org around some of his cljs project, since he doesn't really have the time to work on them cuz of LT 9:16 abp: mpenet, yes I've seen that. Some of my work on my libraries will probably be around jayq, too. Something I need or feel a lack of a nice api will be pulled instantly when present. :) 9:16 mpenet: gfredericks: well some of the last commit are inspired by monads :p mostly to make some sugar, you are not really exposed to the dirty bits though, no need to fear! 9:17 gfredericks: I like monads actually, but they're fun to make fun of 9:17 mpenet: gfredericks: you might like the latest additions then: see do-> in macros.clj 9:17 gfredericks: mzero must be monoids though, right? 9:17 abp: mpenet, and he doesn't even got time to do that? Light Table must really be consuming his time like nothing before. Passion can be really forceful. 9:18 mpenet: gfredericks: it's not 100% "lawfull", it's stuff inspired from roylang mostly 9:18 abp: he seems to be really busy 9:18 gfredericks: illegal monad usage? 9:18 mpenet: abp: and it's understandable imho 9:19 gfredericks: mpenet: why shouldn't the externs file be packaged with the lib? 9:19 abp: Hm, any thoughts on pulling parts of libraries out of clojures contrib libs? The new ones. Theres something in tools.namespace I would like to get standalone and work further on.. 9:19 mpenet: gfredericks: no type system, some "monads" can be hairy fast 9:19 gfredericks: see the tracingMonad from roy for instance 9:19 abp: mpenet, sure. Got a good cash-backing for burning his time on his ideas. I need that, too. ;) 9:20 mpenet: gfredericks: it's called a monad, looks like a monad, but isnt really one 9:20 gfredericks: http://roy.brianmckenna.org/ 9:20 abp: mpenet, looking forward to Typed Clojure on cljs? Eases your monads. 9:20 Probably.. 9:21 mpenet: abp: seems like an interesting project, yes 9:23 gfredericks: about the externs, jayq can be used with a lot of different jquery versions 9:23 gfredericks: and including all of them with jayq didn't seem to be the right thing to do 9:24 gfredericks: I could be wrong though. Also showing where to get them also helps if you need one for underscore.js backbone.js etc since they are all listed at the url indicated in the readme 9:30 gfredericks: mpenet: would it be silly for somebody to post jquery jars to clojars? 9:30 mpenet: I think there is a project that does just that already, with jquery and other libraries 9:31 gfredericks: not sure about externs tho 9:33 abp: Can I check which wich symbols in a given s-expression will evaluate to something via macros? 9:34 gfredericks: abp: wat? 9:35 abp: ,(resolve 'foo) 9:35 clojurebot: nil 9:35 abp: ,(resolve 'map) 9:35 clojurebot: #'clojure.core/map 9:35 abp: gfredericks, I think that's the answer 9:35 gfredericks: ah ha 9:37 abp: gfredericks, finding out which symbols get resolved to vars. I need that to further reduce my graph declarations. Will show you a gist soon if you like to see the mess. ;x 9:38 gfredericks: okay, so if I call (.method ...) on a jquery object, I am doing it wrong 9:38 I have used jayq in the past and did not realize that 9:39 mpenet: gfredericks: http://www.webjars.org/ for the mavenized js stuff 9:39 gfredericks: mpenet: thanks 9:40 mpenet: fascinating 9:41 woah; I can (:require [jayq.core :as$ :refer [$]]) can't I? 9:41 mpenet: gfredericks: never used if myself 9:41 gfredericks: I am not sure it's a good idea to miz as and refer 9:41 miy 9:41 mix 9:41 damn fingers 9:42 gfredericks: mpenet: do you know any reason why that would be? or you just haven't tried it? 9:42 mpenet: gfredericks: you probably want :refer if you are just after$, I almost always use [:as jq]

9:42 gfredericks: never tried it

9:43 gfredericks: but that would mean $/$ to get to jquery.fn.$, feels a bit odd 9:43 gfredericks: mpenet: I want both :D 9:43 mpenet: no I expect just$

9:43 mpenet: gfredericks: oh right

9:43 gfredericks: I just wrote ($/append ($ "body") ...)

9:43 which I think is slick

9:43 mpenet: gfredericks: try it, but I'd be surprised if it works

9:44 gfredericks: I expect this would work in clj-jvm at least

9:44 I know cljs is a bit rougher in the ns departement

9:44 well it compiled

9:44 abp: gfredericks, you're crazy. :D

9:45 gfredericks: well the code didn't run but I think it's cljsbuild being borky

9:46 * gfredericks deletes files and recompiles

9:47 gfredericks: consarnit

9:47 still emitting my namespaces in the wrong order

9:48 mdeboard: I need an "accumulator", a var that is defined globally as nil, but inside a function it is incremented by a value, e.g. https://gist.github.com/4154582 .. I know this is awful so please withhold vomit to the best of your ability.

9:49 I'm not really clear on how to locally bind accum and increment it as required

9:49 gfredericks: mdeboard: why do you need it to be a global? why not a local atom at least?

9:49 mdeboard: gfredericks: I don't need it to be

9:49 just a supposition on my part

9:49 probably wrong :)

9:50 abp: mdeboard, then why would you even mutate something?

9:51 gfredericks: mpenet: it seems to have compiled correctly; still not running how I expect but that's likely a separate issue

9:51 mdeboard: abp: Because I'm porting a piece of software from C# and I need to duplicate a particular component which does this. I want to get it duplicated for testability, so I can modify it later

9:52 gfredericks: using a local would have different behavior for sure, if you're at any point running this function from two different threads

9:52 mdeboard: The original C# is iterating through a hex "fingerprint" in an unusual way, and I'm trying to duplicate that exact behavior

9:52 abp: mdeboard, ok. But you probably want to rewrite it properly from the beginning. You could produce test-cases with the old implementation.

9:53 mdeboard: gfredericks: The original uses a thread-local, I think the reason I was making it global was because I poorly understood something I read

9:53 gfredericks: The thing being (def ^:dynamic...)

9:57 gfredericks: mdeboard: yeah I'd do (let [state (atom 0)] ...) at the very least

9:58 better to rework the algorithm to not be stateful

9:59 jayq.util/clj->js will be in cljs core soon, right?

10:05 mdeboard: gfredericks: What's an algorithm? I'm a web developer

10:05 abp: gfredericks, in master, if I missed no cljs release. mpenet again: https://github.com/clojure/clojurescript/commit/cd66e6b9e63ad5ef1896a9c7a117148beb04301d

10:05 gfredericks: mdeboard: you're translating C# that can't be _too_ true

10:09 is cljsbuild emitting stuff out of order a bug in the compiler itself? that was already fixed? so if I just use cljs HEAD then cljsbuild should work correctly?

10:10 abp: gfredericks, http://dev.clojure.org/jira/browse/CLJS-282

10:11 gfredericks: abp: so...yes? :)

10:11 abp: gfredericks, we need master released now! But I think dnolen wants to finish source maps for cljs first, so on release we're all stunned and can't develop anything anymore.

10:11 gfredericks: ah ha; okeedokes

10:11 thanks

10:14 abp: gfredericks, that was a joke. But hopefully one that gets true.

10:16 mpenet: gfredericks: the next release will happen soon I hope, I think we are mostly waiting on source maps support to be complete

10:17 abp: gfredericks, https://gist.github.com/4142595 exk-calls in exg are my awful unbound symbol search macro.

10:19 I don't know if I really want to include that. Can make debugging awful.

10:20 * mdeboard kicks himself for not bringing his Clojure Programming book into work

10:21 cemerick: mdeboard: that's what the PDF is for ;-)

10:21 mdeboard: oh yeah, hm

10:21 abp: mdeboard, or cemerick :x

10:21 cemerick: eh?

10:22 abp: he can just look everything up in you!

10:22 mdeboard: disturbing

10:22 cemerick: I've forgotten it all.

10:22 abp: oh, then don't care. write another clojure book to refresh. :P

10:23 cemerick: It's like having to read your own documentation or googling for a topic that brings up your own blog post, but way, way more disturbing.

10:23 mdeboard: Damn, I don't think I used my o'reilly account to buy the book

10:24 == no pdf

10:24 abp: mdeboard, ask them, they can be really gracious. Just for future paper-independence.

10:25 mdeboard: I may

10:25 cemerick: mdeboard: IIRC, if you bought just the dead-tree version, you can get the PDF for $5 or something. 10:25 abp: cemerick, yes, just like when people work on projects or something. External facilities guard all the knowledge. 10:25 clojure-newb: hey guys, in a compojure app I'm destructuring a path param with [id], how do I get a header 'foo' in the same mechanism without reverting to manipulations of 'request' or is that not possible ? 10:26 uvtc: cemerick: the best is when it takes until you're in the middle of reading it until you realize that you're the one who wrote it. :) 10:28 cemerick: uvtc: that always makes me feel like an idiot :-P 10:28 abp: clojure-newb, https://github.com/weavejester/compojure/wiki/Destructuring-Syntax see [x y :as r] 10:29 clojure-newb: abp: thx, I'll take a look 10:30 abp: cemerick, do you work with Clojure at your Snowtide? On PDFTextStream? Or is that a business secret? ;) 10:30 mdeboard: oh my god 10:31 cemerick: abp: PDFTextStream was largely built ~2003-2005, definitely predating Clojure. 10:31 mdeboard: I am in PDF hell right now 10:31 abp: cemerick, ah ok. Didn't know that. 10:31 mdeboard: I live in PDF hell 10:31 cemerick: That said, 99% of the code I've written since summer of 2008 is Clojure. 10:31 mdeboard: cemerick: How familiar are you with Callas, itext, etc. 10:32 cemerick: mdeboard: is this a book issue you're struggling with? 10:32 mdeboard: The C# code I'm porting right now is all about workig with PDFs 10:32 yes 10:32 we use itext to extract the word/paragraph/line data 10:32 cemerick: Callas? You mean Calais? 10:32 mdeboard: Sure 10:32 cemerick: Sure, I've tinkered with OpenCalais some. 10:32 mdeboard: Is it really Calais? LOL. I'm just basing the spelling off of how people pronounce it 10:33 abp: cemerick, wow. I just get to work with it at work after one and a half year of discussion.. Do you do contracting work or own projects? 10:33 mdeboard: And no, I mean Callas http://www.callassoftware.com/callas/doku.php/en 10:33 cemerick: mdeboard: FWIW, many, many PDFTextStream customers were prior users of iText and PDFBox. ;-) 10:33 * babilen would expect the pronounciation of "Callas" and "Calais" to be quite different 10:33 mdeboard: We use a wide swath of open-source and proprietary libraries 10:33 babilen: indeed 10:34 cemerick: ah, no, I've never used Callas 10:34 mdeboard: vous avez caillou, calais 10:34 cemerick: The itext api is ... unusual 10:35 cemerick: I've never had much contact with preflight, prepress, pdf generation generally 10:35 mdeboard: cemerick: That's our bread and butter. We're not a content company, but we serve content from textbook publishers, and all they know is PDF. 10:36 cemerick: abp: I used to do some consulting around PDFTextStream through ~2008, but nothing since then. Mostly been building other (failed, so far) products since then, in addition to open source work, writing, etc. 10:37 mdeboard: Sure. We have a few publishers that use PDFTextStream to improve accessibility in various ways, but I don't know the details of what they've built on top of it. 10:37 mdeboard: is there some combination of "doseq" and "while" out there 10:37 cemerick: Interesting, accessibility is our big push right now. 10:38 cemerick: mdeboard: BTW, confirmed that the PDF of 'Clojure Programming' can be had for$5; just log into your account, add the print version to "your products", and hit the 'upgrade' button.

10:38 mdeboard: yeah I'll have to do it at home, I assume I need some serial number from my copy of the book

10:39 TimMc: mdeboard: You could consume from a blocking queue. What exactly do you want?

10:39 cemerick: mdeboard: shockingly, you don't

10:40 mdeboard: TimMc: See lines 6-7 and 21

10:41 * mdeboard hates PDF

10:43 mpenet: ,(doseq [i [1 2 3 ] :while (< i 3)] (print i))

10:43 TimMc: THat actually doesn't look so bad.

10:43 clojurebot: 12

10:43 TimMc: I found it fairly readable, although I don't know what the fingerprint stuff is about.

10:43 mdeboard: TimMc: Me either

10:44 TimMc: >_>

10:44 Wait, nth can be ternary?

10:44 (doc nth)

10:44 clojurebot: "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

10:44 mdeboard: yeah

10:44 cemerick: mdeboard: oh, it can't be _that_ bad

10:45 mdeboard: cemerick: We're hiring, come see for yourself!

10:45 TimMc: haha

10:45 cemerick: ha ha ;-)

10:45 mdeboard: see what I did there

10:45 TimMc: That's an enticement if I ever heard one.

10:46 * devn smacks himself in the forehead

10:46 devn: emacs-live overrides C-v and M-v?

10:46 gah

10:46 TimMc: mdeboard: Oh, I see -- you're porting code.

10:46 mdeboard: TimMc: Yes

10:46 from the original greek

10:47 TimMc: Frankly, the lexical shadowing bothers me more than the while/atom.

10:47 mdeboard: I actually like C# but we don't have any windows devs anymore

10:48 I have no idea what that is

10:49 uvtc: mdeboard: a local in an inner scope shadowing one in an outer scope?

10:49 chronno: devn: yep, it changes some of the default bindings... take a peek into default-bindings.el

10:49 TimMc: "i" serves double duty in your fn (argument and local), as does "fingerprint" (fn name and local)

10:49 devinus: what other sql modelling libs are there out there other than Korma?

10:50 mdeboard: TimMc: Oh, right, definitely poor variable naming

10:50 nDuff: devinus: SQLAlchemy has its own declarative layer these days

10:50 devinus: nDuff: oh, i was referring to clojure specific

10:51 technomancy: devn: wat

10:51 chronno: devn: C-w was another surprise for me

10:51 devn: technomancy: yeah i couldn't believe it either

10:51 chronno: yeah, wtf

10:51 * devn starts an unruly mob

10:52 nDuff: Oh -- sorry.

10:52 * nDuff forgot which channel he was in.

10:52 devn: chronno: yeah, i just went through and fixed those bindings, but man, that's pretty opinionated. Overriding default bindings is a user pack, not the default IMO

10:52 * cemerick thought it was #emacs-orthodoxy

10:53 TimMc: mdeboard: doseq walks i over the indexes of fingerprint, and then the last line walks to that index+1 in fingerprint and pulls out the value. Why not just iterates over the contents of (concat (rest fingerprint) [(last fingerprint)])?

10:53 devn: same deal with this rainbow paren stuff and the replacement of fn with ƒ and so on

10:53 TimMc: devn: fn-replacement also screws with line length

10:53 Mr_Bond: ƒ is pretty cool

10:53 TimMc: It's good only for demos.

10:53 chronno: devn: yep, I guess it suits people not used to emacs but for more seasoned users its surprising (and annoying, the first time)

10:53 devinus: yeah the fn replacement stuff by default made me scratch my head

10:54 uvtc: devn: your views on emacs-live intrigue me and I wish to subscribe to your newsletter.

10:55 technomancy: it also eschews basic packaging hygiene

10:55 mdeboard: TimMc: Good question. I'm kind of flailing here porting this algorithm over step-for-step, the code's hideous for sure.

10:57 TimMc: mdeboard: No need to call (seq (hex 12)) -- map will call seq for you/

10:57 mdeboard: I see

10:58 sundbp: hi - after exiting an emacs session using nrepl I get a lingering jvm process. any tips for how to avoid this?

11:00 seems to spawn 3 subprocesses for the nrepl session, java -client, which spawns java -cp which in the end spawns the actual process doing the work. it's the last process that remain after exiting emacs

11:00 * ucb waits for somebody to say 'use vi'

11:00 ucb: :D

11:01 abp: use eclipse

11:01 mmitchell: is it possible to have a dependency, which contains "resources" that you can "merge" into your project's resources directory?

11:01 sundbp: if there was a nice nrepl and debugger experience i would. using emacs with evil mode, use vim except for clojure work.

11:02 emacs+evil gets things comfy enough that it's comfortable. even got my vi foot pedal hooked up :)

11:02 jweiss: trying to set up emacs/nrepl/autocomplete - something seems to be showing completions for the nrepl buffer even though auto-complete-mode is not on. i want the popup box for completion, not the separate window. anyone know what is doing that?

11:02 Mr_Bond: sundbp: we actually have a usb-pedal here :)

11:02 abp: sundbp, regarding java processes not being killed, I think that's a more fundamental problem than editor choice.

11:02 Mr_Bond: for our robotics projects :P

11:03 found it on dx

11:03 sundbp: abd: this is oracle downloaded jdk on ubuntu. not the openjdk one.

11:03 Mr_Bond: mine is a 3 pedal usb device that was like 25usd or something similar. cheap enough worth the play :)

11:04 abp: sundbp, jdk version neither, more like clojure tooling ;x

11:04 cemerick: mmitchell: yes, though there's no packaging standard for such things. I've been packaging resource artifacts under a /_rsrc "package", which the ring-resources handler can be configured to look under.

11:09 sundbp: abp: yes, my bet is somewhere between emacs, nrepl.el and nrepl lies the answer, someone isn't properly killing their children

11:10 mpan: I see I picked an awkward time to enter the channel

11:15 thorwil: hmm. how to handle a dependency like the aloha editor. should i just add the whole thing to my git repo? or maybe just a bash script to fetch it and put it into place?

11:16 balint: hey,

11:16 I would like to help out with some "entry-level" clojure OS projects

11:16 barfu: INFO chouser

11:17 balint: I say entry-level because I'm not -yet- an expert clojure programmer

11:17 do you know any ones that need help?

11:17 I checked the ones on http://clojurewerkz.org/ but they don't seem to have any open issues

11:19 duck1123: mmitchel_: You might want to check out webjars.org to see how they use resources directories to package js libs

11:19 uvtc: hi balint . I suppose it depends somewhat on what you're interested in.

11:20 balint: uvtc: i'm proficient with web-related stuff so noir/ring are good candidates

11:20 but they seem to be somewhat abandoned

11:21 mdeboard: wut

11:21 uvtc: balint: I think the author of noir is working full-steam on LightTable at the moment.

11:21 mdeboard: Didn't raynes take over noir?

11:21 or am I thinking of korma

11:22 balint: storm is another fascinating one but at first glance it's too complex to grok

11:22 clgv: mdeboard: Raynes did some refactoring and pulled out a lib from noir that contains functions that are useful for non-noir projects as well

11:22 clojurebot: libraries is http://clojure.org/libraries

11:22 balint: uvtc: yes, I believe so, too

11:22 technomancy: compojure and ring are definitely not abandoned, but they're just small enough that there's not a lot of ongoing feature work on them

11:22 uvtc: I think Raynes was doing some work on https://github.com/noir-clojure/lib-noir .

11:23 balint: technomancy: ok, got it

11:23 uvtc: balint: you might poke arond http://clojure-doc.org/articles/ecosystem/libraries_directory.html for some ideas.

11:28 abp: I didn't know about:

11:28 balint: uvtc: great, thank you

11:28 abp: ,(conj {:a 1} {:b 2})

11:28 clojurebot: {:b 2, :a 1}

11:28 reikalus1kka: is rlwrap essential for clojure development?

11:29 nDuff: not _essential_, no.

11:29 if you're using emacs + nrepl/slime, it's completely unimportant

11:29 but having some kind of a nice REPL environment is important.

11:30 uvtc: reikalus1kka: if you're using lein repl, I think it comes with everything you need.

11:30 reikalus1kka: okay. I'm not completely sure what I need or how I should set up my development environment

11:30 uvtc: reikalus1kka: http://clojure-doc.org/articles/tutorials/getting_started.html

11:30 reikalus1kka: I run the command lein repl and I got the message Using JLine for console I/O; install rlwrap for optimum experience.

11:31 nDuff: reikalus1kka: ...so, a lot of this depends on what kinds of keybindings/keystrokes you're accustomed to expecting.

11:31 reikalus1kka: if everything you expect works (ctrl+a, ctrl+k, etc etc), then you're good.

11:31 reikalus1kka: ...if you're going to be using something more capable than "lein repl" for most of your experimentation, then you're also good.

11:31 reikalus1kka: what should those keybindings do? xD

11:32 I plan to use sublime texeditor for writing code.

11:32 texteditor*

11:32 duck1123: reikalus1kka: You might want to look into updating your lein version. But having rlwrap doesn't really hurt much and is handy to have around

11:32 S11001001: reikalus1kka: the readline defaults are based on emacs defaults.

11:32 nDuff: reikalus1kka: does sublime have any kind of REPL integration or paredit support? I'm not saying not to use it, but you might be missing out on a lot.

11:32 S11001001: reikalus1kka: never used rlwrap in ~2yrs of professional clojuring, but I used emacs, so...

11:33 nDuff: reikalus1kka: ...a good LISP-aware editor can do some beautiful things.

11:33 S11001001: reikalus1kka: anyway, readline is wildly configurable with respect to keybindings.

11:33 reikalus1kka: I don't think sublime has it and I didn't know I need to use it. I never used emacs and I feel too dump to use it. and I have no previous experience in any lisp dialect

11:34 uvtc: reikalus1kka: "readline" means making your repl keyboard shortcuts act like a regular GNU/Linux bash terminal.

11:34 S11001001: reikalus1kka: (readline is the library that rlwrap uses)

11:35 uvtc: reikalus1kka: when just starting out, you can just use a terminal window along with your text editor.

11:35 nDuff: reikalus1kka: if you _do_ decide to try emacs at some point in the future, look at "Emacs Live" for an out-of-the-box configuration with everything you need to be productive (and videos/presentations showing what it does / how to use it).

11:37 abp: Any ideas on how to write macros with the semantics of fn? I need to preprocess the arguments to the function, but everything else is just fn.

11:37 reikalus1kka: okay. I'll put that behind my ear

11:37 I will be happy if I can just get started

11:37 S11001001: abp: expand to fn.

11:37 abp: e.g. (fn [gensyms...] (let [fn-args use-gensyms...] body...))

11:39 abp: S11001001, sure, but I need to correctly take the arguments fn takes too, access the argument vector and pass it along. I already got a dumnded down version, but there is a meta-map to be supported etc.

11:40 S11001001: abp: if you want full fn, you need to parse enough of the destructuring language to get what you need without breaking stuff

11:40 essentially that just means knowing what & does

11:40 abp: S11001001, Destructuring doesn't matter. :)

11:41 S11001001: well, there's nothing really special about writing fn variants otherwise.

11:41 abp: S11001001, so not quite all what fn does. Mostly meta/name/rgs, no meta/name/args, no meta/no name/args etc.

11:42 S11001001: you've got string?, symbol?, vector?, map?

11:45 bordatoue: hello

11:45 is it possible to create a local binding that maintains state in clojure.

11:48 nDuff: bordatoue: could you be a little more explicit?

11:49 bordatoue: ...I mean, it's possible to update a thread-local dynamic var, or to modify root bindings, but more background would be helpful to understand the right thing for your use case.

11:49 bordatoue: i would like to have a procedure that returns another procedure modifying the binding of the first procedure

11:52 nDuff: bordatoue: ...well, you can only modify a thread-local binding that's actually valid while you're being called, so the context in which the the returned function is invoked matters.

11:53 bordatoue: within that caveat, nothing's stopping you.

11:53 bordatoue: nDuff: for example http://hastebin.com/rimigojuke.cs

11:53 nDuff: ...okay, I think I misunderstood your question, then, if that snippet has anything to do with it.

11:54 bordatoue: nDuff: how do i update the value bound in the outer procedure

11:55 nDuff: bordatoue: ...first, define a dynamic var outside of the outer procedure, bind it _in_ the outer procedure, and alter its binding in the inner procedure.

11:55 that last piece is done with var-set

11:56 bordatoue: nDuff: http://hastebin.com/cavawaveke.cs

11:56 nDuff: ...

11:56 bordatoue: nDuff: if i define a dynamic var then won't that be accesible to other procedures

11:57 nDuff: Huh?

11:57 jondavidjohn: Could I bother any clojure guru's in here to take a look at one of my first clojure attempts, and give it a critique? http://codereview.stackexchange.com/questions/19073/first-go-at-clojure-and-functional-programming-in-general

11:57 nDuff: bordatoue: That's not true at all. Where do you have that idea from?

11:57 duck1123: In your mind, whenever you find yourself thinking "I need to update..." replace it with "I need to return a new copy of..."

11:57 nDuff: bordatoue: ...unless you mean you want it to still be callable after the scope of the outer binding exits; that's true enough.

11:57 bordatoue: nDuff: i am trying to create an object model using procedures

11:58 nDuff: bordatoue: if that's the case, you might want to bind an atom.

11:58 ...actually, don't need a var at all at that point.

11:58 ...pass the atom around, and it can be eventually returned.

11:58 bordatoue: nDuff: okay so its an atom ,

12:00 nDuff: i need to read on atom , what does that mean futher decomposition is not allowed

12:00 nDuff: bordatoue: ...pardon?

12:01 bordatoue: why is it called atom if we can mutate it , is it like CAS operation

12:01 nDuff: bordatoue: yes, individual changes to the atom are serialized and atomic.

12:02 * nDuff thinks that trying to create an "object model" rather than trying to model a problem functionally speaks to at least some level of setting off on the wrong foot to start with.

12:02 seangrove: If in my cljs I require a non-existant namespace, shouldn't it complain at compile time that it can't find it? My test code just happily goes along with it

12:03 The compiled output from the cljsbuild test that I'm trying to build just has the goog-closure library with the test code appended - none of the required namespaces are included between them

12:04 So when the test (ns example.hello.test (use [example.hello :only [work-you-bastard!]])), in the output.js it goog.provides("example.hello.test") right after the goog closure code, then goog.requires("example.hello"), which isn't in the output

12:04 I can't figure out what I'm doing incorrectly

12:05 duck1123: seangrove: what level of compilation are you using? IIRC, it only complains at the higher levels

12:05 bordatoue: nDuff: can you recommend any way i could create a local fn that would maintain local state, i don't want idempotent fn calls

12:05 seangrove: whitespace

12:06 For the :test build, it's supposed to add the source-path of all other builds, so that requires work properly. It works in the cljsbuild advanced project example, but the same process doesn't work on a different project

12:07 lucian: bordatoue: the simplest way around is to always pass in and return that state

12:07 bordatoue: the other might be an atom

12:07 nDuff: bordatoue: one way to do that is for your function to close over an atom. Really, though, trying to do that is indicative of trying to do things "the wrong way".

12:08 bordatoue: thanks lucian , nDuff .

12:09 nDuff: i can't understand your view on saying "the wrong way", say if you want some local state to be maintained then?

12:09 i am not talking about maintain a global state , just locally to a procedure

12:09 nDuff: bordatoue: keeping local state inside your functions is considered bad practice here.

12:10 bordatoue: nDuff: is that specific to clojure or functional programming in general

12:10 seangrove: jondavidjohn: Just syntax-wise, I believe that (map (fn [p] []) (range num_piles)) is equal to (map #{[]} (range num_piles))

12:11 nDuff: bordatoue: functional programming in general -- one of the Big Ideas is that state should be kept in well-understood places and modified only in well-understood (and observable) ways. Hiding little bits of state all over the place makes reasoning about your logic harder.

12:11 lucian: bordatoue: if you think about it, state local to a function is exactly the same as an argument

12:11 seangrove: ,(map (fn [p] []) (range 4))

12:11 nDuff: bordatoue: ...Clojure provides exceptionally good tools for managing state in this way.

12:11 clojurebot: ([] [] [] [])

12:11 seangrove: ,(map #{[]} (range 4))

12:11 clojurebot: (nil nil nil nil)

12:11 seangrove: Nope, I was wrong, heh

12:11 jondavidjohn: yeah, I tried that, and it was complaining about wrong number of args

12:11 lucian: bordatoue: but the argument makes it much clearer about what's going on

12:11 jondavidjohn: passing hte p made it work

12:13 for speed considerations, should I make each "pile" a transient also?

12:13 ,(map (fn [p] (transient []) (range 4))

12:13 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

12:13 jondavidjohn: ,(map (fn [p] (transient []) (range 4)))

12:13 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map> 12:13 jondavidjohn: ,(map (fn [p] (transient [])) (range 4)) 12:13 clojurebot: (#<TransientVector clojure.lang.PersistentVector$TransientVector@6fc01c8f> #<TransientVector clojure.lang.PersistentVector$TransientVector@2d93299a> #<TransientVector clojure.lang.PersistentVector$TransientVector@189054d6> #<TransientVector clojure.lang.PersistentVector$TransientVector@2bb1ba33>) 12:14 jondavidjohn: and will (persistent! parent) follow and "persistantize" each element if they are transients also? 12:14 Chousuke: no 12:15 don 12:15 don't optimise too much before you actually have a problem 12:15 jondavidjohn: right, just trying to get a best practice approach from the word go. 12:15 Chousuke: if you are making very large vectors, use transients for those. 12:16 and never let transients escape the function where you use them. 12:16 (you will know when to break that rule.) 12:16 jondavidjohn: I'm actually trying to make a comparison to a python c extension I wrote for this same algorithm, speed wise. 12:17 seangrove: duck1123: I think you're write about advanced mode 12:18 jondavidjohn: so If I wanted to transient all the "piles" I would maybe do something like (persistent! (map (fn [p] (persistent! p) parent) 12:19 Chousuke: you can't do that. 12:19 since map will not return a transient 12:19 you will have to loop explicitly. 12:19 but I don't think it's worth it. 12:19 jondavidjohn: so if I map a transient, will it return a persistent list? 12:19 Chousuke: you can't use map on transients. 12:19 jondavidjohn: or you simply can't map a transient 12:19 ok 12:20 Chousuke: in general, transients should be a local optimisation 12:20 first make your code work without them 12:20 then, if performance is an issue, add transients. 12:20 jondavidjohn: right, and it is currently 12:21 Chousuke: how large are your vectors? 12:21 jondavidjohn: since I'm trying to make it compete with my c implementation, every ms counts... I know in the practical world what you're saying makes sense, but as an experiment and learning... 12:21 it's going to be a library, so however large the user wants them to be. 12:22 a library of different types humanoid shuffles 12:22 Chousuke: no, I mean, how large do you expect them to be, relative to each other? 12:22 jondavidjohn: equal 12:22 Chousuke: will you have thousands of piles each containing thousands of items? :/ 12:22 jondavidjohn: if that's what the user wants ;) 12:22 but realistically probably not 12:23 Chousuke: also, will this vector of piles be constructed all in one go? 12:23 transients are only useful if that's the case. 12:23 jondavidjohn: take a look at my full function here... http://codereview.stackexchange.com/q/19073/2776 12:27 Chousuke: jondavidjohn: your problem there is that you're not making the piles themselves persistent. also the concat operation looks suspicious 12:27 seangrove: Is the author of cljsbuild ever in here? 12:28 Chousuke: jondavidjohn: moving things like (count cards) outside the loop might help a slight bit too, especially if cards is not Counted 12:28 jondavidjohn: I was under the impression that I'm the parent vector of piles (vectors) a transient, but each individual pile was persistent 12:29 Chousuke: oh, right, I misread your code 12:29 jondavidjohn: would it be better to make each pile a transient and leave the parent as a persistent? 12:30 since I'm associng on the pile and not the parent 12:30 Chousuke: jondavidjohn: the problem with that is that you still have to update the parent with the new pile when you assoc to the transient 12:30 seangrove: This just doesn't seem to be true, locally: "Note that all of the :source-path entries from the :builds are added to the classpath, so the tests can :require ClojureScript namespaces from, e.g., the src-cljs directory" 12:31 jondavidjohn: ok 12:31 Chousuke: jondavidjohn: since assoc on a transient is not guaranteed to return the same object 12:31 jondavidjohn: so with the count, wrap the loop in a let and assign the card count once there, and use it within the loop? 12:32 and I'm using the concat to push new items on the front of the pile, the opposite of conj 12:32 Chousuke: jondavidjohn: btw you can replace that map thingy with (transient (vec (repeat num_piles []) 12:32 jondavidjohn: so (concat [(new item)] [pile]) 12:32 Chousuke: jondavidjohn: you should use a list instead of a vector for the piles then 12:32 jondavidjohn: coool, that looks much nicer 12:33 Chousuke: (vec (concat foo bar)) is terribly slow 12:33 jondavidjohn: ok, are lists of things more common than vectors of things? and will that impact my usage of vectors elsewhere in the code? 12:34 Chousuke: lists and vectors are for different operations 12:34 lists have fast add to the front 12:34 vectors have fast random access and fast add to the tail 12:34 jondavidjohn: ok 12:34 can you cast a vector to a list and vice versa cheaply? 12:34 kaoD_: list also have fast (rest ) 12:35 nDuff: jondavidjohn: not cheaply, no. 12:35 Chousuke: a vector becomes a list easily 12:35 but not vice versa 12:35 llasram: A vector becomes a *seq* easily 12:35 kaoD_: Chousuke: are you sure about that? 12:35 Chousuke: a seq is essentially a list in this case 12:35 mbcev: I thought a vector WAS a seq? 12:35 Chousuke: nah 12:35 kaoD_: I don't think a vector is easily converted to a list 12:35 Chousuke: vectors aren't seqs 12:35 jondavidjohn: I'd love it if this function could be somewhat collection agnostic 12:35 Chousuke: kaoD_: lists are just non-lazy seqs 12:35 nDuff: mbcev: vectors are seqable, but that's not the same as being a seq 12:36 kaoD_: Chousuke: then a vector CANNOT be converted easily into a list 12:36 right? 12:36 clojurebot: to be fair I dunno that I've ever had code out right rejected, it just sits in jira or assembla or where ever, or if I ask if there is any interest (before writing any code) I get told to go write alioth benchmarks 12:36 Chousuke: okay, well, it can be converted easily into a seq 12:36 but in this case, it doesn't matter if it's a list or a seq 12:36 kaoD_: yeah, sorry, I came late into the conversation 12:37 Chousuke: you still get fast conj to the front. 12:37 kaoD_: I'm currently reading jondavidjohn's question at CodeReview 12:37 cola_zero: but not fast rest, right? 12:37 oops, sorry 12:37 Chousuke: 12:37 Chousuke: kaoD_: nah, rest is fast too 12:37 kaoD_: sure? even for not consed seq'ed vectors? 12:38 jondavidjohn: good grief clojure has such an esoteric lingo it seems, at least for a noob 12:38 Chousuke: I'm pretty sure iterating a vector is fast 12:38 kaoD_: but not as fast as iterating over a list 12:38 (linearly) 12:38 Chousuke: jondavidjohn: seq is the main abstraction in clojure 12:38 jondavidjohn: it's basically a lazy list 12:38 mthvedt: johndavidjohn: is speed a goal? 12:38 Chousuke: or a generator 12:39 jondavidjohn: Speed and generality, which are probably competing interests 12:39 nDuff: jondavidjohn: what are you trying to do in this code? 12:39 kaoD_: iterating over a vector needs access to its buckets or whatever it's called 12:39 resting a list is easy, just strip the head 12:39 Chousuke: jondavidjohn: you can make these seqs out of many things, like vectors, maps, sets or lists, and there are many functions which operate on seqs 12:40 kaoD_: the seq implementation of vector has access to everything it needs 12:40 kaoD_: but it's slower than a list 12:40 jondavidjohn: so maybe turn whatever collection is passed into a seq. Is it wierd to take in one type and return a different type? 12:40 nDuff: jondavidjohn: ...the general abstraction is seqs; they just don't promise that many things other than reading will be fast. 12:40 Chousuke: jondavidjohn: no, if it makes sense to return a seq 12:41 jondavidjohn: in fact, if you can return a lazy seq, it's usually considered good to do so 12:41 jondavidjohn: since then your user can just call your function and take for example the first three things 12:41 mthvedt: i wonder if you can split one seq into several lazy seqs 12:41 Chousuke: and not pay the cost of getting the lest 12:41 rest 12:41 mthvedt: in the manner of a pile shuffle deal 12:41 Chousuke: ;| 12:41 jondavidjohn: so if a user passes me a list to shuffle, wouldn't they expect a list back? or is it common to pass back a lazySeq 12:41 nDuff: jondavidjohn: ...but what's the actual use case here? It's easier to provide good advice when dealing with specifics rather than generalities. 12:42 Chousuke: jondavidjohn: you would return a lazy seq in that case 12:42 devn: ...emacs-live rebinds C-h 12:42 wtf. 12:42 nDuff: jondavidjohn: passing back a lazy seq is common -- improves efficiency, if the consumer only needs part of the list. 12:42 Chousuke: jondavidjohn: since lazy seqs are for all purposes indistinguishable from actual lists 12:42 kaoD_: nDuff: jondavidjohn just wants to shuffle a "pile" 12:42 jondavidjohn: nDuff: I'm implementing a "pile shuffle"(http://en.wikipedia.org/wiki/Shuffling#Pile_shuffle) 12:42 kaoD_: he wants to make a library, so he doesn't know if his users want it lazy or not 12:42 llasram: jondavidjohn: Most sequence functions just return seqs -- that's definitely the common idiom. The user can then turn that into whatever they want 12:43 jondavidjohn: cool 12:43 Chousuke: jondavidjohn: for example, in clojure it's perfectly fine to do the following (map #(Thread/sleep 1000) (range 100000000000)) 12:43 it will take no time providing you actually don't try to get at the latter items 12:44 nDuff: Hmm. A shuffle algorithm isn't necessarily something that _can_ be lazy, then. 12:44 Chousuke: you can imagine Thread/sleep being some hideously expensive computation. 12:44 nDuff: I think there is a lazy shuffle algorithm in contrib somewhere 12:45 jondavidjohn: converting to and operating on a seq will take some rewriting? or is the api similar to a vector? 12:45 nDuff: jondavidjohn: vectors implement ISeq, so if you're operating on the vector using seq operations already, there's no difference. 12:45 Chousuke: jondavidjohn: you have most of the operations available to you except random access 12:46 kaoD_: jondavidjohn: be aware: you cannot random-access a sequence 12:46 because, well, it's SEQuential 12:46 jondavidjohn: Chousuke: cool, which I'm not using 12:46 Chousuke: vectors implement Seqable, not ISeq 12:46 you can call seq on a vector to get a sequence view to it, but it won't be a vector anymore 12:46 clojurebot: doseq is like for, but for side effects instead of values 12:46 * nDuff stands corrected. 12:46 jondavidjohn: how would I return a LazySeq once I'm done building the new seq? 12:47 Chousuke: jondavidjohn: you don't do that 12:47 if you were done building a seq, it would not be lazy :) 12:47 jondavidjohn: hah, right, so is this algorithm even lazyable? 12:47 So in this case I would just return the seq 12:47 Chousuke: I have no idea, but I suspect it isn't. 12:47 nDuff: jondavidjohn: I can think of variants of it that could be, though they'd get more expensive towards the end. 12:47 kaoD_: jondavidjohn: you just deal cards alternatively into "piles", right? 12:47 and then stack those piles 12:48 jondavidjohn: right 12:48 Frozenlock: Is there a way to use maven-plugins with leiningen? 12:48 kaoD_: it's mathematically solvable? 12:48 jondavidjohn: in order, there's probably a way to calculate the new order 12:48 kaoD_: then if you need speed 12:48 THAT is your solution 12:48 since vectors do support pretty fast random access 12:49 jondavidjohn: right 12:49 lucian: so a user could pass in a vector and receive back a seq 12:49 you could use the vector as a source as much as you want 12:49 mthvedt: johndavidjohn: i think this will work: partition by n for n piles, then return n sequences that map get 1..n 12:49 technomancy: Frozenlock: no. you can emit a pom with a <plugin> section though I think 12:49 kaoD_: you could even keep the vector interface and make it still vector-like with random access 12:49 mthvedt: partition and map are lazy 12:50 jondavidjohn: that would be some pretty hard math 12:50 kaoD_: jondavidjohn: I don't think so 12:50 jondavidjohn: dealing n cards into n piles (sequentially) and rejoining them 12:50 Chousuke: hm 12:50 Frozenlock: technomancy: thanks 12:50 kaoD_: it seems like easy math to me 12:51 mattmoss: n-th permutation 12:52 Chousuke: ,(apply interleave (partition 3 [1 2 3 4 5 6 7 8 9])) 12:52 clojurebot: (1 4 7 2 5 ...) 12:52 jondavidjohn: so 10 cards using 3 piles end up [10 7 4 1 8 5 2 9 6 3] 12:53 Chousuke: ,(iterate (comp apply interleave) (partition 3 [1 2 3 4 5 6 7 8 9]))) 12:53 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (1) passed to: core$interleave>

12:53 Chousuke: hmm

12:53 jondavidjohn: to illustrate it better [10 7 4 1 - 8 5 2 - 9 6 3]

12:53 Chousuke: ,(take 1 (iterate (comp apply interleave (partial parition 3)) [1 2 3 4 5 6 7 8 9])))

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

12:53 Chousuke: ,(take 1 (iterate (comp apply interleave (partial partition 3)) [1 2 3 4 5 6 7 8 9])))

12:53 clojurebot: ([1 2 3 4 5 ...])

12:54 Chousuke: hm

12:54 kaoD_: jondavidjohn: it's something along the lines of (piles, size) -> [(n) -> (+ (* (/ size piles) (mod n piles)) (/ n piles))]

12:54 right?

12:54 clojurebot: to be fair I dunno that I've ever had code out right rejected, it just sits in jira or assembla or where ever, or if I ask if there is any interest (before writing any code) I get told to go write alioth benchmarks

12:54 kaoD_: fuck you clojurebot

12:55 jondavidjohn: haha

12:55 llasram: &(letfn [(pile [n cards] (->> (range n) (map #(take-nth n (drop % cards))) (apply concat)))] (pile 3 (range 10)))

12:55 lazybot: ⇒ (0 3 6 9 1 4 7 2 5 8)

12:55 jondavidjohn: an answer on codereview suggests this " (->> (range n) (map #(take-nth n-piles (drop % cards))) (apply concat))"

12:55 llasram: Yeah, that was me

12:55 It got noisy here :-)

12:56 Oh, actually:

12:56 jondavidjohn: llasram: that works but it's reversed

12:57 kaoD_: &(/ 3 21)

12:57 lazybot: ⇒ 1/7

12:57 llasram: Oh, easy enough

12:57 kaoD_: &(div 3 21)

12:57 lazybot: java.lang.RuntimeException: Unable to resolve symbol: div in this context

12:57 kaoD_: what is the integer division operation?

12:57 jondavidjohn: to illustrate it better [10 7 4 1 - 8 5 2 - 9 6 3]

12:57 Chousuke: (I think I have an onelinesr for this now

12:57 jondavidjohn: would be the result I'm looking for

12:57 kaoD_: oooh, you want it REVERSED

12:58 I get it now

12:58 jondavidjohn: Clojure is some serious ninja wizardry...

12:58 kaoD_: (since you're dealing it backwards)

12:58 jondavidjohn: dealing form the top of the original deck, but the first card dealt to a pile ends up the last card in the pile

12:58 Chousuke: ,(take 1 (iterate (comp (partial apply interleave) (partial partition-all 3)) [1 2 3 4 5 6])

12:58 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

12:58 Chousuke: ,(take 1 (iterate (comp (partial apply interleave) (partial partition-all 3)) [1 2 3 4 5 6]))

12:58 clojurebot: ([1 2 3 4 5 ...])

12:58 kaoD_: &(quot 3 21)

12:58 lazybot: ⇒ 0

12:58 Chousuke: hm, still some error there

13:00 llasram: &(letfn [(pile [n cards] (->> (range n) (mapcat #(take-nth n (drop % cards))) (reduce conj nil)))] (pile 3 (range 10)))

13:00 lazybot: ⇒ (8 5 2 7 4 1 9 6 3 0)

13:00 jondavidjohn: haha, almost, can you deal left to right, instead of right to left?

13:00 since we're joining the piles left to right

13:00 mattmoss: &(separate (fn [_] (< (rand) 0.5)) (range 10))

13:00 lazybot: java.lang.RuntimeException: Unable to resolve symbol: separate in this context

13:01 jondavidjohn: I'm sorry, but this is freaking ludicris that you can do that on one line...

13:01 mattmoss: &(filter (fn [_] (< (rand) 0.5)) (range 10))

13:01 lazybot: ⇒ (0 4 7 9)

13:01 mattmoss: &(filter (fn [_] (< (rand) 0.5)) (range 10))

13:01 lazybot: ⇒ (0 3 4 6 7)

13:01 llasram: &(letfn [(pile [n cards] (->> (range n) (mapcat #(take-nth n (drop % cards))) reverse))] (pile 3 (range 10)))

13:01 lazybot: ⇒ (8 5 2 7 4 1 9 6 3 0)

13:01 Chousuke: ,(take 5 (iterate (comp (partial apply interleave) (partial partition-all 3)) [1 2 3 4 5 6]))

13:01 clojurebot: ([1 2 3 4 5 ...] (1 4 2 5 3 ...) (1 5 4 3 2 ...) (1 3 5 2 4 ...) (1 2 3 4 5 ...))

13:02 kaoD_: Chousuke: you can do these tests in private-msgs

13:02 (I'm doing it there so it doesn't get noisy)

13:02 Chousuke: I was doing most of the work in tryclojure actually

13:02 jondavidjohn: or... you know in an actual repl...

13:02 llasram: Haha

13:02 Chousuke: that algorithm is probably horrendously slow for larger decks though

13:03 jondavidjohn: Chousuke: yours or llasram's?

13:03 Chousuke: mine

13:03 it's too lazy

13:04 so if you have lots of piles and large decks you get loads of thunks

13:04 and at some point it will blow the stack

13:04 llasram: &(letfn [(pile [n cards] (let [cards (reverse cards)] (->> (range n) (mapcat #(take-nth n (drop % cards))))))] (pile 3 (range 1 11)))

13:04 lazybot: ⇒ (10 7 4 1 9 6 3 8 5 2)

13:05 jondavidjohn: llasram: so close [10 7 4 1 8 5 2 9 6 3]

13:06 llasram: jondavidjohn: Huh. Why?

13:06 jondavidjohn: the last two piles are reversed

13:06 llasram: Oh, I see

13:06 jondavidjohn: But the problem is this is very cool, but I can't begin to understand what is happening on that line...

13:09 llasram: Ok, reverse the pile selection order, and swap the reversal back to the end:

13:09 &(letfn [(pile [n cards] (->> (range (dec n) -1 -1) (mapcat #(take-nth n (drop % cards))) reverse))] (pile 3 (range 1 11)))

13:09 lazybot: ⇒ (10 7 4 1 8 5 2 9 6 3)

13:11 jondavidjohn: feels like magic...

13:11 llasram: jondavidjohn: It mostly just takes getting familiar with the standard library sequence functions. They are insanely powerful, and because they each return something that the others can consume are easily composable

13:12 Chousuke: functional programming with lazy sequences often does look like magic but it's just unfamiliarity :P

13:12 lucian: jondavidjohn: it's useful to take each bit and give it inputs, see what happens

13:12 Chousuke: also you should understand that these algorithms are not efficient at all. :/

13:12 lucian: jondavidjohn: it's partly like syntax in most languages

13:13 Chousuke: and yeah, looking at what happens at each step is often useful

13:13 jondavidjohn: yeah, going to take me a bit to digest this, but thanks for all the help and info

13:13 lucian: i don't fully understand that expression just by glancing either

13:13 llasram: Chousuke: I'm pretty sure my function is O(n). The constant multiplier is larger an optimally efficient implementation, but I thinkn the allgo is fine

13:13 Chousuke: jondavidjohn: the point about laziness is that you can work with your data as if you always did the entire operation on the data structure

13:14 jondavidjohn: right, evaluate as needed

13:15 Chousuke: it also means you can work with infinite data structures

13:15 jondavidjohn: back to the day job for me (PHP :p), thanks again for everything..

13:17 Chousuke: And even with all this, clojure's flavour of functional programming is significantly less mind-bending than eg. haskell's :P

13:17 * seangrove sighs

13:17 Chousuke: Clojure can do everything haskell does, for the most part, but haskell people actually *use* that crazy stuff.

13:17 seangrove: I'll have to give up on testing cljs code for now, I've been defeated

13:19 dnolen: this is a pretty awesome CLJS series of tutorials - including how to contribute back to the compiler! http://github.com/magomimmo/modern-cljs

13:25 dnolen: SegFaultAX: raphael amiard is not actively working on it from what I can tell, but it seems like it's in decent spot for someone else to pick it up if so inclined.

13:26 kaoD_: jondavidjohn: I still think it's mathematically solvable

13:26 see this

13:26 &(map #(let [per-pile (quot 9 3)] (+ 1 (* (mod (- per-pile 1 %) per-pile) per-pile) (quot % per-pile))) (range 9))

13:26 lazybot: ⇒ (7 4 1 8 5 2 9 6 3)

13:27 kaoD_: it utterly fails with (not= (mod elements piles) 0)

13:27 but hey, it's not bad for starters :P

13:35 uvtc: I was asking about Clojure + Android on the ML. I wonder, has there been any movement on having Clojurescript transpile Clojure to Java?

13:35 mdeboard: wut

13:35 technomancy: you mean compile?

13:36 uvtc: Er, right. Compile Clojure ==> Java.

13:37 S11001001: uvtc: you don't need that; you can convert jvm bytecode to dalvik bytecode. That's what the scala toolchain does.

13:37 technomancy: uvtc: you can't represent locals-clearing in Java

13:38 uvtc: S11001001: I should probably ask about these details on clojure-android...

13:38 S11001001: Thanks.

13:39 technomancy: What is "locals-clearing"?

13:40 technomancy: uvtc: without locals-clearing (or TCO) you get memory leaks when using lazy seqs since keeping them in a local prevents them from being GC'd

13:41 uvtc: technomancy: ok, related to GC. Thank you.

13:41 technomancy: locals-clearing emits bytecode to avoid references to unused locals once they're not used anymore

13:41 but the bytecode it emits can't be generated from javac

13:41 uvtc: technomancy: oh, interesting.

13:42 tomoj: huh, I thought it was just "var = null"

13:43 TimMc: technomancy: Wait, javac doesn't do locals-clearing? o.o

13:43 technomancy: tomoj: yes, but how do you handle it if the last reference is in a call to another method?

13:43 tomoj: you have to null it after it's placed on the stack frame for the call

13:44 mthvedt: TimMc: javac isn't smart enough to figure out if a reference isn't going to be used

13:44 TimMc: Shouldn't it be?

13:45 mthvedt: the general case is a tough problem

13:45 technomancy: not with the granularity needed to deal with laziness

13:46 jonasac: just got reply from the modulecounts.com maintainer today, a couple of weeks ago i suggested he added clojars, and he did :)

13:46 TimMc: technomancy: Apparently this is how you do it manually in Java: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L146

13:47 tomoj: ah, I wondered what that was supposed to do

13:47 TimMc: Someone in the channel explained it to me a while back. (Possibly technomancy!)

13:47 technomancy: TimMc: haha; gross

13:47 wasn't me =)

13:48 aw man, that indentation... ugh

13:51 hcumberdale: Hi ;)

13:51 TimMc: They do it that way to make you cringe.

13:51 hcumberdale: How to add custom jars to my project?

13:51 mthvedt: i don't understand how that code would work

13:51 hcumberdale: they are not in any maven2 repo

13:52 S11001001: mthvedt: order of arg evaluation is guaranteed in java

13:52 uvtc: technomancy: First shalt thou indent the code. Then shalt thou indent 4 spaces --- no more, no less. Four shall be the number thou shalt count, and the number of the counting shall be four. Eight shalt thou not count, neither count thou two, excepting that thou then proceed to four. Five is right out.

13:53 technomancy: uvtc: haha; nice

13:53 S11001001: mthvedt: like common lisp, unlike r5rs scheme

13:53 technomancy: hcumberdale: first step is to get them into a repository

13:53 hcumberdale: technomancy is it not possible to work with an own lib folder

13:54 like having a "lib/own.jar" dependendy in project.clj?

13:54 technomancy: hcumberdale: there is no good way to do it

13:54 there are some bad ways

13:54 hcumberdale: is there any lein2 functionality to add files to the local m2 repo?

13:54 mthvedt: S11001001: so the point is to pass the ref to o to countfrom while clearing it on the stack?

13:55 S11001001: mthvedt: it's not a ref, it's whatever o is. Java is a pass-by-value language; it is merely that so many of those values are references.

13:55 the-kenny: hcumberdale: lein install?

13:56 mthvedt: S11001001: right, i meant ref in the java sense

13:56 hcumberdale: the-kenny lein install third_party_lib.jar ?

13:56 S11001001: mthvedt: then yes.

13:56 welcome to wonderful world of side-effects and operation ordering

13:56 the-kenny: Oh, a random jar. Don't think so. I use maven for that

13:56 technomancy: hcumberdale: a better question might be who is asking you to use a jar without putting it in a repository? because they need to get their act together.

13:56 there's a lein-localrepo plugin to do that

13:57 but it's addressing the symptoms, not the actual problem

13:57 mthvedt: is there a good way to use reify that supports equality among instances of that reified class

13:57 hcumberdale: technomancy it is a licensed third party module

13:57 handed out as .jar

13:57 to use it in java projects within ant files

13:57 or dirty maven hacks

13:58 so I just want to have a third-party-libs folder in my lein2 project

13:58 to move the jar there

13:58 technomancy: you can use localrepo for that

13:58 but you should file a bug report too

13:58 S11001001: hcumberdale: when we dealt with that, we wrote a pom and added it to our maven repo.

13:59 hcumberdale: technomancy a bug report? why?

13:59 S11001001 then you need an own maven repo

13:59 technomancy: because distributing a jar by hand is crazy

13:59 mthvedt: like if i have (defn myfn [arg] (reify MyClass …)), is there a succinct way to have (= (myfn "foo") (myfn "foo"))

13:59 hcumberdale: technomancy, that's how big companies like HP work ;)

14:00 S11001001: mthvedt: = falls back on Object.equals when it doesn't know what to do

14:00 mthvedt: this sucks but is better than nothing

14:00 technomancy: hcumberdale: you mean poorly? =)

14:01 hcumberdale: technomancy they work just like they work. ;)

14:03 technomancy: it's lay

14:03 lazy

14:03 abp: A few minutes ago I thought Java and it's ecosystem are only acceptable for large companies which can afford that waste of time. ;x

14:03 hcumberdale: technomancy what's a better way for them to do it?

14:03 abp: But they waste even more time. :D

14:03 mthvedt: S11001001: i'm having trouble coming up with a non-hideous implementation of equals that works for this

14:03 hcumberdale: Handing it out with a own maven server?

14:03 -a +an

14:04 technomancy: hcumberdale: right

14:04 Frozenlock: technomancy: I'm trying to write a Lein plugin. It need to run after a uberjar. Any suggestion on which function I should hook myself?

14:04 technomancy: it can just be a pile of static files on disk behind http basic auth

14:04 no excuses

14:04 Frozenlock: if it needs to run after every uberjar then just hook the uberjar task function itself

14:05 otherwise write an alias that composes the two

14:05 Frozenlock: Great, thank you very much!

14:05 technomancy: no problem

14:05 xumingmingv: ,(loop [input "help"]

14:05 (println "xxx")

14:05 (print "=> ")

14:05 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

14:07 xumingmingv: why the result of these lines of code will be "=> xxxx" rather than "xxxx =>"?

14:07 devn: cemerick: you around by any chance?

14:07 cemerick: devn: depends :-P

14:08 technomancy: xumingmingv: need to flush stdout

14:08 devn: haha, i think im missing something w/r/t using friend

14:08 let me gist something for you to peek at

14:09 xumingmingv: (loop [input "help"]

14:09 (println "xxx")

14:09 (flush)

14:10 (print "=> ")

14:10 technomancy: like this?

14:12 technomancy: xumingmingv: please don't paste code into the channel

14:12 you need to flush after print

14:13 devn: cemerick: i gisted it, but i just discovered i'm missing ring.middleware.reload, and that seems like a likely culprit, investigating that avenue first

14:13 xumingmingv: technomancy: ah, thanks!

14:14 cemerick: devn: friend definitely doesn't require the reload middleware

14:14 it does require params, keyword-params, and whatever others are mentioned in the readme

14:15 hcumberdale: cemerick friend is awesome

14:15 cemerick: The compojure handlers/api or handlers/site über-middlewares are both well-suited.

14:15 hcumberdale: :-)

14:21 hcumberdale: lein localrepo does not work

14:22 devn: ring.middleware.reload -- where have you gone?

14:22 ah, ring-devel

14:28 mudge: anybody here use seesaw? When I try to compile my code with lein jar, compiling a file hangs

14:30 antares_: mudge: it means you have a top-level code that blocks (like starts a server of some kind)

14:31 mudge: antares_: thanks, but all I put in my code that hangs it is this: (:use seesaw.core)

14:31 antares_: so mabe on startup seesaw is doing something on the network and so hanging

14:31 antares_: mudge: you can use VisualVM to create a thread dump

14:36 mudge: antares_: i don't really want to download and install that software

14:37 antares_: mudge: why?

14:37 mudge: it's one of the most useful tools in the JVM ecosystem

14:38 technomancy: mudge: vaguely recall a bug like that caused by j18n which seesaw pulls in

14:39 you can get a thread dump without visualvm; I think swank supports it too

14:43 mudge: antares_: good to know, I just have enough software to lean how to use at the moment, but I will probably circle around to VisualVM sometime

14:43 hcumberdale: how can I (:require a java class?

14:44 mudge: technomancy: thanks

14:44 hcumberdale: (:require [my.java.class :as abc]) does not work

14:44 borkdude: what's the deal with new similarly looking statically typed imperative languages for the JVM? http://confluence.jetbrains.net/display/Kotlin/Basic+syntax+walk-through

14:44 hcumberdale: (:import my.java.class) works, but no alias

14:44 mdeboard: Anyone know the closest Java analog to C#'s MemoryStream class?

14:45 p_l: mdeboard: SomethingBuffer

14:48 borkdude: Has this been mentioned before here? http://www.infoq.com/research/next-jvm-language

14:48 Frozenlock: I have some difficulties adding a hook to leiningen in a plugin... could someone take a look at this small test and tell me if I have done something horribly wrong? https://www.refheap.com/paste/7033

14:49 mdeboard: p_l: I see

14:50 antares_: Monger 1.4 is released: http://blog.clojurewerkz.org/blog/2012/11/27/monger-1-dot-4-0-is-released/

14:51 hcumberdale: is it possible to include a java class with alias in clojure?

14:52 antares_: hcumberdale: no

14:54 mudge: well my class is compiling, it just takes about 2 mintues to compile --- which is so long. Without (:use seesaw.core) compilation is fast

14:55 kevin5672: How do I go about finding the source of a lein error like this: "Error: Could not find or load main class"

14:55 seangrove: Does clojurescript not come with a clj->js? I'm almost certain I've gotten errors saying it does

14:58 Raynes: seangrove: IIRC it will as of the next release.

14:58 seangrove: Ah, ok, that's fine then, just wanted to make sure I wasn't going mad.

15:07 lynaghk: ping: dnolen, hugod: I just finished up some gnarly record-stuff for doing matching with core.logic: https://gist.github.com/4004131#file_rules.clj

15:08 dnolen, hugod: in case you guys are interested. Basically the problem I needed to solve was to unify against a subset of the keys of records of a certain type. The solution I found was to make a custom record that behaves like a partial-map, but additionally checks the type of the map it is being unified against.

15:09 TimMc: hcumberdale, antares_: Yes, you can alias a class.

15:11 dnolen: lynaghk: hmm, looks like your just looking for a specific value for a key in the other map?

15:11 hugod: lynaghk: interesting! I was considering writing something to allow specification of missing keys in sub-maps (which can't be done now if the sub-map doesn't actually exist)

15:12 lynaghk: dnolen: yes, that and the type of the other map

15:12 dnolen: lynaghk: by type do you mean record?

15:12 type of the other record?

15:12 lynaghk: dnolen: yep.

15:13 dnolen: lynaghk: I guess that hard to express as two more constraints instead of doing it in the unification?

15:14 antares_: this series of tutorials on ClojureScript is seriously awesome: https://github.com/magomimmo/modern-cljs/tree/master/doc

15:14 dnolen: antares_: very awesome

15:14 lynaghk: dnolen: yes, I think it'd be tricky to do with lvars (though I could be wrong)

15:16 dnolen: in particular because you need an lvar for the whole record (so you can constrain its type) and lvars that unify with certain keys inside of that record.

15:16 dnolen: lynaghk: yeah, in anycase, very cool that you were able to solve your problem.

15:17 lynaghk: dnolen: yeah, it's a long time in coming, so I'm jazzed. Once the constraint map stuff lands I'll be set.

15:18 mudge: antares_, technomancy: I did a thread dump and I see that my clojure file with (:use seesaw.core) is compiling so slow because the threads are reading files it looks like

15:18 dnolen: lynaghk: yep, if you can find a second to do the unify bit, I can work on the constraint map stuff next weekend and next week during my travels

15:19 lynaghk: dnolen: unify bit?

15:19 dnolen: lynaghk: or I tackle it as well - just allow the multi-arg unify w/ constraint map last.

15:19 unifier I mean of course

15:20 lynaghk: dnolen: ohhh

15:21 dnolen: I did that a few days ago. I guess Github didn't tell you about it: https://gist.github.com/4116442

15:21 dnolen: lynaghk: sweet!

15:21 hugod: dnolen, lynaghk: I still haven't fully grokked how/where unifier is meant to be used

15:22 dnolen: hugod: it's just an api so users don't have to dig into run if they don't want to.

15:22 hugod: ah, ok

15:23 hcumberdale: do I need with-open when I use with-in-str?

15:24 * devn wonders why (wrap-verbose) isn't causing output to print to nrepl

15:24 hugod: dnolen: am I right in thinking I'll need to do something similar to lynaghk to unify both {:a {:b 1}} and {} with {:a {:c ::not-found}}?

15:24 devn: or rather, why it doesn't print in the nrepl buffer in emacs

15:27 dnolen: hugod: not sure if that applies to what lynaghk is doing - you need to express some kind of or there. or I could ponder some kind of (optional ...) wrapper which w/ will unify w/ ::not-found

15:28 hugod: dnolen: ok - I really want to say that the path [:a :b] in the map is not set, rather than matching the structure

15:29 [:a :c] that is

15:29 dnolen: hugod: sounds like something higher level that can be built on what I described, no?

15:31 hcumberdale: how can I convert StringReader to InputStream ?

15:32 hugod: dnolen: I guess so - unifiying with ::not-found works, and a wrapper for that would be nice not to have to rely on ::not-found directly. I'm not sure how to do the 'or' bit yet.

15:33 antares_: mudge: that's very strange. I don't even thing seesaw is a large library. Please ask on the mailing list?

15:33 dnolen: hugod: pondering it some more this could be done w/ path-constraint ... something like (not-setc x [:a :c])

15:33 hugod: I'm not going to add that by I'll try to cook up a gist later that shows how this can be done.

15:34 mudge: antares_: thanks, I posted on the mailing list a moment ago: https://groups.google.com/forum/?fromgroups=#!topic/seesaw-clj/OoweKH4AiAY

15:34 hcumberdale: >> (ByteArrayInputStream. (.getBytes s)) is this really the best way to do this?

15:34 hugod: dnolen: thanks!

15:38 jonasen: dnolen: another useful feature for the unifier would be segments: (unify [1 ??x 5] [1 2 3 4 5]) would succeed and bind ??x to (2 3 4). Have you discussed such a feature at all?

15:41 dnolen: jonasen: hmm haven't really considered that - it's also not very clear how that should work - has deep repercussions for unification of anything sequential.

15:42 jonasen: or maybe not ... haven't thought about it at all.

15:44 jonasen: dnolen: have you seen http://groups.csail.mit.edu/mac/users/gjs/6.945/psets/ps05/ps.txt

15:44 mudge: antares_: my seesaw directory in classes is 8.5M, that seems large to me

15:44 jonasen: dnolen: it's on pattern matching, but unificatition is kind of the same thing. search for ?? for some examples

15:44 mudge: ls

15:44 lazybot: boot lost+found proc src srv

15:47 dnolen: jonasen: it's worth investigating - would consider it if someone else worked it out.

15:49 jonasen: dnolen: this old gist of mine (https://gist.github.com/2236019) was an attempt to do something like ??x with core.logic but I didn't get very far

15:50 dnolen: jonasen: yeah wouldn't want to do that as a goal - to much hassle - you'd want to change unification.

15:51 cemerick: hcumberdale: yes, though keep an eye on what encoding you're using to get bytes from the string

15:52 dnolen: jonasen: you want a new kind of logic var - if encountered during unification of sequential type a different path would be taken.

15:52 hcumberdale: cemerick, it 'should' be UTF-8

15:53 cemerick: hcumberdale: well, if you don't specify, it'll use your platform default, which almost certainly won't be utf-8 everywhere

15:53 hcumberdale: but I get the "Content is not allowd in prolog" when I try to xml.zip it

15:53 seems to be a encoding issue

15:54 cemerick: "xml.zip it"?

15:54 hcumberdale: (xml-> (zip-str string) :element text)

15:55 cemerick: oh, from zip-filter

15:55 hcumberdale: zip-str from http://nakkaya.com/2009/12/07/zipping-xml-with-clojure/

15:55 jamii: With the latest emacs-live, I get 'Symbol's value as variable is void: feature' on startup

15:55 Not sure how to begin debugging it...

15:58 mudge: Is it normal for leiningen to put the class files of a dependancy into target/classes ?

15:58 wytukasuaarit: hcumberdale, you taste like poo.

15:59 cemerick: hcumberdale: that's pretty old; better to use the newer data.xml and data.zip libraries.

16:01 jamii: Starts breaking between release/1.0-BETA-4 and release/1.0-BETA-5

16:07 tomoj: suppose @x always waits for 1s and then returns 42. so (do @x @x) waits for 2s and returns 42

16:07 if x implements IPending, should realized? always return false?

16:08 or should x not implement IPending?

16:16 antares_: tomoj: I'd say it should keep track of whether 1 second passed. Just like core things that can be dereferenced, they cache their results.

16:16 tomoj: what you mean is that my x should not implement IDeref?

16:17 I don't think I can accept changing x to immediately deref to its result after the first time

16:17 but the result will indeed be cached

16:17 you'll just still get the 1s delay

16:21 TimMc: tomoj: Sounds like a promise.

16:21 tomoj: a clojure.core/promise?

16:21 TimMc: Yes.

16:22 tomoj: no, once a clojure.core/promise is delivered a result, deref'ing will always immediately return that result

16:24 TimMc: Sorry, I mean it sounds like you that's what you *want*.

16:24 tomoj: no, I definitely don't want that

16:24 cljque.promises/promise is closer to what I want but still wrong

16:25 TimMc: Oh, right. And not clojure.core/delay?

16:26 tomoj: indeed, again definitely not because that's only synchronous, but also because (delay (Thread/sleep 1000) 42) only sleeps once

16:27 TimMc: I didn't realize that was desied behavior.

16:27 tomoj: I guess the question is, must (false? (realized? x)) mean "@x has never returned a value for anyone"?

16:29 I just want (true? (realized? x)) to mean "if you do @x now, you'll get a value immediately" and (false? (realized? x)) to mean "if you do @x now, you'll have to wait for a value"

16:32 hmm, shit

16:40 mudge: can a gen-classed .class file use code written in a .clj file? or does code it use also have to be in a .class file?

16:41 nDuff: mudge: gen-classed methods just call through to clojure.lang.RT

16:41 mudge: nDuff: what does that mean?

16:41 nDuff: mudge: so they're completely able to see non-AOT'd code.

16:42 mudge: nDuff: thanks, good to know.

16:42 nDuff: mudge: (it also means they're not particularly efficient)

16:43 mudge: nDuff: you mean the .class files will be more efficent than the .clj?

16:43 nDuff: is that what you are saying?

16:43 nDuff: No.

16:43 I mean that gen-class just builds wrappers.

16:43 ...those wrappers call other code, which will in turn be just as efficient as they would have been were they not called by gen-class

16:44 but, of course, the wrapper itself is a single function call's worth of overhead

16:45 mudge: nDuff: okay. But we need gen-class in order to create a .class file that Java can see right? So there's no way around it.

16:45 nDuff: mudge: well, that depends.

16:47 mudge: ...I mean, if you're writing your own, arbitrary Java code, it can ask the Clojure runtime to give it anything you want, with no wrapper involved. If you're passing a callback to Java code, you can give it something from reify or proxy.

16:47 mudge: nDuff: I'm building a module for a Java Web Start application that uses Swing, so I'm planning to use seesaw which is a nice library using Swing underneath. However when I aot the code the seesaw library gets much larger,

16:47 nDuff: I'm buidling somethign that Java code will call --- and I have no control over the Java code which will use my stuff.

16:48 nDuff: mudge: it's an available option to only build your gen-class wrappers without AOT'ing everything.

16:48 mudge: Okay -- if the entry point is from Java code you don't control, and there's no alternate calling convention that lets you invoke it without a pre-named class, then it sounds like you do have a use case for gen-class.

16:49 mudge: nDuff: cool, do you know of any downsides to that? Because seesaw is like 100kb in .clj and like 8mb when I aot it.

16:49 nDuff: Only real downside is that startup is slower.

16:49 mudge: nDuff: downside to making my gen-class file call .clj files instead of .class files

16:49 nDuff: yup.

16:50 mudge: nDuff: okay. startup of what?

16:50 nDuff: those namespaces need to be compiled from clojure when they're loaded if they aren't compiled ahead of time

16:50 mudge: nDuff: i see, thanks

16:52 nDuff: is there a way to tell lein not to compile the the namespaces that I require or use?

16:52 nDuff: I don't remember what there is, but yes.

16:52 s/there/that/

16:52 mudge: nDuff: okay, tanks

16:52 thanks

16:54 tomoj: there is?!

16:55 mudge: nDuff: okay

16:55 nDuff: ...hrm; that's more than a little old.

16:55 * nDuff shrugs.

16:56 tomoj: wow, lein by default solves the transitive aot problem now? sweet!

16:57 firesofmay: Hi, is it possible to create a web repl for overtone, where the user can write scripts and on the server side it executes them, transports back the sounds generated via some protocol and the browser plays it on the client side.

16:57 firesofmay: I don't know if the browser can do that. So I am curious.

16:58 tomoj: firesofmay: I think that should be possible. but 1) you have to worry about them executing dangerous code and 2) I'm really unsure about this, but I think overtone itself is dangerous, since it calls out to supercollider - so it may be easy for them to crash your jvm

16:59 firesofmay: tomoj, Ah I see.

17:00 technomancy: tomoj: lein includes a workaround

17:00 tomoj: the other hard part is streaming overtone's output out, dunno how you'd do that

17:00 technomancy: there's been an open issue for it since forever =\

17:00 firesofmay: tomoj, The idea from where I am coming from is, I have seen that there is a lot of barrier in just trying out overtone, I myself had lot of problems getting it running.

17:00 tomoj: technomancy: but it still breaks protocols?

17:00 firesofmay: tomoj, yeah, lets forget the whole crashing part, how can you stream the overtone output? Any ideas?

17:00 technomancy: tomoj: yep; doesn't seem to be a way around that problem

17:00 other than not using protocols

17:00 tomoj: :)

17:00 or fixing CLJ-322

17:01 technomancy: which works great for me

17:01 heh; good luck

17:01 tomoj: firesofmay: hmm

17:02 I don't think you can do that inside the jvm

17:02 firesofmay: tomoj, I see.

17:02 tomoj: again, not sure. but maybe you can just wire the SC output with jack to something that streams out?

17:02 firesofmay: tomoj, I am quite to new this so no idea.

17:02 tomoj, okay yeah that may be a good idea.

17:06 could be relevant

17:06 I've been thinking about streaming overtone to a browser for a long time, but never considered a web repl. cool idea

17:07 firesofmay: tomoj, checking.

17:07 tomoj, yeah. having a web repl would mean anyone can checkout overtone without any barrier of installing.

17:08 tomoj, interesting project.

17:14 mbcev: So I don't have a direct clojure question, but it's semi-related... I know the MVC design pattern was born out of SmallTalk (the poster child for OOP), what about with Functional Programming? Are there similar frameworks slash design patterns slash formalisms that seem to fit Functional Programming particularly? Or is it entirely irrelevant because it depends entirely on how you choose to design your particular system architecture?

17:16 TimMc: map/reduce?

17:16 jamii: tomoj, technomancy: I'd be pretty interested in getting streaming working for https://github.com/jamii/concerto too

17:17 I imagine there would be a lot of overlap with any web-repl project

17:17 Frozenlock: Does a uberjar run faster than the equivalent separated jars?

17:18 tomoj: jamii: streaming what?

17:18 Frozenlock: (Any load time difference, or is it just for convenience?)

17:18 p_l: I figure there is possible load time difference, but mostly the convenience of not fucking around with the madness that is CLASSPATH

17:19 technomancy: mbcev: middleware is a common "pattern" in Clojure

17:19 Frozenlock: no difference

17:20 jamii: tomoj: streaming overtone audio

17:21 solussd: is metadata as a way to mark data as validated by a validator a correct use of metadata? I have some code with validators being called in the view layer and in the model layer. Depending if data is coming from the API or the web portal it may be validated twice. I was considering, as an optimization, marking data as validated and having the validator check for that metadata before performing validation. thoughts?

17:22 after all, it is data about the data. :)

17:22 technomancy: solussd: sure, except for the fact that it can't be attached to strings or numerics

17:22 solussd: technomancy: it'll always be a record or map

17:24 bryanl: in clojure, there isn't a way to have a range as a hash key is there?

17:24 mbcev: technomancy: So, with middleware you're referring to Ring, right?

17:25 technomancy: mbcev: ring is probably the first place in Clojure it was introduced, but it's also used in nrepl, clj-http, and Leiningen

17:27 mbcev: technomancy: just found a page painting a better picture of what "middleware" means, thanks. I can see how this idea would be more natural to a LISP, and also just to I/O-esque systems. Thanks! :D

17:28 Frozenlock: Ah excellent! Then my next possibly misguided question: Is there a way to just send every jars into the same folder? Should I just use lein-tar and decompress the result?

17:29 devn: technomancy: best way to get access to some project dependency without adding to .lein-classpath or :eval-in-leiningen?

17:29 mbcev: dakrone: haha, that's I just came up with. That and the wiki for Middleware lol. Thank you!

17:29 technomancy: devn: what?

17:30 devn: i'd like to require src/foo/core.clj in src/leiningen/blah.clj

17:30 Frozenlock: (I've made a lein-plugin around Getdown to enable auto-update for applications, but if the different jars could be separated that would be very nice: less download at each version bump)

17:30 technomancy: devn: eval-in-project is how you do that

17:30 devn: thanks

17:30 technomancy: sure

17:32 TimMc: technomancy: Have you had any thought as to how documentation might be distributed with Clojure projects?

17:33 technomancy: TimMc: Leiningen symlinks things from doc/ into resources/

17:33 works pretty well

17:33 TimMc: Oh yeah? Interesting...

17:34 What happens on NTFS?

17:34 technomancy: that's how lein help readme works

17:34 the symlinks are only used during development

17:35 lein uberjar copies the linked contents into the jar, not the symlinks

17:35 TimMc: but a Windows user would not be able to package the jar properly?

17:35 technomancy: no

17:35 TimMc: Hmm, OK. Not too worried, though.

17:36 technomancy: bin/release is a shell script anyway

17:36 TimMc: I don't know what that is.

17:36 technomancy: oh, I mean the script that generates the uberjar

17:36 unfortunately due to bootstrapping it's more complicated than just running lein uberjar

17:37 TimMc: This is a component that lein uses to build lein, or to build arbitrary projects?

17:37 technomancy: specific to lein

17:37 I just mean symlinks aren't the only thing preventing using Windows for releases

17:38 TimMc: But bin/release only prevents lein from being released on Windows.

17:45 technomancy: I think

17:54 zackzackzack: How does one go about setting the seed for rand?

17:55 ssideris: technomancy: oh, I didn't realize lein uberjar does not run properly on Windows!

17:55 is that a documented limitation?

17:56 technomancy: ssideris: leiningen can't build its own uberjar with documentation on Windows (without Cygwin)

17:56 TimMc: Oh right, Cygwin.

17:56 technomancy: building a typical project's uberjar will work

17:57 ssideris: technomancy: oh ok, thanks, sorry for jumping into the discussion with minimal context :-)

17:59 technomancy: no worries

18:13 solussd: are assertions (*assert*) disabled in production mode for ring?

18:14 technomancy: ring has production mode?

18:15 bozhidar: I guess someone did too much Rails development :-)

18:19 solussd: the jetty adapter appears to take a :mode option

18:19 :prod or :dev

18:20 broader question then- when is *assert* not true?

18:24 brehaut: solussd: do you have a link to the code that uses :mode?

18:24 i suspect im looking in the wrong place

18:26 solussd: ack, sorry, it's not passed to the jetty adapter, it's being used by gen-handler in noir.server (bad code reading)

18:30 could someone help me understand when *assert* isn't true? I'm debating whether or not to use pre/post conditions in some places- I'd prefer not to throw assert errors in production (i'd rather have validators in my model later catch things and generate errors to present to the user)

18:31 muhoo: technomancy: it'd be neat if readme.md and docs got included in jars

18:31 so one could read the docs without having to go find the github page for a lib

18:33 technomancy: muhoo: you can do that with :filespecs {:type :path :path "README.md"} in project.clj

18:33 I don't know if it should be on by default since not everyone uses markdown

18:35 could search for the first file matching README* but the logic gets a lot more complicated when it's not declarative

18:35 (like you need a separate flag to turn it off)

18:35 muhoo: readme.md is the default in lein new, tho

18:36 technomancy: yeah, but markdown is not a very good format

18:36 you shouldn't have to add stuff to project.clj to prevent jar failures just because you are using a better format

18:37 muhoo: maybe there will be an eventual rethink of docs then.

18:37 but self-contained docs in a lib package would be nice

18:37 technomancy: maybe the default could include :filespecs

18:37 I mean the default project.clj

18:38 rather than having it hard-coded in lein itself

18:38 muhoo: makes sense

18:40 i could even see a plugin for lein repl or nrepl to show them

18:40 maybe even some transformation for nrepl.el that turns md into info and puts them in emacs

18:42 technomancy: heh... that would be cool, but info is completely bonkers-insane

18:42 muhoo: well that may be unneccessary since markdown-mode works

18:43 technomancy: it would be nice if there were a pure-elisp HTML renderer

18:43 since you can't rely on w3m being available

18:43 but yeah, markdown is usually pretty palatable on its own

18:44 muhoo: that's easiest. or there's a markdown-mode func that renders it to htm and shows it in the browser

18:46 but i'd love to have M-x nrepl-doc RET friend RET and see the damn readme.md

18:47 as a use case :-)

18:50 dnolen: hugod: ping

18:55 sgarrett|afk: What's the best way to debug in clojure? Or to get good debugging information?

18:57 dnolen: sgarrett: probably ritz

18:58 sgarrett: dnolen: will that work well with lein?

19:00 muhoo: as a use case :-)

19:01 dnolen: sgarrett: seeing as there's a lein-ritz plugin I'd imagine so

19:01 sgarrett: dnolen: Awesome. Thanks!

19:24 seangrove: lynaghk: What's the state of reflex? Is it suitable for production use still, or has it been deprecated for something newer?

20:21 hugod: dnolen: ping

20:21 dnolen: hugod: pong

20:21 hugod: you called...

20:21 dnolen: hugod: http://gist.github.com/4158004

20:22 hugod: getting that to work requires a bit too much knowledge about constraint internals

20:22 hugod: I'm working on a macro that will greatly simplify defining fairly straightforward constriants like that

20:22 hugod: but I'm assuming that's what you wanted in terms of behavior correct?

20:24 hugod: dnolen: yes, thanks very much - though I would call it not-pathc or something

20:24 dnolen: hugod: yeah

20:24 hugod: but looks fantastic :)

20:25 dnolen: hugod: gimme a second, cooking up something even cooler

20:25 constraints are pretty sweet - kinda just starting to realize how cool this stuff is.

20:26 hugod: the interaction of functional and logic is mind-bending

20:27 I'm just wondering how I could use this as a pure constraint (or whatever it is called; something similar to >fd and <fd)

20:27 I think I can just call it

20:28 dnolen: hugod: what do you mean by similar to >fd <fd?

20:29 hugod: it's ok - I think I understand. I'm using these constraints bound to logic vars, so have to project them

20:29 dnolen: hugod: yes I'm fixing that.

20:29 hugod: hold one :)

20:29 you should never have to projet w/ constraints

20:29 project

20:32 hugod: oh, ok - I'm basically doing (run* [q] (fresh [c] (membero c constraints) (project [c] (c))))

20:32 oh and unifying q with a pattern, that includes a logic var that is in c too

20:41 dnolen: it's always fun when you can use a pre-constructred exception for cheap backtracking ...

20:43 hugod: functional!

20:44 dnolen: erg, I guess nrepl doesn't do sensible macroexpand yet ...

20:45 this feel like 2009

20:45 feels

20:45 hugod: I don't think it is recursive yet

20:45 dnolen: I'm not even talking about that

20:45 just pretty printed code w/ namespace clutter

20:45 w/o

20:45 * hugod still uses slime most of the time

20:46 * dnolen is actually impressed w/ nrepl

20:46 dnolen: the only thing that's bitten me is macroexpand and yucky stacktraces

20:46 hugod: it's moving very quickly

20:47 not having multiple sessions is a bit of a limitation I find

21:04 dnolen: hugod: look ma, no project! http://gist.github.com/4158004 :)

21:04 hugod: and considerably less code

21:05 hugod: I added defc, which eliminates all the boiler plate

21:05 note ordering doesn't matter, nor how deeply nested the logic vars are in the terms to the constraint

21:06 the constraint won't run until all arguments are deeply ground.

21:06 I can't imagine this will solve all use cases - but it'll probably handle many of the kinds of simple constraints most people would write.

21:32 hugod: dnolen: wow!

21:32 I'll have to try it to test set membership

21:33 dnolen: hugod: it's a bit experimental let me know how it works out for you.

21:33 hugod: the fun part is that the body of defc is just regular Clojure code

21:34 hugod: but by testing the arguments to see if the constraint is ready to run - it frees you from considering projection - performance hit of course - but in this case the flexiblity is a big win I think.

21:35 hugod: dnolen: having to call project isn't too bad, but nicer without it

21:35 dnolen: being able to defc constraints simply is big though

21:35 dnolen: hugo: exactly :)

21:56 hugod: as far as sets it's likely I add explicit support for CLP(Set)

21:57 hugod: kinda like CLP(FD), but without all the complications.

21:58 hugod: dnolen: you had a comment in the code about unification with sets being a research problem - I take it that set membership is easier

21:58 dnolen: hugod: so you could do things like (inset x #{:cat :bird :dog})

21:58 hugod: :) I could use that!

21:58 dnolen: (unionset x #{:zebra} y)

21:58 hugod: yep, and it's easy to do

21:59 hugod: dnolen: if I have a pattern for a map, can I associate the whole map with an lvar so I can impose a constraint on it? a la {:as ?f}

21:59 dnolen: hugod: I'm putting efficient CLP(FD) on the backburner and focusing on stuff that's easy to implement efficiently.

21:59 hugod: in what context?

22:01 hugod: relational programming with sets is hard

22:01 hugod: sets in the context of constraint programming - easy

22:02 hugod: dnolen: I want to match a map {:some :key} and impose the constraint (not-pathc [:other :key]) on the map

22:02 dnolen: honestly I don't see how you can do anything w/ relational programming that doesn't involve lists.

22:02 hugod: membero seems to work nicely with maps

22:03 dnolen: hugod: well, in Clojure sequences work out as well of course

22:03 hugod: is there something you're describing not covered in the gist?

22:06 hugod: dnolen: I can see how it works in the context of the body of a run, but not when passing the pattern and constraints as logic vars themselves (if that sentenced was parsed)

22:07 jcromartie: why can't I do bitwise operations on BigInteger?

22:07 dnolen: hugod: oh right, you're passing in constraints bound to logic vars?

22:07 hugod: dnolen: yes

22:08 dnolen: hugod: is that the missing bit?

22:08 hugod: (let [rules (map prep [[{:some :key} {:a 1} [(not-pathc ???? [:other :key])]]])] ...)

22:10 dnolen: map destructuring syntax would be nice...

22:10 dnolen: hugod: yeah I'm not sure how your system works so I can't really say

22:11 hugod: would need to take a closer look at how you're trying to solve things.

22:11 hugod: dnolen: I'm just trying to associate an lvar with {:some :key} above, so I can put the same lvar in the not-pathc form

22:12 dnolen: hugod: this is all work you want to do before calling run?

22:14 bryanl: what is -> and ->> called?

22:15 hugod: dnolen: no - I process the constraints - resolving the constraint function symbol in each constraint form and then creating a function that uses reduce to call each constraint with the susbtitution map. That function then gets bound to a logic var and called inside run (that is all working already).

22:16 dnolen: if this is getting too out of scope I'm happy trying things out on my own

22:18 dnolen: hugod: core.logic constraints or something of your own devising?

22:18 hugod: dnolen: these are core.logic constraints (it works with <fd and >fd)

22:19 dnolen: hugod: so why won't it work w/ not-pathc that I gisted?

22:20 aperiodic: bryanl: the threading macros, thread-first and thread-last (though i've also heard the first one called "the arrow macro")

22:21 hugod: dnolen: because I don't know how to get prep to bind an lvar to the {:some :key} map (actually it would be (partial-map {:some :key})

22:21 bryanl: aperiodic: thrush and threading... now it makes sense

22:23 dnolen: hugod: oh like (unifier ({:foo :bar} :as ?x)) !

22:23 hugod: dnolen: yes, I think so

22:25 dnolen: I can probably work around it for now anyway, but putting the map inside a map

22:25 back in 15mins

22:25 dnolen: hugod: yeah I'll ponder that, probably not that hard to add support for in prep and thus unifier

22:25 hugod: I gotta run myself. will think on it

23:14 TimMc: bryanl: I like to call them stitching macros.

23:14 brehaut: TimMc: thats a much better than the other common name that people normally use

23:15 (which i wont mention to minimise confusion)

Logging service provided by n01se.net