#clojure log - Jul 22 2013

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

12:13 seangrov`: gfredericks: Is your fork of Korma with postgress array support merged into the main repo now?

12:17 * gfredericks hrms

12:17 seangrov`: It does not appear to be

12:17 gfredericks: seangrov`: was that for reading or writing arrays?

12:17 seangrov`: Not sure, looking at https://github.com/korma/Korma/commit/9546daf722d5b51e6e248a708b29366db30418f7

12:18 Maybe it's in, but it's been moved around a bit in master

12:19 gfredericks: seangrov`: okay that's for writing

12:19 and I don't know any more than you do about its status in the main branch; I'm actually surprised to see it in the official repo at all

12:19 I feel like I would have been hesitant to propose db-specific changes like that

12:20 seangrov`: gfredericks: It being in the official repo is what prompted me to ask

12:20 Looking to see if Korma has support for Postgres arrays, so I don't have to do create a join table

12:20 Maybe it's in incubator

12:21 Korma works very well, but the fact that it's basically been abandoned brings a tear to my eye

12:21 gfredericks: seangrov`: reading arrays can be done via java.jdbc customization

12:21 but writing has to be supported in korma I believe

12:22 seangrov`: Well, back to basic joins it is then

12:22 gfredericks: (inc chouser)

12:22 lazybot: ⇒ 12

12:23 * seangrov` puts on his ridiculous over-engineering effort gear

12:23 gfredericks: seangrov`: we've been using my fork in production for ~6 months now, so feel free to try that

12:23 chouser: I hope I did that right.

12:23 seangrov`: (inc chouser)

12:23 lazybot: ⇒ 13

12:23 technomancy: chouser: don't let it trouble your conscience

12:24 chouser: technomancy: thanks for the push.

12:25 seangrov`: gfredericks: I think I'm running a local checkouts version too

12:25 Maybe I'll take a stab at updating korma a bit post-cljs-sourcemaps/prototypes

12:26 `cbp`: callen: I think I'll just create a new project since it's a full rewrite pretty much. What should I call it?

12:30 seangrov`: gfredericks: Looks like the postgres modifications are pretty small, what are the jdbc customizations for reading postgres arrays?

12:37 noncom: ,(into {} (partition 2 [1 2 3 4 ]))

12:37 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry>

12:38 noncom: WHY??

12:38 lazybot: noncom: What are you, crazy? Of course not!

12:38 clojurebot: Why is startup slow is busy compiling the `for` macroexpansion

12:38 noncom: but this works:

12:38 ,(into {} (mapv #(into [] %) (partition 2 [1 2 3 4 ])))

12:38 clojurebot: {1 2, 3 4}

12:38 noncom: ?

12:41 `cbp: ,(into {} [[:a 1]])

12:41 clojurebot: {:a 1}

12:41 `cbp: ,(into {} [:a 1])

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

12:41 Anderkent: noncom: into takes a sequence of map entries or 2 element vectors. Partition returns a sequence of lists, these are not recognized as mapentries

12:41 chouser: Hm, well, into basically just call conj.

12:41 ,(conj {} (list 1 2))

12:41 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry>

12:42 Anderkent: (basically it expects its input to be what you get from (seq a-map)

12:42 chouser: I'm just confused as to why the exception says Long instead of List

12:43 But that's probably not noncom's question.

12:43 arrdem: chouser: yeah I'm weirded out by that too...

12:44 Anderkent: chouser: because conj can take a map

12:44 ,(conj {} {1 2 3 4})

12:44 clojurebot: {3 4, 1 2}

12:44 Anderkent: or rather

12:44 ,(conj {} (seq {1 2 3 4}))

12:44 clojurebot: {3 4, 1 2}

12:44 technomancy: isn't conj taking a map widely regarded as a weird and unfortunate quirk?

12:44 Anderkent: so it looks at the arg, sees it's a list, tries to interpret it as a list of map entries, and fails to cast long to it

12:44 chouser: whoa, conj can take a sequence of mapentries?

12:45 Anderkent: technomancy: yeah I'd agree. Still, that's *why* the exception says long

12:45 arrdem: (ink Anderkent) ;; good breakdown

12:45 chouser: I need to hang out here more. I'd learn things.

12:45 Anderkent: arrdem: consider me inked

12:45 arrdem: (inc Anderkent) ;; try that again...

12:45 clojurebot: arrdem is awesome

12:45 lazybot: ⇒ 2

12:45 Anderkent: :D

12:45 * arrdem can't spell on this much coffee

12:46 seangrov`: chouser: were you able to give ops to technomancy so he can preside over the learning in your absence?

12:46 arrdem: I can break 400 APM for you but no spelling

12:46 chouser: seangrov`: working on it

12:46 seangrov`: Cool stuff

12:48 bbloom: chouser: see also https://groups.google.com/d/topic/clojure-dev/NR3qA2mudZA/discussion

12:48 chouser: in general, clojure has some oddities around sequences born from maps

12:50 chouser: bbloom: I actually read that thread. :-)

12:52 bbloom: seems somewhat vestigial from pre-protocols days. type predicates and casts baked in pretty low level

12:54 chouser: well, protocols in Clojure are still built on top of almost everything else, so using them in these low-level places isn't a convenient option

12:57 zilti: Is it possible to create multimethods with more than one argument? It seems like I can't do that

12:57 Anderkent: zilti: yes, it should 'just work'. what error are you getting?

12:57 zilti: I get an ArityException

12:58 I wrote defmulti with a dispatch-fn with two args and defmethod for that which takes two args as well, and no matter what arity I use it never works.

12:58 Anderkent: zilti: I guess the only tricky bit is that your dispatch function must have the same arity as the methods

12:58 huh

12:59 can you post that to refheap or somewhere?

12:59 zilti: Well I tried this now: (defmulti multi (fn [one two] 1))

12:59 (defmethod multi 1 [one two] (println one two))


13:00 arrdem: zilti: somewhere isn't chan :|

13:00 *please

13:00 Anderkent: and you're calling it as (multi 1 2) ? Works for me

