#clojure log - Jun 14 2015

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

1:54 iany: is there a reason why defing a transducer (def a (map inc)) works in clojure but not in clojurescript?

1:55 laggybit: iany: really old cljs version?

1:57 iany: laggybit: latest ones. transducers work, but you can't def them. eg. (sequence (map inc) [1 2 3]) works in clojurescript, but not (def a (map inc)).

2:00 laggybit: iany: hmm, that's interesting

2:01 iany: got a repo that shows that behavior?

2:03 iany: laggybit: unfortunately no, just experimenting with cljs. so this is not by design? you can def a transducer in clojurescript?

2:04 laggybit: iany: as far as I know, yes

2:04 iany: laggybit: aight thanks, at least i know it's a problem on my end now.

2:05 justin_smith: iany: odd, I don't have a cljs project handy right now - can you put a transducer in a let binding? in an atom?

2:10 iany: justin_smith: oh wait. it does work. i looked at the output and thought it was an error message. sorry.

2:10 justin_smith: that's a relief

2:10 laggybit: phew

2:12 iany: silly me.

3:10 elvis4526: Hello! I'm trying to understand multimethods. It's like OOP in the sense that OOP dispatch the method call based on the object, correct ?

3:18 amalloy: multimethods are polymorphism, which is just one of the many features that are glued together under the heading "OOP"

3:26 elvis4526: amalloy: alright thanks

3:29 amalloy: Is there a way to provide a default fn when nothing match the dispatch value ?

3:29 ah I think I can achieve that with :default inside defmethod

4:46 kaffeeboehnchen: Ok, so I created a new file in src/project (leiningen project) and when I get an error that the namespace fails to require itself because of a null pointer?

4:50 Even with just "(ns my-name.space)" -> Failed trying to require my-name.space with: java.lang.NullPointerException

4:51 laggybit: kaffeeboehnchen: what's the path to that file?

4:53 kaffeeboehnchen: laggybit: src/my_name/space.clj

4:54 in my real code its src/project_mox_server/api.clj and (ns project-mox-server.api)

4:55 I have other files in the namespace that are working without a problem.

4:55 https://paste.xinu.at/L6D4/ maybe some of the deps?

4:56 laggybit: oh, it's not empty

4:56 kaffeeboehnchen: ?

4:56 laggybit: right, try removing all the requires

4:56 kaffeeboehnchen: same without the requires and use :(

4:57 laggybit: on a fresh repl?

4:59 kaffeeboehnchen: laggybit: restarted ligth table (I have no clue how to restart the connected repl) and it works :)

4:59 thanks

4:59 laggybit: that's a relief

4:59 clojurebot: I don't understand.

4:59 kaffeeboehnchen: What could have caused that?

5:00 laggybit: I have absolutely no idea

5:00 kaffeeboehnchen: Ok. Thank you very much. :)

5:00 elvis4526: I'm trying to write a macro that use the java interop

5:01 Does the dot have a special value inside a macro?

5:02 laggybit: elvis4526: it's a special form

5:02 elvis4526: i'm gonna pastebin it.

5:05 http://pastebin.ca/3027779

5:05 I would expect the macro to expand to (.controller [...])

5:06 laggybit: ooh

5:06 elvis4526: why it doesn't ?

5:09 laggybit: it actually does

5:09 elvis4526: what ?

5:09 can you paste how you called it exactly ?

5:09 laggybit: but that's also a macro, which would expand to . app controller

5:11 TEttinger: ,(macroexpand '(+ 1 Math/PI))

5:11 clojurebot: (+ 1 Math/PI)

5:11 TEttinger: haha

5:11 wat

5:12 elvis4526: I don't understand. The (.) macro isn't suppose to be expanded when using (macroexpand), right ?

5:12 and (. app controller) is not what I want

5:12 TEttinger: I'm attempting to implement clojure-style macros now, in a lua interpreter

5:12 why not?

5:12 ,(. Math sin 0)

5:12 clojurebot: 0.0

5:13 laggybit: it is, (.controller app) becomes (. app controller)

5:13 TEttinger: ,(.sin Math 0)

5:13 clojurebot: #error {\n :cause "No matching method found: sin for class java.lang.Class"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching method found: sin for class java.lang.Class"\n :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}]\n :trace\n [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]\n [clojure.lang.Reflector invokeInstanceMethod...

5:13 laggybit: try macroexpand-1 on it

5:13 elvis4526: ohshit so (macroexpand) expand on more than one level ?

5:13 laggybit: yes

5:13 elvis4526: what's the difference than between macroexpand-all and macroexpand ?

5:13 laggybit: if you want a single pass, macroexpand-1 does that

5:14 TEttinger: dot space will actually work even on static methods, dot,nospace will as .sin did, break

5:14 but dot space has more complicated rules for how it calls what, so static methods are best called with Math/sin or equivalent

5:16 elvis4526: anyway - thanks !

5:17 laggybit: elvis4526: macroexpand and macroexpand-1 don't expand subforms

5:17 elvis4526: macroexpand-all does

5:18 TEttinger: so I'm a bit confused right now. when are macros expanded in a normal clojure program, and at what point does ~ or unquote get the value of what it unquotes?

5:23 Confusion: In core.logic, you usually use something like (l/run* [a] (l/== a 3)). Now instead of a formula with 'a', I have a formula with a generated symbol. How can I pass the generated symbol to l/run* ? Simply (l/run* [my-symbol-reference] my-logic-formula-with-symbol) doesn't work, as that results in 'my-symbol-reference being literally present in the expanded macro. However, I don't understand how to write a macro whose output is (l/run* [my-sy

5:23 mbol] my-logic-formula-with-symbol)

