#clojure log - Jul 21 2014

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

0:06 ghadishayban: oh my

0:06 arrdem: ghadishayban: you pinged earlier?

0:07 ghadishayban: Have a clojure build using invokedynamic on vars, protocol functions and keyword invokes all working

0:07 hey arrdem

0:07 arrdem: sweet!

0:08 ghadishayban: have no idea how the latter perform, but static vars have a healthy performance pop

0:08 arrdem: can I get an estimate? :P

0:08 ghadishayban: got nearly 2x on this benchmark, https://github.com/clojure/test.benchmark/blob/5b50c61d8991330fe1cef42fd16a6c8e75a33f7c/src/main/clojure/call.clj#L13

0:09 don't hold me too it, won't post public numbers for at least a week

0:09 arrdem: sure

0:09 interesting...

0:10 I'm getting close to having entirely static vars working, I'll be curious to see how they stack up.

0:10 ghadishayban: got rid of the volatile in c.l.Var

0:10 arrdem: 0_0

0:10 ... and replaced it with an invokeddynamic check?

0:11 ghadishayban: indy SwitchPoints give you an effectively final value

0:11 that you invalidate

0:11 arrdem: yep. that'll work.

0:11 nice!

0:12 ghadishayban: i re-used the CallSite for Vars to do the protocol funs too, which look like this:

0:13 GUARD(target.implementsInterf?, target.callInterface, Protocol-IFn.invoke(target..args))

0:14 and the last argument, protocol-IFn, is the var representing the protocol function, re-uses the switchpoint

0:14 haven't benchmarked the KeywordInvoke callsites yet, but just getting all of that bytecode on the other side of an indy callsite should help

0:22 pjstadig: good stuff you wrote on the mailing list

0:22 pjstadig: about indy all those years back

0:23 TEttinger: woah actual clojure dev chat in #clojure, this stuff is way over my head :)

0:24 arrdem: TEttinger: you should see me and Bronsa in -offtopic :P

0:24 -offtopic is really -gsoc

0:24 TEttinger: haha

0:26 arrdem: Grimoire UX question: better to have inline source of Clojure functions, provide a link to the release tag, file and line on GitHub or source that is/has a link?

0:28 ambrosebs: *goes to -offtopic*

0:28 arrdem: I registered -gsoc a while back, but it's seen no use due to the hijacking of -offtopic

0:29 justin_smith: clojure-social is also opened up again, btw

0:29 arrdem: orly?

0:30 ambrosebs: arrdem: inline or github

0:30 or both

0:30 * arrdem facedesk

0:30 arrdem: already doing inline... for some things the inline is useless hence the thought to add github.

0:31 working towards ditching Jekyll. It was nice to get started with but turned out to be 1) slow and 2) inflexible

0:31 (dec ruby)

0:31 lazybot: ⇒ -2

0:34 bsima: Let's say I have a dataset called "data". Is it good practice to do the following (using Incanter):

0:34 (def data (read-dataset "data.csv"))

0:34 (def proc-data ($where {:col "val"} data))

0:34 (def proc-data2 ($where {:col2 "val"} proc-data))

0:34 I go on to use each of the above defs in other functions. I ask in regards to the quote about having 100 functions acting on one dataset. Technically I think I'm creating separate Incanter datasets in this code, so I'm not sure if this is the best way to do it.

0:42 platz: learn about Data.List.Split before doing something crazy

0:42 ah

0:52 cj3kim: Thoughts on assigning a large hashmap to an atom?

0:56 arrdem: if you're using atoms without a very good reason you're probably doing it wrong... also "assigning" isn't really meaningful and has effectively zero memory overhead.

0:56 so... go crazy?

1:11 kristof: Is "the entire hash map" the best coarseness of granularity?

1:11 After all, if one key need to be updated, does that affect the updating of other keys?

1:18 hyPiRion: kristof: no

1:19 kristof: hyPiRion: Those were rhetorical questions for cj3kim's benefit.

1:26 hyPiRion: oh

1:30 hellofunk: i'm curious if dereferencing an atom has any overhead compared to reading a non-atom value. for example, if you have an atom map and you want to read 2 keys, is it better to read each key with a separate dereference, or first dereference the atom, then read each key from the dereferenced value?

1:36 then again this question may have a different answer in clojure vs clojurescript, the latter of which i'm using

1:39 Bronsa: hellofunk: the time spent dereffing an atom should be meaningless

1:39 hellofunk: in cljs it's just a field lookup

1:40 hellofunk: Bronsa: thanks, useful

1:41 Bronsa: hellofunk: well and a function call I guess, but that's almost surely going to be inlined if that's a concern

1:59 amalloy: hellofunk: performance time of accessing the atom is the wrong question to ask. what about correctness? if you deref an atom twice and look at different parts of it, they may not represent a coherent snapshot

2:00 ambrosebs: arrdem: just pushed core.typed 0.2.60. clojure.core.typed/envs will give you a useful map of the current type environments, hopeufully useful enough for grimoire.

2:22 Bronsa: ambrosebs: what does arrdem plan to use core.typed for on grimoire?

2:34 andyf: Bronsa: I see a case with t.a(.j) 0.3.0 where an AST has :raw-forms (clojure.lang.Compiler/LOADER), i.e a list of 1 symbol, whereas with 0.2.2 :raw-forms always seemed to be a list of parenthesized forms. Does that sound expected?

2:35 Bronsa: andyf: yes, it now contains also the raw-forms of macroexpanded symbols

2:35 i.e. clojure.lang.Compiler/LOADER gets macroexpanded to (. clojure.lang.Compiler LOADER)

2:36 andyf: (. clojure.lang.Compiler -LOADER) is the expanded form I see, but understood.

2:36 Bronsa: yeah right

2:38 that's something that just turned out to be useful for tools.analyzer.js

2:38 andyf: ok. Just need to tweak some Eastwood code to handle that case then. Not a big deal.

2:38 Previously I wrote code assuming a list of parenthesized forms.

3:05 at21: Hey guys. Can anyone help me wih emacs cider? When i jack-in sysntax doesn't get highlighted in repl, i.e. if I enter => (println "hello") , then "println" doesn't get highlighted. Why?

3:06 When I turn on clojure-mode, repl stops working for some reason

3:07 vijaykiran: at21: the repl doens't use clojure mode - I think clojure mode and cider repl modes are both Major modes - so only one can be active at any point of time

3:07 at21: But I somehow remember running repl with highlighted syntax. Maybe it was just nRepl itself I'm not sure

3:09 """I think clojure mode and cider repl modes are both Major modes - so only one can be active at any point of time""" <- but I can enable cider-mode, and it works fine

3:15 vijaykiran: at21: ah - not sure then, there was related issue open on GH - let me check

3:20 at21: can you try setting the clojure font-lock in cider ?

3:20 at21: this one > cider-repl-use-clojure-font-lock

3:20 at21: there is no match for such command

3:21 at least in my version

3:21 last

3:21 M-x cider-repl-use-clojure-font-lock right? There is no such command

3:22 vijaykiran: at21: no - it is a customization option - so you need to use (setq cider-repl-use-clojure-font-lock t) or something and eval it in a scratch buffer

3:23 I'm trying it out to confirm

3:23 at21: ... how to do that?

3:23 put it in .emacs?

3:23 vijaykiran: at21: yup

3:24 at21: also you can try 'M-x eval-expression' for your current session

3:26 at21: I did that

3:26 nothing happened

3:26 vijaykiran: at21: try restarting cider ?

3:26 at21: yeap

3:27 i restarted both emacs and cider

3:27 Don't understand what should happen?

3:28 Does your text in cider repl get highlighted??

3:28 lazybot: at21: What are you, crazy? Of course not!

3:28 at21: lazybot: about what?

3:29 ssideris: at21: the highlighting of the line happens only after you've pressed enter