13:00 zilti: Well it was supposed to be on one line :(

13:01 For me it doesn't. Do I have to "reset" the repl first?

13:01 Anderkent: zilti: what clojure version?

13:01 zilti: 1.5.1

13:01 Anderkent: if you defined the dispatch function before then you should try a different name

13:01 redefining multimethods does not really work

13:02 (see http://stackoverflow.com/questions/9368533/reloading-multimethods-via-slime )

13:02 zilti: Ok... Yes, I now restarted the REPL and it works

13:02 Anderkent: yeah if try to redef the defmulti (i.e. change dispatch function) you'll be sad. It's a pain.

13:04 callen: ucb: was it the CMS thing http://github.com/bitemyapp/neubite ?

13:04 ucb: just be aware that I'm putting out something updated soon.

13:05 `cbp: good question. Selmer?

13:20 seangrov`: callen: You go to the clojure meetups here? I've missed the last few on account they're in San Mateo, but would like to get to the next one

13:20 Also, we started the cljs meetup, but have yet to run a meetup

13:21 aaelony: silly question as I investigate cljs a little. I have lein cljsbuild auto running and I can see changes in the browser, but I miss being able to evaluate expressions in emacs in a repl like manner. Is there a way to get that working as it would with nrepl via emacs?

13:21 seangrov`: I think it's time we did, what with core.async, source maps, dommy, etc. etc.

13:21 aaelony: piggieback

13:21 It'll be a bit of a pain to setup, but it's marvelous once it's going

13:21 aaelony: seangrov`: thanks, I'll google it

13:22 seangrov`: aaelony: That's another piece of work from cemerick on his quest to make the world a better place

13:22 dark_element: noncom finally figured out repl-listen

13:23 aaelony: seangrov`: amen, bow, and hat-tip to cemerick !!

13:24 egghead: hey, is there any simple way to get lein cljsbuild to use a cljs from my classpath instead?

13:24 I want to use the latest to get it working with core.async but it keeps pulling in 1806 instead

13:24 seangrov`: egghead: use source-paths

13:25 egghead: https://www.refheap.com/8863ea58efe4b4e87bf63c708

13:25 Hrm, looks like I took clojurescript out of there

13:25 But same idea

13:26 egghead: seangrov`: so the only way to do it is to have a complete checkout of the cljs project?

13:26 callen: seangrov`: not lately, I went to one of Corfield's to teach people Emacs with my dotfiles repo. Not much else.

13:27 I probably should.

13:27 upwardindex: Looking for a way to have communication between my cljs and my clj with less pain than manual xhr, any recommendations?

13:27 egghead: I can't just say for instance that [org.clojure/clojurescript "0.0-1844"] is one of my deps and have cljsbuild pick that one up?

13:27 seangrov`: Need to find a place to hold the cljs meetup

13:27 egghead: Maybe? I seem to recall that working

13:29 `cbp: callen: Selmer it is then

13:32 callen: `cbp: brand of guitar Django used in his later years.

13:32 `cbp: kk

13:32 * seangrov` is about to break down and try datomic in a production project

13:32 BufferUnderpant1: Hmmm… I'm having some odd issue with clostasche

13:33 callen: seangrov`: don't.

13:33 BufferUnderpant1: java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

13:33 For a file that gets slurped just fine

13:33 egghead: hm, looks like it's still using 1806, c'est la vie

13:34 BufferUnderpant1: (file path)

13:35 hexa_: Hi all, if I wanted to create a map with keys and values taken by applying a function to another map element what would be a good way ? First tought was something like : (map #({:test (inc %) :test2 (inc %)}) [1 2 3]) but this tells me i'm passing 0 args to PersistentArray ?...

13:36 seangrov`: egghead: The source-paths method is pretty simple

13:37 Just create a 'yaks' folder, git clone the cljs repo into it, set the entry, and you won't have to touch it again

13:37 egghead: ya, I'm messing around with that now

13:37 giving me errors about data.json not on a the classpath :3

13:38 `cbp: hexa_: use fn not a function literal

13:39 hexa_: you could also do ##(zipmap [:test1 :test2 :test3] (map inc [1 2 3]))

13:39 lazybot: ⇒ {:test3 4, :test2 3, :test1 2}

13:39 silasdavis: in compojure how can I define a set of routes that I can mount relative to some base URL

13:40 hexa_: `cbp, what with an fn literal what would it look like ? map #(fn [element] {:test (inc element) }) ?

13:41 silasdavis: suppose I have (GET '/some-entity/foo' resource) in my routes and I want to achieve the same effect as if I had (GET '/some-base/some-entity/foo' resource)

13:41 for example

13:41 egghead: huh, so this clojurescript project has external deps from clojure core but doesn't specify them?

13:42 https://github.com/clojure/data.json https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/source_map.clj#L4

13:42 jkkramer: silasdavis: compojure.core/context

13:42 `cbp: hexa_: remove the '#'. Although i'm not sure what you want exactly, maybe give me an input => output example?

13:43 silasdavis: jkkramer, thanks

13:44 hexa_: `cbp, I'm just tryng to create a map with the result of a function as keys like for all files in dir get me a map with Name , Path etc...

13:45 silasdavis: hexa_, yeah the # function syntax has an implicit evaluation of the contained form I think you could write something like #(constantly { ... }) as an alternative, but fn is probably better

13:46 egghead: hmm, looks like maybe core.async is just incompatible with the cljs advanced optimization

13:46 seangrov`: egghead: did you include org.clojure/data.json as a dep in your project.clj?

13:46 egghead: using the latest cljs checkout

13:46 sad day

13:46 hexa_: silasdavis, (map (fn [ele %] {:test (inc ele)}) [1 2 3]) not quite right I guess ?

13:46 egghead: seangrov`: yah I added it, a bit annoying that I had to :p

13:47 while core.async works well without optimizations, when I do advanced it throws

13:47 silasdavis: (map (fn [ele] {:test (inc ele)}) [1 2 3])

13:48 egghead: has anyone else tried to do advanced compilation with core.async ?

13:48 hexa_: silasdavis, haa right right thehe thx ! :)

13:48 silasdavis: hexa_, (map (fn [ele] {:test (inc ele)}) [1 2 3])

13:48 hexa_: `cbp, thx too :)

13:50 callen: cemerick: I've definitely met some Ruby programmers that were muppets.

13:52 dnolen: cemerick: pong

13:53 egghead: dnolen: have you messed w/ advanced compilation on cljs/core.async ?

13:53 code that works fine with :whitespace blows up with :advanced

13:54 dnolen: egghead: never encountered a problem myself but do you have a minimal case?

13:55 egghead: dnolen: ah if you have done it successfully it's probably a problem in a dep or something

13:56 thanks, i'll start digging more, if it persists I'll get you a minimal project showing it

13:56 also, what are you guys using for cljs testing?

13:56 I was messing around with https://github.com/cemerick/clojurescript.test but it looks like it's broken for the current version of cljs

13:58 seangrov`: dnolen: When you get a chance, would appreciate some guidance on this source-map https://gist.github.com/sgrove/6050286

13:58 Working for fn params (variadic and non-variadic) and let bindings

14:14 egghead: ah okay, the collission was using the shoreleave library with core.async

14:14 now to figure out how to get my tests working again :)

14:16 ucb: callen: yeah; thanks

14:17 egghead: so are there any good cljs test libs that work with modern cljs?

14:18 seangrov`: egghead: cljs.test is the only one I've had work well at all

14:24 dnolen: egghead: talk to cemerick about clojurescript.test, I'm sure it's a simple fix

14:24 cemerick: egghead: what's the error you're getting?

14:25 dnolen: seangrov`: yes that looks good to me

14:27 dark_element: How can i write update! around set! in clojurescript

14:28 egghead: cemerick: it was actually an error with source maps not being able to be generated, now it's just the set-print-fn! warning

14:28 callen: `cbp: talk to yogthos.

14:28 yogthos: talk to `cbp.

14:28 dark_element: I am trying to create utility functions using set!

14:29 cemerick: egghead: ah, ok; yeah, that was a shim put in before set-print-fn! was in core. It's irritating, but still useful for people not aggressively tracking cljs head.

14:29 dark_element: but i am getting Assert failed: Can't set! local var or non-mutable field

14:29 bbloom: dark_element: set! is a special form, so you could only really usefully wrap it w/ a macro

14:29 dark_element: bbloom ah! ok

14:29 cemerick: It'll go away at some point.

14:29 bbloom: dark_element: but you probably shouldn't be doing that unless you know what you're doing :-P

14:29 dnolen: dark_element: you can't set! locals vars nor non mutable fields

14:30 bbloom: dark_element: if you're coming from a scheme or common lisp background & looking for a way to do something like setq or whatever, you probably should *not do that*

14:30 dark_element: dnolen bbloom i am trying to create something like this https://www.refheap.com/16809

14:30 bbloom: dark_element: use an atom

14:31 egghead: dnolen: I'm sure you're way too busy for this but just wanted you to be aware: cljs 1844 w/ source maps enabled: https://www.refheap.com/16810

14:31 goes away when I don't tell the compiler to make me a source map

14:31 dark_element: bbloom i need to change javascript objects.

14:31 bbloom: dark_element: OH

14:31 egghead: probably an edge case of doing something that doesn't map well or some similar funny biz

14:31 bbloom: dark_element: use aset and aget instead of set!

14:32 aset and aget are basically the object["syntax"] in javascript

14:32 they are functions, and so can be sensibly wrapped

14:32 and will work correctly on json etc w/o being squashed by advanced mode's name compression

14:32 dark_element: bbloom ok

14:33 dnolen: egghead: hmm, yeah if you can create minimal project that demonstrates the issue, open a CLJS ticket with a link, or just with a description of the steps.

14:34 bbloom: dark_element: presumably you could create aget-in, aset-in!, and aupdate-in! which would work similar to get-in, assoc-in, and update-in

14:34 then you wouldn't need to code all the inc! and dec! and all those individual functions

14:35 dark_element: bbloom that was my next question!

14:35 dnolen: bbloom: aset and aget are already variadic

14:35 * bbloom checks

14:35 bbloom: dnolen: glorious. did not know that

14:35 haven't had a need for it yet

14:35 dark_element: well there you go. done for you :-P

14:36 dark_element: dnolen great! checking

