#clojure log - Dec 01 2013

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

1:19 logic_prog: for swap!, is there something that does "swap and return old value" ?

1:19 so update-in returns the new value of the atom

1:20 however, instead of doing update-in, I'd like to update the value ... but also get the old value

1:49 nightfly: I'm not sure that that's possible since swap! isn't guaranteed to be called only once

1:49 you could probably build what you want using refs instead though

1:56 amalloy: i mean, you can do it with an atom if you don't mind making it a bit of a hassle to use the atom for other stuff

1:58 (defn historical-atom [x] (atom [x nil])) (defn swap-returning-old! [hatom f & args] (second (swap! hatom #(apply f (first %) args)))) (defn current-value [hatom] (first @hatom))

1:59 or...well, i got the swap! wrong. but i think the idea is clear enough

2:27 mysamdog: How would I do var folded = new OriDomi(document.getElementsByClassName('responsee.1')[0]); in clojurescript?

2:34 seangrove: mysamdog: (OriDomi. (first (.getElementsByClassName js/document "responseee.1)))

2:34 But of course you'd have to make sure all the deps were loaded properly, etc.

2:35 You just asked for a simple mechanical transformation.

2:36 mysamdog: (-> (.getElementsByClassName js/document "responseee.1) first (OriDomi.)) might be more clear, depending on your background

2:36 mysamdog: Thank you so much

4:31 amalloy: fwiw, seangrove, the way i think reads most nicely is (OriDomi. (first (-> js/document (.getElementsByClassName "responseee.1"))))

4:32 but i dunno. that puts the classname last, whereas i'd like it to be more prominent

5:46 xificurC: Hi, reading about 'Mocking and Stubbing' in 'Clojure in Action' I notice that the author is dynamically rebinding a function, i.e. he has a (defn log-call ...) and somewhere else does (binding [log-call something-else] ...). I understand that this is not possible since then unless you declare (defn ^:dynamic log-call ...)?

5:48 so that means you cannot shadow a var unless it's declared as ^:dynamic, right?

5:53 arcatan: xificurC: yeah

5:53 xificurC: but in earlier versions of Clojure all variables used to be dynamic

5:54 (earlier versions = 1.2 and earlier)

5:54 xificurC: arcatan: thanks

5:54 so that part of the book is practically deprecated

5:56 arcatan: there's still with-redefs, which can be used all variables and which mutates the binding globally (binding does it thread-locally)

5:56 so it's kinda dangerous if you're multithreading, but it can be useful when writing tests

5:57 i recently asked on stackoverflow about it: http://stackoverflow.com/q/20139463/297366

6:01 i wonder if mocking by rebinding variables is popular, or good style.

6:02 xificurC: arcatan: I wonder too. thanks for the tip

6:05 arcatan: cool I only had to change binding to with-redefs in the functions and the tests work as expected. Thanks!

6:37 d11wtq: I notice map returns a lazy-seq. However, when I map over a vector, it doesn't seem to be lazy like it is using a list. What am I doing wrong here?

6:37 (first (map (fn [x] (println (str "Called with " x)) x) [1 2 3 4 5]))

6:37 See the side-effects even when just asking for first. If you switch that vector to a list, the side-effects go away for the rest of the list.

6:48 eigenlicht: clojure's macro system is not hygienic, is that correct? but it avoids the problem of unhygienic macros by not allowing name bindings that hide others

6:49 hiredman: eigenlicht: no, if it did that, that is pretty much the definition of macro hygene

6:50 eigenlicht: clojure has some facilities for automatically generate symbol names for use in macro created bindings that have names that are unlikely to shadow anything

6:51 eigenlicht: hiredman: so even though I use a name that is likely to shadow some other, it internally gets replaced by something else?

6:51 instead of me doing it manually like in CL with gensymbol?

6:51 hiredman: eigenlicht: no, it would get replaced unless you as for it

6:51 eigenlicht: pardon?

6:53 hiredman: eigenlicht: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L794-L804 is what it looks like

6:53 when using syntax quote (which is sort of like the quasi quote other lisps have) a symbol name that ends with # is auto gensymed

6:54 all symbols that do not end with # are assumed to be globals and get namespace qualified

6:54 eigenlicht: hiredman: got it, thanks

6:54 hiredman: so if you want to have a local name inside syntax quote that is not a gensym you have to work at it

6:55 `a

6:55 ,`a

6:55 clojurebot: sandbox/a

6:55 hiredman: ,`a#

6:55 clojurebot: a__57__auto__

6:55 hiredman: ,`(let [a 1] a)

6:55 clojurebot: (clojure.core/let [sandbox/a 1] sandbox/a)

6:55 hiredman: and clojure won't let you bind a namespace qualified name as a local

6:55 eigenlicht: ,`(let [a# 1] a)

6:55 clojurebot: (clojure.core/let [a__114__auto__ 1] sandbox/a)

6:56 hiredman: ,`(let [a# 1] a#)

6:56 clojurebot: (clojure.core/let [a__143__auto__ 1] a__143__auto__)

6:56 eigenlicht: seems reasonable

6:56 hiredman: it has worked ok so far :)

7:04 d11wtq: Noob question, but what should I be looking at if I know (map ..) is not being lazy when it should be? I've tried wrapping the seq with (lazy-seq s) but it's still executing the function for every element in the seq.

7:08 hiredman: d11wtq: http://blog.fogus.me/2010/01/22/de-chunkifying-sequences-in-clojure/

7:08 d11wtq: Ah never mind, it wasn't anything to do with laziness. I was going down the wrong rabbit hole.

7:08 hiredman: thanks. I'll have a look at that in a tick. I definitely need to better understand seqs.

7:09 WWWest1: Hi all

7:10 Has anyone managed to get source maps working on node?

7:13 danenania: hola clojurians, could use a little guidance on compojure/friend if anyone has a minute: http://stackoverflow.com/q/20311952/238751

7:31 Bronsa: hiredman: what I was trying to fix with the current behaviour of validate-loop locals is this: http://sprunge.us/RfMe

9:05 zilti: I have a problem with core.async in clojurescript. >! and <! both block forever, while put! and take! work as intended.

9:25 I have a problem with core.async in clojurescript. >! and <! both block forever, while put! and take! work as intended.

9:58 jph-: anyone know offhand if there's a pretty printing / output formatter for console apps?

9:58 ie formatting data into tables

9:58 ascii tables

10:05 zilti: jph-: Look into the clojure.pprint namespace.

10:07 jph-: zilti: cheers, wasnt sure if that would include table-level formatting or just json-type formatting

10:08 zilti: jph-: You can format things into tables as well, yes

10:08 jph-: zilti: lovely

11:19 danneu: Has anyone hapened to roll their own function that walks arbitrary structures/values and converts values in some way? Ideally I'd just borrow someone's since my attempt sorta sucks https://www.refheap.com/21390

11:22 nvm, the dispatch on map? coll? etc needs to be moved outside the `walk` as well

11:28 rovar: is there a way to explore the classes that are loaded in the classpath from the repl?

11:28 I'm having a hard time finding the correct name to use to load modules

11:30 i run lein repl, and and when I try to require or use, it says it can't find that class.

11:31 specifically: (use 'jiraph.graph) or (use 'org.flatland/jiraph.graph)

11:31 justin_smith: danneu: does clojure.walk2 not do what you want?

11:31 rovar what is the artifact you added to your dependencies?

11:32 rovar: [org.flatland/jiraph "0.12.3-alpha1"]

11:32 seangrove: Looking at picking up JoC, but I don't want any more physical books. Is the ebook reasonably well formatted and enjoyable to read?

11:32 rovar: lein cp indicates that it is referencing it

11:32 seangrove, so far so good. I just picked it up last night

11:32 the 2nd edition from manning

11:32 justin_smith: rovar: flatland.jiraph.graph https://github.com/flatland/jiraph/blob/develop/src/flatland/jiraph/graph.clj#L1

11:32 rovar: they give you a [mobi ebook pdf] file

11:33 justin_smith: also, avoid use, require with an alias helps a lot

11:33 rovar: basically what you want to require is the ns name declared in the file you are using

11:34 rovar: what would be the best approach for a repl?

11:34 justin_smith: usually I do: (require '[flatland.jiraph.graph :as g])

11:35 not too much hassle to type, makes me rembember where the functions came from if I put them in my code

11:37 rovar: that works

11:38 justin_smith: the problem with use, in my experience, is I come back to something later, and need to reorganize, and have no idea where any of these functions came from

11:38 it makes extending or splitting my code very annoying

11:39 rovar: erg

11:41 seangrove: rovar: Did you try it on the Kindle?

11:41 rovar: the good news is there has been significant development work since that documentation was written. The bad news is <<<

11:41 justin_smith: lol

11:41 documentation skew!

11:42 rovar: everything has been moved into new namespaces..

11:42 but the tests are current

11:43 seangrove, uploading the .mobi now

11:43 I have a crappy kindle, so most programming books are not good

11:44 hyPiRion: Ah dang, wish there were some way to couple documentation indirectly with "tests". Although I have a feeling that it's harder than it seems

11:44 justin_smith: using the doc strings in function bodies help - at least they are right there when you edit or move the function

11:44 hyPiRion: It's "hard" to trace down "outdated" documentation.

11:45 yeah, I am more thinking of documentation living outside the source code

11:46 justin_smith: I think for that, you really need a preamble : this documentation is current as of "version"

11:46 someone was having some trouble the other day, some nrepl docs had been s/nrepl/cider/g edited, and were inaccurate because some of the stuff isn't actually working in cider

11:48 hyPiRion: hmm, yeah, that's doable

11:48 justin_smith: it is fairly simple, and you know as soon as you start reading whether it is guaranteed to apply to your version (and how many versions old it is)

11:49 rovar: seangrove, looking at it now on my 7" black and white kindle.. looks good. no tables are mangled, code examples look right.

11:49 justin_smith: speaking of, there are some old caribou docs that should really just be taken down and pointed at the new docs

12:00 jtoy: where is a log function in clojure? its not in math contrib anymore it seems

12:01 justin_smith: ,(Math/log 0.1)

12:01 clojurebot: -2.3025850929940455

12:01 justin_smith: though you may want something with proper numeric tower support

12:02 dunno where you would find that

12:02 jtoy: that should work for now, thanks

12:02 hard to tell from the docs

12:08 justin_smith: jtoy: fyi clojure.contrib.math is not clojure.math.numeric-tower

12:09 https://github.com/clojure/math.numeric-tower

12:18 jtoy: justin_smith: it says Formerly clojure.contrib.math ?

12:20 justin_smith: I meant now, typed not

12:20 oops!

12:32 rubber-duck: if I have a macro (defmacro foo [x]) how do I get (foo y) to return symbol y ?

12:33 ''x will return x, 'x will return y that gets evaluated to y in local ns

12:35 nvm figured it out (defmacro foo [x] `(quote ~x))

12:35 bbloom: rubber-duck: you can write `'~x

12:36 rubber-duck: bbloom, nice

12:40 jtoy: can I add metadata to a defn and then from inside the method access that data?

12:41 hyPiRion: I guess

12:41 (defn foo [] (meta #'foo)) ...

12:42 jtoy: ^ works fine

12:49 exupero: can anyone tell me why when I run `lein trampoline cljsbuild repp-listen` it seems to hang?

12:49 *repl-listen

12:59 holo: hi

13:00 just created a new library template with lein, test file is suffixed with _test instead of a directory named test. what is the rationale behind for this decision?

15:53 solidus_: how do i use clojure async? i did (require 'clojure.core.async) and added the deps in lein project.clj but i can't use any of the macros

15:54 dnolen: bellkev: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/compiler.clj#L355, the entire CLJS AST is represented as maps, and multimethods over them

15:54 bellkev: you'll see similar things if you look at the modern CLJ analyzer and emitter that Bronsa is working on

15:55 coventry: I did run into a problem with using a dispatch map: <http://dev.clojure.org/jira/browse/CLJ-1276>. I they're considered bad style, that's a drawback because it's a largely untested usage.

15:56 *If

15:57 Perhaps if I used a multimethod, I could reunify the code I had to split out because of that bug. https://github.com/coventry/troncle/blob/master/src/troncle/wrap/wrappers.clj

15:59 solidus_: Can you post some code and the error you're getting on refheap.com

16:00 solidus_: coventry : turn out i needed to eval (require '[clojure.core.async :as async :refer :all]) ...

16:01 bellkev: Just briefly looking at defmulti, it looks like it's primarily a way to do something like method overloading by type in Java?

16:01 coventry: bellkev: It's much more general than that.

16:01 justin_smith: bellkev: you can use an arbitrary function for dispatch

16:01 bellkev: so you can have a key declaring the "type" of map it is

16:01 for example

16:02 bellkev: Okay, I'll keep checking it out. In my case, I need between 1 and 4 different methods (named "default", "create", "update" and "delete"), each of which will basically take maps as input/output

16:03 si14: how can I debug random "ClassNotFound" exceptions about one of my records?

16:04 justin_smith: si14: is a record you have redefined at some point in the repl?

16:04 si14: the weird thing is that it's really random. It works in 80% cases, and in 20% exception is thrown

16:04 justin_smith: nope

16:05 justin_smith: are you getting complaints that a class could not be loaded?

16:05 si14: justin_smith: here is the trace: https://gist.github.com/si14/187a43845e3d1eea4544

16:06 justin_smith: and is this a class you can normally access?

16:06 si14: yes

16:06 moreover, it was accessed by previous request

16:08 and it breaks core.async in somewhat funny way that I can't even locate, it just stops to deliver WS messages through the "bridge" I've made

16:08 justin_smith: threads + exceptions can lead to unexpected behavior combinations in my experience

16:09 coventry: justin_smith: Can you give an example?

16:09 tbaldridge: si14: are you using record literals?

16:09 si14: tbaldridge: нуы

16:09 tbaldridge: yes

16:09 (sorry)

16:09 tbaldridge: I'm using cljson that use them

16:10 tbaldridge: si14: yeah, until recently, record literals are a bit buggy with core.async

16:11 si14: tbaldridge: I'm using the last tagged version (""). Does it mean that I should better switch to snapshot?

16:12 tbaldridge: si14: try using

16:13 or you can also move the record literals outside of go blocks (call them in other functions or something) that might help

16:14 and this is only for record literals. Normal record creation like (->Foo 1 a) works just fine

16:15 guns: Was (def ^{:private true} foo …) legal back in Clojure 1.2?

16:16 si14: tbaldridge: tried the newer version and it didn't help. I don't use record literals directly, they are used by a library

16:17 the thing that is the most painful is that it really happens in 20-30%

16:17 tbaldridge: si14: that should be fine then. The problem is only when you use reducers directly inside the body of a go

16:17 si14: it's probably a race condition. A class gets called before it is loaded.

16:18 andyf: tbaldridge: This question might be nonsense, but is there some sense in which core.async is x% of a Clojure compiler, for some non-0 number x?

16:19 tbaldridge: yes, it is a CLJ->CLJ compiler :-)

16:20 coventry: I call my compiler #'identity.

16:20 guns: And to answer myself, yes ^{:key value} metadata is fine in 1.2, but not ^:key

16:20 andyf: tbaldridge: I ask not from deep knowledge of core.async, but just the vague impression that the kinds of bugs experienced in core.async seem to be in some fairly deep corners of the language.

16:24 si14: tbaldridge: how this can be given that the code that uses that class was already run?

16:27 tbaldridge: andyf: yeah, that's very much the case. Most of the bugs in the go macro have come from use cases that 0.01% of Clojure code uses.

16:27 si14: I'm not sure, I haven't seen the code. That's just a guess

16:28 si14: tbaldridge: I mean that I can be wrong in my assumptions about how classes are resolved in JVM.

16:30 Profpatsch: I finally got the Clojurescript brepl working on top of nrepl in Emacs.

16:31 Now I’m experimenting with coding a little on canvas.

16:31 I’ve got a brepl running on 9000 and cider connected to that.

16:32 Then I wanted to pull in dommy, edited the project.clj, edited the require and restarted cljsbuild auto.

16:34 But somehow the repl didn’t quite follow. I can type stuff in the file, save it and reload the page, works just fine, but when I try to eval dommy functions from the repl I get evaluation TypeErrors.

16:34 “Cannot call method ‘call’ of undefined.”

16:35 Is this normal with repls?

16:41 justin_smith: sounds like you are trying to use a function that is declared as a var but not yet bound

16:41 Profpatsch: Woah there.

16:41 I just imported a library. ;)

16:42 The one thing I stumble over a lot in clj is the namespace system.

16:43 si14: finally fixed (or I hope so) the problem with AOT.

16:49 Profpatsch: justin_smith How could that be. When I refresh the browser, the repl should be completely fresh, shouldn’t it?

16:57 justin_smith: Profpatsch: it could be the error has to do with trying to call something that does not even exist

16:58 bellkev: justin_smith: Well, I think I found a more Clojurey way around my whole multi method question...

16:58 Profpatsch: justin_smith: https://www.refheap.com/21393

16:58 justin_smith: bellkev: cool, what is it?

16:59 bellkev: The whole reason I needed methods in the first place was to respond to create/update/delete calls from the AWS CloudFormation custom resource API

16:59 Profpatsch: justin_smith: That’s after reloading the browser.

16:59 bellkev: However, those actually come as a "event" object kind of like an HTTP request, with the "method" as one of the fields in the event

16:59 justin_smith: ahh

16:59 bellkev: So I can make it so that you just have to implement a handler, like a ring handler, that gets the whole request as input

17:00 justin_smith: so you can use the format that comes in

17:00 bellkev: Does that make sense?

17:00 justin_smith: indeed

17:00 bellkev: Yeah, and then handler-developers can do whatever they want with the map that comes in

17:00 coventry: Profpatsch: It looks like sel1 is a macro, meaning it's clojure code, but your repl is trying to execute it as cljs.

17:00 ...unless cljs has been moving so fast it now has native macros, and I didn't notice.

17:01 Profpatsch: Huh. So I can’t use dommy in-browser?

17:01 coventry: Profpatsch: I would be googling for things like "using macros in brepl".

17:03 Profpatsch: Oh, I should use Austin, that seems to support interactive macroexpansion.

17:04 But you are right, in brepl I need to first explicitly evaluate the namespace to make the reader expand the macro.

17:18 jtoy: how can this be true: (println (= "integer" (column-map (first x)))) but this prints false: (println (or (= "bigint" (column-map (first x)) (= "integer" (column-map (first x))))))

17:18 im sure its some silly mistake, but I dont see it

17:20 coventry: jtoy: Try (println (or (= "bigint" (column-map (first x))) (= "integer" (column-map (first x)))))

17:20 (Your paren positions look wrong.)

17:20 jtoy: yes, thats it :(

17:20 thx

17:21 is there a simpler way to write that same expression?

17:21 coventry: (let [r (column-map (first x))] (println (or (= "bigint" r) (= "integer" r))))

17:21 hyPiRion: (boolean (some #{"bigint" "integer"} (column-map (first x))))

17:22 wait er

17:22 coventry: But you might also want to look into an tree-editing mode, like paredit.

17:22 hyPiRion: (contains? #{"bigint" "integer"} (column-map (first x)))

17:22 jtoy: coventry: I do use paraedit, how would htat help me in that situation?

17:23 coventry: jtoy: It should have inserted balanced parens as you built the expression.

17:23 jtoy: coventry: probably from me doing too much editing

17:30 diogenes_: where can i see the clojure conj 13 videos? are they up yet?

17:44 mercwithamouth: question...say i used enlive opposed to enfocus....would the created markup code stress the backend or would it function just the same as all of the code were client side?

17:51 justin_smith: a good templating / rendering engine should not be too much of a load

17:52 I have not used enlive much in production though, except to destructure 3rd party data and render it, and there I was using a cache with a ttl to avoid mainly the overhead of fetching

17:53 but also having the side effect of not calling the rendering function for most requests

18:08 mercwithamouth: justin_smith: i see....i think i'm just going to use hiccup for the basics and enfocus or dommy. i'm toying with dommy at the moment but something tells me i'm going to go the enfocus route

18:15 noncom|2: justin_smith: so, regarding timbre, sorted it out, mthanks, looking at the config contents. the file problem was due to wrong path. did not give an exception though

18:15 justin_smith: noncom|2: cool, so otherwise that config to turn off stdout and turn on file logging was correct?

18:15 noncom|2: yeah

18:33 waf: is there some sort of 'interceptor' function in clojure, where i can apply input/output transformations based on some condition?

18:33 i'm not happy with this code: https://www.refheap.com/21394 and trying to find a more idiomatic way to write it

18:39 justin_smith: waf: the middleware pattern as used with ring is a nice way to do that stuff

18:39 a bunch of small functions that each do some action or transformation on the input, and you define your features / behaviors by how you line them all up

18:40 bellkev: Is there some way to use "require" on namespaces that have been dynamically created?

18:40 Or, put another way, is there a more dynamic way to do something like what the amazonica AWS wrapper does here: https://github.com/mcohen01/amazonica/tree/master/src/amazonica/aws

18:40 justin_smith: (require '[some.ns :as alias]) will work for that

18:40 in a repl for example

18:41 chouser: bellkev: require calls various public functions such as alias and refer

18:41 justin_smith: bellkev: what file are you trying to point to there?

18:41 bellkev: I'm pointing to the collection of files

18:41 Each one is just a tiny wrapper, that dynamically interns a bunch of functions into its namespace

18:41 justin_smith: that looks like a bunch of small namespaces that only exist to create side effects

18:42 waf: justin_smith: ah, interesting. this is a ring app, i'll lookin into pulling it out into middleware

18:42 thanks!

18:42 bellkev: I was wondering if I could do a similar thing programatically with "create-ns" called on a big array of strings basically

18:43 It seems to work, and I can call "use" on the generated namespaces, but if I try to "require" them, I get "file not found" exceptions...

18:43 chouser: bellkev: I'm not sure amazonica is the right approach, but you can absolutely create namespaces dynamically and manipulate them with functions.

18:44 justin_smith: yeah, I haven't looked at this in detail, but they are making some really weird design decisions here

18:44 the whole "namespace that only exists to configure some object as a side effect" thing has me skeptical

18:45 chouser: bellkev: oh, you want your *users* to be able to call require and bring in namespaces that may not actually exist as files on disk?

18:45 bellkev: Well, the motivation (and I have the same motivation) is to wrap a bunch of things that are "namespacey" with corresponding clojure namespaces

18:45 chouser: that's right

18:46 I mean, say what you will about the way amazonica is made, but using it is a joy compared to the Java api and feels very clojurey

18:46 zerokarmaleft: is it possible to "unmap" an imported java class via ns-unmap?

18:47 bellkev: Just do: (require '[amazonica.aws.ec2 :as ec2]) and then (ec2/create-instance {params})

18:47 Which feels pretty nice

18:48 As far as dynamically generating the namespaces though, if you do this: (create-ns 'foo.bar) then (require '[foo.bar :as bar]) you get a filenotfound exception

18:49 Because it seems "require" needs a clj or .class file to be there...

18:50 justin_smith: bellkev: may help to look at the source of require, then the source of load-libs (which is what it calls) etc. until you find the sequence of calls that can map and load an ns without looking for a file

18:51 zerokarmaleft: my motivation is to recompile and re-intern a java class in a repl

18:51 justin_smith: bellkev: probably what you want is clojure.core/alias if you want the :as feature of require

18:52 zerokarmaleft: so you want the opposite of import, basically

18:52 amalloy: zerokarmaleft: why not just skip the import step altogether, and just use the class's full name?

18:52 then you can get your recompile working, which is the hard part, and get back to import if you decide it matters

18:52 bellkev: Yeah, maybe... Except it would be nice if the users of the namespaces I'm making could treat them as normal namespaces, pick their own aliases with ":as", etc...

18:53 justin_smith: the other option is to give them a version of clojure.core/require that is not the real one

18:54 and potentially cause really weird bugs for people who do not realize you have replaced it

18:54 bellkev: justin_smith: you mentioned the questionable design choices of amazonica... can you think of an alternative approach to all this stuff?

18:54 haha, yeah I have no qualms with causing weird bugs for people :P

18:54 coventry: Remind me never to run your stuff. :-)

18:55 justin_smith: bellkev: I'll have to consider it. Creating an object of the top level of a namespace is a bad idea.

18:55 zerokarmaleft: justin_smith: essentially, yes, though as amalloy points out, it's ancillary to the problem of recompiling and reloading

18:55 bellkev: I mean, another way to go about things would be to treat these namespaces as some kind of string constants or keys that get passed into generic functions that process them

18:56 justin_smith: bellkev: a namespace is a hash map where the keys are vars and the values are their definitions

18:56 bellkev: rather than dynamically generating a bunch of similar but differently named functions

18:56 justin_smith: bellkev: if you want weird behaviors that are not quite right for a namespace, then make those maps as regular maps

18:57 bellkev: You mean use regular maps if I *don't* want weird behaviors, right?

18:57 justin_smith: no, maps are open ended, you can do all sorts of stuff with them

18:57 namespaces are more restricted in terms of proper usage

18:57 amalloy: use regular maps if you want behaviors that are weird for namespaces

18:58 bellkev: oh, I see what you mean

18:58 coventry: I used a programmatically created namespace and vars in it for internal communication between invocations of a macro. But I wouldn't use it for an API.

18:58 justin_smith: yeah, that's what I meant

18:59 coventry: At least, not an API want people to program to. A short namespace can be useful for interactive repl work.

19:00 bellkev: Once created, these namespaces will be pretty normal namespaces (maps of vars/values)

19:00 It's just the question of how to make them, or to use something besides namespaces

19:01 Are there any good examples out there of libraries that use a whole bunch of (possibly nested) string constants? Because that's another way to think of this I suppose...

19:01 coventry: They're easy enough to make. The functions at the bottom of http://clojure.org/namespaces suffice. But it's too much magic.

19:01 justin_smith: having namespaces without files breaks a bunch of pretty reasonable assumptions about clojure code. At the very least make an empty namespace file with a comment that it is filled in programmatically in such and such way.

19:02 but even then I would be skeptical

19:02 bellkev: Maybe just a big map of keywords would be better?

19:03 That could be used like (create-aws-resource (-> resources :ec2 :instance)?

19:03 justin_smith: I think so. It is idiomatic.

19:04 people will be less likely to hate you forever, because I totally expect a map to be built dynamically and not be represented literally in a file. But if I find a bug in using a namespace and I cannot even find a file defining it...

19:05 coventry: Where is amazonica making these namespaces It looks like it creates big maps.

19:05 bellkev: They do have a file per namespace

19:06 But each file is just a little stub with a function in it that interns a bunch of functions into that namespace

19:06 justin_smith: well, no, a bunch of them just run some code on some other object

19:06 they just exist to make a side effect happen if you require them

19:06 which is awful

19:08 coventry: Oh, I see. Yeah, why would a simple function be inadequate to that purpose?

19:08 justin_smith: seriously

19:08 bellkev: Well, I think the stuff it's doing with other objects is using reflection to pull all the method names out of the Java API objects

19:09 You guys mean use a simple function that can take some keyword/name or something and invoke the appropriate java method based on it? Rather than dynamically generate all the Clojure functions like amazonica does?

19:10 justin_smith: is that what amazonica is doing? I didn't get far enough in the inter-file spaghetti to even figure out that much

19:11 coventry: I suggest at least implementing it that way first, then maybe going back and making the convenience namespaces if it really seems to simplify the usage dramatically for some reason.

19:11 bellkev: Haha, if you think THAT'S inter-file spaghetti than you must not have to look at enterprise Java apps very much... :P

19:11 justin_smith: I strive to have higher standards

19:12 bellkev: Don't you see? MORE files means MORE robust software!

19:14 justin_smith: so amazonica.core has the functions which will take the various amazon classes and generate the functions in the apropriate namespaces which interop with that class?

19:15 bellkev: Yeah, that's right

19:15 justin_smith: so where would I go to figure out what functions actually exist - dynamically query the ns-exports in a repl?

19:16 bellkev: eeh, that or look at the Amazon Java API documentation and convert everything from CamelCase to hyphen-case

19:17 justin_smith: wouldn't it be less work to just use the interop forms on the original java objects?

19:19 bellkev: That AWS Java API makes you set up a request object for everything before calling one of the methods on the "client" object

19:19 I haven't done too much Java interop in Clojure yet... Is there some easy way to call "new" on a class and map a Clojure hash map onto all its setters?

19:20 Because if so, then it would be pretty easy to use the AWS Java API directly...

19:20 justin_smith: ,(Date.)

19:20 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Date, compiling:(NO_SOURCE_PATH:0:0)>

19:20 justin_smith: ,(java.util.Date.)

19:20 clojurebot: #inst "2013-12-02T00:20:34.944-00:00"

19:20 justin_smith: calling new is easy

19:20 bellkev: and setting a bunch of crap?

19:21 just use standard Clojure map manipulation for that?

19:22 amalloy: https://github.com/flatland/uncle/blob/master/src/uncle/core.clj has some examples of using java's bean inspector to convert hashmaps into objects with setters, but it's kinda ant-focused so you can't just use it by hand

19:22 er, can't just use it directly

19:25 justin_smith: ,(doto (java.util.HashMap.) (.put 1 "hello") (.put 2 "world"))

19:25 clojurebot: {1 "hello", 2 "world"}

19:26 justin_smith: if you want automatic finding of the methods available and conversion to a map, there are things like bean and clojure.reflect. Amazonica uses the clojure.lang.Reflector class directly

19:29 amalloy: actually it looks like https://github.com/flatland/uncle/blob/master/src/uncle/core.clj#L25 sets properties according to a hashmap, in a way that is not dependent on ant at all, so you could try that if you want

19:29 bellkev: Well, I think keep using amazonica for now to interact with the AWS API, but for my own stuff (which is just manipulating a bunch of JSON) I'll try to keep things data-oriented and avoid too much namespace fiddling :)

19:29 TEttinger: ,(java.util.HashMap. {"a" 1 "b" 2})

19:29 clojurebot: {"b" 2, "a" 1}

19:30 coventry: bellkev: Good call.

19:30 bellkev: Oh, thanks though amalloy that does look cool...

19:40 akhudek: is it possible to lazily parse a file with gloss? (e.g. if the file is bigger than available memory)

19:40 ztellman: akhudek: yes

19:41 akhudek: ztellman: do I need to use channels for that to work?

19:41 ztellman: see gloss.io/lazy-decode-all

19:41 and no

19:44 akhudek: ztellman: ok, thanks, I'll play around with it.

20:20 rubber-duck: if I put clj file in the same folder as my cljs files and use :require-macros it should get used by cljsbuild right ?

20:21 akhudek: ztellman: what does lazy-decode-all take as input? A bytebuffer?

20:35 rubber-duck: why would cljs compiler not load my clj macro file even when it's finding it on the path ?

20:36 I intentionally put a error inside the file it's not complaining, all it's saying is "WARNING: No such namespace: at line 1 client/prodtr/app.cljs" and complains about use of undeclared vars from that ns

20:36 clojurebot: 'Sea, mhuise.

20:51 seangrove: Alright, now for the other horrible half: given a datastructure, sync the UI state.

20:52 amalloy: rubber-duck: your ns form is probably broken

20:54 Bronsa: andyf: fixed #TANAL-15, I had to rewrite the uniquify pass but now is *much* simpler and works as expected, thanks for finding that bug

20:56 rubber-duck: amalloy, I just moved the clj file in to a different folder and it worked :\

20:57 amalloy, it was in top level folder with cljs files, I created a subfolder "macro" and referenced foo.macro.myns and it worked where foo.myns wouldn't work - looks like a cljs bug to me

21:06 akhudek: hmm, what's a good strategy for lazily (and quickly) loading a stream of variable sized binary data frames?

21:06 bitemyapp: akhudek: lazy-seq?

21:06 akhudek: that doesn't really address the file buffering problems

21:07 I've managed to use gloss to write this sort of data quickly.

21:07 but reading it back lazily requires managing the buffering

21:07 which isn't that easy because each data frame can be a different length

21:07 bitemyapp: your kingdom for Data.Conduit? :P

21:07 the data frame length is a non-issue so far as I know.

21:09 akhudek: switching to haskell might be a bit of work :-)

21:09 bitemyapp: explain to me how lazy-seq is a problem with buffering?

21:10 akhudek: lazy-seq just allows you to construct lazy sequences

21:10 bitemyapp: right, and programming languages allow you to construct programs.

21:10 how is lazy-seq not empowering you to solve this problem?

21:11 if you need read-ahead buffering slap a seque on top of the lazy-seq.

21:12 akhudek: http://clojuredocs.org/clojure_core/clojure.core/seque

21:12 akhudek: if you have variable length frames, you can query each for it's length and read in exactly that length

21:12 but that's probably not a good buffering strategy if the lengths are smallish

21:12 bitemyapp: keep it simple stupid.

21:27 amalloy: akhudek: you're worrying about a non-issue. generations of computer scientists have made buffered file i/o easy for you. just read from the file using a handle that buffers, and then it doesn't matter if your reads are large or small

21:32 akhudek: amalloy: that's a good point. I'm going to blame my not seeing the obvious on a lack of sleep.

21:33 kylev: just call it a premature optimization and call it good :)

21:33 read stuff, worry about efficient reading later

21:33 (and then discover you didn't need to worry later)

21:35 akhudek: I think gloss not being able to read from a stream is throwing me off. It can handle reading variable sized frames, but it appears to require me to provide it a bytebuffer of exactly the right size to decode a frame, which means I have to write my own decoding code anyways. Confusing.

21:37 hiredman: akhudek: I would guess it can take of a seq of bytebuffers

21:37 andyf: Bronsa: It was a lucky accident. Thanks for the quick fix.

21:45 also: anyone here use counterclockwise?

21:45 trying to figure out how to debug into leiningen dependencies

21:46 justin_smith: lein deps :tree helps with debugging your dependencies

21:46 also: i mean, i want to use the eclipse debugger

21:47 to step into a java class

21:47 justin_smith: so wait, this sounds like it has nothing to do with leiningen

21:48 also: it has to do with the treatment of leiningen dependencies by counterclockwise

21:49 "The JAR of this class file belongs to container 'Leiningen dependencies' which does not allow modifications to source attachments on its entries"

21:49 "Leiningen dependencies" here being something provided by counterclockwise

21:50 justin_smith: OK, I thought I could help, but that is clearly very counterclockwise specific

21:50 good luck

21:53 also: :) thanks anyway

21:54 what's the current state of the art in debugging clojure applications?

21:54 I tried counterclockwise simply because i used to use eclipse

21:54 seangrove: also: It's not very sophisticated, tooling wise

21:55 dnolen: also: in CCW it supposedly "just works"?

21:55 seangrove: Most people just work in a repl with interactive development. There is ritz if you can get it to work.

21:55 also: dnolen: it seemed to work pretty well in my local clojure source

21:55 justin_smith: I heard good things about cursive, I think you need to sign up for the beta to get that

21:55 also: but not so well with the java dependencies

21:56 justin_smith: I have seen hlship demonstrate debugging his java deps with cursive

21:56 cursive is also an eclipse plugin iirc

21:58 also: justin_smith: intellij, looks like

21:58 but i'm not picky

21:58 justin_smith: ahh ok

22:00 also: i think the easiest path for me is going to be starting the repl with -Xdebug and connecting from a java ide

22:04 justin_smith: with schmetterling we have been able to view both clojure and java stackframes, and view locals in each

22:04 it doesn't do source browsing per se though

22:08 also: justin_smith: i hadn't seen that, thanks!. it looks interesting, even if it doesn't help right now

22:09 justin_smith: it is still a young project, so it should be acquiring new features shortly. But it still has some good use cases already

22:12 akhudek: hiredman: think you are right, but it still seems to require each bytebuffer to represent a complete seq of frames

22:16 bitemyapp: oh we're still discussing this?

22:17 akhudek: can I give you some drugs so you relax and get back to coding?

22:19 akhudek: bitemyapp: suspect you are the only one worked up here

22:20 technomancy: ~gentlemen

22:20 clojurebot: You can't fight in here. This is the war room.

22:23 indigo: bitemyapp: Drugs?!?!?

22:24 * also wonders how to clojurebot

22:25 technomancy: also: factoids are triggered with ~ and eval is triggered with ,

22:25 but you kind of have to know the factoids up front

22:26 unless you trigger them by accident

22:26 how?

22:26 clojurebot: with style and grace

22:26 seangrove: hah

22:26 ~technomancy

22:26 clojurebot: technomancy is to blame for all failures

22:27 bitemyapp: akhudek: I'm perfectly chill, I'm just trying to get you to where I am.

22:27 seangrove: clojurebot: technomancy is a god amongst men.

22:27 clojurebot: You don't have to tell me twice.

22:27 technomancy: ~hiredman

22:27 clojurebot: hiredman <3 XeLaTeX

22:27 bitemyapp: akhudek: you are way too hung up on bits that don't particularly matter. Just write something that works.

22:27 ~technomancy

22:27 clojurebot: technomancy is a god amongst men.

22:27 technomancy: oh you

22:28 brehaut: he just wants a free copy of lein

22:28 also: someday, clojurebot will know my name

22:28 amalloy: clojurebot: also is this real life?

22:28 clojurebot: Excuse me?

22:28 amalloy: oh, i forgot, he can't learn factoids ending with ?

22:29 that's lame

22:29 technomancy: also: there's like a 1% chance that any random line will be interpreted as being addressed to clojurebot, so that leads to some crazy stuff too

22:29 plus the wacky inference engine

22:29 ~inventory

22:29 clojurebot: I am carrying 0) a poorly-calibrated inference engine, currently leaking 1) a well-worn copy of clojure 1.2 tucked deep away inside a classloader 2) the last shreds of what was once my sanity

22:29 indigo: ~bitemyapp

22:29 clojurebot: Gabh mo leithscéal?

22:30 bitemyapp: I don't have a factoid.

22:30 brehaut: clojurebot: drop sanity

22:30 clojurebot: excusez-moi

22:30 brehaut: clojure: drop shreds

22:30 clojurebot: drop shreds

22:30 clojurebot: Huh?

22:31 brehaut: these text adventures are all the same. i can never get the right verbs and nouns

22:31 bitemyapp: ~APL is a comonad

22:31 clojurebot: Ik begrijp

22:31 seangrove: hahaha

22:31 * brehaut is eaten by a grue

22:31 bitemyapp: ~APL

22:31 clojurebot: APL is a comonad

22:31 seangrove: clojurebot: brehaut is eaten by a grue

22:31 clojurebot: 'Sea, mhuise.

22:32 bitemyapp: ~APL is the language of choice of octopodes

22:32 clojurebot: Ik begrijp

22:32 bitemyapp: eggscellent.

22:32 akhudek: bitemyapp: I know how to write this myself, just though that gloss would do it with less hassle, but it doesn't seem to address this use case. Not a big deal.

22:34 * also reads clojurebot/clojurebot-facts/src/clojurebot/factoids.clj

22:34 * also is enlightened

22:38 bitemyapp: ~also is enlightened

22:38 clojurebot: Ik begrijp

22:38 bitemyapp: ding ding ding, we have a winner.

22:38 * bitemyapp lazily yawns in akhudek's face

22:58 justin_smith: so how long until you can get "micro-drone" instances via aws?

23:20 xpe: I'm following the steps on http://pedestal.io/documentation/service-war-deployment/

23:21 I've got the jetty dependencies in a leiningen :dev profile

23:21 when I examine the generated WAR, they are in the libs directory, which I think may be a problem

23:21 justin_smith: xpe: why would you have a jetty dependency if you are deploying a war?

23:21 xpe: justin_smith: I don't want one

23:22 but I want to keep it in the project.clj so I can still run the repl and run-dev command

23:22 justin_smith: the url you posted says "service war deployment"

23:22 xpe: justin_smith: yes, I know that :) I'm leading up to my point, you were too fast

23:22 justin_smith: oh, sorry

23:22 xpe: it looks like mvn dependency:copy-dependencies is paying no heed to the :dev profile -- it seems to be copying everything

23:22 I need to confirm that

23:23 side note: lein deps :tree doesn't distinguish between profiles either

23:23 noprompt: in tbaldridge's macro videos i noticed that when he evaluates a form in a buffer it is copied into the repl as well; does anyone know how that's configured?

23:25 coventry: noprompt: He gave code for doing that in the github repository for his core.async talk at the recent conj.

23:25 xpe: justin_smith you see that I would want to be able to run in the REPL and still deploy, right?

23:25 justin_smith: xpe: looking at that, I wonder why lein ring uberwar wouldn't work with a pedastal project? it is much simpler than those steps

23:25 xpe: right

23:25 coventry: noprompt: https://github.com/halgari/clojure-conj-2013-core.async-examples#usage

23:25 justin_smith: xpe: I have used lein ring uberwar and had no container conflicts

23:25 noprompt: coventry: thanks!

23:26 xpe: justin_smith: thanks I will give it a look. I'm glad I did the steps, though, because now I see what is happening in extreme detail

23:28 justin_smith: you've used it with pedestal, am I understanding you right? with Jetty? Tomcat? something else?

23:29 justin_smith: not with pedastel

23:29 that's why I was asking why it wouldn't work with it

23:30 I doubt they are so different from what I have deployed that the ring uberwar task would break

23:30 specifically various versions of caribou, deployed to tomcat containers

23:34 xpe: justin_smith: I'm skeptical about `lein ring uberwar`. It is yelling at me: for not having `:ring {:handler your.app/handler}`

23:34 justin_smith: you have a handler right?

23:34 xpe: I'm sure it works great for ring, but I don't think it is meant for pedestal

23:34 justin_smith: that key is used during war generation

23:34 OK

23:35 oh wait, I thought pedastal used ring

23:35 shows you how much I know

23:35 oh wait

23:35 yes it does use ring

23:35 just tell it where the handler is

23:38 xpe: justin_smith: I'm no expert, but I remember the pedestal team modifying some parts of ring to work with interceptors

23:38 justin_smith: oh, ok

23:38 xpe: the other catch is that I don't have the "standard" ring handler lying around in my app

23:38 justin_smith: if there isn't a ring handler (or the equivalent), then yeah lein ring uberwar won't work

23:38 xpe: in any case, I have no fear of doing this "by hand" for now

23:39 justin_smith: what do you mean by standard ring handler?

23:39 like there is no one function that puts requests into the middlewares?

23:39 xpe: justin_smith: I'm not really sure what I meant by that :) just referring to what the lein ring plugin wanted me to point to

23:39 justin_smith: I'll put a gist up

23:40 justin_smith: the handler is the function that would take a request, pump it through the middleware, and return the response

23:40 I see that pedastal splits this up into two stages, but there should still be one entery point

23:42 xpe: justin_smith: maybe so. https://gist.github.com/xpe/d8644065ada8e5ffdc6f

23:43 justin_smith: based on the service-war-deployment page you linked above, it looks like YOUR_APP_SERVER_NAMESPACE/servlet-service would be the analog

23:43 and I could have come to the same conclusion from seing your gist

23:43 heh

23:44 xpe: justin_smith: so, I don't mind doing the steps by hand per the pedestal page

23:44 i'm really close, I have scripts

23:44 justin_smith: OK

23:44 xpe: the problem is my :dev profile is getting included in the libs

23:44 i'd like to find a way to tweak the maven command, if possible, to only copy over my main deps

23:44 justin_smith: you can prune things you don't want it to have from the jar, right?

23:45 xpe: justin_smith: i mean, sure, by hand, but I'm sure maven can figure it out? or maybe I can borrow some leiningen code

23:45 if the lein ring plugin can do it, the information is there somewhere

23:46 justin_smith: thanks for taking a look

23:46 justin_smith: there must be an argument to tell it to use the production / deployment profile

23:46 which would not include dev

23:46 np

23:46 thought it would be simpler

23:46 xpe: re: argument: exactly

23:47 justin_smith: pedestal looks interesting, but since it is made for end-to-end clojure it didn't really work for our own use case

23:47 our front end guys are not all excited about switching over from html/js to edn templates and clojurescript

23:47 bitemyapp: justin_smith: pedestal offers the most advantage when you're doing a lot of data chucking back and forth between server and the smart web-client.

23:47 justin_smith: makes sense

23:48 bitemyapp: if you don't have a relatively small number of complex views, it's not going to make a lot of sense.

23:48 xpe: FWIW, lein profiles are really powerful: https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md

23:48 justin_smith: but as I said, the people we have writing the web client stuff aren't clojure people, so it would be a hard sell for us

23:48 seangrove: technomancy: Go get 'em! https://twitter.com/ericpallen/status/407356656113045504

23:49 xpe: hmm "In order to prevent profile settings from being propagated to other projects that depend upon yours, the :default profiles are removed from your project when generating the pom, jar, and uberjar"

23:50 also "By default the :dev, :provided, :user, :system, and :base profiles are activated for each task, but their settings are not propagated downstream to projects that depend upon yours."

23:50 also: interesting promotion on twitter from t-mobile ceo: http://files.ryanberdeen.com/Sjb7

23:52 xpe: justin_smith: I learned a nice command: lein with-profile base deps :tree

23:53 justin_smith: well that's a chain of two

23:53 with-profile

23:53 and deps :tree

23:55 xpe: justin_smith: I had to chain them to get the particular deps tree I wanted

23:56 justin_smith: yeah, just saying

23:56 xpe: it is not entirely obvious (to me) about which profile is active for which lein task. I think they vary.

23:57 strike that. I just had to re-read what I wrote above

Logging service provided by n01se.net