3:34 at21: ssideris: I've only noticed that. It now does highlight only after pressing Enter with (setq cider-repl-use-clojure-font-lock t)

3:35 thank you. I think there's no way too use both major modes in emacs repl

3:35 vijaykiran: ssideris: thanks

4:08 xsyn: Hi

4:08 how do I replace a string with a nil ?

4:09 (clojure.string/replace "NULL" "NULL" nil)

4:09 doesn't work

4:09 I understand why, but yeah I just what nil in my vectors where "NULL" currently exists

4:11 vijaykiran: ,(let [s "NULL"] (if (= s "NULL") nil s))

4:11 clojurebot: nil

4:12 vijaykiran: xsyn: it doesn't feel "right" though

4:12 TEttinger: ,(replace ["NULL"] "NULL" nil)

4:12 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/replace>

4:13 TEttinger: (doc replace)

4:13 clojurebot: "([smap coll]); Given a map of replacement pairs and a vector/collection, returns a vector/seq with any elements = a key in smap replaced with the corresponding val in smap"

4:13 boxed: a string and a vector are two different things…

4:13 TEttinger: ,(replace {"NULL" nil} ["NULL"])

4:13 clojurebot: [nil]

4:13 xsyn: sure, I was thinking to map it though

4:13 TEttinger: right, but what would you be replacing it in otherwise

4:13 vijaykiran: ,(mapv #(if (= % "NULL") nil %) ["one" "two" "NULL" "stuff"])

4:13 clojurebot: ["one" "two" nil "stuff"]

4:14 TEttinger: nil can't be in a larger string

4:14 boxed: ,(clojure.string/replace "fooNULLbar" "NULL" "\u0000")

4:14 clojurebot: "foo

4:14 boxed: hah, clojurebot doesn’t handle that nicely :P

4:14 TEttinger: ,(replace {"NULL" nil} ["one" "two" "NULL" "stuff"])

4:14 clojurebot: ["one" "two" nil "stuff"]

4:14 boxed: but I think that proves that the code works :P

4:14 TEttinger: yep

4:14 xsyn: TEttinger: No, I've got a vector with "NULL" in it, and I'm trying to make it more clojurific

4:15 Nice

4:15 thank, yiou

4:15 TEttinger: no prob

4:16 ,(replace {"NULL" "\u000B\u000B"} ["one" "two" "NULL" "stuff"])

4:16 clojurebot: ["one" "two" " " "stuff"]

4:16 TEttinger: that's a fun trick to fiddle with IRC clients, not all handle it

4:16 \u000B is the vertical tab char, which on my client makes a single message span multiple lines

4:17 pyrtsa: xsyn: String input where the word "NULL" has a special meaning? Just check that you won't need to handle Mr. Null with that code. :-P http://stackoverflow.com/q/4456438/26981

4:17 boxed: colloquy doesn’t… but colloquy is pretty weird in a lot of ways :(

4:18 ruoshan: System Info: CPU Speed: 2 @ 2.40 GHz · RAM: 8 GB · OS X: Version 10.9.4 (Build 13E28) · Uptime: 9 days · Load Averages: 1.52 1.47 1.48

4:19 xsyn: pyrtsa: I'm receiving the data like that, and trying to clean it

4:19 chamomile: question, are there any clojure 'best practices' project templates? i'v looked, don't know if that's even a thing

4:19 pyrtsa: xsyn: Sure. Just joking, a bit. ;)

4:20 augustl: chamomile: not sure if that is a thing :)

4:20 boxed: chamomile: beyond the templates in leiningen?

4:20 augustl: chamomile: Stuart Sierra's components are pretty commonly used I think

4:20 https://github.com/stuartsierra/component

4:22 TEttinger: boxed: so far only Floe works with it to my knowledge

4:32 boxed: TEttinger: with what?

4:32 TEttinger: oh, the vertical tab thing

4:32 boxed: ah

4:32 TEttinger: it's possible there are others, but Floe uses WPF which needs to handle some funky enterprise data display stuff

4:33 vertical tab has been recommended to not be used since the 80s I think

5:08 noncom: ,(mapv #([(str "a-" %) %]) ["apple" "potato" "cat"])

5:08 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentVector>

5:08 noncom: why? ^

5:08 ,(mapv #(vector (str "a-" %) %) ["apple" "potato" "cat"])

5:08 clojurebot: [["a-apple" "apple"] ["a-potato" "potato"] ["a-cat" "cat"]]

5:08 noncom: this works ^

5:09 but why not the short form ?

5:09 opqdonut: noncom: #([(a %) %]) is the same as (fn [x] ([(a x) x]))

5:09 broquaint: You're invoking the vector in the first instance, noncom.

5:09 opqdonut: noncom: see what's wrong with that?

5:09 noncom: ah, i see...

5:09 wow

5:10 well, thanks for the explanations :)

5:22 amalloy: noncom: (juxt a identity) is a more fun way of writing what you meant by #([(a %) x]) anyway

5:23 noncom: amalloy: hehe, thats fun :)

6:37 luxbock: I wanted to write a macro to creates fn-definitions from a JS-object that holds an API for a library I'm using, but this appears to be impossible since CLJS lacks `resolve`, or is there some way around this?

6:45 __daniel__: luxbock: http://stackoverflow.com/questions/12020576/resolve-function-throws-an-error-in-clojurescript-but-not-clojure

6:45 looks like u can hack it with aget if u export the symbols

6:46 luxbock: hmm I see, thanks

7:39 noncom: hi, is there any real and up-to-date support of C# in emacs ?

7:39 oops, sorry, wrong channel

7:54 luxbock: `(cljs.tagged_literals.JSValue. nil)` the same as `#js {}`?

7:55 is*

8:41 sspross: hi everybody, is somebody familiar with om (cljs/reactjs)?

8:48 boxed: sspross: try asking the question and we’ll see if we can help. Personally I had a lot of trouble with Om and am using Reagent instead

8:49 sspross: @boxed ok, thanks! I'm struggling with the basic tutorial, getting a "Unsupported major.minor version 51.0" error while trying to use lein cljsbuild on my MacOS X 10.9, any hint?

8:50 john2x: how do I require a new clojure file/ns in a running repl?

8:51 ah wait, it did find the new file, it's just a new dependency isn't installed.

8:52 boxed: sspross: osx ships with java 1.6, and you’re trying to use a class file that requires 1.7

8:54 sspross: @boxed uh... ok, bad idea to install java 1.7 on mac os x or usual?

8:55 boxed: sspross: I haven’t done so and haven’t had any problems.. did you download some jar file manually?

8:56 sspross: boxed: hm no, i'm just trying to follow the tutorial and failing at second cmd :) https://github.com/swannodette/om/wiki/Basic-Tutorial but i don't want to bother you, i try something else...

8:57 boxed: sspross: try Reagent :P

8:57 sspross: boxed: hehe, I'm on it ;)

10:35 hcumberdale: Hi :)

10:36 How can I make my fn seq aware so that it will recur if a seq is passed?

10:36 (defn gen-id [node] (str (:x node) ":" (:y node))) ;; for example

10:38 (if-not (seq? node) (str....) (recur ?))

10:38 jeremyheiler: hcumberdale: you could create another function that maps over gen-id

10:39 so like: (map gen-id (:seq :of :nodes))

10:39 hcumberdale: yes jeremyheiler that whould be easy

10:39 But I thought it would be better if my fn is aware of seq as argument

10:40 jeremyheiler: i woudln't overload your function like that

10:41 but, i'm missing context, as i don't know what you're doing

10:41 i'd just keep it simple

10:42 hcumberdale: I thought there is a simply way I'm not seeing

10:44 verma: how do you guys chain your async calls? I need to make an HTTP request, based on success or failure of that I need to make another one, I seem to be following the node.js pattern for doing this, any suggestions/ideas on how you guys do it?

10:57 AeroNotix: verma: http-kit takes a callbackl