14:36 dnolen bbloom thanks!

14:38 magnars: Just released my first clojar: catenate. It's a Ring middleware to serve concatenated static files with cache buster URLs in production. Comments are welcome. :) https://github.com/magnars/catenate

14:50 dark_element: dnolen it works. created update-in wrapping around it.

14:52 callen: `cbp: https://github.com/yogthos/Selmer/

14:54 konr: How can I check whether something is a function?

14:54 llasram: Like this? ##(fn? identity)

14:54 lazybot: ⇒ true

14:54 konr: yeah! thanks

14:55 bbloom: see also: ##(doc ifn?)

14:55 lazybot: ⇒ "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"

14:56 clj_newb_234: is rich hikey's clojure.core.async talk available online?

14:57 bbloom: not yet, i don't think

14:57 clj_newb_234: this is a crime against humanity

14:57 HolyJak: :)

15:00 atyz: Hey guys, Is there string interpolation in clojure? I've found core.incubator but I'm not sure if that will be around for long as the impression I get is that it's a testing ground

15:01 bbloom: the str function is variadic, which is close enough

15:01 atyz: Hmm ok

15:01 Thanks

15:01 bbloom: (str "compare to " language " and you won't miss interpolation")

15:02 OneFourSeven: What's the difference between parenscript for Common Lisp and Clojurescript?

15:02 bbloom: OneFourSeven: they are completely different languages

15:02 atyz: bbloom: I know - just would have made my life a little easier for a second

15:02 `cbp: callen: Should I clone that? I already had my project made but no commits yet

15:03 I was also picturing tags to work a bit differently

15:04 yogthos: hi

15:05 dnolen: OneFourSeven: far as I know parenscript isn't really a stand alone language

15:06 OneFourSeven: ClojureScript is an implementation of Clojure

15:07 nDuff: Hrm.

15:08 duck1123: how do you get hiccup to emit namespace declarations? When I use {:xmlns/jk "http://tomcat.apache.org"}, it just emits jk="http://tomcat.apache.org"

15:09 duck1123: nDuff: https://github.com/duck1123/jiksnu/blob/master/src/jiksnu/model/webfinger.clj#L24

15:09 use strings

15:10 callen: `cbp: just talk to yogthos. Sync up with him. He wants to work with you on it.

15:11 `cbp: ok

15:11 pandeiro: what is the proper way to bring core.async into a cljs project?

15:11 dnolen: pandeiro: you need to run lein install on your system or include a reference to the sonatype staging maven repo

15:12 nDuff: duck1123: ahh; thanks.

15:12 duck1123: nDuff: Not the prettiest, but it did the trick and saved me fron hunting for a better solution

15:13 pandeiro: dnolen: it's one lib for both hosts, right? git clone <async> && cd <async> && lein install ?

15:13 dnolen: thanks for the explanatory post btw, very cool

15:13 nDuff: duck1123: yup. Works for me too, though I'm currently cloning hiccup to see about submitting a patch to make things less ugly.

15:15 dnolen: pandeiro: yes that works, np

15:16 `cbp: yogthos: lmk when you're available

15:27 duck1123: nDuff: Also, you cna use :xmlns:jk like in https://github.com/duck1123/jiksnu/blob/master/src/jiksnu/views/site_views.clj#L33

15:27 seangrov`: bbloom: Roughly how long after Rich receives the CA until the contributors page is updated and I can join the clojure-dev ml/edit the confluence wiki?

15:28 bbloom: seangrov`: i don't recall

15:28 seangrov`: Alright, just wondering if there's a implicit understanding of his habits

15:29 bbloom: there's definitely somebody much better equipped than me to answer that question

15:29 nDuff: duck1123: Oh! That's not so bad, then. Thanks!

15:29 bbloom: not sure who it would be tho :-P

15:29 seangrov`: bbloom: I'll just check through the channel handles alphabetically

15:29 bbloom: a wise plan, i'm sure

15:30 seangrov`: Anyway, not the biggest deal, just eager to get the changes submitted before it gets too big

15:30 kovas: seangrov`: my understandind is that the CA goes to relevance

15:30 (thats what the address is)

15:30 seangrov`: kovas: I sent mine to the address listed on http://clojure.org/contributing

15:30 kovas: yeah, thats relevance

15:31 and then someone there takes care of it

15:31 seangrov`: Heh, good stuff

15:31 kovas: i don't think it will be sitting on a desk for a long time

15:31 but there might be a weekly batch or something

15:31 seangrov`: Awesome, thanks

15:31 Oh, I'm listed now!

15:32 I guess it was processed already, wow

15:42 squidz: why arent clojurescript objects treated as json objects?

15:42 or the other way around

15:44 arrdem: so where does the ^:integer wind up in &(read-string "^:integer 'foo")

15:46 amalloy: arrdem: (set! *print-meta* true) and see

15:46 arrdem: amalloy: is that not just (meta) ?

15:46 amalloy: huh?

15:47 chronno: ls

15:47 lazybot: lib lost+found selinux src tmp

15:47 arrdem: lewl

15:47 chronno: oops, wrong window

15:49 akurilin: Anybody seen weavejester around in the past few days?

