#clojure log - Jul 28 2015

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

0:35 lunaticleo: newbie question (.getPath (java.nio.file.FileSystems/getDefault) "/tmp" "/foo") get ClassCastException java.lang.String cannot be cast to [Ljava.lang.String; user/eval2979 (NO_SOURCE_FILE:1)

0:36 oops maybe I should try #clojure-beginners

0:40 amalloy: lunaticleo: have you tried typing some key words from that error message into google? eg, a search for "clojure java getpath string cast" brings the answer as the second result

0:41 lunaticleo: ah. Note to self try easy stuff first

1:00 namra: hm how to pass a fn name to a macro which will then be evaluated by the macro?

1:00 ,(defn hello [] (println "hello, world"))

1:00 clojurebot: #'sandbox/hello

1:01 namra: ,(defmacro with-hello [f] `(let [msg# "Macro"] (println msg#) ~f))

1:01 clojurebot: #'sandbox/with-hello

1:01 namra: (with-hello hello)

1:01 ,(with-hello hello)

1:01 clojurebot: Macro\n#object[sandbox$hello 0x678697ba "sandbox$hello@678697ba"]

1:06 namra: ,(defmacro with-hello [f] `(let [msg# "Macro"] (println msg#) (~f))

1:06 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

1:06 namra: ,(defmacro with-hello [f] `(let [msg# "Macro"] (println msg#) (~f)))

1:06 clojurebot: #'sandbox/with-hello

1:06 namra: ,(with-hello hello)

1:06 clojurebot: Macro\nhello, world\n

2:28 sm0ke: how do you simulate something like (deref futur 10000 :timeout) with core async channels?

2:29 something like (<!! chan 10000 :timeout) would have been helpful but i am sure its not there

2:38 amalloy: sm0ke: use alts on a timeout channel

2:38 sm0ke: yea but that will return nil

2:39 which makes it looks like channel has closed

2:44 there is a :default in alts! , not sure what it does

2:56 Seylerius: What's the easiest way to find the greater of two numbers?

2:58 sm0ke: ,(max 1 2)

2:58 clojurebot: 2

2:58 sm0ke: ,(max 1 2 3 4 5 6 100)

2:58 clojurebot: 100

2:59 Seylerius: sm0ke: That's it. I was feeding it a vector. Simple change to just give it the values directly.

3:10 sm0ke: i made one https://www.refheap.com/107112

3:11 hope its correct

3:32 Seylerius: Rounding time.

3:32 I've got a decimal: how do I reliably round up or down?

3:36 dstockton: ,(Math/round 0.23)

3:36 clojurebot: 0

3:36 dstockton: ,(Math/round 0.5)

3:36 clojurebot: 1

3:36 Seylerius: ,(doc Math/round)

3:36 clojurebot: Pardon?

3:37 Seylerius: dstockton: Thanks. Can that control which way I round?

3:37 I.E. can I specify to round up in one function, down in the other?

3:38 dstockton: no, ties round up, otherwise the closest int

3:39 ,(Math/floor 0.5)

3:39 clojurebot: 0.0

3:39 dstockton: ,(Math/ceil 0.5)

3:39 clojurebot: 1.0

3:39 Seylerius: There we go.

3:39 Thanks.

3:39 (inc dstockton)

3:39 lazybot: ⇒ 1

3:39 dstockton: yw

3:41 in case you aren't aware, these are all java methods

3:41 http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html

3:42 Seylerius: dstockton: I suspected that, but yes.

3:48 Grr... I hate when computer algebra solvers produce absurd output.

3:49 I am so not in the mood to solve a fscking quadriatic...

5:19 kaiyin: why can't compareTo be resolved here? Number n = new Integer(0); System.out.println((Integer)n.compareTo(new Integer(4)));

5:24 Chousuke: kaiyin: that looks like you're casting the result of the compareTo call.

5:24 try ((Integer) n).compareTo...

5:29 kaiyin: Chousuke: ah, i see. thanks!

6:21 sheldonh: in the exercises i'm doing, there's a lot of (f (first a-seq) (g (rest a-seq))). does clojure have a function that applies this pattern?

6:36 i hand-rolled my own: (defn traverse [f g a-seq] (f (first a-seq) (g (rest a-seq))))

7:41 dnolen: Bronsa: appears you forgot to drop munge from the cljs.tools.reader ns form, fails to compile :)

7:44 Bronsa: also ns-resolve and ns-map aren't a thing.

7:45 and they aren't going to be

7:47 nogden: Is there anyway to persiatantly rebind a var in the current thread?

7:48 i.e. not have to always use (binding [...] ...)

7:53 Bronsa: dnolen: did you remove support for that at some point? I'm 80% sure I checked and they were implemented

7:57 dnolen: Bronsa: like more than a month ago

7:57 Bronsa: the record problem needs to be handled in some yet undetermined way

7:58 Bronsa: dnolen: are you fine with leaving it an unimplemented feature for now?

7:59 I don't feel comfortable reverting to the old impl using js/eval + munge

7:59 dnolen: Bronsa: yeah you shouldn't do that you just need to give up on the feature period

7:59 both the record ctor thing and resolve-symbol.

8:00 resolve-symbol should be dynamic var that throws

8:00 it has no sensible interpretation without the ClojureScript compiler being bootstrapped

8:01 Bronsa: dnolen: so throw on resolve-symbol? that means that reading backquoted forms will throw

8:07 dnolen: Bronsa:

8:07 I don't see why this is a problem. People can bind it if they think they can make it work.

8:08 Bronsa: dnolen: ok, fine with me. previous impl just expanded ns aliases and left symbols otherwise unexpanded

8:25 dnolen: ok changes committed, reader tests are passing using last cljs

8:32 dnolen: Bronsa: everything works, if you have chance cut a new release I can make ClojureScript depend on it and simplify my current convoluted dev setup :)

8:33 Bronsa: 0.10.0-alpha3 on its way

8:33 dnolen: Bronsa: thanks!

8:48 IceD^: hey

8:49 using drift (https://github.com/macourtney/drift) and want to redefine this https://github.com/macourtney/drift/blob/master/src/drift/config.clj#L7

8:49 for some legacy/tooling purposes wana keep them in different directory

8:49 what's prefered way to do this?

8:51 it's your typical lein project etc

8:51 justin_smith: IceD^: you can set dynamic bindings in project.clj

8:52 IceD^: *global-vars* https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L258

8:53 IceD^: awesome

8:53 (and that's why I love clojure - in (rare) cases of some issues I can get immidiate answers ;])

9:09 justin_smith: follow up question - this var is in drift.config ns. I'm lazy and/or stupid and can't find way to specify ns

9:27 lein does this: ~@(map (fn [[k v]] `(set! ~k ~v)) (:global-vars project))

9:38 so - simplifying question - how to set! var in different ns

9:50 dabd: Could someone help me with using negative lookahead with instaparse? I was expecting to be able to parse the following expression with this grammar: https://gist.github.com/dabd/eb5cb233f9214e527870

9:50 (foo-parser "bar")

9:51 how can I specify a rule to parse anything that does *not* start with foo?

9:52 expez: ! is not part of the syntax for context-free grammars

9:53 nevermind, there's a PEG extension too, right?

9:53 dabd: yes

9:53 if i understood correctly you can use the some PEG operators in CFGs

9:53 use some*

9:54 expez: anyway, your use of negative lookahead is wrong, I think

9:54 all negative lookahead does is look ahead to ensure that the parser is not satisifed by the following characters

9:55 dabd: any ideas on how I can parse all lines that start with foo and slurp in the the 'other' non-terminal anything that doesn't match?

9:55 expez: so instead of !foo you should just create a rule which matches whatever, IIRC PEG rules are ordered

9:57 dabd: how would you define a rule that matches whatever?

9:57 expez: foo / whatever, first tries to match foo and then tries to match whatever

9:57 CookedGryphon: is there some reason we can't use (into "" (some-transducer-producing-strings) some-coll)?

9:57 dabd: and how do you define the non-terminal 'whatever'?

9:57 CookedGryphon: other than it not being defined currently

9:59 expez: dabd: whatever ::= #"."+ should probably work. You should check out the instaparse README it covers everything in a very clear manner imo

10:01 sveri: Hi, is tower currently the go to tool for internationalization?

10:12 John63: 74 http://www.n-games-dev.net/black-fps/

10:53 lellis: Good morning, I'm beginning to set up my test environment and was in doubt how best to create the database, it is generally used the same development bank? Created and destroyed in memory? thanks

11:05 IceD^: lellis: depends

11:09 lellis: Did u guys always make integration tests or use mock for those?

11:10 justin_smith: lellis: by preference I separate pure stuff from side effects, put any nontrivial logic in the pure part, and test that

11:15 lellis: of course that doesn't always work, but it's a nice way to do it when it does

11:21 lellis: ok ty

11:22 justin_smith: lellis: it depends what I am testing when it comes to integration vs. mock - in my database abstraction lib I use an in-memory h2 instance for most tests

11:23 lellis: if using the database is just part of the app logic, and is already tested (in the lib that provides the db abstraction I am using), I'll use with-redefs or arrange for the data source to be passed in so that I can stub it out with a lambda

11:49 ,(defn n [i] (->> (all-ns) (mapcat ns-publics) keys (mapcat #(clojure.string/split (name %) #"[*-.!?]")) shuffle (take i) (clojure.string/join \-) symbol))

11:49 clojurebot: #'sandbox/n

11:49 justin_smith: ,(n 3)

11:49 clojurebot: macroexpand-atom-streams

11:49 justin_smith: ,(map n (repeatedly #(rand-int 5)))

11:49 clojurebot: (ensure-inc-flush get-unquote-unchecked-val method-char-flush-quot set-long shutdown-Throwable ...)

11:51 justin_smith: ,(map n (repeatedly #(rand-int 5)))

11:51 clojurebot: (partition fn-file-dissoc seq resultset--add-into ...)

11:51 oddcully: i like ensure-inc-flush and shutdown-Throwable

11:51 justin_smith: heh

11:51 oddcully: set-long seems quite useful

11:52 (set-long 5 2) ; from now on (== 5 2)

13:53 mglvl: Hi all, anybody can help me with this question: http://stackoverflow.com/questions/31680028/clojure-core-match-error-with-variant ?

13:58 dnolen: mglvl: not enough context what is Mobile a deftype?

13:59 mglvl: dnolen: a defalias wich is '{:left Branch, :right Branch}

13:59 justin_smith: dnolen: toward the top it is a t/defailias for '{:left Branch, :right Branch}

13:59 oh, heh

14:00 dnolen: mglvl: doesn't tell me anything at all

14:00 mglvl: does defalias make a deftype? a defrecord? a map?

14:01 mglvl: one immediate thought is that you probably don't intend to match the local?

14:02 mglvl: this is a "feature" of core.match borrowed from other pattern matchers that can be counter-intuitive

14:02 mglvl: dnolen: well I'm not sure how core/typed works - what I intended it to be was an alias for a map with a left Branch and a right Branch

14:02 dnolen: mglvl: that `mobile` is a parameter and you're going to match that

14:02 `mobile` in the pattern does not introduce a new binding

14:02 i.e. not a wildcard

14:03 expez: dnolen: if I provide a data-reader for #js, can I use the clj reader to read a cljs file?

14:03 mglvl: dnolen: then why does it work in the other case?

14:03 dnolen: expez: probably never tried it myself.

14:03 mglvl: because `local` isn't a local parameter

14:04 to summarize

14:04 (fn [x y] (match x y)) != (fn [x] (match x y))

14:04 expez: dnolen: will cljs in cljs eliminate the need for :refer-macros?

14:05 dnolen: in the former x must equal y

14:05 expez: ClojureScript has macro system that is fundamentally incompatible with Clojure's.

14:05 so no ... never going to happen.

14:07 expez: dnolen: is there an equivalent of the classpath in cljs, e.g. if I want to query the runtime for a list of all available deps?

14:08 dnolen: expez: internally yes, but there's no good public way to get at that at the moment, ClojureScript can load many kinds of JavaScript files in many kinds of ways.

14:08 expez: dnolen: so this: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-add-missing-libspec won't be possible for a while yet in cljs?

14:09 dnolen: expez: that works for me in Cursive I believe, you just have to sort out the resolution yourself.

14:09 expez: shit that gif is pointing to the old clunky version :/

14:10 mglvl: dnolen: I'm sorry, I'm not sure I understood you correctly. Is it because I'm using the same name for a variable already defined, right? so its trying to match against that variable's value and not as a wildcard?

14:10 dnolen: expez: short story you must consider classpath, :libs & :foreign-libs

14:10 mglvl: yep

14:10 mglvl: dnolen: ok, thanks!

14:24 slester: Is there a fancy way of accessing what's in a project.clj file without slurping it in & fishing out what you want? I couldn't find anything so I assume not.

14:24 drbobbeaty: slester: Nope. That's it. But I've done it - even when it's in an uberjar, and it's very slick.

14:24 slester: drbobbeaty: slurping?

14:25 drbobbeaty: slester: Yup. You can `slurp` from an uberjar as well.

14:25 slester: drbobbeaty: oh! sorry, misunderstood. good to hear, thanks.

14:27 arrdem: Bronsa: expected stackmap at branch target. howdoi.

14:28 amalloy: slester: lein puts your project.clj in META-INF/leiningen/[groupid]/[artifactid]/project.clj

14:30 so you can slurp that path and probably find it. or you can just slurp the path "project.clj" and *probably* find it. but this only works when you're looking for the project.clj in charge of the uberjar; dependencies bundled into a jar don't get their project.clj put anywhere in particular as far as i can tell

14:40 Bronsa: arrdem: got a minimal example?

14:40 is it the one on jira?

14:42 arrdem: Bronsa: no this is another one, I'm working on a patch for TEMJVM-14 and broke something... trying to understand what/how

14:47 seangrove: What's the overhead of using partial or comp on the jvm? It's pretty expensive and should be avoided in a tight loop for cljs

14:51 amalloy: seangrove: it's one object allocation with one constructor argument per closed-over variable

14:52 oh, and i guess since you're talking about comp and partial the closed-over variables are just the arguments

14:52 justin_smith: seangrove: #() creates a new class while partial does not iirc

14:52 kwladyka: how works tail-call optimization? I need go into lazy deep checking tree https://ivoroshilin.files.wordpress.com/2015/02/backtrack.png not wide. Is it possible with loop and recur? I don't think so?

14:53 amalloy: justin_smith: i know you know this, but it's good to be clear when answering: it creates a new class once, at compile time, not every time you evaluate it

14:53 justin_smith: amalloy: right, thanks

14:53 s/evaluate/use of course because eval again would create a new one :P

14:54 eval of the form that made it that is

14:54 amalloy: well, evaluate is different from "call eval on"

14:55 justin_smith: so you are talking about calling the bound value?

14:55 amalloy: like (repeatedly 10 #(+ 2 2)) evaluates #(+ 2 2) 10 times but only makes one class

14:55 justin_smith: right

14:55 amalloy: i guess it doesn't actually evaluate that 10 times

14:55 i meant more like... (repeatedly 10 (fn [] #(+ 2 2)))

14:56 justin_smith: right, my mental model was create class when evaluating, but evaluate only once per binding (and re-use the binding)

14:56 amalloy: per binding?

14:56 andyf_: kwladyka: Anything that can be implemented using recursion can also be implemented using iteration with no function calls, if you are willing to implement your own stack by hand.

14:56 in any language, not just Clojure

14:58 justin_smith: amalloy: hmm, maybe that's the wrong term - in (fn [] #(+ 2 2)) the inner lambda is bound (captured is the more idiomatic term here of course) only once, no matter how many times the outer is called

14:58 or in (let [f #(+ 2 2)] (repeatedly f)) it's bound and evaluated once and reused

14:58 amalloy: justin_smith: it's not, though. it's in the body of the function, not closed over and saved. if you call that fn twice you will get out two different (but equivalent) lambdas

14:59 andyf_: kwladyka: Here is a Stackoverflow Q&A on the topic. I'm sure there are others: http://stackoverflow.com/questions/159590/way-to-go-from-recursion-to-iteration

14:59 justin_smith: amalloy: oh... OK

14:59 amalloy: ,(let [f (fn f [] #(+ 2 2)), g (f), h (f)] [g h (= g h)])

14:59 clojurebot: [#object[sandbox$eval25$f__26$fn__27 0x2962230 "sandbox$eval25$f__26$fn__27@2962230"] #object[sandbox$eval25$f__26$fn__27 0x4e9e7ea3 "sandbox$eval25$f__26$fn__27@4e9e7ea3"] false]

14:59 justin_smith: ,(let [f (fn [] #(+ 2 2))] (= (f) (f)))

14:59 clojurebot: false

14:59 justin_smith: OK

15:00 noncom: kwladyka: clojure does not provide tail-call optimisation. you have to manually place (recur) in correct tail places

15:00 amalloy: it would be easier to realize if the example were like (fn f [n] #(+ 2 n)) (f 1) (f 2)

15:00 there it must be two different lambdas, but there's nothing qualitatively different about the two examples, just whether something is closed over

15:00 justin_smith: right, there is a possible optimization there of course, which for some reason I assumed could happen

15:00 noncom: kwladyka: you also have to define what you do on each step and how do you advance in the tree

15:01 amalloy: sure, it could be optimized for no-closure lambdas

15:01 noncom: from that you'll get a clearer view of how your tree-work will work

15:03 kwladyka: but as a general advise , i usually separate the stepping function from decision-making function... however that is just a preference of taste.. to me it makes things a little cleaner

15:04 kwladyka: also, it is desirable to use (recur) in case of too many calls - not to blow up the stack. or sometimes it is possible to use reduce for that..

15:05 kwladyka: andyf_, even a backtracking algorithm?

15:05 noncom, i read clojure has some tail-recursion optimisation on stackoverflow somewhere

15:06 ed-g: Hello I'm trying to debug a problem with Friend interactive-form workflow. My form is calling the interactive-form login page, but it isn't accepting any user or password in my testing map. However when I call the bcrypt-credential-fn using the same username and password my form is submitting, it returns a {:role ...} map. Any suggestions for debugging techniques? I'm afraid I may have wrapped the ring handler in the wrong order or something but have no

15:06 idea how to diagnose if that is the case.

15:06 andyf_: kwladyka: If recursion can do it, it means there is a call stack with return addresses and arguments. This can be simulated with your own code. It isn't necessarily as short or clean as a recursive version would be to read or understand.

15:07 noncom: kwladyka: even with backtracking - your looping index in case of a cycle may represent, say the depth level, so you can go up a level even if you use a while{} or for{}

15:07 but that seems dirty and goto-like

15:08 kwladyka: no, it does not have tail call optimisation.. it has some means, like the (recur) statement to make recursion without an actual funcall (without putting one more frame in the stack)

15:08 that's it i think

15:09 you can use (recur) with (loop) or without it

15:11 ed-g: looks like Friend is calling my password map with an empty username. Anyone seen this before?

15:11 kwladyka: so are you suggesting use http://clojuredocs.org/clojure.core/iterate or it is the same name by incidence?

15:12 backtracking with iterate?

15:12 gfredericks: fun fact: (binding [*out* nil] (/ 42 0) (catch Exception e :caught)) => :caught

15:13 noncom: kwladyka: no, i do not think this is a good choice... that'll just make the thing much trickier. why don't you just use (recur) ?

15:13 ed-g: never used that..

15:13 kwladyka: noncom, i need lazy algorithm and recur make it unlazy

15:13 noncom, loop with recur

15:14 domokato: hey guys, is it idiomatic to use delays when you need to perform some side effects in the middle of a large let binding?

15:14 gfredericks: domokato: what is the goal?

15:14 kwladyka: noncom, https://ivoroshilin.files.wordpress.com/2015/02/backtrack.png <- i have to get as deep as possible branch and then next one, and next one, i can't do it in wide way

15:15 for now i am doing this with (for) but maybe it is better way

15:15 noncom: kwladyka: yeah, you don't have to.. it all depends on your algorithm..

15:15 domokato: gfredericks: the goal is to avoid having a large let binding, followed by a couple lines with side effects, followed by another large let binding

15:15 gfredericks: instead combining them into one let

15:16 noncom: kwladyka: i have to go, but maybe these links can help you http://stackoverflow.com/questions/11409140/stumped-with-functional-breadth-first-tree-traversal-in-clojure and http://squirrel.pl/blog/2010/07/26/corecursion-in-clojure/

15:16 domokato: gfredericks: reducing nesting

15:16 noncom: good luck

15:16 kwladyka: noncom, thx

15:17 domokato: gfredericks: previously i've used _ bindings, but it looks ugly to me

15:17 gfredericks: domokato: like (let [a b, _ (delay c), d e] ...)?

15:19 (I can't figure out how you can use delays to avoid having the _ binding)

15:19 domokato: gfredericks: one sec...

15:22 gfredericks: previously, i would use (let [a b, _ c, d e] ...) but would it be better to do something like (let [a b, d (delay e)] c @e) ?

15:23 er

15:23 gfredericks: (let [a b, d (delay e)] c @d) i mean

15:25 gfredericks: the other thing I'm trying to avoid is (let [a b] c (let [d e] ...)) because of too much nesting sometimes

15:26 gfredericks: (where c is a function call or something with side effects needed by e)

15:34 gfredericks: ah yes I see how that works

15:36 domokato: I would _probably_ think about how to refactor it into separate functions so you don't have this problem

15:36 but I've definitely run into it too

15:37 and sometimes imagine a fancy macro that would let you insert a :do clause

15:37 but I don't actually go write it

15:37 amalloy: gfredericks: the macro would be to find all instances of :do and replace them with _ because that already works?

15:37 gfredericks: it seems like a useful kind of syntactic salt

15:38 amalloy: I suppose that would be the easiest impl now that you put it that way, yes

15:38 amalloy: still kind of dirty, since you're poluting the lexical environment with gensyms or something, but whatever it's just imaginary

15:39 amalloy: right, it's just a silly implementation that points out how silly the potential macro is

15:39 domokato: well, :do would be a little more readable than _ but still kinda ugly, imo

15:40 gfredericks: amalloy: :P

15:41 csd_: how can i instantiate java generics in clojure?

15:41 Vector<int> for example

15:42 gfredericks: no need to

15:42 Empperi: first of all, Vector<int> can't be made, second the generics have type erasure and thus aren't there when using reflection or at runtime

15:42 thus no need to

15:43 TEttinger: ,(doto (java.util.HashMap.) (.put "key" 1) )

15:43 clojurebot: {"key" 1}

15:44 csd_: ,(java.util.Vector.)

15:44 clojurebot: []

15:45 csd_: got it, thanks

15:45 TEttinger: period after a class name, like ClassName, is short for (new ClassName)

15:46 new as a macro or special form or whatever it is is rarely used in clojure, the appended dot is much more widely used

15:46 csd_: i'd accidentally imported [java.lang.Vector], figured it was a different problem than it was :-/

15:56 domokato: i gotta say, it's pretty readable using the delays

16:05 justin_smith: ,Vector

16:05 clojurebot: #error {\n :cause "Unable to resolve symbol: Vector in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: Vector in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6611]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: Vector in t...

16:07 justin_smith: (inc delay)

16:07 lazybot: ⇒ 1

16:08 justin_smith: ,(doto (java.util.Vector.) (.add 42))

16:08 clojurebot: [42]

16:09 arrdem: Bronsa: the case I'm encountering is on c8db1c8, attempting to emit clojure.core/line-seq something to do with then when-let ifnul not being structured correctly.

16:10 Bronsa: sorry ducked out for lunch, will be hanging out here when you get a chance to look.

16:14 ed-g: Ok, turns out the problem is I *did* need to wrap my Ring handlers in a different order. In general how should I determine which order to wrap ring handlers? Do I look at each projects documentation or are there rules of thumb?

16:14 justin_smith: ed-g: most ring handlers apply after the one they wrap

16:15 ed-g: but theoretically each handler could do some work before they one they wrap, and some more after

16:17 ed-g: justin_smith, thanks. I suppose I was surprised I should wrap using Friend's authenticate wrapper before Ring's site-defaults. I would have thought that Friend would want things such as GET and POST parameters and anti-forgery.

16:22 Yep, in the friend source authenticate* does do some work before calling the next handler down the line. I suppose I should write my own ring middleware then it will all be clear ;-)

16:23 justin_smith: ed-g: yeah, after writing enough middlewares in that style, it starts to make more sense - each wrapper has the power to redirect or mangle input to or output from each thing it wraps...

16:24 ed-g: my mental model of a middleware is like dude jumps into a lion robot then lion robot jumps up and becomes part of voltron etc.

16:30 ed-g: justin_smith, lol what I've discovered is its a good idea to have dude wear a GoPro so I can see what is going on.

16:30 to be fair I remember that Rails routing and wrappers were equally confusing but much more of a mess. no offense intended to any Rails developers here.

16:33 TimMc: justin_smith: or a middleware could run the handler multiple times and pick the output it likes best...

16:35 arrdem: you could also just add a data flow dependency language for automatically composing middlewares...

16:35 expez: Where can I find the documentation for the cljs ns form?

16:36 ed-g: ok robo-voltro-tur-ducken analogy is going into the code comment.

16:39 justin_smith: TimMc: true - or it could filter handlers and not run the ones it doesn't like

16:41 TimMc: justin_smith: Swap the request for whatever is currently in some atom and then use that one instead.

16:42 like one of those silly Starbucks pay-for-the-next-person chains

16:54 Fare: are the arguments received by a *stararg or **kwarg guaranteed to be fresh lists and dicts?

16:54 are they frozen? can they be mutated?

16:54 what if the function was itself called with a *stararg or **kwarg — are they copied or shared?

17:00 amalloy: Fare: is this a clojure question in disguise?

17:04 oddcully: smells like python?

17:06 Fare: oops, wrong channel — though I'm implementing that in clojure

17:08 slester: If I want to maintain the state of four players in a game, what should I use? defrecord? (yes, total newbie)

17:11 justin_smith: slester: start with a hash-map, upgrade to defrecord if you have a compelling reason to

17:12 slester: justin_smith: cool, with update-in?

17:13 justin_smith: slester: yeah. I would imagine a recursive function that updates game state and the state of each player on each iteration, returning a lazy-seq of played rounds?

17:14 slester: justin_smith: good idea! I am ripping myself off the OOP way of thinking so I'll need a lot of thinking to make that work in my head. thanks.

17:16 justin_smith: slester: the lazy-seq version is like oop, in that the state is organized into the "objects", except the data is a series of frozen states over time, and every "method" takes the frozen (immutable) state of a game and returns an updated game object (new frozen state)

17:16 so the objects disappear into their time traces

17:16 it sounds pretty cosmic when I put it that way, lol

17:16 slester: hahah

17:18 justin_smith: the objects in the game world can still have black-box logic like in normal oop, but you also have the added flexibility of knowing you don't have to control access, just update

17:41 amalloy: huh, just ran across http://stackoverflow.com/q/13616471/625403 - it seems strange to even ask whether clojure needs let or not

17:45 justin_smith: I think that guy would like scheme, and his favorite implementation would be the one he could write in a weekend

17:46 this is just wild speculation

17:54 TimMc: amalloy: Referring to the use of a lambda instead of a let... "this is a pattern I tend to use a lot & I love it"

17:54 amalloy: right!?!?

17:54 TimMc: That's fascinating, and I don't think I'd want PRs from them. :-/

17:54 amalloy: who doesn't love to write ((fn [a b c] (+ a b c)) 1 2 3) instead of (let [a 1 b 2 c 3] (+ a b c))

17:55 * arrdem mutters about inlining

17:56 TimMc: This appears to get at their discomfort a bit: http://stackoverflow.com/a/13618303/20772

17:56 turbofail: lol

17:56 arrdem: here lets save a character in a symbol for another class, more jit pressure and two more parens

17:57 justin_smith: amalloy: ITYM ((fn [a] ((fn [b] ((fn [c] (+ a b c)) 3) 2) 1)

17:57 TimMc: arrdem: I don't think it's the alphabetic char count that bothers them. :-)

17:58 arrdem: (inc justin_smith)

17:58 lazybot: ⇒ 281

17:58 TimMc: from my link, it appears to be the "imperative flavor" of some uses of let -- rebinding.

17:58 arrdem: I mean in fairness when I see that I try to replace imperative uses of let with -> or ->> as appropriate to avoid rebindings...

17:59 but (let [ _ (println ..) .. ] ..) is legit

17:59 TimMc: I always feel dirty when I do that.

18:00 arrdem: yeah but assert in your bindings is kinda nice

18:00 turbofail: there is no way in which the ((fn [a] ...) b) pattern is superior to that though

18:00 amalloy: TimMc: this was all a trap to get you to post a SO referral link so i could find out who you are on SO

18:01 TimMc: ?

18:01 Is that a thing SO does?

18:02 amalloy: TimMc: the Share link creates one that has your userid in it, yeah

18:02 TimMc: that's terrible

18:02 So I'm 20772 then?

18:03 amalloy: you can choose to, instead, just ctrl-L ctrl-C to copy the url from the url bar, which is the generic url that would turn up in google results

18:07 TimMc: I sent them a feedback thingy to say "stahp".

18:21 ed-g: Every library author thinks I want to use their macros. I do not want to use their macros, I want to use the functions that their macros use.

18:24 justin_smith: ed-g: they keep trying to make "fetch" happen

18:27 amalloy: sigh, dynamic types pls. i'm trying to fix an issue in code someone else wrote, and i cannot for the life of me figure out if this "field" of a struct-like map is supposed to be a set or a map. it starts out as a set, and then some stuff is conjed onto it, and then later somehow there is a map in the same slot, and then that map is conjed into a set so that you have a set of map entries

18:28 justin_smith: classic

18:29 clearly that field is of type wooly-milkable-egg-laying-pig

18:29 amalloy: i think it's supposed to be a map, because there is code that does stuff like (let [method ((:methods m) whatever)] ...), but then why did it start out as a set? and if i make it a map from start to finish, it breaks because someone tries to conj a string into it while it's expected to be a set

18:31 to add to the confusion, this is all inside of the fnparse monadic parser, so there is a :methods key in the "state" half of the state monad thingy, and also sometimes a :methods key in the "value" half so maybe they are two distinct unrelated objects

18:38 arrdem: what are you doing in the guts of fnparse...

18:38 isn't instaparse king these days or just old code

18:41 {blake}: So...I figured something out that's been annoying me for a while, and I'm not sure whether it's just a personal tic, or something I should communicate to others (like, say, Weavejester, since it's lein-ring related).

18:41 I've mentioned it here: Sometimes when running lein-ring, my code fails to reload because it can't find a function.

18:42 Which began, not surprisingly, when I moved that function into a new namespace.

18:43 But I thought I had caught all the references. After all, my code was running. It just wouldn't reload when running lein ring server...but only sometimes.

18:43 And I discovered that I hadn't changed the references in my tests (which, heh, I haven't been running).

18:44 So, that seems to be the issue: Sometimes, but not always, lein code reloading would trigger the tests being pulled in. Or so it now seems, since I've corrected that, the error has not re-occurred.

18:47 Seylerius: Anyone know if it's possible to force Gorilla REPL to use a fresher version of nREPL? Cider's throwing a fit about insufficient freshness.

18:49 amalloy: arrdem: like i said, it is old code

18:49 i think fnparse was old long before this was written, but here i am all the same

18:50 arrdem: Seylerius: yeah should be possible, I think a note about this was just added to the CIDER README.md

18:50 Seylerius: it's just an override either in your project.clj or profile.clj

18:51 Seylerius: Good deal. I'll look that up and tweak it.

18:51 (inc arrdem)

18:51 lazybot: ⇒ 45

18:51 * arrdem sad panda at delta to justin_smith

18:51 Seylerius: (karma systems are fun)

18:59 arrdem: Where does the cider readme live?

19:03 justin_smith: Seylerius: I would expect it to be on the cider github page https://github.com/clojure-emacs/cider

19:04 Seylerius: justin_smith: I thought Gorilla was talking about a cider-specific readme somewhere in the gorilla project.

19:04 Huh.

19:04 That makes more sense.

19:04 Too much sense.

19:04 Who said the Clojure community could be so sensible?

19:05 justin_smith: Seylerius: did you just call arrdem Gorilla?

19:05 Seylerius: No, the Gorilla page mentions the same thing.

19:05 justin_smith: oh, OK

19:05 Seylerius: Since the whole reason I'm asking about this has to do with the Gorilla REPL project.

19:06 Of course, the one other annoyance that I have about Gorilla is that it eats my emacs-style keybindings from conkeror.

19:10 eriktjacobsen: Is anyone familiar with Beckon / Signal handlers? I am using a function “core.print-health” which seems to work fine for first day or two of the jar running, but after a couple days it starts erroring out with “classdefnot found core.print_health”. I dont know why scope would suddenly change a couple days into running jar.

19:11 it errors out inside the signal handler as it tries to call the function

19:16 justin_smith: eriktjacobsen: wouldn't the class include the full package name not just starting with "core" ?

19:17 eriktjacobsen: apologies, yes: Exception in thread "SIGTRAP handler" java.lang.NoClassDefFoundError: pipeline/core$print_health$fn__326

19:17 this is after several days of calling that function without fail

19:17 killing / restarting jar fixes it

19:18 hiredman: eriktjacobsen: how are you running this thing?

19:18 justin_smith: oh, so it's an internal class (anonymous function inside the function) that is suddenly missing?

19:18 hiredman: I've seen similar things happen serving a war via jetty-runner, and jetty runner unpacks wars in to /tmp and some systems clear out /tmp once a day

19:19 eriktjacobsen: No, not anonymous. In the core file there is a defn, and then that is passed to the beckon signal handler via: “(reset! (beckon/signal-atom "TRAP") #{print-health})”

19:19 I’m running with just java -jar file.jar

19:20 justin_smith: eriktjacobsen: foo$fn_xyz means an anonymous function inside the function foo

19:21 eriktjacobsen: This is inside pipeline.core ns : (defn print-health [] —code—)

19:21 justin_smith: eriktjacobsen: right, what I am saying is that the thing it can't find is an anonymous function iside print-health, that's what that message means

19:22 eriktjacobsen: hmm

19:22 outside of timbre logging / deref and atom resetting,this is the only function

19:22 “ (dorun (map (fn [[name agent]]

19:22 (if (realized? agent)

19:22 (report "HEALTH" name " is down.")

19:22 (report "HEALTH" name " is running."))) @agents)))”

19:23 justin_smith: eriktjacobsen: the first arg to map is an anonymous function

19:23 oh, that's what you were saying, heh

19:24 anyway, maybe it's a bad locals clearing? that's weird though

19:25 eriktjacobsen: it can't hurt to change that to (map (fn health-checker [[name agent]] ...) ...) - then if that is the class not found, the message will indicate it (clojure uses the anon fn pseudonym if provided)

19:25 eriktjacobsen: yeah I wouldnt think it could lose that inside the map. Agents is also top level in pipeline.core… there are no arguments to print-health or any let statements anywhere so no locals i think

19:25 Thank you justin_smith, will definitely try that

19:25 hiredman: what does the stacktrace say?

19:26 eriktjacobsen: darn I actually lost it when I restarted.. im sure will happen again though, just give it a day =\ Actually I have to run now. Will try that just to narrow down whats failing

19:27 hiredman: it could easily be logging stuff causing the error, different logging frameworks can end up doing class inspection

19:27 eriktjacobsen: the only things I saw was the beckon handler, clojure internals and then print-health was last thing. Didnt see anything logging related in stacktrace

19:27 amalloy: also useful to know is whether you are aot-compiling

19:28 hiredman: not directly related, but I would consider ditching beckon for directly using the sun.misc signal handling stuff

19:29 https://github.com/hiredman/songs-of-future-past/blob/master/src/com/manigfeald/sofp/signals.clj#L14-L19

19:30 (beckon is slightly larger than five lines)

19:34 (also putting fns in sets or using them as map keys is gross)

19:34 (same with any type with non-value equality)

20:06 gfredericks: is there any particular reason why = is extensible but </>/<=/>=/min/max/min-key/max-key are not?

20:08 hiredman: == is not

20:09 gfredericks: that's not meant as an explanation, right?

20:09 hiredman: it is meant as a rexamination of the premise the question is based on

20:10 gfredericks: you're saying == is in the same family because they all work on mixed-exactness numeric types?

20:10 hiredman: right, and = is this weird thing that works on everything

20:10 basically I suspect it comes down to the fact that Object implements .equals but not .compareTo

20:11 and various follow on decisions from that echoing down through the ages

20:11 gfredericks: there are other functions that do arbitrary comparisons and throw when necessary

20:11 compare, sort, sort-by

20:12 I guess they all take comparators

20:12 and the other functions are variadic so couldn't

20:13 hiredman: it may also just be the seam where the ml standard library meets the jvm and common lisp

20:14 gfredericks: I don't know nearly enough about ml or CL to interpret that

20:14 hiredman: well rich took stuff from cl and ml when creating clojure's core, and then there is java interop

20:16 so maybe the semantics of </>/<=/>= etc came from ml, while comparitors and universal equality stuff came the jvm interop (and egal I guess)

20:16 basically, you'd have to ask rich, and when was the last time he was irc?

20:18 it may even be a performance concern

20:19 ==,>,<,etc are considered real hot paths to be made fast, while =, because it interops with .equals is open to any stupid thing

20:21 xemdetia: bool equals() { TwitterRequest.ask("sooo like does "+a.toString()+"="+b.toString()); }

20:23 that is an awful joke

20:23 arrdem: I had a laugh

20:24 xemdetia: I just had a flash of some imaginary obfuscated jvm performance bugs contest

21:05 gfredericks: hiredman: thanks

21:09 hiredman: it is interesting to try and come with as possible reasons for something to be the way it is

21:19 vas: Ohhh is a future a way of doing stuff asynchronously in clojure?

21:20 like (normal thang) (normal thingy) (future thingy-that-might-take-a-while) (normal thang)

21:20 lispiphanies

21:22 arrdem: vas: yep. future is a way to express threaded async. core.async is for "real" single or multiple threaded async/CSP

21:25 vas: hmm I have heard much about this new style of code-fu known as "code.async" ...

21:25 core.async*

21:25 CSP = ?

21:26 justin_smith: $google programming CSP

21:26 lazybot: [Communicating sequential processes - Wikipedia, the free ...] https://en.wikipedia.org/wiki/Communicating_sequential_processes

22:42 namra: hm using atoms within macros is kinda annoying

22:43 justin_smith: namra: why?

22:44 amalloy: using compile-time atoms would be a hassle, i imagine. but emitting code that deals with atoms at runtime should be no problem

22:44 justin_smith: ,'@foo

22:44 clojurebot: (clojure.core/deref foo)

22:45 namra: there's an atom in the same namespace that the macro is and the atoms value initially is nil and will be reset during runtime

22:46 justin_smith: namra: so deref it at runtime?

22:46 namra: justin_smith: but that means that all other namespaces that use that macro must also know about that atom

22:47 i'd like to avoid that

22:47 justin_smith: namra: if the atom is needed in order for the macro to be correct, then the namespaces using the macro need to access the atom (at least in macroexpanded code) in order for the code to be correct

22:49 namra: does the atom update arbitrarily at runtime? is it only set once as some sort of initialization?

22:50 namra: only set once at startup

22:51 justin_smith: namra: consider a delay or promise instead of an atom then - they are safer because they only get set once

22:52 namra: justin_smith: thanks alot

22:52 amalloy: why do the other namespaces need to know about the atom, even if you left it as an atom? your macro will just be emitting code that uses it, but they won't have to know about it

22:53 justin_smith: amalloy: the macro would break if the var was private, right?

22:53 amalloy: i mean at the worst case you can emit (swap! #'whatever/atom inc). but it doesn't have to be officially-private in order for other namespaces to not use it

22:54 er, (swap! @#'whatever/atom inc)

23:19 vas: So I have a list of keys, I have a fxn that takes 2 keys and returns a number. I want to compare every key against every other key.. doseq seems like the logical choice...

23:20 justin_smith: vas: (doseq [a keylist b keylistt] (f a b)) >

23:20 unless you need the results...

23:20 then you want for not doseq

23:20 vas: > means descending?

23:20 justin_smith: it was a typo for ?

23:21 vas: Oh, cool. yes I want the "results" not just side-effects of running f. but maybe pprint will do for now

23:21 justin_smith: use for instead of doseq

23:21 pretty much the same syntax

23:21 vas: Okay, groovy.

23:22 justin_smith: note this will compare each thing against itself

23:22 maybe that's OK

23:24 vas: Yeah that is Ok. it will just gimme a 0.0

23:30 I would assume comparing them all against themselves should give me n^2 values returned...

23:30 amalloy: vas: try it and see

23:38 vas: Hmm. How can I go from ("string1" "string2" "stringC") to a vector of strings?

23:39 amalloy: why do you need a vector rather than a list?

23:39 vas: actually I think mapv will do the trick.

23:40 reason being " java.lang.String cannot be cast to clojure.lang.IFn"

23:41 justin_smith: vas: wait, were you trying to make a list literal?

23:43 vas: So I have a list of tags... ({:tag "heart"} {:tag "cool"} {:tag "whatever}) ... the comparing fxn takes 2 strings, figures out the tag overlap and stuff, needless to elaborate ...it returns a number. but i'm not sure how to format it to play nicely with my comparator ... trying some baby data worked with tags in a vector ["heart" "cool" "whatev"] .. but not in a list

23:47 Okay I think I figured it out. I was trying to short-cut by doing (for [tag1 (mapv :tag (show-all-tags)) tag2 tag1] ... )

23:47 because tag1 and tag2 are the same, right? but for some reason, that does not work.

23:47 so it's not like "let" in that sense, it seems.

23:48 amalloy: vas: tag1 isn't the whole list of tags, it's a particular item in it, remember

23:48 vas: explicitly defining tag1 as (mapv :tag (show-all-tags) and tag2 as (mapv :tag (show-all-tags)) Works, however.

23:48 Oh!

23:48 amalloy: you can tell, because in the body of your for, you're treating it like an item

23:48 vas: Thank you amalloy

23:48 amalloy: so you can reuse a definition, but not if you put it inside the for

23:48 vas: Aha. that is good learning right there.

23:49 no wonder they all came back 0, it was doing identities

23:50 Thanks for the help. =]

23:51 And it returns n^2 items now, yay. =]

23:56 =) this is fun

Logging service provided by n01se.net