5:24 TEttinger: oh boy, macro macros

5:25 Confusion: you are in for either hair-pulling or a lot of fun, http://amalloy.hubpages.com/hub/Clojure-macro-writing-macros

5:26 Confusion: Yeah, I was afraid of that, *diving in, send a search party if I'm not back in an hour* :P

5:26 amalloy: are these formulas generated at compile time or runtime?

5:27 TEttinger: amalloy! what are you doing up?

5:27 amalloy: and why are you allowing the symbol chosen to be different? if you are producing these formulas, you can simply require that the goal always be named q or whatever, with no loss of generality

5:27 TEttinger: I had some macro questions that I think should be quick for you to answer, if you have the time amalloy

5:27 amalloy: you can always ask

5:28 TEttinger: mainly... uh... I am having a hard time figuring out what the question is

5:28 I guess at the basic level, when are macros expanded?

5:28 is it a phase before the evaluation of the fns?

5:29 amalloy: TEttinger: the answer will make you laugh

5:29 "at macroexpansion time"

5:29 TEttinger: indeed.

5:29 when is macroexpansion time, in the process of compiling a clojure program?

5:29 amalloy: really it is closely related to compile time

5:30 generally the compiler does things one form at a time. for each form, it checks to see if it's a macro call, and if so expands it. then it does that recursively, finding all macro subforms and expanding them too. then, it compiles the fully-expanded top-level form

5:31 often, forms are evaluated right after being compiled, but not always

5:31 TEttinger: what if a macro call expands to another macro call?

5:32 so the other question is, when does unquote have access to the actual values of the unquoted symbol?

5:32 amalloy: that's the recursive part

5:32 whatever form a macro expands to, it's as if you wrote that fomr by hand

5:32 so, if it expands to some other macro, it's just like you wrote that macro by hand; of course this means that it is expanded too

5:33 the other question is more vague. what do you mean "actual values of the unquoted symbol"?

5:33 TEttinger: because unquoting something like (def foo (slurp "foo.txt")), then later getting ~foo in a macro... will it be nil? will it be the value of foo when the macr is called?

5:35 (def foo (slurp "foo.txt")),(defmacro foo-get [] `(str ~foo)),(foo-get)

5:35 amalloy: TEttinger: the stuff that happens in ` and ~ is, mechanically, totally unrelated to how macros are expanded. it will help you to not think of them as the same thing

5:35 TEttinger: oh boy.

5:35 amalloy: you can syntax-quote outside of macros, or write macros without syntax quoting

5:36 TEttinger: yes

5:36 amalloy: they just *tend* to be in the same place

5:36 TEttinger: I have actually done this

5:36 amalloy: so. once you have your mental model for how macroexpansion works, and for how `~ works, you can answer your own questions

5:36 TEttinger: I'm just unsure how the macro call can have runtime values

5:36 amalloy: eg, try writing out by hand what `(str ~foo) is short for

5:37 and then thinking about how that would work, as a macro definition

5:37 TEttinger: (list 'clojure.core/str '~clojure.core/foo) ; guessing here?

5:38 amalloy: no, how could '~ be there in the expansion?

5:38 TEttinger: ,`(str ~*clojure-version*)

5:38 clojurebot: (clojure.core/str {:major 1, :minor 7, :incremental 0, :qualifier "master", :interim true})

5:38 amalloy: you can even ask clojurebot to do it for you

5:38 ,'~(str ~foo)

5:38 clojurebot: (clojure.core/unquote (str (clojure.core/unquote foo)))

5:38 amalloy: er

5:38 ,'`(str ~foo)

5:38 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/str)) (clojure.core/list foo)))

5:38 amalloy: well of course that is totally illegible because of the seq/concat junk

5:39 but it is the same as (list `str foo)

5:39 TEttinger: well it has quote around str, so I was wondering if that was the same as 'str

5:39 amalloy: sure. `str is 'clojure.core/str

5:40 TEttinger: ohhhh

5:40 you meant the '~ digraph

5:40 not the two characters ' and ~

5:40 amalloy: yes

5:40 TEttinger: ,'`(str ~*clojure-version*)

5:40 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/str)) (clojure.core/list *clojure-version*)))

5:41 TEttinger: so the version that's produces by '` , that's what a macro returns, am I right?

5:41 *produced

5:42 amalloy: remember, ` is nothing to do with macros

5:43 (defmacro foo [x] (f x)) is called like a function named foo, which is run at compile time instead of runtime

5:43 and since you can already reason about how functions behave, such as (list `str foo), you can reason abotu how (defmacro blah [foo] (list `str foo)) will behave

5:44 eg, foo will be the symbol '*clojure-version*