15:49 arrdem: amalloy: I don't follow. you're saying that (with-bindigs [*print-meta* true] (pr ^:integer 'foo)) should show that metadata, but if I query the symbol via (meta) it won't show?

15:49 xeqi: $seen weavejester

15:49 lazybot: weavejester was last seen quitting 3 days and 21 hours ago.

15:49 hyPiRion: hey, whene did lazybot get back up?

15:50 amalloy: i'm not saying that. i'm saying if you print the value with *print-meta* set to true, you will see exactly where all the metadata is; calling meta is another plausible approach, which you brought up yourself

15:51 would work in this case, since the meta is on the topmost object, but if it were nested inside somewhere you wouldn't see it

15:52 arrdem: hum... I follow but I'm not succeeding in printing any metadata in my repl.

15:53 dnolen: squidz: not sure what you mean

15:55 amalloy: arrdem: (pr ^:integer 'foo) is very different from (pr (read-string "^:integer 'foo")))

15:55 the second case is read as data, while the first is evaluated as code

15:57 arrdem: amalloy: ah. I have the latter behaving, I guess my question is why in the first case is {:integer true} not (meta foo).

15:57 oh wait it's (meta (quote foo))

15:57 yogthos: cbp what's your github id? :)

15:57 `cbp: what's your github id? :)

15:57 `cbp: yogthos: cesarbp

15:59 yogthos: `cbp: ok you should be in :) https://github.com/yogthos/Selmer

15:59 `cbp: not much there yet, I'll check the stuff I've been experimenting with when I get home though

16:00 check in even :)

16:00 `cbp: yogthos: I had a small parser + filters implemented so far

16:01 yogthos: Maybe we can talk more when you're available

16:01 yogthos: `cbp: yeah I started on parser, but it's pretty early stages

16:01 `cbp: can chat a bit now if you've got time

16:01 * nDuff scowls at nrepl.el (nrepl-ac.el? dunno) printing extraneous newlines

16:02 nDuff: ...there was a bug report against nrepl-ac.el for that, but I'm running a much newer version than where it was supposedly fixed/closed

16:02 ivan: https://github.com/kingtim/nrepl.el/issues/315

16:02 squidz: dnolen: I just wanted to see what the reason we always have to use clj->js and js->clj is

16:03 dnolen: may be a silly question

16:03 nDuff: ivan: not sure if that's it -- I'm seeing large runs of subsequent newlines, typically 10-20 or so, rather than one every K or therebouts.

16:03 ivan: nDuff: try commenting out that line anyway

16:04 * nDuff does so...

16:04 konr: squidz: a clojure hash cannot be mapped to a js object, for example, because this can have both a method 'foo' and a field 'foo'

16:05 ivan: js objects can have a foo method and a foo property?

16:05 konr: ivan: that's why we need .-foo and .foo

16:06 ivan: unless I'm having a serious brain malfunction I think you are mistaken about js

16:06 squidz: why dont we just map to one of them or both?

16:07 dnolen: squidz: ok, yeah I don't really see how it could work any other way - ES 6 Proxies could simplify this issue

16:07 gfredericks: consarnit that seangrov fellah left; does anybody know him? is he on twitter?

16:08 dnolen: gfredericks: sgrove on twitter

16:08 gfredericks: dnolen: excellent thanks

16:08 ivan: konr: maybe I misunderstood, I thought you were saying they can have both at the same time

16:09 nDuff: ivan: it's not that the same thing can be both, but you don't know if it should be called or accessed as a property

16:09 ivan: right

16:11 akurilin: btw that "where was x last seen?" feature of lazybot is amazing

16:11 kudos to whoever made that.

16:13 nDuff: ivan: Seems to be resolved, though the codepath I've been seeing it through is somewhat sporadic (smells like it's related to what the autocompletion plugin is/isn't doing), so I don't have certainty around that yet. Thanks.

16:14 akurilin: github etiquette question: is it very impolite to file an issue again someone's repo if you suspect it might have an issue, but you're not really sure? Is emailing the owner preferable?

16:14 callen: akurilin: just file the issue.

16:14 ivan: github issues are the new email, man

16:14 technomancy: akurilin: I would say personal email is not appropriate for bug reports unless it's listed in the readme or something

16:15 callen: akurilin: but you should totally call technomancy on his cell phone whenever you have a problem with Leiningen.

16:15 technomancy: issues are easy to close and leave a public paper trail for posterity

16:15 callen: ^^ yep.

16:15 akurilin: Ok thanks, til.

16:15 technomancy: joke's on you; I get no reception here

16:17 Raynes: akurilin: That would be me, sir.

16:17 callen: technomancy: does Heroku use wikis? If so, which ones?

16:17 technomancy: if not, how is documentation handled?

16:17 akurilin: Raynes, thumbs up, love it :)

16:18 hyPiRion: (inc Raynes)

16:18 lazybot: ⇒ 33

16:18 technomancy: callen: internally or for public-facing stuff?

16:19 Raynes: hyPiRion: amalloy tells me that Gaiman is going to write more Sandman this fall.

16:19 callen: technomancy: internally

16:19 Raynes: don't tease me.

16:19 hyPiRion: Raynes: oh, that's awesome

16:20 callen: I'm already suffering under the yoke of Eliezer Yudkowsky

16:21 technomancy: callen: a few use github wikis, but most use a doc/ dir full of .md files

16:21 fikusz: why nrepl btw? what's wrong with slime?

16:21 amalloy: hyPiRion: i heard him say so on ttbook, if you are interested in verifying it yourself

16:21 callen: not this again :|

16:21 fikusz: I always get confused when switching between cl and clojure projects...

16:22 hyPiRion: amalloy: no thanks, I'll just believe you and complain to you when he doesn't write more Sandman.

16:22 amalloy: hyPiRion: just file a github issue, please

16:22 technomancy: fikusz: the slime protocol isn't documented and changes approximately whenever they feel like it

16:22 hyPiRion: amalloy: alright, will do later

16:23 technomancy: so there's really no way to support it without locking to an old version, and thus making it basically impossible to hack on both cl and clojure anyway

16:23 fikusz: technomancy: I understand, is there an easy way of making the emacs interface compatible? (basically I mean the keybindings...)

16:23 technomancy: fikusz: define-key?

16:24 fikusz: technomancy: also repl shortcuts, like the comma

16:24 technomancy: the comma stuff isn't implemented in nrepl

16:25 fikusz: technomancy: okay, thanks for the info!

16:26 technomancy: sure

16:26 futile: thanks

16:26 fikusz: technomancy: btw, the wikipedia page for slime (http://en.wikipedia.org/wiki/SLIME) lists lots of languages which use slime

16:27 futile: technomancy: so I was going to rename test2 to test-ease, but something tells me that's not a good idea

16:27 fikusz: technomancy: even Ruby and GNU R

16:27 technomancy: well also Clojure apparently :)

16:27 TimMc: futile: That sounds like a project the Ruby community would produce.

16:27 technomancy: fikusz: what's not shown is how broken each individual implementation is

16:27 futile: TimMc: whoa so it does

16:28 I really hate that I was part of the Ruby community

16:28 technomancy: fikusz: it's not that hard to make it work with a specific snapshot, but continued stable support over time is very difficult

16:28 futile: It was an accident, really!

16:28 TimMc: Well, now that it's "no longer cool

16:28 ", maybe it will get nicer.

16:28 futile: Wait, who says its no longer cool?

16:28 fikusz: technomancy: ok, thanks again

16:29 TimMc: Some interblog or another, I dunno.

16:29 technomancy: plus the nrepl protocol is just a better design

16:29 futile: TimMc: well this Ruby guy tells me otherwise http://rosiesaysblog.files.wordpress.com/2012/04/brogrammer.png

16:30 TimMc: Only one popped collar, I call fake.

16:30 fikusz: technomancy: are there any resources for people coming from slime? It must be where most people come from...

16:31 wink: how do I escape a variable in replace? i.e. something like (let [x "foo"] (clojure.string/replace "foobar" #^x "z")) <- the x

16:31 technomancy: fikusz: the only difference I can think of is C-c M-n to change namespaces since they're not called packages in clojure

16:31 futile: I'm so disillusioned by programmers.

16:31 bbloom: wink: your syntax is bad there

16:31 `#^x "z"

16:32 ,#^x "z"

16:32 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

16:32 bbloom: the ^ applies metadata

16:32 ,#"^x z"

16:32 clojurebot: #"^x z"

16:32 wink: bbloom: it's a literal #"^foo"

16:32 fikusz: technomancy: well and debugging, inspection, the threading features

16:32 technomancy: fikusz: oh yeah, that stuff is mostly handled by ritz

16:33 bbloom: wink: you want to construct a regex from strings?

16:33 fikusz: technomancy: ritz?

16:33 bbloom: you can call the java RegExp constructor

16:33 technomancy: fikusz: the nrepl debugger library

16:33 wink: hm. thanks. uglier but doable, yeah

16:34 bbloom: wink: use ##(doc re-pattern)

16:34 lazybot: ⇒ "([s]); Returns an instance of java.util.regex.Pattern, for use, e.g. in re-matcher."

16:34 fikusz: technomancy: well ritz still seems to have a swank server

16:35 technomancy: fikusz: it has both

16:35 * futile is so screwed.

16:36 fikusz: technomancy: I think I'll try it, just for good measure :)

16:36 nDuff: ivan: ...had that happen again w/ the patch applied.

16:36 futile: As Puddleglum would put it, "This time next week, I probably won't have a job, I shouldn't wonder."

16:41 What do you all think of this crazy idea? Instead of setting attributes by maps with keywords as keys, you update attributes by function.

16:41 hyPiRion: update-in, you mean?

16:41 futile: So instead of (merge (new-widget) {:price 1 :quantity 10}), you would do (-> (new-widget) (set-price 1) (set-quantity 10))

16:42 I really mean basically adding some verbosity to your business logic in the name of typo-safety.

16:43 I've been bitten by the names of keys being slight different in some places in my app, and legitimately typing it one way here and another way there, but sometimes mixing them up.

16:43 pandeiro: is it possible to hook a clojurescript repl up to any arbitrary webpage?

16:43 arrdem: pandeiro: I believe not

16:43 pandeiro: clojurescript is not self hosting

16:43 TimMc: pandeiro: You could probably do it with an intercepting proxy.

16:43 justin_smith: futile: you could use defrecord for that while you are at it (defining fields that are callable to return a modified version of the record) and gain some runtime efficiency as well

16:43 technomancy: futile: racket does that with structs. it means you have to multiply cross-module references. not a fan personally, but there's nothing outright wrong with it.

16:44 futile: justin_smith: oh that doesnt sound half-bad

16:44 dnolen: pandeiro: no you need to setup the repl communication channel

16:44 pandeiro: if i have a precompiled cljs.js, include that, start the repl process and then do clojure.browser.repl.connect() ?

16:44 futile: technomancy: phoo

16:44 justin_smith: unfortunately defrecord isnt compatible with Hyperion

16:44 (nothing is)

16:44 dnolen: pandeiro: could probably do something via the Chrome debugging protocol, but somebody would need to work on that

16:45 hyPiRion: In my case, the biggest issues with development isn't typos.

16:45 futile: oh goodness no, not the biggest by far.

16:45 what's yours?

16:45 hyPiRion: Proper system design.

16:45 futile: Oh good, then we're in agreement.

16:45 That's my first biggest issue.

16:46 My second biggest is the wrong libraries being extracted too early.

16:46 And now they're hard-coded into the app.

16:46 forever.

16:46 * futile is getting depressed

16:46 futile: But those aren't battles I can win. So I have to find some morale boost in the small victories.

16:46 pandeiro: dnolen: ever looked at https://github.com/skeeto/skewer-mode ?

16:47 dnolen: pandeiro: nope

16:48 pandeiro: I find JS live REPL tools considerably less useful in practice because people tend to hide their code in closures because they don't have modules / nameespaces

16:49 bbloom: dnolen: pandeiro: i wrote about why JS (and most non-lisp) REPLs suck: http://www.brandonbloom.name/blog/2012/12/21/the-nodejs-repl-is-broken/

16:49 pandeiro: dnolen: true but while we wait for lighttable to have emacs bindings and a terminal console, there's that...

16:49 bbloom: cool i will check that out

16:50 i just find that i prefer typing in emacs than the chrome devtools console

16:50 (if setting it up is as frictionless as C-S-i)

17:01 dnolen: TimMc: actually the method i described above does work, apparently

17:01 it just wasn't working on Github b/c of its Content Security Policy not letting scripts from localhost be executed

17:02 TimMc: Oh, does it use JSONP for communication?

17:03 pandeiro: it uses some black magic from the goog.net package

17:03 isaacbw: I keep writing code and it keeps just working

17:03 this is a weird feeling

17:03 ToxicFrog: Hee

17:04 futile: isaacbw: how are you able to do that!?

17:04 isaacbw: functionaaal prograaaaaaaaaamiiiiiiiiiing whee

17:04 technomancy: futile: fizzbuzz

17:04 futile: wth??!?!?

17:04 pandeiro: goog.net.xpc.CrossPageChannel

17:05 * futile explodes

17:06 pandeiro: very neat to be able to eval cljs on any non-github page :) ... since i could never figure out where to begin fixing himera... and browser extensions can't use eval anyway...

17:06 futile: this day is too much.

17:08 programming is easy. but in real life, programming is hard.

17:08 oh crap, im complaining gain. oops.

17:08 *a

17:13 pandeiro: when did cljs get clj->js?

17:14 futile: ffffff

17:14 seangrove: pandeiro: Sounds like a question for codeq

17:15 Wish someone ran some kind of service you could query for these questions :P

17:15 dnolen: pandeiro: been around since about Clojure/West

17:15 pandeiro: seangrove: don't look at me ;P

17:15 aeyk: why does (apply + (range 1 1000 3)) work but (apply + (range 1 1000 3) (range 1 1000 5)) doesnt?

17:15 pandeiro: dnolen: you were against it i remember...

17:16 seangrove: pandeiro: wei_ and I wrote Jida to be able to ask these kinds of questions, but it needs a backend server for the workers to run, and we let the server die

17:16 I should reload it... maybe next weekend

17:17 amalloy: aeyk: because only the last argument to apply is "unpacked"

17:17 one reasonable change would be (apply + (concat (range ...) (range ...)))

17:18 pandeiro: seangrove: i wouldn't even know how to query that...

17:18 aeyk: amalloy: so i just have to call apply twice then to do that?

17:18 seangrove: pandeiro: With codeq, it's just datalog. Pretty simple

17:19 pandeiro: i don't think i ever saw the presentation on codeq

17:19 dnolen: pandeiro: true, but I also hadn't seen a solution that covered the associative type cases in a good extensible way.

17:19 pandeiro: "just datalog" :/

17:19 :)

