#clojure logs

2015-09-10

00:12simon1234Hi there! I have a problem with using get-method. I defined a multimethod with (defmulti describe (fn [a b] [(foo a) b])) ; and a matching describe: (defmethod describe [:blue :oneline] )
00:13simon1234It works fine, but I can't use get-method. (get-method describe [:blue :oneline]) won't work even if (describe :blue :oneline) will
00:13simon1234(and I can't say: (get-method describe :blue :oneline)
00:13simon1234Any input would be great, thanks!
00:14justin_smithsimon1234: your multimethod takes two args
00:14justin_smithis that intentional?
00:14simon1234justin_smith: yes
00:14simon1234justin_smith: to define both the entity to describe and the level of information you want to get out
00:16simon1234I know I could do (defmulti describe (fn [a & args] a) and then have a case in a defmethod. But I decided to go this way for now. I'm just wondering if I can use get-method with this kind of implementation
00:17justin_smithsimon1234: sorry for being slow, I realize what you are getting at now
00:17simon1234justin_smith: ahah, not a problem at all! thanks for the help!
00:17justin_smithmy approach has been to use a varargs dispatch, yeah, but it is clumsy
00:19justin_smithsimon1234: clearly get-method should have the semantics of apply (or else accept varargs and use apply to call the dispatch function internally)
00:21simon1234justin_smith: oh sorry i'm stupid...
00:22justin_smith?
00:22devn(he's not stupid)
00:22devn:D
00:22simon1234it works in fact, I need to call it this way: (get-method describe [(foo :blue) :oneline])
00:22simon1234not (get-method describe [:blue :oneline])
00:22simon1234(I was thinking that the multimethod function would get applied
00:22justin_smithsimon1234: oh you call it with the result of your dispatch
00:22simon1234before trying to see what function would fit for the dispatch
00:22justin_smithnot the input to your dispatch?
00:23justin_smithnow it makes sense
00:23simon1234I used to call it with the input, I have to apply the dispatch-fn function to it
00:23simon1234justin_smith: well sorry to have wasted your time and thanks a lot for your help
00:23justin_smithoh no, I learned (or at least was reminded of) something
00:24simon1234Well, no a complete waste then, cool ;)
00:24simon1234s/no/not
00:26devni know "there be dragons," but anyone have thoughts on the best way to go about exposing the contents of __extmap on a defrecord as if they had been defined on the record in the first place?
00:26simon1234You can get the internal dispatch fn using: (.dispatchFn core/describe*)
00:26devn(namely, so code you don't control won't need to know anything special)
00:27simon1234(.dispatchFn <your multimethod>)
00:28amalloydevn: huh? (a) what would it mean to expose it "as if" it had been defined on the record, and (b) what good would it do?
00:30devnallow someone interacting with the record to use (.-foo rec) even though foo was not in the definition of the record
00:31devnbut was instead assoc'd on sometime later
00:31devnamalloy: ^
00:32amalloywhy would you do that? if you're interacting with some unknown record, just use (:foo rec) for all fields, instead of (.-foo rec)
00:32amalloyit would pollute the definition of .- a lot, if it looked up things which aren't java fields
00:33devnbecause code that i do not control currently only accesses fields via `.-foo`
00:33devnamalloy: aye, im not saying i'd use it, necessarily, just interested in the problem
00:34justin_smithdevn: how about using reify to create an object with the fields you want the consumer to see?
00:34amalloyyou can't make fields with reify
00:34devn^
00:34amalloywhat code do you imagine someone writing that interacts with the fields of an unknown object?
00:38amalloy(and how could you meaningfully participate in that?)
00:38amalloythey wouldn't write it in java, because that's super hard to do; they wouldn't write it in clojure, because keywords are better and easier anyway
00:47devnim either failing to convey the situation, or i'm looking for light at the bottom of a well, but
00:48devnbut in clara, you use a macro `defrule`, and on the left hand side of the rule, you bind things like `(= ?foo foo)`, where `foo` refers to the field on the record.
00:49devnand now that i write that, i realize that i haven't yet tried to use :foo instead of foo yet in one of those definitions
01:09devnamalloy_: namely it's this bit:
01:10devn,(defrecord FooBar [a])
01:10clojurebotsandbox.FooBar
01:11devn,,(clojure.lang.Reflector/invokeStaticMethod ^Class FooBar "getBasis" ^"[Ljava.lang.Object;" (make-array Object 0))
01:11clojurebot[a]
01:11devn(i think)
01:59amalloyso, that doesn't actually interact with any fields on a record, devn
01:59amalloyit takes a class, and returns a seq of symbols
02:32devnamalloy: yeah, thank you, that makes sense
02:32devni can actually destructure just like it's a map
03:23doctorinserenityDoes anyone know whether I can use lein-oneoff REPLs integrated with Emacs?
03:37luxbockdoctorinserenity: it should work if you use `cider-connect`, but I haven't tried it
03:40OlajydHi TEttinger :)
03:41TEttingerhello Olajyd!
03:44doctorinserenityluxbock: thanks i'll give that a go!
03:44OlajydI was trying out something (reduce #(if (pos? (compare %1 %2)) %1 %2) [["Coke" "16" ""]["Coke" "2" "3"] ["Coke" "" "36"]["Coke" "35" "3"]]) how can we compare based on the second column value
03:47TEttingerOlajyd, so this is a string comparison, right?
03:47TEttinger,(> "12" "9")
03:47Olajyd can we try this use case: [[“Coke" "16" ""]["Coke" "2" "3"] [“Pepsi” "" "36"]["Coke" "35" "3"]] so instead of ;=> [“Pepsi” "" "36"] we’ll get ;=> ["Coke" "35" "3"]
03:47clojurebot#error {\n :cause "java.lang.String cannot be cast to java.lang.Number"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to java.lang.Number"\n :at [clojure.lang.Numbers gt "Numbers.java" 229]}]\n :trace\n [[clojure.lang.Numbers gt "Numbers.java" 229]\n [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [...
03:47TEttinger,(compare "12" "9")
03:47clojurebot-8
03:47OlajydTEttinger, yeaa
03:49Olajyd,(reduce #(if (pos? (compare %1 %2)) %1 %2) [["Coke" "16" ""]["Coke" "2" "3"] ["Coke" "" "36"]["Coke" "35" "3"]])
03:49clojurebot["Coke" "35" "3"]
03:50TEttingerI'm not sure why that works. I think comparing vector to vector will be just based on the length of the vector
03:50TEttinger,(compare ["" "" "" ""] ["" "" ""])
03:50clojurebot1
03:51OlajydI think the default is for every first element, then if its the same it moves to the second element..my assumption though
03:51TEttinger,(reduce #(do (print (pos? (compare %1 %2))) %2) [["Coke" "16" ""]["Coke" "2" "3"] ["Coke" "" "36"]["Coke" "35" "3"]])
03:51clojurebotfalsetruefalse["Coke" "35" "3"]
03:52TEttingerit seems like this should be a sorting thing, not sure
03:53TEttinger,(reduce #(if (pos? (compare (second %1) (second %2))) %1 %2) [["Coke" "16" ""]["Coke" "2" "3"] ["Coke" "" "36"]["Coke" "35" "3"]])
03:53clojurebot["Coke" "35" "3"]
03:53TEttingerlet's try a different collection
03:53TEttinger,(reduce #(if (pos? (compare (second %1) (second %2))) %1 %2) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
03:53clojurebot["Coke" "35" "3"]
03:53TEttingerand with the original...
03:54TEttinger,(reduce #(if (pos? (compare %1 %2)) %1 %2) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
03:54clojurebot["Pepsi" "" ""]
03:54Olajydok
03:55TEttingerI think the comparison with vectors is... not predictable unless you have a single item to compare with
03:55TEttingeror rather, it is predictable, I just don't know what makes it do what it does
03:56Olajydlol
03:56TEttingerthere's also sort-by which may be what you want
03:56TEttinger(doc sort-by)
03:56clojurebot"([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."
03:57TEttinger,(sort-by second [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
03:57clojurebot(["Pepsi" "" ""] ["Coke" "" "36"] ["Coke" "16" ""] ["Coke" "2" "3"] ["Coke" "35" "3"])
03:57TEttingeryep, sorted character by character in the string
03:58TEttingerempty strings are lowest, strings starting with "1" are lower than ones starting with "2"...
03:59TEttinger,(sort-by #(Integer/parseInt (str "0" (second %)) 10) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
03:59clojurebot(["Pepsi" "" ""] ["Coke" "" "36"] ["Coke" "2" "3"] ["Coke" "16" ""] ["Coke" "35" "3"])
03:59TEttingerthat gets the 16 after the 2, which may be desired
04:00Olajyd(reduce (fn [x y] (let [a (get x col) b (get y col)] (if (pos? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]]) I also tried this to though
04:00Olajyd,(reduce (fn [x y] (let [a (get x col) b (get y col)] (if (pos? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
04:00clojurebot#error {\n :cause "Unable to resolve symbol: col in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: col in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: col in this conte...
04:01Olajyd,(reduce (fn [x y] (let [a (get x 1) b (get y1)] (if (pos? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
04:01clojurebot#error {\n :cause "Unable to resolve symbol: y1 in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: y1 in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6704]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: y1 in this context"...
04:01Olajyd,(reduce (fn [x y] (let [a (get x 1) b (get y 1)] (if (pos? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
04:01clojurebot["Coke" "35" "3"]
04:02TEttingeryep, that's pretty much the same as mine. (get x 1) and (second x) are very very similar but get would also work for hash-maps and supports an extra arg as a fallback if x has less than 2 elements
04:03TEttingerso what's the intended output?
04:03TEttingerthat looks like the largest thing in the second column
04:04OlajydTEttinger, yep
04:05OlajydHow about getting the minimum
04:06TEttinger,(reduce (fn [x y] (let [a (get x 1) b (get y 1)] (if (neg? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]["Pepsi" "" ""]["Coke" "" "36"]])
04:06clojurebot["Coke" "" "36"]
04:06TEttingerthere's two choices there
04:06TEttingerI just changed pos? to neg?
04:06Olajydoh
04:06Olajydnice
04:07TEttingerif using sorted stuff, you can get first or last
04:07Olajyd,(reduce (fn [x y] (let [a (get x 1) b (get y 1)] (if (neg? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]])
04:07clojurebot["Coke" "16" ""]
04:08TEttingeryep, lowest starting character
04:08OlajydTEttinger, did you notice something the min is suppose to be ["Coke" "2" "3"] but its giving ["Coke" "16" ""]
04:09Olajyd,(reduce (fn [x y] (let [a (get x 1) b (get y 1)] (if (neg? (compare a b)) x y))) [["Coke" "16" ""]["Coke" "35" "3"]["Coke" "2" "3"]])
04:09TEttingerah, that's the thing I was trying to say
04:09clojurebot["Coke" "16" ""]
04:09Olajydoh ok
04:09TEttingercomparing strings compares the charactrs
04:09Olajydhmmm
04:09TEttinger,(map int "12")
04:09clojurebot(49 50)
04:10TEttingerso each char has a number, sometimes called a codepoint, that is how it is stored. you can do...
04:10TEttinger(map char [49 50])
04:10TEttinger,(map char [49 50])
04:10clojurebot(\1 \2)
04:11TEttingerso that "16" and "2" are getting compared with their first chars first, and "16" has 49 first, "2" has 50 first
04:11Olajydok
04:12OlajydTEttinger, gotcha :)
04:12TEttingerso even though "16" is a longer string and a bigger number if you are reading off what it means, the 2 goes first because of that character being later in the order
04:13TEttinger,(map #(Integer/parseInt (str "0" (second %))) ["16" "2" "" "0"])
04:13clojurebot(6 0 0 0)
04:13TEttingeragh
04:13OlajydSo we use the sorting right?
04:13TEttinger,(map #(Integer/parseInt (str "0" %)) ["16" "2" "" "0"])
04:13clojurebot(16 2 0 0)
04:13TEttinger,(map #(Integer/parseInt (str "0" %)) ["16" "2" "" "0" "99"])
04:13clojurebot(16 2 0 0 99)
04:13TEttingerdon't need to sort
04:14TEttingeryour way works fine, but you should do some processing like with the fn I just used on the string-ified numbers
04:14TEttinger,(Integer/parseInt "")
04:14clojurebot#error {\n :cause "For input string: \"\""\n :via\n [{:type java.lang.NumberFormatException\n :message "For input string: \"\""\n :at [java.lang.NumberFormatException forInputString "NumberFormatException.java" 65]}]\n :trace\n [[java.lang.NumberFormatException forInputString "NumberFormatException.java" 65]\n [java.lang.Integer parseInt "Integer.java" 504]\n [java.lang.Integer parseInt "Int...
04:14TEttingerthat's why I add a "0" before the string
04:20brackiWhat's the clojure equivalent of .setFoo(double... foos)?
04:21bracki(into-array Double '(1 2 3 4))
04:21bracki,(into-array Double '(1 2 3 4))
04:21clojurebot#error {\n :cause "array element type mismatch"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "array element type mismatch"\n :at [java.lang.reflect.Array set "Array.java" -2]}]\n :trace\n [[java.lang.reflect.Array set "Array.java" -2]\n [clojure.lang.RT seqToTypedArray "RT.java" 1726]\n [clojure.core$into_array invokeStatic "core.clj" 3324]\n [clojure.core$into_array invok...
04:21brackidoesn't work
04:24amalloyTEttinger, Olajyd: (doc min-key)
04:26amalloyalso, vectors compare first by length and then lexicographically
04:26TEttinger(inc amalloy)
04:26lazybot⇒ 304
05:15bracki,(into-array Double/TYPE '(1 2 3 4))
05:15clojurebot#object["[D" 0x7738ca7d "[D@7738ca7d"]
05:22TEttinger,(double-array '(1 2 3 4))
05:22clojurebot#object["[D" 0x7b8d2062 "[D@7b8d2062"]
05:23noncomthere is clj-slack, an RPC library, does anyone have any thoughts, is it useable to organize a network of agents?
05:24noncomi presume heartbeat messages in 1 second interval, some RPC calls and occasional continous transfer of text data
05:24noncomup to 2-3 Mb in 10-20 minutes
05:25noncomjust wondering, maybe someone has some experience with clj-slack
05:27ashnuranyone using spacemacs_
05:27ashnur?
05:28ashnuri am trying to find a suitable replacement for paredit, because this evil-lisp-state thing it has by default doesn't even have documentation
05:29noncomashnur: why don't you just install paredit?
05:29ashnurnoncom: it has issues with spacemacs, hard to rebind the keys, or so I read
05:30noncomheh... well, if the only problem is the keys, i would just somehow try to fix it. because you want functionality of paredit, but the only problem are the keys. why would any other analog of paredit with same functionality have no problems with keys then
05:31mobius-engsmartparens
05:31mobius-englispy
05:32mobius-engparedit binds the keys in such a way, it's impossible to rebind them
05:32noncomah
05:33ashnurthx, checking those
05:34ashnuri saw the names before, but because i am just starting with clojure (or any lisp), i haven't used anything. from the tutorial i can see it's very useful
05:34mobius-engI'm using smartparens at the moment
05:35mobius-engit is a bit of work to setup compared to paredit
05:35ashnurare you also using spacemacs or just emacs?
05:35mobius-engjust emacs
05:36mobius-engAFAIK, spacemacs uses evil
05:37ashnuryes
05:37mobius-engNot what would be the best way to bind the keys for different modes
05:37mobius-engNot sure ...
05:37ashnurwell, i am trying to find someone who uses both :D
05:38ashnurthey will know
05:38mobius-engok :)
05:38ashnurhttps://github.com/syl20bnr/spacemacs/tree/master/contrib/!lang/clojure#cider-and-clj-refactor there is this layer for spacemacs, but none of the things included seem to be on par with the features of paredit
05:38ashnuri will keep looking, definitely need to check the two you said, maybe there is a layer for those too
05:42ashnurhmm. i should try these :( https://github.com/syl20bnr/evil-lisp-state/blob/master/evil-lisp-state.el
05:42pydave6367What is the idiomatic way of storing project settings in Clojure?
05:42ashnurthis is what i already have
05:45noncompydave6367: you mean the project.clj file that is a project description for the buinding tool "Leiningen" ?
05:45noncom*building
05:46pydave6367I meant things like database info - project.clj is fine for that stuff?
05:47sm0keso i recently faced this problem with a macro i had written which was something like (with-foo bar ....)
05:47pydave6367noncom: I should clarify - I am indeed using Leiningen.
05:47sm0keand i was calling the macro like (with-foo (baz) ...)
05:48sm0keand the macro expanded and whereever bar was reference in marco it got expanded to (baz)
05:48sm0kesince then i am very scared of macros in general
05:49sm0kedo library writers keep this in mind?
05:49sm0kewhat guidelines do you follow while writing your macro?
05:50noncompydave6367: ah, so you mean just configuration files for your app
05:50pydave6367That's exactly right. I should have been more clear - my apologies. Long day!
05:50noncompydave6367: i think that the most idiomatic way is to store them as .edn files and read/write them with the edn reader/writer
05:52noncomsm0ke: your impression is understandable, it is ok for the initial touches with the macros
05:53pydave6367noncom: Hadn't come across .edn files before. Thank you so much for the pointer!
05:53noncomsm0ke: your best bet is just to write as much macros is possible for various things. ask here if you have questions. it will sort itself out soon.
05:54ddellacostanoncom, pydave6367 I haven't heard that before--I would instead advocate for using environ (https://github.com/weavejester/environ) and using either your ~/.lein/profiles.clj file to store sensitive information, or pass it in as environment vars as described in http://12factor.net/
05:54sm0kehurmm
05:55ddellacostathis also has the benefit of avoiding the risk of committing something like AWS config to a repo
05:55noncomddellacosta: pydave6367: yes, this is another approach, from a different angle
05:56ddellacostanoncom: what benefit does using edn files give you that you can't get more reliably/safely/with less effort from environ?
05:56sm0kenoncom: can you look back and say all my macros are safe against unwated expansion
05:56pydave6367ddellacosta: Love 12 Factor! I'll explore both options. Thank you so much for the time, I really appreciate it.
05:56ddellacostapydave6367: sure thing
05:56sm0keideally one can do something like (let [dup# ~bar] ... reference dup# now..
05:57sm0kebut wanted to know if its the right way
05:58noncomddellacosta: probably nothing but simplicity and less dependency. i do not actually see how it helps with safety of not committing something. but you are right, the environ solution can be considered more professional.
05:59noncomddellacosta: in the end, environ is just a buildup on working with edn, a library.
06:00ddellacostanoncom: yes, but it enforces good practices and keeps config details out of a git repo. And if you want to know why the latter is important, here is a good place to start: https://www.humankode.com/security/how-a-bug-in-visual-studio-2015-exposed-my-source-code-on-github-and-cost-me-6500-in-a-few-hours
06:00ddellacostanoncom: furthermore, just means less reading in things, parsing them, etc--it's one more step you don't have to do.
06:01noncomddellacosta: yep, all that is true
06:02noncomsm0ke: not sure i really understand your problem
06:03noncombut also - nothing prohibits me from not commiting the config file to the repo anyway, don't see it as a problem.. OTOH managing environment variables on Windows is hell
06:04noncomlinux is better for that
06:05sm0kenoncom: lets say one person The Great Mogambo has written a macro (defmacro hail [name] `(println ~name ~name)).. and one other person Mr. India is calling it like (hail (very-constly-name-getter)) , unintentionally the macros will expand to (print (costly..) (costly..)) and doom Mr. India
06:06ddellacostanoncom: yeah, I'm just saying anything that helps automate that part of it is a good thing--no idea about managing env vars on Windows, obviously I'm biased toward Linux/OS X usage
06:06sm0kealthough its a stupid contrived example but you get the point ?
06:06noncomsm0ke: yes, i see, so you want the (costly...) be evaluated once?
06:06ddellacostanoncom: in general, I just questioned you because it's good for newbs to see why people who have been using Clojure for a while think about these things--not sure it would have been clear why to use one over the other for the person asking
06:07sm0keyes of course
06:07sm0kealthough i can use (let [precious (costly)] (hail precious))
06:07ddellacostaand both perspectives have their good and bad points
06:07noncomddellacosta: yeah, sure, this is very good that we have described the moment from these angles!
06:07sm0kebut do i really need to keep that in mind?
06:08noncomsm0ke: why not (defmacro hail [name] (let [res# name] `(println name# name#)) ?
06:08sm0kei already mentioned that noncom
06:08noncom(defmacro hail [name] (let [res# name] `(println ~name# ~name#)) ?
06:08noncomthis is the correct way to do this
06:09sm0kebut i am saying is it a common practice? do people keep this in mind while writing macros?
06:09noncomomg, i mixed up all the names of the variables :D
06:09noncoma tough morning for me, sorry )
06:10noncomsm0ke: yes, this is common. after all, macros is plain clojure code executed to rewrite your original form. it is okay to maintain some computation before you are ready to return the changed form
06:10sm0kecan you point me to some famous library or core macro doing this?
06:11sm0kealso you want (defmacro hail [name] `(let [res# ~name] (println res# res#))
06:12noncomsm0ke: yes, them are pretty common everywhere, like even in the clojure core https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L1579
06:13noncomsm0ke: nope, i mean (defmacro hail [name-producer] (let [res# (name-producer)] `(println ~res# ~res#)))
06:13sm0kenoncom: its not the same thing.. that macro is manipulating the list directly
06:14noncomsm0ke: what about https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L1742
06:14sm0kethere is no expansion
06:14nickenchuggetsI always read Sandra Bullock as Sandra Bollocks
06:14kungiIs anyone using expect-call for mocking and testing if a function is called?
06:14nickenchuggetsoops, wrong channel
06:14nickenchuggets:)
06:14noncom:D
06:15sm0kenoncom: yep thanks
06:15sm0kewhen-let is simpler and ideal example of this
06:15noncomsm0ke: that is actually an essintial part of the macros - define a tiny computation within computation
06:16noncomwell, not always tiny but you get the idea
06:16sm0kethanks for all the help noncom :D
06:16noncomthe macros which return a `(...) right away are simply.. what's the term in english... reduced forms maybe
06:16sm0ke(inc noncom)
06:16noncomyeah yeah :)
06:16noncomthanks!)
06:16clojurebotexcusez-moi
06:19OlajydPlease I’m not really clear with the use of ->> and ->
06:22ddellacostaOlajyd: -> is when you want to push a value through a bunch of functions which take some value as the first argument to the function. ->> is the same but when functions take the value you care about at the end.
06:23ddellacostaOlajyd: both of them are intended to provide more clarity on sequential operations
06:23ddellacostaOlajyd: for example
06:23Olajydhmm
06:23ddellacosta&(-> {:foo "foo"} (assoc :bar "bar") (update :foo clojure.string/reverse))
06:24ddellacostadon't fail me now lazybot
06:24ddellacosta,(-> {:foo "foo"} (assoc :bar "bar") (update :foo clojure.string/reverse))
06:24clojureboteval service is offline
06:24ddellacostaright
06:24ddellacostadid lazybot's trigger prefix change?
06:24ddellacostaanyways, Olajyd, that's rather contrived but hopefully expresses the point
06:25Olajydyeaa
06:25OlajydDefinitely
06:25OlajydThanks ddlellacosta
06:26OlajydThanks ddellacosta
06:26ddellacostaOlajyd: I tend to find -> is quite useful when dealing with maps, whereas ->> is better for operations on other collections, to generalize
06:26ddellacostaOlajyd: sure thing!
06:26ddellacostagotta go, cheers
06:30noncomOlajyd: just to spice up your day: https://github.com/rplevy/swiss-arrows
06:31Olajydlol noncom :)
06:31noncom:D
06:31TEttingerI learned what a swiss arrow is outside of that context today
06:31TEttingersomething like a range extender for a dart
06:32TEttingera heavy arrow with a notch cut in it and a string wrapping the notch
06:33noncomwow
06:33TEttingeralso known as a pathfinder dart it seems
06:34OlajydTEttinger, is (->> (s/split line ";") (map #(Float/parseFloat %))) and (-> (s/split line ";") (map #(Float/parseFloat %))) not the same
06:34TEttingercorrect, not the same
06:36TEttinger,(->> (clojure.string/split "0.0;4e-4;1.2" ";") (map #(Float/parseFloat %)))
06:36noncom-> just puts the previous result on the second place in the next form, and ->> puts it on the last
06:36clojurebot#error {\n :cause "java.lang.String cannot be cast to java.util.regex.Pattern"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to java.util.regex.Pattern"\n :at [clojure.string$split invokeStatic "string.clj" 217]}]\n :trace\n [[clojure.string$split invokeStatic "string.clj" 217]\n [clojure.string$split invoke "string.clj" -1]\n [sandbox$eval26 invok...
06:36TEttinger,(->> (clojure.string/split "0.0;4e-4;1.2" #";") (map #(Float/parseFloat %)))
06:36clojurebot(0.0 4.0E-4 1.2)
06:37TEttinger,(-> (clojure.string/split "0.0;4e-4;1.2" #";") (map #(Float/parseFloat %))) ;; with -> this fails
06:37clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: sandbox$eval80$fn__81>
06:37TEttinger,(macroexpand (-> (clojure.string/split "0.0;4e-4;1.2" #";") (map #(Float/parseFloat %))))
06:37clojurebot#error {\n :cause "Don't know how to create ISeq from: sandbox$eval107$fn__108"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: sandbox$eval107$fn__108"\n :at [clojure.lang.RT seqFrom "RT.java" 535]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 535]\n [clojure.lang.RT seq "RT.java" 516]\n [clojure.core$seq__4116 invokeStatic "core.clj" 1...
06:37TEttinger,(macroexpand '(-> (clojure.string/split "0.0;4e-4;1.2" #";") (map #(Float/parseFloat %))))
06:37clojurebot(map (clojure.string/split "0.0;4e-4;1.2" #";") (fn* [p1__133#] (Float/parseFloat p1__133#)))
06:38TEttingerthat macroexpand shows what -> turns into
06:38TEttinger,(macroexpand '(->> (clojure.string/split "0.0;4e-4;1.2" #";") (map #(Float/parseFloat %))))
06:38clojurebot(map (fn* [p1__158#] (Float/parseFloat p1__158#)) (clojure.string/split "0.0;4e-4;1.2" #";"))
06:38TEttingerthis is more what you want
06:39OlajydNice
06:39TEttingerthe first macroexpand shows that it tries to map using a function, but it isn't given one... (clojure.string/split "0.0;4e-4;1.2" #";")
06:39Olajydgotcha
07:29xenohi, is it a good idea to combine lein with idea?
07:37oddcullyxeno: yo many "idea" we are talking idea intellij?
07:37oddcullyxeno: in that case, you should go with cursive. all that other stuff in the plugin repos of jetbrains is basically deprecated
07:38oddcullywell
07:40xenooddcully: yes
07:40xenoand the la clojure plugin
07:41xenoI notice the leiningen plugin is in version 0.0.3 and not updated in 5 years
07:44oddcullyxeno: i tried half a year ago and half of the things don't work
07:44oddcullyxeno: safe yourself the time and get cursive
07:49cflemingoddcully: xeno: Yeah, the other lein plugin is long dead, and La Clojure is now officially deprecated in favour of Cursive
07:51xenosure... is it actually released? on the web page there's "Archive" and "EAP"
07:52snowell+1 for Cursive. I went way too long not using it
07:52oddcullyno it's not yet released
07:52oddcullybut it works™
07:56xenothat's the important part
08:09xenoyou're sure it works? I tried defining a function now, but it refuses to let me insert the end paranthesis
08:17snowellxeno: That's probably because structural editing is on. I always have that same problem
08:18xenodo you get used to it or do you turn it off?
08:18snowellEdit -> Structural Editing -> Toggle structural editing
08:18snowellI turn it off because I couldn't figure it out. Chances are its really awesome and powerful, but I may never know ;)
08:19xenoI love it in other languages, but there you can override it
08:19xenoin cursive it seems you can't
08:19snowellWell yeah, you can toggle it
08:34cflemingxeno: You can turn it off any time
08:35cflemingxeno: I recommend getting used to it though
08:35xenothen I'll do that - I don't like to settle for half-arsed quick fix compromises :)
08:36cflemingxeno: Some doc (a little outdated) here: https://cursiveclojure.com/userguide/paredit.html
08:38ceruleancitystructural editing is really awesome once you get used to it. It took me a few days of frustration but I’m glad I stuck with it. I always miss it when I use repl now :(
09:13snowellOK fine, you've convinced me to try it again :)
09:14snowellMaybe I'm getting old or something, when I default to hating something just because I don't understand it immediately
09:26neurostormBest video introduction to Clojure?
09:28oddcullyintroduction for whom? boss, management, java devs, ...?
09:29neurostormDevelopers with limited experience.
09:29neurostormLimited development experience.
10:18akabanderSo I'm working on a multilingual project, and just spent a couple of weeks in Python-land.
10:18akabanderIt's true... You can't go home again.
10:18akabanderI FEEL SO DIRTY.
10:19snowellIt could be worse. I'm being forced to write…Javascript
10:20snowellAnd specifically not allowed to use Clojurescript. Such a tease
10:20akabanderOof, that seems like a punitive restriction
10:20galauxHello !
10:21ceruleancityI’m with you right now snowell… feelsbad
10:21galauxHas anyone ever played with clj-gson configuration?
10:21galauxI see there is a example.clj-gson.clj in the git tree
10:21snowellI gave them compelling reasons to use Cljs/Om/Reagent instead of React.js with a crapton of libraries bolted on. They said "That's nice" and then proceeded to dictate just JS
10:22snowellDespite the fact that the POC I showed them that took me 2 weeks to write was ahead of the current prototype that's taken a team a month to do
10:23ceruleancityso what was the argument for just JS?
10:23snowellThat down the line it's easier to find developers that know JS instead of this "small, relatively unknown" technology called Clojure
10:23oddcullylet me guess... everyone knows JS. its easier to find developers?
10:23snowellDINGDINGDING
10:23ceruleancitylol
10:24snowellPlus all the big companies are going this React.js route. "It's not going anywhere"
10:26ceruleancityit “won"
10:26oddcullywell the problem is, to get _good_ JS devs
10:33TMAthe problem is to get any, when you dont want to pay them much
10:36TMAsnowell: if it is any consolation I have been forced to use plain Java instead of Clojure, even though the POC took half day to write offering more functionality than equivalent java POC that took a week to write
10:37snowellI guess it feels OK to know I'm not alone in my suffering ;)
10:50dstocktonits a good opportunity in a way
10:54justin_smithsnowell: and the thing is, in half the time it took them to replicate your work in js, they could have gotten the team up to speed to code at least as fast in clojure as they do in js
10:59snowellIndeed
11:26huaoguoe
11:26huaoguoAnybody here?
11:27MasseRNope, completely empty channel
11:27huaoguoe..
11:28MasseR:)
12:29sgs03I have a list of maps where the values are vectors. How can I merge them so that the values end up as lists of the original vectors?
12:31Bronsasgs03: ({:foo [1]} {:foo [2]}) -> {:foo ([1] [2])} ?
12:32sgs03Bronsa: yes that's what I'm going for
12:32Bronsasgs03: what if there's no common keys? a list of 1 element or just the element?
12:32Bronsa,(apply merge-with list '({:foo [1]} {:foo [2]}))
12:32clojurebot{:foo ([1] [2])}
12:32Bronsa,(apply merge-with list '({:foo [1] :bar [1]} {:foo [2]}))
12:32clojurebot{:foo ([1] [2]), :bar [1]}
12:32Bronsado you want :bar to be ([1])?
12:33sgs03Bronsa: if no common keys, then just one map with all the keys
12:35lumaBronsa, that fails if there are more than two maps with the same key
12:35luma,(merge-with list {:foo [1]} {:foo [2]} {:foo [3]})
12:35clojurebot{:foo (([1] [2]) [3])}
12:35sgs03luma: yes, that's the problem I've been running into using merge-with
12:40Bronsaluma: right, #((if (seq? %) conj list) % %2) should work then
12:40Bronsaa bit ugly
12:40Bronsa,(apply merge-with #((if (seq? %) conj list) % %2) '({:foo [1] :bar [2]} {:foo [2]} {:foo [3]}))
12:40clojurebot{:foo ([3] [1] [2]), :bar [2]}
12:48justin_smith~.
12:48clojurebotNo entiendo
12:49justin_smith~. is justin_smith is having screen problems.
12:49clojurebot'Sea, mhuise.
12:50Bronsa//win 39 is hiredman having irssi problems
12:51sgs03thanks guys
12:57justin_smithheh
13:03BalvedaAnyone using Cursive? For some reason new .cljs files aren't being parsed as such by the IDE
13:04dnolenBalveda: I use it, haven't seen that problem
13:08BalvedaHuh, the problem is only when I try to make a file named components.. weird, fixed
13:24justin_smithBalveda: I assume by fixed you mean "fixed" -- as in working around the problem by not naming the file components.cljs?
13:24BalvedaYes, "fixed" is right
13:24BalvedaI wouldn't dare commit code to Cursive :p
13:27justin_smithI don't think cfleming even makes that easy.
13:28blake_Balveda: I use Cursive. But not much for cljs yet.
13:29akabanderI use Cursive, but just clj so far.
14:19dysfuni've just added cljs support to one of my libraries, but this means that i now list clojurescript as a dependency. i want the library to be usable from both. what's the best way to proceed?
14:22dnolendysfun: [org.clojure/clojurescript "1.7.NNNN" :scope "provided"]
14:22dysfunsorry, what does 'provided' do?
14:24justin_smithdysfun: it says that you don't distribute or propagate the dep, because it is provided by your host / end user
14:24dysfunaha, perfect
14:24dysfunthanks guys
14:29uptowni have an async pub/sub question: if i have subs coming and going all the time, what are my lifecycle responsibilities when a subscriber goes away? do i have to unsub per topic per subscriber or will a publisher see a closed channel and clean up its internals by itself?
14:52devnIs there any way of extracting which functions were used in a HOF like comp? For instance, is there any way to tell that `integer?` and `number?` were used in the function returned by (comp integer? number?)
14:55blake_devn: I don't see how, not without putting some hook in. Like, you could write your own comp that does that. But generically? I'm not sure whom you'd ask.
14:57blake_Or when you'd ask. "Hey, remember that function I just called? What'd I do with it?"
14:57blake_devn: You could try a mocking/stubbing type approach, though.
15:11BalvedaAny ideas how to call a java function from a lein console? I'm getting an exception I'd like to extend
15:11devni suppose i could use metadata
15:11BalvedaRather the exception says to call getNextException to see the cause
15:13blake_Balveda: Sure, just "Class/methodName" for class methods, and (.methodName objectOfClass) for regular object methods.
15:15blake_,(java.lang.String/CASE_INSENSITIVE_ORDER)
15:15clojurebot#object[java.lang.String$CaseInsensitiveComparator 0x33cf5657 "java.lang.String$CaseInsensitiveComparator@33cf5657"]
15:16blake_,(java.lang.String/valueOf 1)
15:16clojurebot"1"
15:16blake_,(.indexOf "abcdef" "c")
15:16clojurebot2
15:40lodin_devn: What's the use case?
15:40jack0Do GSoC students get invited for conferences for free? :)
15:55justin_smithdevn: these questions you ask make me imagine writing code as if you were a secret agent, and using sneaky methods to extract information from your caller
15:56justin_smithdevn: actually, in some cases, literally "sneaky methods"
15:59amalloyjustin_smith: d'ye see these footprints here? and this broken branch? a sure sign there's an integer? about in the underbrush
15:59justin_smithhaha
15:59justin_smith(inc amalloy)
16:03sdegutisIs it a best practice to avoid function composition (using comp or similar) for functions you might want to redefine at runtime, and rather call it on an anonymous function?
16:07troydmany vim users here who would like to test drive a plugin I'm working on?
16:08troydmanyway here is a plugin https://github.com/troydm/hiparen.vim just load it and then open any clojure source code and disable syntax highlighting by pressing :set ft= and try navigating parens in normal/insert mode
16:09troydmif anyone is knowleadgeable enough to suggest me how to make it work with syntax on will be help me a lot
16:11oddcullytroydm: could you elaborate on how this differs from `showmatch`?
16:12troydmoddcully: it highlights paren entirely even if the cursor is not on a matching paren
16:14justin_smithsdegutis: for runtime redefinition during dev, it should suffice to put it in a var (rather than using a lexical capture / closure), for production a) why? b) better to use an atom or something I would think
16:14sdegutisjustin_smith: I think the migration to Components will make this problem almost entire entirely go away, yeah.
16:15justin_smithsdegutis: that's almost not a non-sequitor, sure
16:15sdegutisjustin_smith: But even then, the way Compojure's defroutes works isn't compatible with redefinitions by default.
16:15justin_smithyeah, part of why I prefer to use a router that works more directly with regular data
16:16sdegutisI'm trying to figure out what else I need to take into account though. For example sometimes I have pretended a little too far that Clojure is Haskell, defining functions like (def f (comp g h)) which isn't friendly to redefining g or h inside CIDER.
16:17justin_smithyou just need to re-evaluate the def when you do it
16:17justin_smithunless your f is captured, which means you need to pass #'f instead of course
16:18justin_smithsdegutis: or maybe (comp #'g #'h) would be the secret sauce
16:18justin_smithI don't think I like that, but I think it would work
16:18justin_smithhrmph
16:19toluHi
16:19sdegutisjustin_smith: I don't like it either because it assumes REPL development by default rather than Production use by default.
16:19justin_smith,(do (def f inc) (def g inc) (def h (comp #'f #'g)))
16:19clojurebot#'sandbox/h
16:19justin_smith,(h 0)
16:19clojurebot2
16:19justin_smith,(def f dec)
16:19clojurebot#'sandbox/f
16:19justin_smith,(h 0)
16:19clojurebot0
16:19justin_smithit works!
16:19sdegutisRight.
16:19sdegutisWhy wouldn't it?
16:20toluPlease I would like to conjoin multiple elements into a vector at the same time.
16:20sdegutistolu: then do so
16:20toluI did this:
16:20justin_smithsdegutis: I don't know, maybe I'm just hungry for external validation today
16:20tolu(map (fn [row] (conj row ["6" "7"])) [["1" "2" "3"] ["4" "5"]])
16:20sdegutistolu: see (doc conj)
16:20sdegutisjustin_smith: :P
16:20toluand got thi: (["1" "2" "3" ["6" "7"]] ["4" "5" ["6" "7"]])
16:20justin_smithtolu: use into, or apply conj which is basically equivalent
16:20blake_justin_smith: You're good enough. You're smart enough. And gosh darnit, people like you.
16:20justin_smith(inc blake_)
16:21toluI would like my result like this: ;;=> (["1" "2" "3" "6" "7"] ["4" "5" "6" "7"])
16:21justin_smith,(map (fn [row] (into row ["6" "7"])) [["1" "2" "3"] ["4" "5"]])
16:21clojurebot(["1" "2" "3" "6" "7"] ["4" "5" "6" "7"])
16:21sdegutis(map (fn [row] (conj row ["6" "7"])) )
16:21sdegutisOops wrong button.
16:22justin_smith,(map (fn [row] (conj row "6" "7")) [["1" "2" "3"] ["4" "5"]])
16:22clojurebot(["1" "2" "3" "6" "7"] ["4" "5" "6" "7"])
16:22justin_smithtolu: so you have a couple options there
16:22sdegutis,(-> [["1" "2" "3"] ["4" "5"]] (apply conj ["6" "7"]))
16:22clojurebot#error {\n :cause "Wrong number of args (3) passed to: PersistentVector"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (3) passed to: PersistentVector"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 40]\n [clojure.lang.AFn applyToHelper "AFn.java" 160]\n [cloj...
16:22toluthanks
16:22justin_smithsdegutis: I think you wanted a map and a ->> in there
16:22sdegutisOh yeah oops.
16:22sdegutisI'm slow today.
16:22sdegutisJust finished today's work, woo! Now to get a head start on tomorrow's work.
16:23blake_OK, I have functions f and g, and I want to do this "while f collect g". The thing is, f may raise an exception, at which point I need to call h, but not stop the loop. So, something like -> (try (if (f) (collect (g)) (catch Excepion e (h)))
16:24sdegutisblake_: (doc take-while)
16:24sdegutis(take-while f g)
16:24blake_sdegutis: Yeah, I looked at take-while...but what about h?
16:24sdegutisOh yeah ugh, exceptions.
16:24sdegutisblake_: what do you need to do with h?
16:24sdegutisblake_: use it in place of f when f throws?
16:25sdegutis(let [f2 #(try (f) (catch Exception e (h)))] (take-while f2 g))
16:25jack0Do GSoC students get invited for conferences for free?
16:26blake_sdegutis: OK, I was sort of headed that way.
16:26justin_smithjack0: couldn't hurt to ask for such an invite, puredanger might have more info
16:26blake_So, simplify the function so I can use take-while. Lemme see.
16:27sdegutisSure.
16:27jack0puredanger: Any info?
16:28justin_smithjack0: this being IRC, you might have to wait a while for a reply
16:28jack0Sure
16:28jack0justin_smith :)
16:28blake_sdegutis: OK, I think the other part of the problem is that (h) is not guaranteed to ensure the success of (f) on the next call.
16:28sdegutisblake_: so you want to quit-out when you get (h)?
16:29cflemingjack0: You could also send email, I think events@cognitect.com is the address you want
16:29blake_sdegutis: No. It's a DB read where the records may be bad. Multiple records in a row may be bad, but they should be skipped.
16:29blake_(And skipping might take you to the end.)
16:30sdegutisblake_: sounds like you also want filter then
16:31sdegutisblake_: I would use map and filter here -- map to call the db-function on the thing and return maybe a map including a status and a db result, and filter to remove ones with invalid status
16:31sdegutisblake_: in some cases you can simplify it and just return nil when the db-value returned from (f) will always be non-nil and non-false, and then just do (remove nil?) on the resulting coll to get rid of bad entries
16:31blake_sdegutis: OK, cool. Just wanted to make sure I wasn't overcomplicating.
16:32sdegutisblake_: but in other times, a simple map works, like {:ok db-value} or {:error error-string}, and then when you're done, (filter :ok) and then (map :ok) to get the db-values
16:33sdegutisblake_: don't take my word for it, I may be overcomplicating it too; a lot of it depends on your problem domain
16:33sdegutisblake_: are you using datomic?
16:33blake_sdegutis: Monger.
16:34blake_sdegutis: It's got this great thing to download everything as a map, but an exception in the Java just stops it cold.
16:35sdegutisOh cool. That sucks tho btw.
16:37blake_sdegutis: Yeah, I'm not crazy about...any of it. Heh.
16:38sdegutisMaybe you can use Datomic? We switched from MongoDB to Datomic a few years ago and it's great.
16:38sdegutisWe've got a low load though, so we're only using Datomic Free, which I'm not entirely comfortable with but it seems to be working fine.
16:38blake_sdegutis: I'd be willing to push it. Any good starting references?
16:39blake_sdegutis: Oh, hell, this mongo stuff is paltry. I'm not convinced of its applicability for high volume. I'd probably store this stuff in text files, frankly.
16:39blake_But I'm weird.
16:39sdegutisI just don't like how MongoDB locks the whole database on /every query/.
16:39sdegutisMaybe that's changed since I used it but I doubt so.
16:40sdegutisblake_: Sorry, I don't have any references off hand. Ask in #datomic or https://clojurians.slack.com/messages/datomic/
16:41blake_sdegutis: Cool. I'll check it out. =)
16:49sdegutisThis is so exciting! I'm writing an immutable recursive descent parser and lexer that keeps track of file line/char positions and has decent and informative error handling!
16:53blake_Neat.
16:57Balveda-2I'm getting this error on a response (I suppose), after making a successful entry into a DB
16:57Balveda-2http://pastebin.com/8Kwvi9md
16:58Balveda-2I haven't touched the middleware, it's more or less a standard luminus app
17:52sdegutisIs it possible to destructure several levels of {:keys} ?
17:52sdegutisI don't even know what that syntax would look like.
17:56gfrederickssdegutis: maybe not what you're imagining, but you can do nested destructuring
17:56sdegutisYeah that is basically it.
17:56gfrederickssdegutis: plumbing.core/{fnk,letk} is a bit more readable for that
17:57gfredericks,(def my-data {:foo {:bar 12}})
17:57clojurebot#'sandbox/my-data
17:57gfredericks,(let [{{:keys [bar]} :foo} my-data] bar)
17:57clojurebot12
17:57sdegutisSo if I have {:foo {:bar [1 2 3]}} then I know I can do (let [{:keys [foo]} m]) but I dunno how to get foo to destructure :bar inside the same {}.
17:57sdegutisOh I see how you did that.
17:57sdegutisYou used the non-:keys way.
17:57gfredericksyeah you have to fallback to non-:keys
17:57sdegutisHaven't seen that way in ages.
17:58sdegutisI like it.
17:58gfredericksit comes up from time to time
17:58sdegutisThanks g-fred
17:59gfredericksnp
18:11sdegutisI really like this state machine. It's just built in plain old clojure.core functions but it feels like the most flexible and expressive thing ever.
18:32robstoryhi clj friends. looking at http://kotka.de/blog/2010/03/proxy_gen-class_little_brother.html
18:33robstoryare there any current workaround for the proxy multi-arity issue?
18:33robstorye.g. I need to proxy two arities, and have proxy-super call the other
18:33robstoryreasonably sure the implementation of proxy-super makes this impossible, but wanted to confirm
19:33ben_vulpesdoes anyone use cider for simultaneous clojure+script work?
19:34ben_vulpesthe question i'd like to answer is if it's possible to host my nrepl in the browser or if i must connect the browser repl to a process running on the dev machine.
19:41justin_smithben_vulpes: afaik clojurescript repls use an http server plus a websocket connection, and none of them directly implement nrepl (which is a more general tcp based protocl)
19:42justin_smithben_vulpes: for starters, how would you listen for connections on an arbitrary port without this being a huge security hole in the browser?
19:45justin_smithben_vulpes: though, now that cljs has some limited self-hosting, you could eg. connect a repl to a websocket (but this would not be nrepl, though you could make a websocket to tcp bridge as a shim)
20:22ben_vulpesblee
20:22ben_vulpesokay okay
20:22ben_vulpesthank you justin_smith
20:23ben_vulpes(although the counterargument is that the browser itself *is* a security hole, but let's let that one lie)
20:23ben_vulpesyou are full of wisdom as always
20:23justin_smithI'm just saying listening to connections on a random port is more blatent than any other messed up thing we let browsers do
20:23justin_smithhaha, I try
20:40fireplaceHelphello clojure people. i'm confused about nrepl behaviour when using "vim-fireplace". i start a repl in some terminal, then i connect to it in vim, and i can evaluate expressions *in vim*. but i can't use those definitions in the terminal repl
20:41fireplaceHelpi.e. it doesn't seem to be using the same session?
20:41fireplaceHelpor do i totally misunderstand how this should work?
20:41ben_vulpesfireplaceHelp: are you switching into the correct namespace in your re
20:41ben_vulpesrepl*
20:41ben_vulpes?
20:41fireplaceHelphmm...
20:41fireplaceHelpno.
20:41justin_smithyeah, probably a question of what ns you are in
20:42justin_smith(doc in-ns)
20:42clojurebot"([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."
20:42justin_smithfireplaceHelp: (in-ns 'your.ns) ; as long as it's been loaded at least
20:42fireplaceHelpbrilliant.
20:43fireplaceHelpworking now.
20:43fireplaceHelphow stupid of me
20:43fireplaceHelpthanks!!
20:44justin_smithfireplaceHelp: the only stupid questions on #clojure are the ones sdegutis asks, and he's doing it on purpose
20:54ben_vulpesjustin_smith: look i can be useful too
20:55justin_smith:)
21:00LelandAero_hello
21:26bltAnyone have an example of using enlive templates in a jar?
21:26justin_smithblt: in general the trick to using things packed in your jar is use io/resource instead of io/file
21:27justin_smithor (slurp (io/resource "relative/path")) instead of (slurp "the/whole/path")
21:43bltjustin_smith: it's funny, (io/resource "relative/path") works great when I am just running my server from the repl. When I try to run it from the jar, when i hit the url, it prompts me to download a zero byte BIN file.
21:43blti can replicate it on heroku as well as locally
21:44justin_smithblt: is the file in your jar? in order to end up in an uberjar it has to be in a directory that is on the resource-path
21:45bltthe template files live in resources/client/...
21:45justin_smithso you are doing (io/resource "client/...")
21:45simon1234Hi all! I'm using a ThreadLocal with a threadpool and with core.async go (no green thread only >!! <!!). And at one point, it seems that some ThreadLocal var get reused in some way but by a different thread (checked by (.getId (Thread/currentThread)) + I think I clear the ThreadLocal var (but this is not even the same thread). Not sure I made myself clear, but how such a behaviour could be made possible? Thanks...!
21:45bltjustin_smith: yes i am
21:45justin_smithsimon1234: threadlocals do not work with core.async
21:45simon1234justin_smith: even with <!! and >!! ?
21:46justin_smithyou meantioned go
21:46simon1234yeah
21:46justin_smithinside go, threadlocals are liable to break
21:46justin_smithand to end up being accessed by other go blocks
21:46simon1234justin_smith: I'm not using a threadlocal myself but slf4j is (with the logging context)
21:47simon1234and in my test I get weird errors from times to times
21:47justin_smithsimon1234: perhaps you can move the sl4j calls outside of the core.async context, by making a normal thread that loops and does a blocking read from a channel
21:48justin_smithbecause things that use threadlocals will do weird things inside go blocks, there's not much you can do to prevent that, because of how core.async allocates and re-uses threads
21:50blthow might I inspect a the jar file that is created with uberjar? I'd like to explore the resources
21:50TEttingerit's actually just a zip
21:50TEttingerwith a fancy file extension
21:51justin_smithblt: it's a zip file, you can use the jar command too (works much like *nix tar)
21:51bltTEttinger: oh, well then
21:51justin_smithalso, you can use the gnu version of the tar command with jar files too
21:51TEttingerI usually use 7zip for inspecting things that may or may not be archives. plus 7zip can compress things to outrageously tiny archives in some cases
21:52justin_smithalso emacs and vim can open jars as if they were folders
21:54bltthanks
21:58bltjustin_smith: so, when I explore the jar file, I see my "client/..." in the root of the jar. But I still get that zero-byte file download prompt when I hit "/" of my app
21:59justin_smithblt: do you see the actual template file?
21:59justin_smithmaybe there's an issue with your routes - are you using wrap-file middleware?
21:59bltthe template file for "/" is client/index.html and it's listed in the jar
21:59justin_smithbecause if you are using wrap-file you need to turn that into wrap-resource
21:59bltjustin_smith: negative
21:59justin_smithOK
22:00blti don't seem to be using wrap-resource eigher
22:00blteither*
22:00simon1234justin_smith: oh thanks a lot, sorry I got carried away
22:00justin_smithso client/index.html is there, and you are able to do (slurp (io/resource "/client/index.html")) but only from the repl not the jar?
22:00simon1234ah yeah so it reuses thread in some way, what is weird is that the thread id does change
22:01justin_smithsimon1234: that is odd - but core.async definitely has a fixed pool and recirculates the threads, so I wouldn't be surprised by odd things happening when a lib tries to do things based on threadlocal bindings
22:01bltjustin_smith: (slurp (io/resource "client/index.html")) works in the repl
22:02justin_smithoh, I might have been wrong about using the leading slash
22:03bltoh well, close enough.
22:04bltbut yeah, i have to use (template (io/resource "client/index.html")), leaving out the slurp for enlive to work
22:04bltbut that doesn't work when i generate a jar
22:04justin_smithright, slurp was just an example of a thing that requires the valid resource
22:05bltgotchya, yep it's valid
22:05justin_smithblt: what about (slurp (io/resource "clojure/set.clj"))
22:05justin_smith(from the jar)
22:05justin_smithjust random example of a file that will be there if clojure is
22:06bltjustin_smith: i'm sorry but I'm actually not sure how to run the repl from the jar
22:06justin_smithblt: java -cp your-jar.jar clojure.main
22:06bltthanks
22:06justin_smithfor bonus usability rlwrap java -cp ...
22:07justin_smithalso you may be able to narrow down how to use the resource with the template
22:07justin_smithblt: could it be that the template function requires (io/input-stream (io/resource "your/template.html")) and instead of erroring just returns an empty string?
22:07justin_smithbecause some things refuse to use a resource directly and need you to do the input-stream conversion
22:08justin_smithor io/reader (if it's not input stream)
22:08justin_smithyou can easily try all these from that jar repl
22:08blti'm happy to try both out
22:22bltjustin_smith: i attempted both io/input-stream and io/reader but still get the zero-byte d/l prompt
22:22justin_smithblt: what about directly using the template function from the repl
22:23justin_smithseems like you would get quicker feedback on what happens / what goes wrong
22:25bltjustin_smith: when I try to start the repl I get "could not find or load main class clojure.main"
22:26justin_smithuhh - make an uberjar
22:26justin_smith(or make sure you are using the uberjar)
22:28bltah, I guess it generated two jars and one of them works. but when I (in-ns 'my-ns) and try the template fn I get unable to resolve symbol, sigh
22:28justin_smithblt: you need to require your code
22:29justin_smithblt: (require 'my.ns) (in-ns 'my.ns)
22:29justin_smithafter using in-ns without require you need to do (require 'this.ns :reload)
22:29bltjustin_smith: thanks, sorry I'm a noob when it comes to the jar stuff
22:29justin_smitherr
22:30justin_smith(clojure.core/require 'this.ns :reload)
22:30justin_smithblt: it's OK, I forget that other people don't know the underlying stuff their tooling uses
22:31justin_smithblt: but don't worry, it's not that thick a layer between the tools you are used to and what clojure can do on its own
22:31bltjustin_smith: well, (template "client/build/index.html") actually does the correct thing
22:31justin_smithblt: you might need to try this from a different directory?
22:31justin_smithsince it will be looking in the current dir right?
22:32justin_smithor no, wait
22:32justin_smithso the whole resource thing was a boondoggle, there is some other problem?
22:32bltjustin_smith: it would seem so i guess
22:33bltboondoggle, nice
22:36bltthis is some of the code: https://www.refheap.com/327cfbe43e923bf58c6c1fb48
22:39justin_smithblt: that "or" call on line 29 is weird
22:39justin_smithyou know it will always return the first branch, right?
22:40bltfrick, you're right
22:40bltand i'm trying to get into that second case
22:40justin_smithyou probably wanted an if-let there
22:40justin_smithor something
22:40bltbefore they used to be io/resource wrapping the str calls
22:40justin_smithahh, then the or would make sense
22:42simon1234justin_smith: so thanks a lot for your input, I removed core.async. No more problem, this is quite dangerous :s Thanks a lot!
22:43justin_smithsimon1234: you could probably find a way to segregate the slf4j stuff from the core.async
22:44simon1234justin_smith: hopefully, but well for now that will do it, I was only relying on core.async for test purpose. Thanks :)
23:06bltjustin_smith: yeah, definitely seems like it's further up unfortunately
23:08bltpretty frustrating that it works when running from the repl but not jar sigh
23:11bltmy goal is to get a jar that heroku can run
23:26bltjustin_smith: thanks for the input amigo. i guess i'm going to keep trial and erring and see if i can get it
23:59nowprovisionrefactoring a function, my first attempt was pretty poor (having not touched clojure for a few months), v2 seems cleaner, but still seems wrong to take 100 and then do last? any thoughts https://www.refheap.com/109420