5:45 another way to play with this, rather than calling macroexpand, is to just do it without macros: (defn blah [foo] (list `str foo)), and then quote the arguments every time you call blah: (blah '*clojure-version)

5:47 TEttinger: so the reason I'm asking is, I'm attempting to implement macroexpansion in my clojure-like lisp targeting lua

5:48 I want to do it in a way that's very close to clojure (# suffix for autogensym was tricky with my parser, so it's a $ prefix instead, otherwise same)

5:49 however if I don't get a better grasp on, uh, what I'm doing, it will be the blind leading the blind when anyone tries to use this language

5:54 laggybit: TEttinger: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6758

5:55 Confusion: amalloy, the expressions are parsed from a language. Users may choose (== a 3) or (== flibbly-di-floop 3). I know which ones are free and my current approach is to replace them in the logic expressions themselves, keep a mapping of the replacements, so I can report back what the solutions are.

5:56 So initially, I basically have: expressions + a list of strings that are the known free variable names. And I want to pass that to l/run*

5:57 amalloy: if you know which ones you need to test for, why can't you just write (or expand to) (run* [q] (== q [a b c d e]) (...expressions with a, b, c, d, and e...))?

5:57 TEttinger: laggybit: uh... this is very hard to understand. for one, ObjExpr fexpr = (ObjExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form), "eval" + RT.nextID());

5:57 fexpr has a very very different meaning than what is used here

5:57 amalloy: and i guess also add a (fresh [a b c d e]) around that

5:58 TEttinger: for another, holy crap that is like all references to other parts of core.clj's implementation

5:58 laggybit: TEttinger: this is clojure's actual implementation of eval

5:59 if you're looking for a reference, this is it

5:59 Confusion: amalloy, If a need to replace variables by symbols a, b, c ..., I wouldn't I still need to generate a finite list of symbols to replace the variables with? So wouldn't I still be stuck with a list of symbols to put in??

5:59 amalloy: no, you can just use the symbols the user gave you

5:59 it doesn't have to be abcde

6:00 TEttinger: laggybit, I'm not looking to copy clojure's JVM implementation, for one thing lua doesn't even HAVE try/catch/finally

6:00 Confusion: Well, those may clash with other symbols in the environment?

6:00 amalloy, and they are entered as strings, resolved into symbols, so I would then need to pass those symbols (constructed from the strings) in... wouldn't I run into the same problem then?

6:01 amalloy: i think that is unlikely, but i suppose it's not impossible

6:01 TEttinger: I'm trying to have similar behavior, but the implementation is going to be VERY different

6:01 amalloy: Confusion: okay so here is the thing. you are doing this at runtime, and you need data that exists only at runtime (the users' expressions)

6:01 that stuff doesnt exist at macroexpansion time, which is compile time, so you cannot have access to it

6:02 TEttinger: amalloy: that actually answers some of my questions too, as an aside

6:02 amalloy: if you want to splice runtime expressions into a brand-new core.logic expression, at runtime, you have no real choice but to use eval. this doesn't exactly solve your problem, since you'll have to generate the same code to pass to eval that you would have to macroexpand to anyway

6:03 TEttinger: strings are magic, though. strings are life

6:03 laggybit: TEttinger: you should certainly be able to get identical behaviour, thoough of course the implementation will be quite different

6:04 TEttinger: laggybit, it's just, that was line 6758 of the file. I'm not going to be able to understand all of Compiler.java in a meaningful period of time

6:04 Confusion: amalloy, yes, I've been trying to have the macro generate a form containing an eval... but I couldn't get things to work

6:05 amalloy: that's not right. there is no point writing a macro that expands to eval. you might as well just write a function that calls eval

6:06 Confusion: Ah, of course

6:08 (I still have to figure out to what extent a macro differs from calling eval on a function that generates a list (that is supposedly evaluable of course). I figured things like symbol generation might only be available inside a defmacro)

6:09 amalloy: Confusion: there is no difference except that one of them runs at compile time and the other at runtime

6:09 as i was telling TEttinger, the fancy stuff done by ` is totally divorced from macroexpansion. you can do it in functions too, it's just a shorthand for writing code that outputs lists

6:10 julianleviston: Hey all. Optimisation question… https://www.refheap.com/102534

6:10 … wondering if there’s a faster way to store updated keys as meta-data… (this is my “dirtying-“ variant of assoc, or other fns)

6:12 Confusion: amalloy, ok, the fancy stuff is provided by `, that's convenient :)

6:18 TEttinger: amalloy, I think I may be figuring out some questions that may be more clear. A macro receives its args as quoted symbols. when a macro is expanded, if anything in its body is unquoted, that unquote acts just like it does in a fn, and so, if I understand this right, the expanded macro will contain an identifier that is not quoted, so when the code that the macro expanded to is evaluated, THEN it looks up what that identfi

6:19 Confusion: Got it!

6:19 TEttinger: all right! woo Confusion!

6:20 Confusion: Thanks amalloy, TEttinger, justin_smith (for some necessary advice last week)

6:20 TEttinger: justin_smith is full of advice all the time

6:20 (inc amalloy)

6:20 (inc justin_smith)

6:21 hm, no lazybot

6:31 mmeix: I'm just contemplating switching from Reagent to Rum for my SVG-driven music-UI - someone have experience with it? (Datascript sounds quite interesting too...)

6:34 julianleviston: mmeix: all I know is rum is more agnostic as to how it approaches things, in particular with theis cursors. Have you had a look at freagent? While it’s experimental, it actually doesn’t use react, so you can do a lot faster animation rendering stuff in it, from what I’ve reen. Depends - why switch?

6:37 mmeix: I'm early in development, just building graphic functions. so far everything is hiccup-like without user interaction so far, so it's open, and I just found some praises for Rum, and datascript seems to be a good fit for this project. Thanks for the hint re freagent, will look it at

6:41 ah, it's called freactive

6:43 julianleviston: haha sorry yes. <sigh> my brain!

6:43 mmeix: np :-)

6:43 julianleviston: it doesn’t help that there are like about 7 of these for CLJS alone… let alone all the similar pure JS ones.

6:44 It’ll be interesting to see Om next whenever that’s likely to come out…

6:45 mmeix: why can’t you use datascript with reagent? I see no reason.

6:45 mmeix: of course ...

6:46 it seems to play rather well with Rum, that's what I read

6:46 just looking around

6:46 julianleviston: mmeix: I don’t know what that means, but ok :)

6:47 mmeix: my English might be a bit Austrian, sorry ...

6:47 thanks for thoughts :)

6:47 julianleviston: mmeix: sorry, that sounded a bit dismissive. Just not sure how it will play better or worse with any of the rest of the cljs world…

6:47 mmeix: maybe because it has the same author?

6:47 mmeix: yes

6:48 julianleviston: mmeix: no worries.

7:11 TEttinger: mmeix, I would not have guessed that your English was anything other than "fluent"

7:12 mmeix: leo.org is open constantly ...

7:13 TEttinger: it's been kinda odd, in #libgdx, which is a java game lib channel (also has clojure bindings!), there are constantly coders coming in with a very very poor grasp of English, but that trait seems rare in #clojure

7:14 mmeix: maybe gamers are a bit different sociologically :P

7:15 TEttinger: I did have one memorable debugging session, across the atlantic. There was a definite language gap, he was in France, and he offered to host a TeamViewer session so I could edit his complex Eclipse/Gradle project. Fun times, navigating a French version of Windows XP (may have been vista or 7 with an older look) despite not knowing any French

7:16 (I managed to get it working after about an hour and a half of this, he had an 8 hour deadline that was coming up fast)

7:16 mmeix: ah, the French ... la Grande Nation is particularily fond of its language ...

7:16 wow. this is one heroic story!

7:16 TEttinger: but man. gradle is such an inferior tool to leiningen

7:17 it's still marginally better than Maven

7:17 mmeix: Is Boot a really better alternative? for someone still learning, I mean ...

7:18 TEttinger: the issue was he had a gradle project synced to eclipse, but needed to get the project to see certain maven jars. any changes to eclipse, next time he updates gradle ever, changes disappear.

7:18 mmeix: (Datascript seems to lend itself to my project - I guess this will be this afternoon's read ...)

7:18 TEttinger: I needed only to install maven, install the jars in his cache

7:19 mmeix: that sounds like a panic situation, yes

7:19 TEttinger: and get gradle to see the local repo

7:19 yes

7:19 I'm glad the guy was nice about it!

7:19 mmeix: he must owe you a box of beer or two ...

7:20 TEttinger: with a name like Muhammad, I kinda doubt it, but I don't drink either, heh

7:20 mmeix: :-)

7:22 my wife and me, we're emptying a bottle of wine over the course of three days or so, so ...

7:27 nooga: I'd gladly empty a bottle of wine over ztellman/gloss because I'm completely stuck :F

7:27 anyone had experience with implementing binary protocols in clj?

7:31 mmeix: (not this learner ...)

7:32 TEttinger: nooga, from what I understand gloss is the way to do it.

7:32 I have never used gloss though

7:32 ztellman is not here right now, I suspect it is early morning wherever he is located

7:33 nooga: TEttinger: I know it is because it works really well with aleph+mainfold and these things are awesome

7:33 but then I have problem describing a legacy protocol with stupidly constructed headers

7:34 and gloss doc doesn't give me any ideas on how to proceed

7:35 I guess I'll hang out until I can bother ztellman :D

12:23 mmeix: how do I sort by a given key order? Say I have [:foo :baz :bar :foo] and I want it sorted by :baz, :bar, :foo

12:24 ==> [:baz :bar :foo :foo]

12:25 (the example in https://clojuredocs.org/clojure.core/sort-by is not helpful, or I don't get it...)

12:30 never mind, just found it: (sort-by (juxt :baz :bar :foo) ...)

12:31 no ...

12:31 jjttjj: ,(doc sort-by)

12:31 clojurebot: "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator. If coll is a Java array, it will be modified. To avoid this, sort a copy of the array."

12:32 jjttjj: so sort just calls the keyfn on whatever you're sorting and orders the result by the result of that fn

12:32 *sort-by i mean

12:33 mmeix: yes, so far I understand

12:35 ah, ok

12:38 so:

12:38 justin_smith: ,(defn bad-shuffle [c] (sort-by (fn [& _] (rand)) c))

12:38 clojurebot: #'sandbox/bad-shuffle

12:38 mmeix: ,(let [c [:foo :baz :bar :foo], comp {:baz 0 :bar 1 :foo 2}] (sort-by #(% comp) c))

12:38 clojurebot: (:baz :bar :foo :foo)

12:39 justin_smith: ,(bad-shuffle (range 100))

12:39 clojurebot: (18 78 26 53 56 ...)

12:40 mmeix: so is giving a map with keys and "weights" a good solution?

12:40 (as a comparator, I mean)

12:40 justin_smith: mmeix: yes, that will work - but you can simplify that code

12:40 mmeix: how?

12:40 clojurebot: with style and grace

12:40 justin_smith: ,(let [c [:foo :baz :bar :foo], comp {:baz 0 :bar 1 :foo 2}] (sort-by comp c))

12:40 clojurebot: (:baz :bar :foo :foo)

12:41 justin_smith: because hash-maps are callable

12:41 mmeix: ah!

12:41 great!

12:41 justin_smith: if you think of the mathematical definition of a function, it should make sense that maps are functions

12:41 also, comp is an iffy name, because it is already a quite useful function

12:41 mmeix: yes, I just forgot ...

12:41 justin_smith: (doc comp)

12:41 clojurebot: "([] [f] [f g] [f g & fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc."

12:41 mmeix: yes, ofcourse

12:42 justin_smith: mmeix: eg. in that case I would likely call the map "weights"

12:42 or perhaps "ordering"

12:43 mmeix: ,(def myorder {:baz 0 :bar 1 :foo 2})

12:43 clojurebot: #'sandbox/myorder

12:43 mmeix: ,(sort-by myorder [:foo :baz :bar :foo])

12:43 clojurebot: (:baz :bar :foo :foo)

12:43 mmeix: thanks!

12:43 noncom|2: for some reason i cannot find some repositories that i've uploaded earlier to clojars

12:44 i've noticed it when lein failed to fetch the deps on a new machine

12:44 i also cannot find the repositories on clojars website

12:44 mmeix: lein clean?

12:44 noncom|2: what could that have happened to them?

12:44 lein clean does not help.. i even removed all lein and maven related stuff from the pc and did all again

12:45 what's strange is that clojars web interface does not show the jars also

12:48 mmeix: ,(inc justin_smith)

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

12:48 mmeix: ugh

12:48 (inc justin_smith)

12:49 vivekramaswamy: Hello all, quick question, I was trying an example from "Living Clojure" book which requires the library, camel-snake-kebab.core, which I added in my project.clj file as [camel-snake-kebab "0.3.1" ], after this I gave the command lein deps, bit still keep getting the error when I give this command (:require [camel-snake-kebab.core :as csk]) any ideas?

12:49 I get the error class not found

12:51 noncom|2: could you please paste the exact exception stack trace here? https://www.refheap.com/

12:51 vivekramaswamy: sure

12:55 noncom|2: vivekramaswamy: and give us a link! :)

12:55 s/a/the

12:59 vivekramaswamy: https://www.refheap.com/102550

13:01 noncom|2: vivekramaswamy: hmmm... can you also show your project.clj?

13:03 vivekramaswamy: https://www.refheap.com/102551

13:04 I have tried with both version 0.2.4 as given in the book and 0.3.1 both give the same error

13:04 noncom|2: vivekramaswamy: hmmm all looks fine... strange

13:06 what does lein-deps give you?

13:06 i mean "lein deps"

13:07 vivekramaswamy: what IDE do you use?

13:08 vivekramaswamy: Emacs + cider

13:09 noncom|2: vivekramaswamy: i use CCW + Eclipse, and it fetches the dep ok. However, upon launching the repl, i get this warning: https://www.refheap.com/102552

13:10 it might be that your IDE prevents hooking up of this library due to the warning

13:10 consider adding the recommended :exclusions param

13:10 vivekramaswamy: when I use the 0.2.4 version it gives me no error but when I use 0.3.1 I get a bunch of warning which I have posted here https://www.refheap.com/102553

13:11 yeap I used the exclusion as suggested [camel-snake-kebab "0.3.1" :exclusions [org.clojure/clojure] ]

13:11 noncom|2: nothing?

13:11 i would advice you asking this question again on #leiningen

13:11 all this is pretty strange

13:11 vivekramaswamy: ok will do

13:11 noncom|2: today here is not many ppl

13:12 maybe someone on leiningen will be there

13:12 vivekramaswamy: let me go there, as this error is whacking me up for the last 2 hours

13:17 noncom|2: vivekramaswamy: btw, is your library in your local maven repo ?

13:17 i mean, does it get downloaded at least?

13:19 vivekramaswamy: let me check

13:20 yes it does get downloaded, I can see them in the repository directory

13:23 noncom|2: and if in your project do just "lein repl"

13:23 and then require the lib?

13:23 i mean, "lein repl" from terminal

13:23 not emacs

13:24 vivekramaswamy: yeap I did just that

13:24 noncom|2: same?

13:26 vivekramaswamy: user=> (:require [camel-snake-kebab.core :as csk])

13:26 CompilerException java.lang.ClassNotFoundException: camel-snake-kebab.core, compiling:(/private/var/folders/c7/wqsnz32j6xq9wzd1mjcj13cw0000gn/T/form-init1232222862510638668.clj:1:1)

13:30 justin_smith: vivekramaswamy: :require only works inside the ns form

13:30 on the top level, it's require, and you need to quote the args

13:30 (require '[camel-snake-kebab.core :as csk])

13:33 noncom|2: ah, that's what!

13:33 vivekramaswamy: Thanks a ton justin, that works in my local repl, when I compile the code in emacs, I still get the error that class was not found this is what I am using in my code (:require [camel-snake-kebab.core :as csk])

13:33 noncom|2: sorry, did not think you were using this form outside of (ns)

13:33 :)

13:35 vivekramaswamy: (ns serpent-talk.talk

13:35 (:require [camel-snake-kebab.core :as csk]))

13:35 ok I got it, that was the mistake I was doing

13:36 noncom|2: justin_smith: can you imagine, i find that a couple of jars i pushed to clojars are missing from there? haven't run into that issue?

13:36 vivekramaswamy: Thanks a ton noncom, and justin for your help

13:36 noncom|2: vivekramaswamy: yeah, sorry, it was just that :D

13:36 justin_smith: noncom|2: I've never had that happen

13:46 mmeix: I do find, that :require, require, :refer, use ...etc. is a bit confusing for beginners

13:47 justin_smith: mmeix: I think it's helpful to remember they are all functions

13:47 mmeix: yeah, but :require as a function name is not intuitive

13:47 for example

13:47 justin_smith: mmeix: no, I mean require, refer, use, etc. are all functions, and the keyword version just calls those

13:48 mmeix: yes, of course

13:48 it's confusing anyway, if you begin ...

13:50 and in the Style Guide it says " In the ns form prefer :require :as over :require :refer over :require :refer :all. Prefer :require over :use; the latter form should be considered deprecated for new code."

13:50 and lot of example code uses "use", so it needs some time to sort this out

13:51 justin_smith: yeah, and a lot of old timers haven't heard the news that use is deprecated

13:51 mmeix: never mind, it was just one of those things, which was quite unclear in the beginning

13:51 were

13:52 justin_smith: mmeix: oh, I agree that those things are confusing to newcomers

13:52 mmeix: one ,ore form the Style Guide:

13:52 "Avoid the use of namespace-manipulating functions like require and refer. They are entirely unnecessary outside of a REPL environment. "

13:53 causes additional head scratching

13:53 justin_smith: mmeix: on the other hand, the way clojure uses namespaces is very different from most languages (and better), so I think it would be worse if namespace stuff was intuitive... it would simply delay the shock of getting used to an unfamiliar system

13:53 mmeix: but a low price to pay for proper namespace isolation, of course!

13:54 agreed

13:56 justin_smith: mmeix: and my experience coming from common lisp / scheme / ocaml where library usage is similar was much easier. But I think there is an inherent difficulty of learning how proper namespacing works that can't just be fixed by changing syntax or naming of things.

13:56 mmeix: I can see that

13:56 justin_smith: and I had the same difficulty and confusion coming from the C world to those languages

13:57 mmeix: I guess I will give the namespace chapter another good read today, won't hurt ...

13:58 justin_smith: mmeix: what helped for me was looking at the various clojure functions which work with namepsaces

13:58 mmeix: good idea - thanks!

13:58 justin_smith: mmeix: ns-publics, resolve, ns-refers

13:59 once you see how namespaces are structured, and how that structure is manipulated by the familiar require etc., I think it starts to make more sense

13:59 (it's a simple structure)

13:59 mmeix: yeah ...

13:59 justin_smith: ,(ns-publics *ns*)

13:59 clojurebot: {}

14:00 justin_smith: ,(def a 0)

14:00 clojurebot: #'sandbox/a

14:00 justin_smith: ,(ns-publics *ns*)

14:00 clojurebot: {a #'sandbox/a}

14:00 mmeix: I see

14:00 justin_smith: ,(ns-refers *ns*)

14:00 clojurebot: {primitives-classnames #'clojure.core/primitives-classnames, +' #'clojure.core/+', decimal? #'clojure.core/decimal?, restart-agent #'clojure.core/restart-agent, sort-by #'clojure.core/sort-by, ...}

14:00 justin_smith: that one probably requires your own repl, and pprint

14:01 mmeix: here's another neat one:

14:01 ,(apropos #"^ns-")

14:01 clojurebot: (clojure.core/ns-aliases clojure.core/ns-imports clojure.core/ns-interns clojure.core/ns-map clojure.core/ns-name ...)

14:01 mmeix: uff

14:02 ok, saving those lines for further analysis

14:02 justin_smith: apropso is a decent way to "bootstrap" your understanding of hte language :)

14:02 *apropos

14:02 mmeix: hte?

14:02 the

14:02 ok

14:02 justin_smith: haha, I'm a terrible typist

14:02 mmeix: sorry

14:04 (looking up function apropos)

14:04 justin_smith: related is find-doc

14:04 mmeix: I see

14:04 justin_smith: apropos searches names of vars, find-doc searches doc strings

14:05 (doc apropos)

14:05 clojurebot: "([str-or-pattern]); Given a regular expression or stringable thing, return a seq of all public definitions in all currently-loaded namespaces that match the str-or-pattern."

14:05 justin_smith: (doc find-doc)

14:05 clojurebot: "([re-string-or-pattern]); Prints documentation for any var whose documentation or name contains a match for re-string-or-pattern"

14:05 mmeix: ,(apropos "comp")

14:05 clojurebot: (clojure.core/*compile-files* clojure.core/*compile-path* clojure.core/*compiler-options* clojure.core/comp clojure.core/comparator ...)

14:05 mmeix: great

14:06 justin_smith: ,(find-doc "compose")

14:06 clojurebot: nil

14:06 justin_smith: ,(find-doc "composition")

14:06 clojurebot: -------------------------\nclojure.core/comp\n([] [f] [f g] [f g & fs])\n Takes a set of functions and returns a fn that is the composition\n of those fns. The returned fn takes a variable number of args,\n applies the rightmost of fns to the args, the next\n fn (right-to-left) to the result, etc.\n-------------------------\nclojure.core/extend\n([atype & proto+mmaps])\n Implementations of p...

14:06 mmeix: ,(find-doc "keyword")

14:06 clojurebot: -------------------------\nclojure.core/agent\n([state & options])\n Creates and returns an agent with an initial value of state and\n zero or more options (in any order):\n\n :meta metadata-map\n\n :validator validate-fn\n\n :error-handler handler-fn\n\n :error-mode mode-keyword\n\n If metadata-map is supplied, it will become the metadata on the\n agent. validate-fn must be nil or a side-...

14:06 mmeix: helpful!

14:06 thanks

14:07 ah, and

14:07 justin_smith: wow, find-doc keyword would be a lot of output

14:07 mmeix: ,(source juxt)

14:07 clojurebot: Source not found\n

14:07 mmeix: ,(source "juxt")

14:07 clojurebot: #error {\n :cause "java.lang.String cannot be cast to clojure.lang.Symbol"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to clojure.lang.Symbol"\n :at [clojure.core$ns_resolve invoke "core.clj" 4214]}]\n :trace\n [[clojure.core$ns_resolve invoke "core.clj" 4214]\n [clojure.core$ns_resolve invoke "core.clj" 4211]\n [clojure.core$resolve invoke "core...

14:07 TMA: ,(source 'juxt)

14:07 clojurebot: #error {\n :cause "clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol"\n :at [clojure.core$ns_resolve invoke "core.clj" 4214]}]\n :trace\n [[clojure.core$ns_resolve invoke "core.clj" 4214]\n [clojure.core$ns_resolve invoke "core.clj" 4211]\n [clojure.cor...

14:08 mmeix: ,(source max)

14:08 clojurebot: Source not found\n

14:08 justin_smith: ,(source juxt)

14:08 clojurebot: Source not found\n

14:08 justin_smith: hrmph :)

14:08 works in the repl

14:08 mmeix: yes

14:08 TMA: &(source juxt)

14:08 justin_smith: ~lazybot |is| sometimes here.

14:08 clojurebot: A nod, you know, is as good as a wink to a blind horse.

14:08 mmeix: #(source juxt)

14:09 justin_smith: mmeix: that would be ##(source juxt) but that only works with lazybot, who is somewhere else being lazy right now

14:09 mmeix: however - good tips as always

14:11 today I discovered Datascript

14:11 which seems a good thing to use in my project

14:11 but docs are rare

14:17 Datomic learning first, of course

14:17 stuff for weeks still ahead :-)

14:58 skelternet: Gah! just figured out I've been getting bit by keyword scoping for roles in friend.

15:14 mmeix: Question: I'm trying to dsipatch a multimethod on a vector of three values, like [3 true false] - is there a way for a method to ignore one of this values, like in [3 true _]?

15:14 (not sure, if the question is clear...)

15:20 justin_smith: mmeix: a dispatch function for a method can do anything a function can do, because it is a function

15:20 ,(defmethod speak (partial take 2))

15:20 err

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

15:20 justin_smith: ,(defmulti speak (partial take 2))

15:20 clojurebot: #'sandbox/speak

15:21 justin_smith: ,(defmethod speak [:big :dog] [_] :WOOF)

15:21 clojurebot: #object[clojure.lang.MultiFn 0x11a090b0 "clojure.lang.MultiFn@11a090b0"]

15:21 justin_smith: ,(speak [:big :dog :whatever])

15:21 clojurebot: :WOOF

15:22 Bronsa: daily reminder I dislike a lot the new default unreadable object printer

15:22 justin_smith: Bronsa: any particular reason? just because of how errors show up in this channel now?

15:23 Bronsa: justin_smith: no i'm talking about the #object thing, not #error. that is clojurebot-specific i think

15:24 justin_smith: it's too verbose for human consumption

15:24 justin_smith: Bronsa: that's how all my exceptions print with newer clojure versions, just asked because I actually find the whole #error thing a bit noisy for the channel

15:24 Bronsa: agreed

15:25 Bronsa: justin_smith: really? i just tried with 1.7.0-master and http://sprunge.us/OiNW

15:26 justin_smith: Bronsa: weird - I am definitely getting #error with my project - maybe it would go away if I updated to the latest master

15:26 Bronsa: justin_smith: maybe it's nrepl vs clojure.repl?

15:26 clojure.main, that is

15:27 justin_smith: Bronsa: I have seen the behavior in both (I use both kinds of repl)

15:27 Bronsa: justin_smith: nevermind something broken at my end

15:28 and it's my brain. mvn package is not mvn install

15:28 justin_smith: ahh, so with a newer one you see the same?

15:28 Bronsa: yeah

15:46 TimMc: H4ns: lein-diff is making progress!

15:53 H4ns: TimMc: nice! i'll not be hacking much in this coming week, but i'll have a look at it for sure. it's about time that we slash our monolith into pieces and get our project.clj's in order.

16:01 TimMc: There, `lein diff HEAD~4 HEAD` now works if you install the plugin. :-D

16:01 Assumes git and assumes project.clj in current directory (or root of project? not sure.)

16:05 https://github.com/timmc/lein-diff

16:11 amalloy: TimMc: this includes transitive dependencies, or no?

17:22 underplank: Hi all. Im trying to run tests using cider in emacs. I using the C-c M-, command and although its running the tests, once I modify them it doesnt re-run the changes. Any ideas why? Cider 0.8.2

17:26 Hmm… ok.. seemed to have sorted it out by adding a cider auto-refresh hook.

17:34 mearnsh: having some problems with netty/aleph, seems like i need to set the underlying maxFramePayloadLength of the netty WebSocket08FrameDecoder, not sure if that's possible? https://www.refheap.com/102558

18:08 underplank: Ok now, it seems that cider connects but does open up the repl.

18:47 mearnsh: i solved my problem for now, realized i can cut down the size of the frames i'm sending over ws.

18:50 gfredericks: is str the cleanest way to distinguish 0.0 from -0.0?

19:12 laggybit: gfredericks: (= (Math/copySign 1.0 0.0) (Math/copySign 1.0 -0.0))

19:12 gfredericks: ,(= (Math/copySign 1.0 0.0) (Math/copySign 1.0 -0.0))

19:12 clojurebot: false

19:12 gfredericks: ,(Math/copySign 1.0 -0.0)

19:12 clojurebot: -1.0

19:12 gfredericks: laggybit: nice!

19:12 laggybit: ^^

19:45 Surgo: is there some way I can have pr-dup able to print java objects that implement Serializable, without having to write my own implementation for the multimethod? it feels like someone else must have had this problem before

19:46 gah, there's a second part to that of course, print them in a way that they can be read-string'ed back in :)

19:53 saeedSarpas: Is there anyone here who has tried scientific simulation using clojure?

20:19 TimMc: amalloy: Yes, lein-diff compares transitive deps. I'd like to expand it to compare plugins and profiles as well, maybe even projects.

20:41 gfredericks: ,(Math/scalb 1.0 -1022)

20:41 clojurebot: #error {\n :cause "More than one matching method found: scalb"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: More than one matching method found: scalb, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.IllegalArgumentException\n :message "More than one matching method ...

20:41 gfredericks: ,(let [^Double x 1.0] (Math/scalb x -1022))

20:41 clojurebot: #error {\n :cause "Can't type hint a local with a primitive initializer"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.UnsupportedOperationException: Can't type hint a local with a primitive initializer, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.UnsupportedOperationException\n :message "...

20:41 gfredericks: O_O

20:42 ,((fn [^Double x] (Math/scalb x -1022)) 1.0)

20:42 clojurebot: 2.2250738585072014E-308

20:42 gfredericks: ^ is that really what it takes?

20:42 ,(let [x (double 1.0)] (Math/scalb x -1022))

20:42 clojurebot: #error {\n :cause "More than one matching method found: scalb"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: More than one matching method found: scalb, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.IllegalArgumentException\n :message "More than one matching method ...

20:42 gfredericks: ,(Math/scalb (double 1.0) -1022)

20:42 clojurebot: #error {\n :cause "More than one matching method found: scalb"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: More than one matching method found: scalb, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.IllegalArgumentException\n :message "More than one matching method ...

20:42 TimMc: What even is a scalb?

20:42 gfredericks: dunno it's whatever

20:43 the problem is there's two sigs, one takes double and one takes float

20:43 there appears to be no way of calling it with unboxed math

20:43 this is not remotely a blocker for me it just surprised me that I couldn't call it

20:43 TimMc: The successor to scala, I guess.

20:44 * gfredericks waits for Bronsa to point to some open jira ticket

20:46 TimMc: ,(loop [d ^double (identity 1.0)] (Math/scalb d -1022)) ;; gfredericks: duh

20:46 clojurebot: 2.2250738585072014E-308

20:46 gfredericks: smells like boxing to me

20:47 TimMc: *Obviously* you want to erase type info and then re-apply it. :-)

20:49 gfredericks: I just wrote a totally different version of rationalize https://github.com/gfredericks/doubles/blob/master/src/com/gfredericks/doubles.clj#L91-97

20:51 arguably less useful, but at least more honest

21:05 TimMc: gfredericks: That 2047 is bothering me as an unnamed constant. I think you should create a library twenty-forty-seven.

21:06 gfredericks: what? a library for every number? when would it stop!!??

21:07 think of the children

21:07 TimMc: which children

21:07 How many are there?

21:07 Please express the answer as a library.

21:07 gfredericks: I have two and you have one, so at least three

21:07 TimMc: wow, that's a lot of children

21:07 gfredericks: I refuse to make a library because of the children

21:14 skelternet: I have spent the afternoon tying routes into knots with friend and oauth2.

21:15 I think I have somehow tried to protect the oauth2callback endpoint so it is in a redirect loop.

21:16 TimMc: Sounds secure! ;-)

21:21 skelternet: heh. Yeah.

21:40 cschep: hey can someone help me understand logging? I installed hbs recently to my web project, and started getting a bunch of "SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder"."

21:40 so do I need to install l4j AND use clojure.tools logging?

21:41 OR what is what?

21:41 and do I need to have a log4j.properties file?

21:51 shoot, got disconnected. can canyone explain how slf4j / l4j / clojure.tools logging come together? or i guess just.. if one of my dependencies needs it.. how I can satisfy that dependency?

22:22 skelternet: cschep, I have only some guesses based on using slf4j in Java, not clojure. I hope someone more knowledgable answers you.

22:27 If I recall correctly, slf4j is an API that purposefully does not specify an implementation. You may need to find an implementation and add it to your project's dependencies.

22:28 again, I have yet to get my mind wrapped around logging in clojure.

22:28 It should be a fun problem to tackle async logging and using the MDC.

22:51 cschep: skelternet thanks for replying, i added both l4j and logging from clojure.tools, and then added an l4j.properties file

22:51 seems to be working..

22:51 :)

22:52 skelternet: cool beans

23:21 clojurescript is a strange animal

Logging service provided by n01se.net