17:19 seangrove: Well, I find it easier than SQL most of the time...

17:19 * seangrove is literally dealing with some join tables right now that's making him squint as he nails down the right schema

17:21 gfredericks: seangrove: I tweeted you the watsit

17:22 * seangrove checks the twitters

17:23 seangrove: wow, very simple. Nicely done gfredericks

17:40 gilbertw1: seangrove: Hey, I just updated that clojurescript macro I was talking to you about on Friday, asynchronize. I just implemented the dual channels per callback (one for success, and one for failure), I also have it now throwing an exception containing the err result when the callback is invoked with an error

17:40 seangrove: Do you think that an exception is an idiomatic way to handle this in clojure?

17:41 seangrove: I'm pretty used to scala, and in this case the idiomatic way to handle this scenario would be to use the Either monad containing a left or right for failure or result

17:42 seangrove: gilbertw1: Yeah, that seems reasonable if it's an exceptional thing

17:43 Not sure what the code looks like with that though - is everything in a try/catch block?

17:43 Does try/catch work with core.async?

17:43 gilbertw1: yep

17:44 this is what it'd look like to use it: http://d.pr/i/1TTv

17:46 it's my understanding with nodejs that the err callback is reserved for exceptional cases.....I think it fits semantically

17:46 seangrove: gilbertw1: What if I wanted to try/catch each of those individual defs?

17:46 gilbertw1: it'd behave as expected

17:46 seangrove: Very nice

17:47 gilbertw1: every callback statement is handled independently in place

17:47 seangrove: And the err there is the value given to the generated callback?

17:47 gilbertw1: yea

17:47 seangrove: Wow, pretty cool

17:47 Why def inside of a defn though?

17:47 gilbertw1: http://d.pr/i/EnqQ

17:47 seangrove: I don't suppose that could be a let?

17:48 gilbertw1: absolutely, that example I actually used when I was showing that to a nodejs guy here at work

17:49 figured i'd make it look as much like js as possible

17:50 seangrove: gilbertw1: Could I see an example defn with a few nested lets, and a few try/catches?

17:50 gilbertw1: in that link I basically use alts! to select from the fail or success channel.....when I receive a value I see which channel it came from, if success return value, if fail then I throw the err returned

17:50 sure

17:53 dnolen: seangrove: gilbertw1: try/catch is actually broken at the moment for CLJS core.async, waiting for tbaldrige to take a look

17:55 gilbertw1: interesting....I'll have to double check my error scenarios. Maybe the one inside the go block wasn't working

17:57 dnolen: gilbertw1: it may work w/ earlier versions of CLJS, but definitely doesn't work w/ more recent ones

18:04 gilbertw1: yep, it's not working.....I had a bad test case set up for that

18:05 seangrove: theoretically though, if try catch blocks within go blocks in core.async are working, then the macro should work correctly as well :)

18:05 seangrove: Keywords are not functions in ruby

18:05 gilbertw1: they should be

18:06 seangrove: gilbertw1: Looking forward to it, that's a pretty awesome macro actually

18:06 gilbertw1: thanks!

18:07 seangrove: Curious to see inter-fn composability with it, but for the single-fn case, looks good

18:07 akurilin: In clojure.jdbc, is there a straightforward way to start a transaction, perform a bunch of jdbc operations, and then commit the transaction at the end?

18:07 chord: anything new?

18:08 akurilin: Oh, I think the (db-transaction) macro is meant to take in a body of code into it and then basically hijack whatever jdbc operations you do inside.

18:09 wei_: is there a way to destructure the request map inside the compojure route? i.e. is there a more compact way to write https://www.refheap.com/16813

18:10 clj_newb_2345: is the UI library used by lightttable

18:10 useable / available to use outside of lighttable?

18:12 seangrove: wei_: Says here that it can be a full clojure destructuring form https://github.com/weavejester/compojure/wiki/Routes-In-Detail

18:14 nDuff: Hmm.

18:23 sandover: clj_newb_2345: do you mean node-webkit, the framework that's used?

18:24 wei_: seangrove: thanks, I couldn't use the vector shortcut for route params in that case. came up with this, which is a bit shorter https://www.refheap.com/16813

18:26 seangrove: wei_: Not too bad. Why not capture it all in request as in the first example, and then destructure in the let using {keys [...]} request?

18:29 wei_: how would that differ from the first example? it'd be ideal to have something like this, but compojure doesn't support that https://www.refheap.com/16813

18:30 the goal was to avoid the extra let, if possible