10:59 hcumberdale: (defn gen-id [& nodes] (map #(str (:x %) ":" (:y %)) nodes)) << found it :)

10:59 jeremyheiler: hcumberdale: ah ok. it wasn't clear that you wanted varargs

11:08 hcumberdale: jeremyheiler: varargs are just my way to solve it...

11:09 maybe it's also possible with 2nd vararg and recur

11:11 verma: AeroNotix, hmmm, that's ok I guess then, However, I've found that promises model is pretty awesome also since you can use the -> form (-> (get-promise) (.then #()) (.then #()))

11:15 justin_smith: verma: core.async lets you write async state machine / callback based code as if it were normal synchronous code

11:16 verma: justin_smith, any examples? or does it work in clojurescript?

11:23 justin_smith: yes, it does

11:23 there are many examples

11:23 http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/

11:23 this was one, but I was just googling, I am sure you can find many others

11:24 verma: justin_smith, nice! thanks, looking

11:27 teslanick: Note that in clojurescript you only get the non-blocking take/put functions (>! and <!, and not >!! and <!!)

11:28 Because the JS runtime is single-threaded and (for practical purposes) unblockable.

11:28 verma: teslanick, yes, thanks

11:29 teslanick: Although it's surprising to me that Workers don't have access to blocking functions (aside from importScript)

12:08 scape_: manjaro is pretty great.

12:20 zanes: Lately when I use clojure.tools.namespace.repl/refresh it seems like it’s failing to load all of the namespaces back in. I wind up getting java.lang.ClassNotFoundExceptions and need to go to each individual file and cider-load-current-buffer it to get things working again. Anyone else encountered this issue?

12:20 hcumberdale: any idea how to ("xy") => "xy" and "xy" => "xy" ?

12:21 with list? and if ?

12:22 technomancy: don't use clojure.core/list?

12:23 it is one of the worst functions in clojure

12:23 ,(when-not (list? (cons 1 nil)) (println "what a crappy function"))

12:23 clojurebot: nil

12:23 hcumberdale: thx :)

12:24 technomancy: aw come on clojurebot

12:24 hiredman: ,(type (cons 1 nil))

12:24 clojurebot: clojure.lang.PersistentList

12:24 hiredman: (haha)

12:25 technomancy: wat

12:25 nobodyzzz: ,(first (flatten (list '("xy")))

12:25 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

12:25 technomancy: ,(type (cons 1 (cons 1 nil)))

12:25 clojurebot: clojure.lang.Cons

12:25 technomancy: I don't even

12:25 nobodyzzz: ,(first (flatten (list '("xy"))))

12:25 clojurebot: "xy"

12:25 nobodyzzz: ,(first (flatten (list "xy")))

12:25 clojurebot: "xy"

12:26 nobodyzzz: yey =)

12:26 no if and list on the other hand

12:28 technomancy: hcumberdale: anyway, what you probably want is c.c/seq? instead of list?

12:35 hcumberdale: technomancy: solved it with a simple (apply str

12:35 wanted a string to stay a string and a list with a string to become a plain string

12:39 TimMc: )

12:48 sm0ke: is there something like try with resource in clojure like in java

12:49 pyrtsa: with-open

12:49 sm0ke: like (try [f (future ...)] .. (catch (cancel f)))

12:49 no not just for calling close

12:50 for trapping exceptions

12:50 http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

12:51 i think try catch is fundamentally broken

12:51 why should try block vars be available in catch!

12:51 shouldnt*

12:51 pyrtsa: sm0ke: Which ones?

12:52 The ones already initialised, or the ones uninitialised as well? How would that work?

12:52 enn: Hello, I'm a Cider user looking to get method signatures to show up in the minibuffer as I type (Slime-style). Right now it's working perfectly in cider-repl-mode but not in cider-mode. Is there a switch somewhere for this?

12:53 technomancy: enn: I don't know the exact setting, but eldoc is what that's called

12:54 sm0ke: hurm

12:54 well they could be null

12:55 pyrtsa: sm0ke: You can always opt in to that (regardless of whether Clojure or Java): just declare them outside the try block (and in case of Clojure, use e.g. atoms so that you can reset them).

12:56 enn: technomancy: ok, thanks, that will give me something to look for

12:56 sm0ke: yeah but that's te clumsy solution

12:57 can a future cancel itself?

12:59 i am working with play-clj, it is really hard to do interactive development error is causing whole repl to crash

12:59 as error*

13:00 which is weird because i am putting whole main inside a try catch

13:03 i mean whole body of main

13:17 zanes: Anyone have any luck getting test.check with cider-test-run-tests?

13:52 vendethiel: anybody using intellij with clojure ? I've tried la clojure, but it seems to crash when I restart intellij :(.

13:52 teslanick: I tried to use it with Cursive for a while, I decided it wasn't worth it.

13:54 arrdem: I've seen the estimate that 50% of the Clojure user base works in emacs throw around before. It doubles as a nice commentary on the state of tooling for different editors...

13:54 *thrown

13:59 SegFaultAX: vims support has improved significantly in the last 6mo-1y

14:20 aaelony: Hi, if I use type hints in a defrecord, are those hints put to use in Clojure 1.6 ?

14:21 shiranaihito: is it difficult to get Clojure to reload namespaces while running? .. i'm trying this: "(require 'application.main :reload-all)" .. but it doesn't seem to work

14:22 aperiodic: shiranaihito: what do you expect to happen?

14:23 shiranaihito: wel, "application.main" contains a handler function that i'm using with embedded Jetty

14:23 justin_smith: shiranaihito: one gotcha is that if in application.main you started some long term process, reloading the ns is not going to change the definition of the process

14:24 shiranaihito: use #'handler instead of handler when running jetty, and ring will do the right thing

14:24 shiranaihito: i'd like to have changes to the handler to show up without restarting the server (and whole Java process)

14:24 justin_smith: yeah, #'handler instead of handler fixes that

14:24 shiranaihito: i'm not using ring though :/

14:24 aaelony: I guess hinted fields are mentioned on line 364 of https://github.com/clojure/clojure/blob/f7215fdb8ca7d23faa7b47865d5acab1af8437a3/src/clj/clojure/core_deftype.clj#L285-L370 but I'm not sure I understand if those hints are being acted on...

14:24 aperiodic: shiranaihito: you'll need to use the new things you pick up after the reload. so, using a var forces the var's value to be looked up every time, meaning if its definition changes you'll see the new thing

14:24 amalloy: waaaaaaat. not using ring?

14:24 shiranaihito: hmm.. well, "application.main" is a namespace.. i'm not supposed to try and reload vars, right?

14:25 justin_smith: shiranaihito: yeah, I hope you have a very good reason to not use ring

14:25 shiranaihito: yeah.. i wanted a different way to dispatch requests to handlers

14:25 justin_smith: how so? :P

14:25 justin_smith: shiranaihito: point is that a long running process isn't going to have its code change just because of an ns reload

14:26 shiranaihito: ring's request to handler dispatch is very good and very flexible, for example it makes it easy to use a new handler after ns reload

14:26 shiranaihito: justin_smith: alright.. hmhm well, i didn't quite follow you there.. what's the problem with long-running processes then?

14:26 justin_smith: if you are using plain jetty, well, good luck I guess

14:26 shiranaihito: :P

14:26 justin_smith: shiranaihito: you can manually do it by doing a var lookup in your handler for the actual function to call

14:26 shiranaihito: i doubt it's _that_ horrible a choice

14:26 justin_smith: then a function redef will cause the new code to run

14:27 shiranaihito: ring is one of the best things in clojure, and I don't know of many reasons to avoid it

14:27 I'd be interested in yours if you have one

14:27 shiranaihito: var lookup & redef? .. how does that relate to require :reload?

14:27 justin_smith: shiranaihito: require :reload rebinds the var

14:28 amalloy: shiranaihito: are you actually sure you're not using ring? just about every clojure webserver uses ring underneath, so you might not even realize you're using it

14:28 justin_smith: if you are not doing an explicit var lookup, than it can look it up once, and keep using that

14:28 shiranaihito: well, i wanted a different way to structure my apps, and arranged for dispatching requests in a different way

14:28 justin_smith: so for a reload to do what you want, you need to manually deref the var on each request

14:28 shiranaihito: try using ring but not compojure then

14:28 ring is extremely open ended

14:28 shiranaihito: nah i'm using embedded jetty :P the request gets dispatched by my little thing

14:29 hmm

14:29 justin_smith: ring does not do dispatch at all

14:29 I think you are confused

14:29 shiranaihito: could be

14:29 justin_smith: well, it calls the handler function you provide it

14:29 but that's it

14:29 the rest is up to whatever lib you use (compojure, or whatever else)

14:29 shiranaihito: right well, compojure is the correct comparison, yes

14:29 justin_smith: try lein deps :tree

14:29 you may just see ring in that tree

14:30 shiranaihito: if it helps clear it up, i'm not using ring, and not using compojure, but a request gets dispatched anyway (because i made it happen :P)

14:30 justin_smith: shiranaihito: once again, ring does not do the dispatching part at all

14:30 shiranaihito: yes

14:30 i got it already

14:30 justin_smith: it turns a request into a map, and later turns a data structure into an output stream

14:30 shiranaihito: compojure

14:30 i'm not using compojure either

14:30 ok? :P

14:31 justin_smith: but your code is using an input stream and an output stream or something, OK

14:31 shiranaihito: yeah, embedded Jetty

14:31 justin_smith: ring uses embedded jetty

14:31 as one backend among others

14:31 shiranaihito: the jetty adapter?

14:31 yep

14:31 i used that as a basis for calling my dispatch thingy

14:32 justin_smith: anyway, using ring will be easier, but if you really want to not use the best lib for the job, then manually deref the var that points to your dispatch / handler function for each request

14:32 and then :reload will do what you expect it to

14:33 shiranaihito: hmm

14:34 i'm confused by that deref stuff.. is it enough just to put a @ in front of a var's name?

14:35 technomancy: justin_smith: actually isn't the point to *not* deref the var?

14:35 just call it directly

14:40 enn: All of the examples I can find for defmulti seem to use an old, now-changed syntax (where the second argument is a hierarchy name). And the defmultis I am writing based on the arg list don't work. I tried to make one with only a default method:

14:41 (defmulti foo) (defmethod foo :default [whatever] whatever)

14:41 when I try to call it I get a null pointer exception in clojure.lang.MultiFn.invoke

14:41 amalloy: enn: you need a dispatch function somewhere

14:41 enn: amalloy: what function would I use if I just want to dispatch based on class?

14:43 gfredericks: ,(doc class)

14:43 clojurebot: "([x]); Returns the Class of x"

14:45 enn: with (defmulti foo class) I get exactly the same exception.

14:45 ah, I guess it doesn't replace the earlier definition. If I use a new name it works.

14:45 Thank you

14:46 amalloy: defmulti strikes again

14:48 bbloom: amalloy: yeah :-/

14:48 alpheus: Google App Engine doesn't allow listening sockets, and I want to get nrepl working. What if I change nrepl to make an outgoing connection instead?

14:49 amalloy: clojurebot: defmulti |strikes| again

14:49 clojurebot: Roger.

14:49 technomancy: alpheus: it's easier to use the http nrepl transport; check out drawbridge

14:49 alpheus: cool, thanks

14:49 teslanick: That's what I've used with Heroku (prior to it getting socket support)

14:49 technomancy: also https://devcenter.heroku.com/articles/debugging-clojure

14:52 so... just published https://github.com/technomancy/leiningen/wiki/SigningDeployedJars and would like feedback on it

14:52 docs for how to sign artifacts you've already deployed

14:54 vendethiel: SegFaultAX: so, vim is still better ? IDEA not worth it, in your opinion ? (if you've tried idea, that is)

14:56 amalloy: technomancy: the four-line code snippet with cp/gpg won't work, because the jars don't live in the place you're copying from

14:56 technomancy: amalloy: ah right; I should just put [...] or something

14:56 because you can't copy it verbatim anyway

14:57 amalloy: also, you should settle on whether the version is 1.3.1 or * (i don't recommend *, which might suggest signing all versions of a jar at once)

14:57 technomancy: oh right; I didn't mean to suggest **

14:57 I'll just stick with 1.3.1

14:58 amalloy: and *also*, gpg -ab mylib-1.3.1.{jar,pom}

14:59 technomancy: http://p.hagelb.org/mrfp.gif

14:59 heh, but thanks

14:59 I guess the same syntax can be used for the cp?

14:59 amalloy: i love the {a,b} expansions in bash

15:00 yeah

15:00 Glenjamin: i dunno if it'd use them in a tutorial like this

15:00 *i'd

15:00 amalloy: Glenjamin: this is the perfect opportunity to teach folks they don't need to slavishly retype everything!

15:00 Glenjamin: yeah, but then you need a comment to say what it does

15:00 which detracts from the core example a bit

15:01 amalloy: adn it's not like people signing stuff on clojars on the command line are technologically illiterate

15:01 technomancy: amalloy: gpg only accepts one file at a time for -ab

15:01 Glenjamin: i guess it depends how many people would recognise the shell expansion

15:01 amalloy: Glenjamin: what. why would you need that. there's nothing exlpaining what the -ab flag to gpg means

15:02 technomancy: works for cp though

15:02 Glenjamin: hrm, i see what you mean

15:02 my intuition is its less guessable

15:02 amalloy: technomancy: drat. i read `man gpg` but couldn't immediately tell if it would work or not; i made an optimistic guess

15:03 *shrug* i'm in favor of teaching things all the time, Glenjamin, and i don't think it detracts from the tutorial

15:04 really, i think people will just copy all the stuff in here to copy artifacts and then forget what it all means, which imo is fine. but the {a,b} syntax may be interesting enough to retain

15:04 Glenjamin: i do find myself stopping people at work mid-command to tell them about this feature

15:04 i think you have convinced me

15:05 technomancy: too late anyway, it's out there

15:05 though... it *is* a wiki

15:05 amalloy: technomancy: hahaha that cp command. i love it

15:05 you forgot the . at the end, and instead rename the jar to .pom

15:05 technomancy: derpy mcderp

15:06 Glenjamin: heh, for a second i thought that was on purpose, and was royally confused

15:06 technomancy: this is what happens when you try to get clever!

15:06 platz: If I have an nrepl/cider session in emacs, is there an easy way to add a new dependancy to my project.clj and have it downloaded, without killing the cider/nrepl session and starting it again?

15:06 amalloy: it's true, technomancy. technology is a sin

15:06 platz: i.e. if i want to suddenly parse json in the file I'm working on

15:08 technomancy: amalloy: punishment for hubris

15:10 amalloy: actually, technomancy, i'm a little dubious on this whole prospect of post-signing deployed artifacts. are authors *really* going to carefully inspect every character of every file to see if some attacker has changed a true to a false or something, disabling a key safety feature? it's way easier to trust the contents of a file on my local hard drive that i'm about to deploy, compared to one i downloaded after publishing months ago

15:13 and we're *deleting* the copy in our ~/.m2? if the idea of signing is that we want to verify no attacker has modified the published artifact, we've just lost a safe-ish comparison point that we could be diffing against

15:13 so it all works great unless there's been a security breach, in which case it seems unlikely to work

15:13 silasdavis: in clojure.test deftest can you not use the for macro?

15:14 amalloy: for is not a loop

15:14 it is a lazy list-comprehension

15:14 silasdavis: yes

15:14 it is

15:14 right

15:14 doseq?

15:14 clojurebot: doseq is like for, but for side effects instead of values

15:15 amalloy: sure, although clojure.test/are is supposed to do that

15:19 silasdavis: looks like I'd have to do (apply are ... (for ...)) to get similar effect

15:19 that doesn't seem particularly nice

15:19 amalloy: er...probably not, but i suppose i don't know what you're testing

15:20 silasdavis: something like all possible paths through a tripartite graph

15:21 same (is ...) assertion for each path

15:21 for does it nicely

15:21 amalloy: yeah, you want doseq

15:21 hyPiRion: (inc amalloy)

15:21 lazybot: ⇒ 150

15:21 silasdavis: amalloy, thanks

15:21 amalloy: what've i done now, hyPiRion?

15:23 ogi: using core.match, can i get something to the effect of (match ... [x x] ...)?

15:23 enn: the code in an :or clause gets run regardless of whether or not the key is supplied ... what's the rationale behind that?

15:24 hyPiRion: amalloy: provided the right answer

15:24 amalloy: ,(macroexpand-1 '(let [{x :x :or {x 1}} {}] x))

15:24 clojurebot: (let* [map__27 {} map__27 (if (clojure.core/seq? map__27) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__27)) map__27) x ...] x)

15:24 amalloy: &(macroexpand-1 '(let [{x :x :or {x 1}} {}] x))

15:24 lazybot: ⇒ (let* [map__16660 {} map__16660 (if (clojure.core/seq? map__16660) (clojure.core/apply clojure.core/hash-map map__16660) map__16660) x (clojure.core/get map__16660 :x 1)] x)

15:24 amalloy: the key point here is the (let [x (clojure.core/get map__16660 :x 1)])

15:26 enn: sure, I am just wondering why it was done that way. It feels unexpected (especially considering the short-circuiting behavior of the similarly-named or macro)

15:26 gfredericks: ,(defmacro eval-when [cond expr] `(if ~cond ~expr '~expr))

15:26 clojurebot: #'sandbox/eval-when

15:33 gfredericks: I don't think that does exactly what I wanted

15:34 technomancy: amalloy: I'll admit it's not ideal

15:35 maybe I should add a warning saying if you can't thoroughly audit the artifact, it's better to just deploy a new signed version

15:36 amalloy: or alternatively, write something that diffs a jar/pom against a git tag?

15:36 Glenjamin: that in itself would be neat

15:36 amalloy: diffing against a git commit is an interesting plan. should be safe enough to do, and while it doesn't cover everything it's better than nothing

15:37 technomancy: actually giving security advice on a wiki is probably kind of dumb in the first place =D

15:37 Glenjamin: if you have a jar with source+class, can you trust the two match?

15:37 amalloy: Glenjamin: no

15:37 Glenjamin: and is source->class deterministic?

15:37 amalloy: also probably no

15:37 technomancy: Glenjamin: good question

15:37 Glenjamin: i get the sense we're all a bit screwed from a security pov

15:38 technomancy: well, the number of scenarios in which it's OK to deploy .class files to clojars is already very low to begin with

15:38 so that helps

15:38 I wouldn't be surprised if AOT with the same JDK would be deterministic though

15:39 amalloy: technomancy: i would be a *little* surprised if it produced exactly the same output, but *very* surprised if it were actually deterministic (ie, guaranteed to do so)

15:40 technomancy: well

15:40 we'll just have to wait till someone to actually care enough to try it

15:40 amalloy: i dunno, maybe that's pessimistic

15:40 gfredericks: ,(defmacro then [] (str (java.util.Date.)))

15:40 clojurebot: #'sandbox/then

15:40 gfredericks: ,[(then) (then)]

15:40 clojurebot: ["Mon Jul 21 19:38:05 UTC 2014" "Mon Jul 21 19:38:05 UTC 2014"]

15:40 gfredericks: ,(then)

15:40 clojurebot: "Mon Jul 21 19:38:11 UTC 2014"

15:40 gfredericks: ,(then)

15:40 clojurebot: "Mon Jul 21 19:38:14 UTC 2014"

15:40 gfredericks: wait oh

15:40 hm

15:40 amalloy: ,(and (then))

15:40 clojurebot: "Mon Jul 21 19:38:23 UTC 2014"

15:40 gfredericks: right

15:41 enn: I have a frustrating API that will give me the name of a java class as a string, but expects an actual reference to the java class elsewhere. How can I find the class given the string?

15:41 gfredericks: ,(Class/forName "java.util.Date")

15:41 clojurebot: java.util.Date

15:41 gfredericks: ,(-> "java.util.Date" read-string resolve)

15:41 clojurebot: java.util.Date

15:41 verma: ,((fn [{:keys [a b]}] (+ a b)) :a 5 :b 10)

15:41 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: sandbox/eval190/fn--192>

15:42 enn: gfredericks: thank you

15:42 gfredericks: ,((fn [& {:keys [a b]}] (+ a b)) :a 5 :b 10)

15:42 clojurebot: 15

15:42 verma: ah, thanks gfredericks

15:43 gfredericks: enn: verma: you're welcome

15:43 verma: ,((fn [& {:keys [a b]}] (+ a b)) :a 5 :b 10 11)

15:43 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: 11>

15:43 verma: nice

15:43 (inc gfredericks)

15:43 lazybot: ⇒ 77

15:59 SagiCZ: ff

16:16 amalloy: did contains? ever used to work on sequences? http://stackoverflow.com/a/24866960/625403 claims it did but i'm quite doubtful

16:18 SagiCZ: amalloy: I don't think so.

16:20 amalloy: yeah, i can't find it with a dive through the git logs either

16:29 mikerod: amalloy: wouldn't that break the perf characteristics that contains? is going for

16:29 amalloy: mikerod: of course

16:30 it's plausible that back in like 2008 contains? might have behaved that way, although i don't think it did

16:30 mikerod: ah, way back in history perhaps. I think that would have been weird still though.

16:45 stuartsierra: amalloy_: `contains?` never *worked* on lazy sequences. On anything non-associative, it returned nil.

16:46 Starting with Clojure 1.5, it throws an exception instead.

16:46 technomancy: maybe "worked" here is shortand for "doesn't asplode"

16:46 shorthand

16:47 gfredericks: &*clojure-version*

16:47 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

16:47 gfredericks: &(contains? () 8)

16:47 lazybot: ⇒ false

16:47 gfredericks: ,(contains? () 8)

16:47 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentList$EmptyList>

16:47 gfredericks: &(contains? :haha 42)

16:47 lazybot: ⇒ false

16:48 stuartsierra: Even better, &(get :not-a-map 42)

16:48 => nil

16:49 As I tried to fix in http://dev.clojure.org/jira/browse/CLJ-1107

16:50 gfredericks: yeah I wonder what intentional behavior he has in mind

16:50 technically every change is breaking

16:50 ogi: i'm using cider with emacs. once i add a function to a module, i have to (use module) in repl again to bind the function name. is there a better way?

16:50 gfredericks: in the "could theoretically break something" sense

16:54 arrdem: I mean... we had a huge "breaking" change in 1.3..

16:54 gfredericks: ogi: you can change your repl to that namespace, if it's just one namespace that's bothering you

16:54 arrdem: rm -rf src/clj/clojure/contrib

16:54 gfredericks: ogi: also require with :as doesn't have that behavior

16:54 arrdem: contrib never shipped with clojure I don't think

16:55 andyf_: arrdem: And I think that and other changes in 1.3 have led to a wish to avoid such changes in the future

16:55 Or so I have heard

16:55 ogi: gfredericks: thanks, but if i change the default namespace then i have to "use" things like clojure.repl, although admittedly only once

16:55 arrdem: andyf_: my point is that of we were using SemVer or something else for clojure.core we'd be on 2.X already, so the idea of quibbling over "breaking" changes when every release is potentially breaking is kinda absurd.

16:56 gfredericks: ogi: yeah, that bothered me so much I started creating a namespace called . so I could refer to it fully qualified from everywhere

16:56 andyf_: gfredericks: Someone could know about get's behavior, and rely on no exception being thrown for unsupported types

16:56 gfredericks: replaces clojure.repl & anything else I want

16:57 andyf_: yes, that argument technically applies to any change; I'm just sayin' it's a continuum

16:57 arrdem: gfredericks: .... you what

16:57 gfredericks: oh. ./. right.

16:57 ogi: gfredericks: thanks! that feels a bit hacky but seems very practical

16:58 gfredericks: ogi: I ever made a plugin: https://github.com/gfredericks/dot-slash :(

16:58 s/:(/:)/

16:59 s/ever/even/

16:59 ogi: yeah any other approach to making stuff available everywhere felt a lot more hacky

17:00 and evaling stuff in arbitrary namespaces is just too useful especially with cider

17:01 fifosine: is there a lazy sequence that provides the seq you give it at the start and then repeatedly some specified character when it runs out? For example (take 8 (my-seq-fn '(1 2 3) 0)) yields (1 2 3 0 0 0 0 0)

17:01 ogi: gfredericks: make a plugin you did :) thanks again!

17:01 Glenjamin: (concat X (repeat Y)

17:01 )

17:01 gfredericks: ogi: np

17:02 fifosine: Glenjamin: Thanks!

17:07 andyf_: Bronsa: I guess it is intentional that primitive type hint checking got more strict from taj 0.2.2 to 0.3.0 ?

17:21 fifosine: Is there a way to simplify the code duplication here?

17:21 (if mybool

17:21 (let [a 1 b 2]

17:21 (func a b))

17:21 (let [a 2 b 1]

17:21 (func a b)))

17:23 amalloy: stuartsierra: interestingly enough, while reading through the git logs, i found that actually in the very early days contains? threw an exception on sequences; it was changed to return false later, and then much later it went back to exceptions

17:24 fifosine: (apply func (if mybool [1 2] [2 1]))?

17:24 one of numerous reasonable approaches

17:24 fifosine: ooh I like that

17:30 ,(map list (list "1234" (concat "12" (repeat "0"))))

17:30 clojurebot: (("1234") ((\1 \2 "0" "0" "0" ...)))

17:32 amalloy: see https://github.com/clojure/clojure/blob/91b5515e/src/jvm/clojure/lang/RT.java#L453-L470 if anyone is curious: a snapshot from back in 2008 where (contains? () :x) threw an exception

17:32 fifosine: ,(map list "1234" (concat "12" (repeat "0")))

17:32 clojurebot: ((\1 \1) (\2 \2) (\3 "0") (\4 "0"))

17:33 amalloy: wow, this was back before clojure.core existed. src/boot.clj, (in-ns 'clojure)

17:43 fifosine: amalloy: Can you see a way to reduce the # of calls to map to 1?

17:43 (defn map-pad [f x c1 c2]

17:43 (if (< (count c1) (count c2))

17:43 (map f (concat c1 (repeat x)) c2)

17:43 (map f c1 (concat c2 (repeat x)))))

17:43 hiredman: ~paste

17:43 clojurebot: paste is https://refheap.com/

17:45 amalloy: i mean, of course you can reduce it to 1, by writing (apply map (if ...)). but the main problem is the repetition of concat/repeat/count, and the fact that you've written a totally non-lazy map

17:46 if you write it to be lazy, the nicer way to do things sorta falls into your lap along the way

17:48 fifosine: amalloy: Can you be more specific? I'm not used to writing things lazily

17:50 amalloy: well, if you wanted to write this correctly and lazily, https://www.refheap.com/cee3428d51e888b8b4a995f39 is one way

17:51 the point is to never look any further ahead in any sequence than you need to, which means you can only go one at a time

17:51 and of course a version that only works for exactly 2 collections is kinda silly - why not more? 2 is a suspicious number

17:52 fifosine: amalloy: So the benefit of this is that no more than necessary is calculated?

17:54 SegFaultAX: vendethiel: Emacs is still clearly the winner since that's where the most time and effort has been spent.

17:54 vendethiel: But as a vim user, I'm happy to report that support for vim is perfectly workable.

17:56 fifosine: amalloy: The way you've written it, it's kind of like a generator in python, right?

17:57 amalloy: no more than any other lazy sequence function is

17:58 fifosine: amalloy: That's what I mean. This stuffs new to me but cool

17:59 amalloy: Why is that "when" call necessary? We can't assume each thing in coll is a collection?

18:00 amalloy: try taking it out and see what happens. then think about why it happened

18:02 bortreb: Is there a way to ignore a single *.clj file from compilation when using leiningen?

18:02 meaning I have a normal source directory, but I want to disregard a single flojure file and compile the others as normal

18:03 hiredman: why are you compiling anything?

18:03 (I assume by compiling you mean aot compilation)

18:03 technomancy: bortreb: do you understand how clojure's transitive compilation works?

18:04 there's basically no way to compile a namespace without compiling everything it requires

18:04 bortreb: I mean exclude the file from everything leinengen does completely, not just for compilation. For example, I don't want it to include it in the jar when building a jar, nor try to evaulate any forms in the file

18:05 technomancy: bortreb: you could put it in a directory that's not on the classpath except in the dev profile

18:05 bortreb: I have a src folder with say 5 clojure files, but one of the clojure files has problems that I want to deal with later, so have leinengen disregard it. (none of the other files depend on it.)

18:06 ahh -- thanks technomancy I think that's a clean way of handling it

18:06 I'll do that

18:07 technomancy: if it has problems you can just comment it out

18:09 bortreb: It's part of transitioning from a really old-school cloure setup (from clojure 1.0/1.1 before leiningen) to using leiningen -- the problem file depends on other source files that I don't realy want to be part of the project, but I still want to use it with the old system. But moving it to a different folder that leiningen doesn't track will work nicely for now, thanks!

18:10 technomancy: cool beans

18:17 shaun__: loon: how do you write a zipmap

18:19 loon: shaun__: very carefully

19:00 PigDude: how do you determine if a value implements some protocol?

19:01 nathan7: PigDude: satisfies?

19:01 PigDude: (satisfies? protocol value)

19:02 amalloy: although often if you're calling satisfies? it suggests you're using protocols wrong. you should generally only be accepting things which satisfy some protocol, not things which *might* satisfy it

19:04 PigDude: amalloy: i was going to use it in a precondition

19:04 amalloy: is that right?

19:04 amalloy: if you're a fan of preconditions, that's a reasonable thing to do

19:05 PigDude: how else would you only be accepting things which satisy some protocol though?

19:05 amalloy: just assume they satisfy it, and call the protocol functions. if not, things blow up. just like when you call ##(+ 5 "apple")

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

19:06 PigDude: ah ok

19:06 "5apple"

19:06 :)

19:08 amalloy: 5Napple

19:08 that's why you can't add bigints to strings - it looks like product placement

19:11 johnwalker: is lambdajam going to be livestreamed?

19:11 i really want to watch rich's keynote tomorrow morning

19:12 looks like it's going to be amazing. alex miller is going to run a datomic workshop

19:14 woahh and reiddraper

19:14 bbloom: ztellman: before i go benchmark it... does immutable-int-map speed up lookups too? measurements in the README only show construction

19:14 ztellman: bbloom: I think it was mostly equivalent

19:14 there are benchmarks in the tests

19:15 bbloom: ztellman: k, i have a relatively large maps of longs and faster lookup would actually be a win

19:15 ztellman: double-checking now, I'm a bit hazy

19:15 bbloom: ztellman: awesome, thanks

19:16 amalloy: ztellman only appears hazy because he is a being of pure energy

19:16 ztellman: shush, don't give away my secrets

19:17 bbloom: how large is "relatively large"?

19:18 bbloom: ztellman: thousands on the low end

19:18 tens of thousands more generally

19:18 ztellman: bbloom: ok, my benchmark is for 1mm entries

19:18 bbloom: even better :-)

19:18 ztellman: it's basically equivalent, but much faster than sorted-map

19:20 50ns for basic lookup, 400ns for sorted-map

19:20 bbloom: ztellman: i don't need sorted at all

19:22 ztellman: bbloom: sorted is automatic, you get if you like it or not

19:22 bbloom: doesn't hurt to have it

19:32 ztellman: more annoying is how destructuring uses nth on a sequence and so Class.isArray sucks up a bunch of time in a tight loop :-/

19:32 ztellman: for bbloom: so use something which is Clojure.lang.Indexed

19:32 ?

19:34 bbloom: ztellman: yeah, but the issue came up b/c of varargs in assoc-in

19:34 ztellman: oh, hmm

19:34 yeah, no answer for that

19:34 bbloom: would be nice if variadic functions could be called with something Indexed if the call site used a fixed number of args

19:36 ztellman: if rest on an Indexed returned an Indexed, totally doable

19:36 unfortunately only clj-tuple does that

19:37 amalloy: bbloom: variadic functions *are* called with something indexed when there are a fixed number of args

19:37 specifically, an ArraySeq

19:37 but assoc-in doesn't take varargs, it destructures a sequence

19:37 bbloom: amalloy: d'oh good catch

19:40 i just specialized assoc-in for my particular use case & it's nice and fast now

19:40 thanks guys

19:41 amalloy: bbloom: what were you calling assoc-in with that you were getting bad performance?

19:41 bbloom: amalloy: a tight loop :-P

19:41 amalloy: no, the args to it

19:41 bbloom: a vector

19:41 amalloy: Class.isArray is only called near the end, after most of the performant options

19:41 bbloom: but it's still called before using first/next

19:41 ztellman: amalloy: ArraySeq is an IndexedSeq

19:41 not Indexed

19:41 which have nothing to do with each other, hilariously

19:42 amalloy: ugh, the trickery. i forgot about that

19:42 ztellman: wow, this is dumb

19:42 it could be Indexed trivially

19:42 which would help everything

19:42 amalloy: oh yeah, and when you destructure a vector into first/rest what you get back isn't a vector anymore

19:42 so it's not indexed, even though of course it could be

19:43 * bbloom 's work is done here... ztellman is on it

19:44 amalloy: man. nthFrom and seqFrom could use some work

19:44 bbloom: amalloy: yup, i find that i have to call .nth instead of nth in quite a few hot spots

19:44 ztellman: amalloy: hackday

19:44 seriously, let's just fix Clojure-land a bit

19:44 bbloom: every time i profile anything, you can be sure that java.lang.Class is on the hotpath

19:44 :-/

19:52 ztellman: i was only half kidding... can i ignore this problem and assume you'll submit a patch ;-)

19:52 ztellman: I dunno, I've pretty carefully avoided JIRA back-and-forth

19:53 but I think I have enough dangling issues that I'm going to just do them all

19:53 try to get amalloy to join me in this masochistic venture, but he's gunshy

19:53 technomancy: don't look at me; I'm allergic to jira

19:54 amalloy: technomancy: find me a picture of someone who's allergic to something delicious and keeps eating it

19:54 this will refer to myself, who keeps getting pulled back to jira

19:54 technomancy: gimme like a hundred seconds

19:55 http://wondermark.com/1k37/

19:55 amalloy: excellent. strawberries are what i was thinking of

19:55 perhaps because i have read that already

19:56 technomancy: yeah you totally set me up for a soft ball, thanks =)

19:56 amalloy: wait, i guess i haven't. that's from last month. i haven't read wondermark in a couple years

19:56 andyf_: Submitting to jira is only masochistic for those who can't stand waiting a year or 2 for a commit to master - wait maybe that is the definition of masochistic?

19:56 amalloy: it just looks so familiar

19:56 technomancy: years??

19:56 lazybot: technomancy: What are you, crazy? Of course not!

19:56 amalloy: andyf_: i've got several patches waiting longer than that

19:58 bbloom: i didn't mean to start another jira bitchfest :-/

19:58 (but i would have submitted two dozen more patches if i felt it was gonna do any good)

19:59 andyf_: It is a bit easier if Clojure core agrees the issue is a bug, rather than enhancement.

20:00 amalloy: bbloom: it's okay. factual is having a hackday next week, and i'll include fixing up ArraySeq on my list

20:00 bbloom: amalloy: awesome, thanks :-P

20:00 technomancy: amalloy: then you missed the 4th of July special? http://wondermark.com/1k43/

20:02 amalloy: not at all, technomancy, i just put it off for two and a half weeks, apparently

20:03 technomancy: whew

20:08 garth: Is there a reason to do (apply max someList) over (reduce max someList) or vice versa?

20:09 amalloy: i wonder if it's right to make ArraySeq_int and friends implement Indexed. they probably don't want to box up their values for nth

20:10 bbloom: garth: in both cases, you need to make sure someList is not empyt, since max requires at least one argument

20:11 garth: but generally, reduce will be faster than apply because apply will create an intermediate lazy sequence

20:11 amalloy: that's a good question

20:11 amalloy: bbloom: wat

20:12 bbloom: amalloy: wat wat?

20:12 amalloy: what you just said about reduce/apply makes no sense. for max it's clearly wrong, and for most other cases i can think of as well, although i won't say it's wrong in *all* cases

20:13 i guess you're thinking of reducers, and assuming that your input is something reducible that's a fair point

20:14 bbloom: garth: ok apparently don't listen to me

20:14 amalloy: but if you want the max, and what you have is a seq or something like that, there's no real advantage to calling reduce instead

20:16 still, i spoke too hastily - i always forget that these days reduce is actually clojure.core.reducers/reduce

20:17 PigDude: amalloy: good one :)

20:17 amalloy: (earlier, internet died where i was)

20:23 amalloy: bbloom: are you familiar with the amusing thing that happens if you try these two very similar expressions? https://www.refheap.com/be5d3b5a42039c9228e8367b1

20:24 bbloom: amalloy: nope

20:24 amalloy: lazy seqs are reducible, but if you use any of the reducer transformers on one, you hold its head for the whole computation

20:24 ztellman: haha, whee

20:26 amalloy: basically because there's no mechanism for a reified CollReduce impl to behave like a ^:once fn*

20:26 it's saving the collection for you just in case you want to reduce over it again

20:31 the lazy seq world is nice, and reducers are nice, but my opinion (mentioned on at least one jira ticket somewhere) is that trying to bridge them is folly

21:18 blur3d: Hey, I have the following app-state/data, and I am trying to avoid nesting the data under the kind and label-id keys. Is there an easy way to update a sensor value in the hashmap? Or is it better to just use nested maps as indexes (and just duplicate the data in the sensor hashmap)?

21:18 http://pastebin.com/WQ1dj2EW

21:27 ghadishayban: amalloy_: i have a fix for the lazy-seq reducible thing in CLJ-1250

21:27 TEttinger: you're just a fixing machine lately, ghadishayban!

21:34 ghadishayban: TEttinger: ain't no fix if it doesn't go through the process and get applied

21:34 justin_smith: blur3d: would you want multiple sensors of the same kind? if not it seems it would be convenient to put the sensors in a hash map with kind as the key

21:35 ghadishayban: A periodic reminder to vote for JIRA tickets: http://jafingerhut.github.io/clj-ticket-status/CLJ-top-tickets-by-weighted-vote.html

21:35 blur3d: justin_smith: yeah, I was hoping to support multiple sensors of the same kind. And the lablel would be how people can tell them apart

21:35 justin_smith: blur3d: also, you can use 1 as a label, instead of :1, I think that would make things easier

21:36 blur3d: yeah I might just use numbers, but then I can’t (:1 labels)

21:36 justin_smith: blur3d: how about something like {{:kind "altimeter" :label "0"} {:updated-at ... :value ...}}

21:36 blur3d: but you can use get

21:36 blur3d: but I need to use get anyway, incase a label is empty

21:37 justin_smith: since you need both kind and label (only the combination will ever be unique) it seems like they need to be combined to make a proper unique key

21:37 blur3d: can you use that kind of destructuring in an update-in/assoc-in?

21:37 yeah, that is what I am after… rather then double nested hashmaps

21:38 justin_smith: ,(update-in {[0 1] 0} [[0 1]] inc)

21:38 clojurebot: {[0 1] 1}

21:38 blur3d: a way to use the kind + id as a index when updating

21:38 justin_smith: with only two pieces of data, a two element vector may be better than a small map, in terms of readability

21:38 blur3d: index/unique key

21:39 justin_smith: ,(update-in {{:a 1} 0} [{:a 1}] inc) but of course a hashmap works too

21:39 clojurebot: {{:a 1} 1}

21:39 blur3d: well, I plan to support a timeseries of values which get conj to the :values [] key

21:40 justin_smith: ok, I think that's outside the current question, but totally doable of course

21:40 blur3d: I think will work fine

21:40 justin_smith: so like [{:time ... :value ...} ...] as the values in the map

21:41 blur3d: yeah, I haven’t worked out how I plan to graph the data yet…. even just a vector should be ok [time value]

21:42 I like http://code.shutterstock.com/rickshaw/, but its support for timeseries seems limited to a constant update interval - and the data is updated during user defined events

21:44 justin_smith: blur3d: there was this algorithmic music composition tool called cecilia, that is kind of defunct now but it had great tools for manipulating data in graph form (like you could click buttons to make each data point random walk from the current value, or to shrink or expand by some factor in the x or y range)

21:45 this is suprisingly rare, as graphing is usually seen as read-only and a way to display existing data, not a way to interactively create an interesting dataset

21:46 blur3d: sounds interesting

21:47 justin_smith: yeah, even the ability to click and drag data points is rare (and probably scary to many statisticians)

21:48 blur3d: what I am working on is a real-time dashboard for Arduinos. Basically, you include a library in you arduino code, add a couple lines (1/2 per sensor/input) and then it will send data via serial/tcp/bluetooth to a web app (likely node-webkit) and automatically create a dashboard that updates

21:50 justin_smith: The destructing hash keys work great - thanks

22:06 justin_smith: blur3d: cool, regarding the node-webkit webapp, you could go all tiny and run that on a beagle-bone

22:06 beagle bone ships with a node web server that allows js access to all its sensor ports

22:08 blur3d: yeah, I was hoping to support raspberry pi’s and any low powered ARM devices that support node webkit - and potentially, you only need data collection ‘server’, so other devices would only need a web browser and javascript

22:08 justin_smith: http://www.element14.com/community/community/designcenter/single-board-computers/next-gen_beaglebone?CMP=KNC-USA-DC-SBC-BBB-BRAND

22:08 blur3d: I’ve got the arduino code library written. It sends data via extending the Firmata library/protocol

22:09 justin_smith: cool

22:09 blur3d: and I’ve prototyped several ways to read the data… over serial/tcp

22:10 I was hoping to just use browser support for serial/tcp, but it is too early and chromium doesn’t support it enough yet

22:11 so that led me to looking at node-webkit, and running a light weight node server (hopefully in clojurescript) that can read the data and send it to clients via websockets

22:12 nkozo: blur3d: maybe is better to send the data using Data RTC

22:12 justin_smith: blur3d: so arduino->serial->compuer->www->client ?

22:13 blur3d: I haven’t really looked into Data RTC… I’ve tested websockets tho

22:13 yeah, that looks right

22:14 nkozo: blur3d: Data RTC is like UDP, maybe is an advantage over websockets for your use case

22:14 justin_smith: you could skip the computer and still have the hardware inputs (and still be running node as your server) if you used a beagle bone

22:14 beagle->www->client

22:15 blur3d: I’ll look into it… I have it all working just using clojure… but i’d rather package it as an multi-platform app - so whatever node-webkit can support, it likely what I have to work with

22:15 I need to get myself a beagle

22:15 justin_smith: well with the profile described above, it would just be a standard node web page

22:16 blur3d: yeah… node webpage should work.. but I don’t know node webkit that well

22:16 the toolchain seems very broken

22:17 justin_smith: well the beagle comes with the node webserver running and connected to the hardware ports by default

22:17 blur3d: and using node_modules with C extensions (like for serial), has been giving me problems

22:17 justin_smith: but also has enough power that you should be able to pull off running jvm clojure

22:18 technomancy: the beagle bone is super pokey at jvming

22:18 justin_smith: one of the first things I tried with mine was sshing into the box, connecting an led to some hardware ports, and using bash to turn the led on and off

22:18 blur3d: I dont think I need the jvm - except for development

22:18 justin_smith: technomancy: OK, that sucks

22:18 yeah I have heard bad things about the jvm on arm actually

22:18 technomancy: I had better luck with racket

22:19 justin_smith: ooh, that is an interesting option, yeah

22:19 blur3d: I’ve run simple clojure apps on the raspberry pi

22:19 technomancy: they just added badass arm jit in racket

22:19 blur3d: worked fine

22:21 hmm, It’s interesting that with the beagle I wouldn’t need any arduino library… so somehow the user would need to specify/read sensor values

22:22 in any case, I plan to make the dashboard as generic as possible.. and you just send it data and it builds itself automatically as data comes in

22:22 justin_smith: blur3d: with a beagle it runs linux and you can just cat files under /proc to get port values or set them

22:22 cat out to proc/foo/bar to send a voltage, cat from proc/foo/bar to read it

22:22 blur3d: yep. but I am writing the dashboard to just be a dumb terminal

22:23 justin_smith: OK

22:23 blur3d: so somewhere you would need to tell it what to display

22:23 http://dashingdemo.herokuapp.com/sample

22:23 I’d like something along the lines of that

22:23 justin_smith: I hope you are considering using om

22:24 blur3d: justin_smith: but, I don’t see why the dashboard can’t be forked or extended for specific beagle use

22:24 justin_smith: sure

22:24 blur3d: yeah, plan to use React + om… that is what I needed the data transformation for

22:25 justin_smith: also you should be able to pull in dashboard directly into beagle, since on default bootup it already has node serving web pages and able to read from / write to all the hardware ports via js

22:25 blur3d: this is actually the inspiration for the project - Bret Victor, Seeing Spaces http://vimeo.com/97903574

22:25 cespare: I just found that if one of my test files has a syntax error, lein test ignores it completely.

22:26 blur3d: nice, that could be cool

22:26 cespare: is there a way to make it not do that?

22:26 because, y'know, that's terrible

22:26 justin_smith: blur3d: awesome demos in that vid

22:27 blur3d: Yeah, Ive got a spare core (an arduino with built in wifi), and I’ve been using it to test tcp… and it is really cool to see it all working

22:28 myguidingstar: Hi all, I'm considering a workflow for project using cljx+clojurescript.test

22:28 blur3d: being able to see the internals is magical

22:28 sparkcore” http://spark.io

22:29 The arduino API is very simple

22:29 #include "TestDrive.h"

22:29 TestDrive.begin();

22:29 TestDrive.setLabel(2, "Main Bedroom");

22:29 TestDrive.sendTemperature(2, temp);

22:29 myguidingstar: I think it would be too slow to run auto cljx build + cljs build + running tests

22:30 but instance feedback is essential to me

22:30 any suggestion?

22:31 blur3d: nkozo justin_smith technomancy: thanks for the discussion. I’ve got to head out.

22:32 justin_smith: I’ll try and let you know what I have something working enough to push to github

22:32 might be a few weeks

22:33 I’ve started to play with om, and I really like it, but I need to learn a fair bit

22:33 justin_smith: blur3d: awesome, do keep me updated

23:01 cespare: nvm, looks like a bug that's been fixed.

23:51 visof: hello

23:52 i'm starting embedded server using java inside clojure, but only i need to return the object but verbose of the server also returned with the object

Logging service provided by n01se.net