18:33 mirari_: Hello. I'm new to Clojure. Using Intellij Idea; trying to compile (println "Hello World") gets me IOException file not found from the clojure compiler. Any hints?

18:33 Standard install, new project etc.

18:42 squidz: mirari_: sounds like it may not be finding clojure. Have you tried another IDE? Intellij isn't normally used

18:43 maybe eclipse with the counterclockwise plugin

18:43 mirari_: squidz I can run it from the commandline, must be an intellij idea problem. What is the recommended IDE (besides Emacs I guess ;)

18:43 squidz: eclipse with the 'counterclockwise' pluin is as close to Intellij

18:44 http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise

18:46 sandover: for just starting out (sans emacs skillz), i still think clooj is pretty good

18:48 squidz: mirari_: lighttable looks really cool, but I'm not sure what it takes to get up and going

18:48 turbopape: Hi all,

18:49 Still playing around with emacs / nrepl

18:49 But I noticed when I start a "lein repl" session over my project

18:49 I get java class names auto completion

18:49 but not in emacs (I am connecting to this very session )

18:49 Any Idea why ?

18:50 I get completion for clojure stuff (ac-nrepl seems to be ok...)

18:50 Thanks :)

18:51 gtrak: light table's pretty easy to get going, you just point it at a leiningen project

19:07 augustl: just blogged about using ZeroMQ instead of HTTP for internal services, using Clojure. http://augustl.com/blog/2013/zeromq_instead_of_http/ :)

19:08 technomancy: augustl: do you use the native drivers or the pure-java ones?

19:09 augustl: technomancy: I use the native ones for now, mostly because the pure-java ones uses TCP for inproc and that's kind of annoying..

19:09 technomancy: augustl: that is pretty badass that you can use compojure for that kind of thing

19:09 wink: augustl: have you heard about mongrel2? :)

19:09 augustl: wink: only heard about, actually, not sure what it's all about

19:09 technomancy: yeah it's lovely

19:09 technomancy: "Wow, you made it this far! Or perhaps you just skimmed and got to this part. I'm proud of you either way." eerily prescient

19:10 augustl: hah

19:10 wink: augustl: conceptually it's like "wsgi done with zmq" - so the webserver talks to the workers/backends via zmq

19:10 augustl: wink: interesting. Does it actually use ZeromQ?

19:11 wink: augustl: yeah. someone even wrote a ring adapter back then https://github.com/mikejs/ring/tree/master/ring-mongrel2-adapter/

19:11 augustl: sadly it's been kind of stalling for a year

19:12 augustl: well, why use mongrel when you can use ZeroMQ. Props to Zed for being years ahead of the curve again though. (Implying using ZeroMQ is the curve.. :P)

19:13 technomancy: so I know zmq isn't built around a broker model, but in practice wouldn't you end up implementing that on top of zmq anyway?

19:13 like... I don't want all my clients to have to keep a listing of all other peer nodes up-to-date; I just want to send off a job and get a result back

19:13 bbloom_: technomancy: yes, it's extremely common to implement broker-like systems w/ 0mq

19:13 technomancy: in fact, 0mq calls such things "devices"

19:14 and the 0mq guide discusses many well considered patterns for types of devices, including classical brokers

19:14 augustl: technomancy: yeah, in my article you could easily have a DEALER/ROUTER pair on a separate server instead of only on the server itself

19:14 wink: augustl: yep, valid criticism :) the idea sounds ace but in practice there's not so much gain over using what's tried and tested (basically fastcgi)

19:14 augustl: you can also do fan outs and pub/sub and what not, though

19:14 technomancy: I guess I can think of a few isolated cases where I'd appreciate the lower-level access, but for everything I've actually used in real-life the amqp model is a better match

19:15 callen: technomancy: http://www.zeromq.org/whitepapers:brokerless

19:15 wink: re: zeromq: pieter hintjens' blog has a lot of interesting stuff

19:15 callen: technomancy: they talk about it at length.

19:15 bbloom_: technomancy: my experience has been the opposite

19:15 callen: bbloom_: but you're weird and atypical.

19:15 bbloom_: true story.

19:15 the important thing isn't whether or not you use a broker

19:15 the important thing is you PUT YOUR SHIT ON A QUEUE

19:15 augustl: technomancy: for me using ZeroMQ was mostly about practicalities. I only had a single server, and I couldn't find a library for rabbitmq/amqp where I didn't have to manually reconnect on startup if broker is down, etc etc

19:15 callen: bbloom_: I don't mean to dismiss your experience by saying you're weird, but I'm going to have to dismiss your experience.

19:15 bbloom_: once you have serialize/deserialize & asynchronousy, you can swap out the queue/broker/whatever w/ relative ease

19:16 wink: one does not simply put shit in queue

19:16 augustl: and I didn't have to manually if-test for the "request id" on the responses ;) REQ/REP is slightly more native to ZeroMQ than RabbitMQ

19:16 technomancy: forcing every node to keep track of its peers sounds like a lot of work that you just get for free with rabbit

19:16 wink: it depends a little how you're used to work with queues.

19:16 technomancy: and you have to push rabbit hell of hard before it's a bottleneck

19:17 bbloom_: technomancy: fixed topologies are really easy to create. if you don't need absurdly high levels of uptime & whatnot, you can just parameterize your app w/ some fixed endpoints and connect to them at startup

19:18 wink: it wasn't exactly lightning fast in ubuntu 10.04 times though

19:18 bbloom_: considering how many apps run with like 1 to 10 servers at "web scale" the fixed topology approach is often far preferable thanks to it's simplicity

19:19 technomancy: bbloom_: I'd much rather design around disposable nodes

19:19 wink: but your broker isa SPOF then

19:20 technomancy: wink: rabbit has HA options

19:20 wink: technomancy: see above, 1-10 nodes :) but I agree

19:20 technomancy: it'd be a good fit for building a dynamo-like system on top of though

19:21 bbloom_: *shrug* at crazy scale, disposable nodes are the way to go. but one thing that bothers me a lot about the hacker-news armchair architect crowd is this idea that scale is hard & that it's important and all that crap

19:21 technomancy: it's just that most systems don't need to be dynamo themselves; they can sit on an existing dynamo implementation

19:21 bbloom_: running a few services on a few reasonably reliable boxes is MUCH EASIER

19:21 http://highscalability.com/blog/2011/3/3/stack-overflow-architecture-update-now-at-95-million-page-vi.html

19:21 that's a pretty good case study

19:22 ~20 servers

19:22 clojurebot: Pardon?

19:22 nDuff: bbloom_: *shrug*. Some of that is second-system-effect from people who designed without any eye to scalability and found themselves up a creek.

19:22 bbloom_: in a fixed configuration

19:22 technomancy: nothing I've read about 0mq looks easier than rabbit

19:22 easier than sockets, sure

19:22 but it always ends up looking like a ton of work

19:23 bbloom_: technomancy: i think 0mq is SIMPLER and rabbit is EASIER. however, in this case, i wouldn't give a shit if you choose easier, since *having a queue is the important part* :-P

19:23 wink: bbloom_: unless it's MSMQ

19:24 bbloom_: lol or oracle's AQ thing

19:24 holy hell, what a nightmare

19:24 also worth considering it HornetMQ, which is used inside Datomic. Apparently it's really good, but java-centric

19:25 wink: MSMQ has one fun part. you can install it even on xp and it works out of the box with vb.net/c#

19:25 but you're in for a surprise if you want to interface any *ix-system

19:25 technomancy: insist on magic erlang scaling powers for your queue #lifehacks

19:25 bbloom_: wink: i wouldn't be surprised in the slightest

19:25 wink: bbloom_: hey, officially it has a SOAP api :P

19:26 that we didn't managed to talk to...

19:28 callen: technomancy: I've broken RabbitMQ before. a lot.

19:28 technomancy: I'm still not sympathetic to the "lets pretend brokers aren't really useful!" camp.

19:29 technomancy: callen: right; I've had a few problems with it, but I still trust it more than something I would cobble together myself

19:29 callen: technomancy: mos def.

19:31 technomancy: maybe I'm just biased from the way the packaging around the 0mq native dependencies used to be a big headache

19:31 wink: augustl: after reading all of it, the only "mhm" part for me is the "no manual connection management" - I think your example with localhost defeats that a little.

19:31 technomancy: could be!

19:33 augustl: wink: hmm, by connection management I mean initial reconnects and in-flight reconnects. That could probably be clearer

19:33 wink: thanks for reading btw :) Spent way to long writing this blog post..

19:33 wink: augustl: I'm a huge fan of zeromq, just waiting for the killer use case :P

19:33 as in: need to solve a real problem

19:34 something mongrel2 failed :(

19:34 augustl: and it's not really management - it's just connecting and then done.

19:34 squidz: reading article now

19:34 wink: still I'm not seeing a huge difference of "keeping a list of connections" here and via http. just a little more explicit state

19:35 or I'm thinking of the wrong use cases

19:36 augustl: wink: the main difference for HTTP is that HTTP can only do sequential req/rep over a single connection

19:36 wink: zeromq can do them concurrently over a single connection

19:37 wink: augustl: true, but that's not connection management, os it?

19:37 augustl: no, and the connection management stuff that ZeroMQ does is certainly possible with HTTP (local queuing, etc)

19:44 lynaghk: dakrone: ping

19:47 seangrove: I know the answer to this is going to be disappointment, but with korma.incubator, is there a way to pull a column from the join table in a many-to-many?

19:47 I should probably just figure out how to port the sql query to korma manually

19:50 callen: yogthos|away: remind me to show you a keen example of why I am persnickety about 12-factor.

19:56 yedi: does forloop.counter exist in clabango

19:58 doesn't look like it, rough

19:58 billybob_: anybody have experience with webscrapers?

19:59 justin_smith: billybob_: like extracting data from webpages?

19:59 billybob_: yeah

19:59 justin_smith: I use enlive/html-resource to turn it into a clojure data structure

19:59 then manipulate it

20:00 then run it through #(apply (str enlive/emit* %)) before sending the result to the frontend

20:00 yedi: does anyone know of a good method for doing: [1 2 3 4 5 6 7 8 9 10] => [[1 2 3] [4 5 6] [7 8 9] [10]]

20:00 justin_smith: ,(partition-all 3 (range 11))

20:00 clojurebot: ((0 1 2) (3 4 5) (6 7 8) (9 10))

20:01 justin_smith: err almost!

20:01 ,(partition-all 3 (map inc (range 10)))

20:01 clojurebot: ((1 2 3) (4 5 6) (7 8 9) (10))

20:02 justin_smith: billybob_: mind you this is for a client that owns both web pages, I do not advocate stealing content

20:04 billybob_: justin_smith: so, if I'm trying to build a front end for a legacy web app, and it'd require logging in, navigating three pages deep, clicking buttons, etc...

20:04 My client owns both sites as well

20:04 callen: augustl: no.

20:05 billybob_: justin_smith: So would it be better to use enlive (and friends)... or run a browser automation tool, like clj-webdriver

20:05 justin_smith: billybob_: you can use clj-http to get the cookie for login

20:05 unless there are features that totally break without javascript

20:06 billybob_: yea, there are javascript dependent features, some hover balloons with content I need

20:06 justin_smith: we use scraping to show "featured stories" from their wordpress site (grabbing the teaser, the top image, etc.) and this way it automatically updates when their content on the wordpress site updates

20:07 regarding browser driving, I have never had to do something like that

20:07 futile: Fun design question.

20:07 I'm designing a function like (add-item-to-cart! cart item)

20:07 justin_smith: but I still recommend using the enlive methods once you have the html itself, unless you need the whole path

20:08 gfredericks: say there are a pair of methods

20:08 foo(Runnable r) and foo(Callable c)

20:08 can I pass a fn and somehow specify which method I want to call?

20:08 futile: It's got to be reduce-able, so I can get the updated cart back every time, like (let [cart (reduce add-item-to-cart! cart items)] ...)

20:08 But it also has to return error(s) that occurred when adding to cart somehow.

20:08 Ideas?

20:09 augustl: callen: wut? :)

20:10 futile: One idea is to store :errors on the cart, and just conj onto it when necessary. But that clutters the domain model, since it's not really a cart error, it's really an add-to-cart error.

20:10 Another idea is to seed reduce with {:cart some-cart :errors []} and let the function expect/return this instead. But that's more wordy and ugly.

20:11 justin_smith: futile: what about a cart like {:contents [] :errors []} or maybe [{:purchaser ... :item ... :errors [...]} ...]

20:11 gfredericks: seems it emits a type hint warning...

20:11 but can't figure out how to hint correctly

20:11 `cbp: futile: use vectors or maps to return multiple values and then destructure

20:11 futile: `cbp: i.e. idea #2?

20:11 justin_smith: i.e. idea #1?

20:12 Just clarifying to make sure I understand you guys right.

20:13 `cbp: it seems strange to have (defn add-item-to-cart! [[cart errors] item] ...) because its expecting you to input an errors arg when you really only want it on return.

20:13 justin_smith: My gut tells me handling errors from actions should be kept separate from the domain model.

20:14 `cbp: futile: there's nothing wrong with adding initial values such as nil when you reduce a collection

20:14 justin_smith: futile: should errors follow the customer / cart in future access?

20:14 billybob_: anyone know of any good webscraping tutorials that involve logging into a site and actually crawling from one page to another, using links found in the page, etc...?

20:15 futile: justin_smith: nope, only for showing as the response to this action.

20:15 `cbp: your nick is hard to autocomplete :P

20:15 justin_smith: futile: then the errors belong in the response to the request, in parallel with the cart

20:16 though you can have one function that returns a cart and any/all errors

20:16 futile: `cbp: but still... (reduce add-item-to-cart! [cart []] items)

20:16 justin_smith: in parallel

20:16 callen: augustl: ZMQ instead of HTTP as a default internal API? no.

20:16 futile: justin_smith: so, just hide this ugliness inside another function, and pretend it isn't there? :)

20:17 justin_smith: futile: no, redefine add-to-cart as being a function in two simultaneous domains - the domain of the cart data model and the domain of customer interaction

20:17 the final cart goes in the former, the errors go in the latter (and finally get reported etc.)

20:18 augustl: callen: ok :)

20:18 `cbp: futile: Then avoid having to handle 2 values at once if you don't like the ugliness :P

20:18 callen: `cbp: plz talk to yogthos :)

20:19 `cbp: callen: I have, has something happened?

20:20 gfredericks: How to avoid this reflection warning? https://gist.github.com/fredericksgary/6058783

20:20 callen: `cbp: oh, no, just checking :)

20:20 yogthos: `cbp: not as far as I know :)

20:20 futile: Well I don't know what approach seems best. But none seem perfect.

20:20 callen: gfredericks: that's pretty impressive actually.

20:21 futile: Normally I wouldn't care, I would just get depressed and move on, pretending like nothing happened.

20:21 But this is Clojure, not Ruby or Python.

20:21 I've grown to expect that I can express my intentions perfectly in this language.

20:21 gfredericks: callen: check out the comment I just posted

20:21 justin_smith: futile: that only works if your intentions map to the domain

20:21 `cbp: futile: design is hard, spend more time on it

20:21 gfredericks: going to dinner, but I'll check back for responses

20:21 justin_smith: the domain has one operation with results in two conceptual areas, that must be accomodated

20:22 `cbp: keep things as simple as possible and clojure will work for you

20:22 augustl: gfredericks: perhaps generics...? Since it's Callable<T> and you just give it Callable. Wild guess tbh..

20:23 justin_smith: if you were taking square roots, no amount of design would prevent needing a representation of imaginary numbers

20:23 *arbitrary square roots

20:24 brehaut: augustl, gfredericks: but generics are erased at compile time and dont exist outside of Java the language

20:24 augustl: brehaut: ah, good to know. I should read a book about the jvm or something..

20:25 brehaut: augustl: i cant remember who made did the presentation, but theres one out there about the myths that java provides that dont actually exist in the jvm

20:25 augustl: i would recommend it as a good starting point

20:25 augustl: generics and checked exceptions are the two big obvious ones

20:34 futile: I, on the other hand,

20:34 http://bit.ly/162iGAi

20:38 I think the real problem is that I'm trying to make this function fit reduce, instead of looking for alternative ways to add multiples while returning the updated immutable cart.

20:38 That's the age-old problem, you get an implementation detail in your head, and suddenly you shape everything else around it, which is all backwards.

20:39 meoblast001: hi

20:39 why does this not have any results? http://pastebin.com/R2FfV3iH

20:44 futile: Okay, immutability in Clojure is hard.

20:47 Maybe the real problem is that I'm combining validation with action. Maybe I should have (can-add-item-to-cart?) be separate from (add-item-to-cart!)

20:47 seangrove: futile: Almost certainly

20:47 futile: Yeah. That actually works much nicer.

20:49 Raynes: futile: I like to make my programs all be one big function.

20:49 callen: I conflate those all the time. lol.

20:50 futile: Then I can do (map can-add-to-cart? items), filter out the ones that actually can be added, and then just (reduce add-to-cart! valid-items)

20:50 technomancy: Raynes: speaking of which ... http://software-lab.de/skaro.pil

20:50 futile: Raynes: in Perl, right?

20:50 Raynes: callen: I think you mean 'complect': http://da.gd/0LR17

20:50 technomancy: someone was golfing skaro and got it way down in picolisp, but only because he collapsed it into a single function

20:51 Raynes: futile: Why do you need to map before you filter?

20:51 futile: Raynes: probably don't.

20:51 Raynes: good point, thanks.

20:51 Raynes: (filter identity (map can-add-to-cart? items)) if you're into that sort of thing, but...

20:51 :p

20:51 futile: NO


20:51 (remove nil? (map ... items))

20:52 Raynes: Eh?

20:52 futile: Oh sorry for blacking out there.

20:52 Raynes: If your function has a question mark at the end of it, it should never return anything other than true or false, making identity a sound choice.

20:52 futile: I meant to say, I hate "filter identity" in terms of readability.

20:52 It's usually much more correct to type (remove nil? ...)

20:53 Raynes: I like to read it as "Take all of those who have a sound understanding of themselves …"

20:53 futile: Or (remove false? ...)

20:53 Derander: Raynes: ++

20:54 futile: But look, I'm not here to change you and you're not here to change me. We're all really just here for the free money anyway, right? So let's boogey.

20:54 or something

20:54 Raynes: I'm here to change you, sir.

20:54 You will conform.

20:54 futile: Okay.

20:54 Derander: it's the arockalypse. get ready for the rockening.

20:54 futile: I'll change anything but my religion, cuz wutevz

20:55 Derander: futile: you'll change your mind when the rockture comes 'round

20:55 technomancy: there was a discussion ages ago about making filter use identity as its default predicate

20:56 I don't think it'll ever happen (partly because jira and partly because an optional first arg is vaguely sketchy) but it's an interesting idea

20:56 futile: technomancy: me no likey

20:56 that is, if my opinion counts for a vote

20:56 and if this is a democracy

20:57 technomancy: ~laugh

20:57 clojurebot: ha ha

20:57 callen: technomancy: I wouldn't want it.

20:59 futile: Is it really true that open source is mostly a social thing and not a technical thing?

20:59 That might explain why I suck at it.

21:00 technomancy: that was supposed to be a mad cackle

21:01 kind of a weak laugh, clojurebot

21:01 futile: technomancy: why I oughta

21:01 fix that bot for you.

21:01 technomancy: clojurebot may be beyond repair

21:01 futile: Oh right. Not enough Ruby.

21:02 I realized why I like Clojure so much more than most other languages I've used in my "professional" career.

21:02 It's because it's mostly context-free.

21:02 Raynes: futile: You should go submit a pull request to Elixir to rename it to liquid.

21:02 futile: Almost nothing is automatic or implicit.

21:02 Raynes: if only I had the money to

21:06 technomancy: futile: the magic of referential transparency

21:06 futile: huh?!?

21:06 man you guys so craaazeh

21:07 technomancy: oh yeah, that.

21:07 Yeah, I hate referential opacity.

21:07 That kind of opacity is best served 0.0

21:08 Also clojure.core being sane helps.

21:08 Seems like Matz kinda had the right idea.. at some point

21:09 It just.. doesn't work

21:12 technomancy: thanks for teaching me how to say it better: test2's goal is referential transparency

21:13 That's why I think it should be named "test-ease"

21:13 And yes, I'll continue with that joke until someone acknowledges it with hearty laughter.

21:14 justin_smith: meoblast001: that is kind of weird, it should work I think

21:14 meoblast001: i found it's wrong

21:14 i should use (re-seq)

21:15 what i was using finds what to break it on

21:15 i was looking for what the segments should match

21:15 justin_smith: ahh, so you throw away every match of #".{1,80}"

21:15 of course

22:53 OneFourSeven: In Emacs, how do I change the default nrepl buffer? I have two repls open because of Clojure and Clojurescript and I want a way to change which one code is evaluated in

23:06 akurilin: What is the fundamental difference between with-bindings and with-redefs?

23:09 bbloom_: akurilin: with-redefs is not thread safe

23:09 akurilin: redefs just set & then later setback the vars

23:09 squidz: doesy anybody know why my anonymous function in line 11 doesn't seem to be executing? it's javascript

23:10 bbloom_: akurilin: with-bindings, however, maintains a thread-local STACK of values & pushes/pops from that stack

23:10 so with bindings, you can capture the stack of bindings too with bound-fn, etc

23:10 dynamic vars are a bit heavier weight than normal "static" vars, which are themselves slightly heavier weight than say java statics

23:11 akurilin: bbloom_, got it, that's helpful, thank you.

23:14 squidz: are anonymous functions runnable from clojurescript let forms?

23:14 bbloom_: squidz: i'm not really sure what you're asking… but why don't you try it?

23:15 squidz: I am and it's not working but I cant debug my way out of it

23:16 bbloom_: squidz: gist a minimal reproduction at the repl

23:18 ChongLi: hmmm

23:18 lein-ring doesn't seem to want to auto-reload my code?

23:18 I'm running it with lein ring server-headless

23:18 anyone else have this issue?

23:23 ahh nevermind

23:23 squidz: bbloom_: line 11 is the problem https://www.refheap.com/16844

23:23 ChongLi: it only works with server

23:23 not server-headless

23:23 :)

23:26 bbloom_: squidz: what error do you get?

23:27 squidz: I dont get any error. but that line 10 produces dom elements like expected.

23:28 and when I try to console out in the anonymous function nothing happens

23:28 bbloom_: squidz: then i assume your function isn't getting called

23:28 you've got a bug, not cljs

23:29 squidz: hm but I wouldnt know why it's not getting called

23:29 the previous line properly creates the rows var which the next line depends on

23:29 bbloom_: does the selectAll "td" return any values?

23:30 what does data do when it's given a function?

23:30 how does it know if it got a function? does it check typeof or whatever? if you give it a different function, like (.-log js/console), does it work?

23:30 squidz: it works kind of like map

23:31 ChongLi: hmmm

23:31 so lein-ring is reloading now

23:31 but it doesn't reload an enlive template properly

23:31 bbloom_: you're gonna need to debug it :-P

23:31 ChongLi: is there some kind of hook I can use for this?

23:32 it only reloads correctly when I save a clj source file

23:32 squidz: hmm this bug's tricky

23:34 bbloom_: I pasted the javascript that gets created https://www.refheap.com/16844

23:35 bbloom_: minus the confusing lack of parens around that "scope" function, that looks fine to me

23:36 squidz: below I pasted the javascript that i am trying to produce, that is javascript that works https://www.refheap.com/16844

23:37 bbloom_: the compiler output looks correct to me

23:37 squidz: its not even letting me console.out though from the within the anonymous function

23:38 bbloom_: squidz: what do you mean "not letting". do you mean it's NOT BEING CALLED? or do you mean you're getting a compiler error

23:39 squidz: its not being called

23:39 I am getting absolutely no erros

23:40 bbloom_: squidz: you have a bug that is 100% unrelated to clojurescript

23:40 the compiler output is correct

23:41 squidz: it okay it must be in the library i'm using I will dig deeper into it when I'm not so sleepy. Thanks for the help anyways

Logging service provided by n01se.net