#clojure logs

2015-07-21

00:02crocketI just looked at lazybot code, and it doesn't provide a sandboxed environment for plugins.
00:02justin_smithcrocket: it has a sandboxed eval
00:03justin_smith&(System/exit 0)
00:03lazybotjava.security.AccessControlException: access denied ("java.lang.RuntimePermission" "exitVM.0")
00:03crocketHowever, developers will only accept plugins in the 'core' if it doesn't go beyond the boundary of a plugin.
00:23kavkazAfter using the REPL I feel like putting a right bracket after every sentence I type
00:23kavkazwhether it be IRC or SMS on my phone
00:27rhg135(like this)
00:29kavkazrhg135: yes
00:30kavkazIn some example code in a book about clojure, I'm seeing the character & being used like this: &{}
00:30rhg135(not (ready-for? world this))
00:30kavkazwhat does this mean?
00:30kavkazI know #{} is a set literal
00:30kavkazbut what does & mean in this context?
00:30kavkazI couldn't find the character on the clojure cheat sheet.
00:31rhg135De structuring
00:31justin_smithkavkaz: ##((fn [&{a :a}] (inc a)) :a 1)
00:31lazybot⇒ 2
00:31justin_smith& indicates that all following arguments are collected
00:31lazybotjava.lang.RuntimeException: Unable to resolve symbol: indicates in this context
00:31justin_smith:P
00:32justin_smithand &{ ... } means it will be collected into a key/value hash map
00:32rhg135lazybot: disappointed
00:32justin_smithmost people advise against using &{} actually
00:34crocketclojure 1.7 has new features like transducers, reader conditionals, warn on boxed math, update, and run!.
00:36rhg135I'm excited for 1.8
00:41kavkazjustin_smith: Thank you, I'm starting to get it
00:41kavkazI've started clojure and functional programming a couple days ago, so it's taking some careful looking at
00:41kavkazjustin_smith: Why do most people advise against it?
00:42kavkazIt's just a map right?
00:42justin_smithkavkaz: a common thing to do in clojure is write a function that takes the same args, does some work, then calls the original function
00:42kavkazsorry hashmap
00:42justin_smiththis is harder to do with & {}
00:43justin_smithso, unless the usual usage of & (where you can use apply), you are stuck building the call by hand, or writing "mapply" or something
00:43justin_smithit's inconvenient
00:44kavkazjustin_smith: How would you do the example code you showed me without &{}
00:44kavkaz?
00:44kavkazI'm just curious because I'm new to clojure
00:45justin_smith,((fn [{a :a}] (inc a)) {:a 41})
00:45clojurebot42
00:45justin_smithin this case, the args are in an actual explicit hash-map
00:46justin_smithwhich means that you can use the hash-map to modify the args before calling the original (if you were extending it somehow)
00:48kavkazjustin_smith: Okay, I see, thank you
00:48kavkazI'll just have to keep coding and reading this book and the documentation lol
00:54kavkazjustin_smith: Oh actually, I've been looking at & in the context of the parameter vector
00:54justin_smithkavkaz: yes. That's where it is used.
00:55kavkazOh true
00:57crockethttp://blog.cognitect.com/blog/2014/8/6/transducers-are-coming
00:57kavkazwell in the example it was [a b & { <map> }
00:57crocketjustin_smith, Can you tell me more about sandboxed eval?
00:58kavkaz[a b & { <map> }]
00:58justin_smithkavkaz: sure, same as the other examples, except the a b part
00:58justin_smithcrocket: I'm about to turn in for the night actually
00:59kavkazAfter reading some documentation i thought the use of the ampersand in this case was [a b & more]
00:59crocketclojail
00:59justin_smithkavkaz: the a and b are optional
00:59kavkazwhere more would be Nil if the passed parameters were only a and b
00:59crocketIt uses clojail.
00:59kavkazbut anyways I'll keep looking into it
00:59kavkazthank you justin_smith
00:59justin_smithand "more" is handled differently if it's a hash-map
01:03kavkazgood night guys
01:04crocketclojail is messy.
01:04crocketIt requires ~/.java.policy
01:07tolstoyIs there an implementation of the ~ operator in Clojure somewhere?
01:08tolstoybit-complement?
01:10TEttingertolstoy: the bit-??? fns do pretty much everything bit-related. Do you mean ~ in... which language?
01:10tolstoyPython.
01:10TEttingerwhat does it do in Python? I'm not a python guy
01:10tolstoyBasically, swap all 1 bits for 0 bits.
01:10TEttingerah
01:10TEttingeruh
01:10TEttingerhang on
01:11tolstoyI'm porting some code, so that's what's catching me up.
01:11TEttingerthat seems not very handy, unless it takes more than one arg
01:11tolstoyIf I knew the exact size of the integer, I could just use bit-flip.
01:11TEttinger,(bit-and 0 15)
01:11clojurebot0
01:11tolstoyseed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B)
01:12TEttingerdoes it also swap all 0 bits for 1 bits?
01:12tolstoyI think so.
01:12tolstoyhttp://stackoverflow.com/questions/791328/how-does-the-bitwise-complement-operator-work
01:13tolstoyOh. bit-not, maybe?
01:13TEttingerbit-not yeah
01:13TEttinger,(bit-not 8)
01:13clojurebot-9
01:14tolstoyPython: ~2 -> -3
01:14TEttinger,(bit-not -2r1000)
01:14clojurebot7
01:14tolstoyClojure: (bit-not 2) -> -3
01:14tolstoy,(bit-not 2)
01:14clojurebot-3
01:14TEttingerwoo
01:14tolstoyGood enough to continue the struggle.
01:14TEttingerthe 2r thing is handy in case you haven't used it
01:15tolstoyWhat is it?
01:15TEttingerr for radix, it's base 2 literal
01:15TEttingeryou can actually use any radix from 2 to 36
01:15TEttinger,2r101101
01:15clojurebot45
01:15TEttinger,36rFUNZILLA
01:15clojurebot1242216307918
01:16tolstoySo, give me the base 2 number 101101?
01:16tolstoyAnd then the printer prints it in base 10.
01:17tolstoyThat is very handy.
01:17tolstoy,16rFFF0
01:17clojurebot65520
01:18crocketIt feels like a huge mistake to make namespace mutable.
01:20TEttingertolstoy: if you want to print in base (2 to 36), do ##(Long/toString 1242216307918 36)
01:20lazybot⇒ "funzilla"
01:20TEttingertolstoy: if you want to print in base 2, do ##(Long/toBinaryString 1242216307918)
01:20lazybot⇒ "10010000100111001110111001001110011001110"
01:23crocket,(println "say bitch")
01:23clojurebotsay bitch\n
01:25crocketHow do I sandbox arbitrary code without ~/.java.policy?
01:27TEttingerI think the contents of java.policy can be added programmatically
01:36crocketIs into lazy by default?
01:39crocketListen to one of rich hickey's greatest videos. https://www.youtube.com/watch?v=6mTbuzafcII
01:58bjainto is strict
02:00bjaerr, eager
02:36namrasomeone using metrics-clojure-ring and can tell me what the rates mean for handling-time.METHOD events?
02:36namrathe rate of requests/s for that method over 1/5/15min?
04:42crocketIt feels as if eduction is similar to sequence.
05:14crocketMan, it is difficult to understand transducers...
05:18kungiDeraen: Ping! Could you help me for a second with my compojure.api code. I upgraded to compojure api 0.22.1 and tried the upload. But now I get the following error: No method in multimethod 'restructure-param' for dispatch value: :multipart-params
05:19kungiDeraen: For some reason the multimethod definition from compojure.api.meta is not loaded?
05:29crocketDoes anyone know a decent transducer learning material?
05:52crocketOk, map returns a transducer. A transducer is passed another transducer or a reducing function to create another reducing function.
05:52crocketfn in fn in fn
05:55crocketThis is a brain massage.
06:05sandbagsIs there anyone who can help me with lein-wsimport (yes may god have mercy on my soul, SOAP) and a problem I am having enabling external scheme (error 'chema_reference: Failed to read schema document 'xjc.xsd', because 'file' access is not allowed due to restriction set by the accessExternalSchema property'). I've tried specifying :jvm-opts ["-Djavax.xml.accessExternalSchema=all"] in my project.clj which is - i think - the right way
06:05sandbags to solve this but no dice. Help!
06:06sandbagsproject.clj & full error here https://gist.github.com/mmower/78a1b440ffce7035832b
06:10sandbagsi wonder if the problem is that wsimport is not being run with the jvm options... i've no idea how that bit works
06:21sandbagslein-wsimport is calling WsImport#doMain so, presumably, will inherit JVM opts so this should work
06:30sandbagsfrak... according to (System/getProperty "javax.xml.accessExternalSchema") it is set to "all" ... :-(
06:30sandbagssorry for the stream of consciousness... obv nobody here with any insight into wsimport and probably (just as I would have been) little interest :)
06:31crocketCan anyone help me understand transducer step arity?
06:31crocketWhen is it called?
06:33crocketAh
06:33crocketok
06:33crocketCompletion arity in transducer feels like a boiler plate, doesn't it?
06:43crocketI think I found a bug in completing.
06:43crocketcompleting doesn't add 0 arity to a reducing function.
06:44crocketsdg
06:44crocket-
06:50crocketOuch
07:59diyfupecoIs there a way to automatically load new code when something changed on disk?
08:00diyfupeco(using leiningen)
08:05crocketIs it ok to not define a 0 arity in a transducer?
08:06wasamasadiyfupeco: environments like figwheel do that kind of thing
08:06crocket,(doc completing)
08:06clojurebot"([f] [f cf]); Takes a reducing function f of 2 args and returns a fn suitable for transduce by adding an arity-1 signature that calls cf (default - identity) on the result argument."
08:07justin_smithoh, that's very nice
08:07crocketcompleting is not going to work because a transducer requires a 0-arity signature.
08:08crocketI understand completing as a way to convert a reducing function into a transducer.
08:09justin_smithit addresses the common case where you have an accumulator that holds things other than your result, to simplify getting the part of the accumulator you actually want in the end
08:10crocket???
08:10lazybotcrocket: How could that be wrong?
08:11justin_smithcrocket: often when I use reduce, the accumulator holds other values along with the actual result
08:11justin_smithso I end up needing another function which gets the part I actually want out of the accumulator at the end
08:14crocketWhat is the accumulator?
08:14crocketYou mean the reducing function?
08:14justin_smith,(reduce (fn [[runs run] v] (if (= v (peek run)) [runs (conj run v)] [(conj runs run) []])) [[] []] [:a :a :b :b :b :b :c :c :a :d :d])
08:14clojurebot[[[] [] [] [] [] ...] []]
08:14justin_smitherr
08:15justin_smithcrocket: the first arg to the reducing function is the accumulator
08:15crocketok
08:15crocketinitial value
08:15crocketAnyway, a transducer created by completing won't serve as a general transducer.
08:16crocketI am not sure when the 0-arity signature is used in a transducer.
08:16justin_smith ,(reduce (fn [[runs run] v] (if (= v (peek run)) [runs (conj run v)] [(conj runs run) [v]])) [[] []] [:a :a :b :b :b :b :c :c :a :d :d])
08:16clojurebot[[[] [:a :a] [:b :b :b :b] [:c :c] [:a]] [:d :d]]
08:17justin_smiththat needs a final step, where [:d :d] is conj'd on the end
08:18crocketYour example is hard to read.
08:21crocketjustin_smith, Can you tell me when the 0-arity signature is used in transducers?
08:35justin_smithcrocket: it is mentioned by the doc string for transduce
08:36justin_smith,(transduce identity (completing (fn [[runs run] v] (if (= v (peek run)) [runs (conj run v)] [(conj runs run) [v]]))) [[] []] [:a :a :b :b :b :b :c :c :a :d :d])
08:36clojurebot[[[] [:a :a] [:b :b :b :b] [:c :c] [:a]] [:d :d]]
08:38justin_smithcompleting adds a 1-arg arity
08:39justin_smithcrocket: I don't know where this 0-arg is that you are talking about
08:39crocket,(doc transduce)
08:39clojurebot"([xform f coll] [xform f init coll]); reduce with a transformation of f (xf). If init is not supplied, (f) will be called to produce it. f should be a reducing step function that accepts both 1 and 2 arguments, if it accepts only 2 you can add the arity-1 with 'completing'. Returns the result of applying (the transformed) xf to init and the first item in coll, then applying xf to that result and ...
08:39crockettransduce avoids using 0-arity signature.
08:39justin_smithwhere is the 0 arity signiture you keep mentioning?
08:39crocketBy calling (f) directly.
08:40crocketjustin_smith, http://clojure.org/transducers#toc8
08:41justin_smithcrocket: OK. It's used to create an initial value for the transduce when none is explicitly supplied. Like it says.
08:41crocketjustin_smith, https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L7323
08:42kwladykaWhat about sets performance vs vectors?
08:42kwladykaadd/remove first/last positions
08:42crocketjustin_smith, https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6566
08:42justin_smithkwladyka: sets do not have a "first" or "last" position
08:42justin_smithkwladyka: they are not ordered
08:43justin_smithcrocket: like I said, the docs are clear now that you link them, it creates the initial value for transduce
08:43kwladyka,(first #{1 2})
08:43clojurebot1
08:44justin_smith,(first #{1 2 3 4 5 6 7 8 9 10})
08:44clojurebot7
08:44justin_smithfirst will return a value, it will not return the first item, because there is no such thing
08:44kwladykaso when i will use it with loop and recur and use first and rest it will work or not?
08:44justin_smithdefinitely not, no
08:45kwladykaso bad
08:45justin_smithI mean maybe by accident, depending on what you are trying to do...
08:45justin_smithbut you can't count on any particular item being the first without relying on implementation details
08:45Wild_Catkwladyka: if you want to iterate on the entire contents of a set, use map
08:45justin_smithkwladyka: actually, first and rest should split one item off...
08:46kwladykabut... if first always return the same element (not exactly first) rest should return always the rest?
08:46justin_smithyes, that's true
08:46crocketThe doc forgot to mention that completing also adds 0-arity signature.
08:46justin_smiththe order is just weird and undefined
08:47kwladykai don't care about order too much, but i guess performance of sets should be as good as vectors?
08:47justin_smiththey are slower
08:47crocketI think completing should be used as (partial completing f) since cf is the reducing function.
08:47kwladykado you know any statistic? I can't find information liek that
08:48Wild_Catkwladyka: sets are O(1) for insertion, but with a higher constant than vectors
08:48Wild_Catkwladyka: if you don't explicitly care about the uniqueness constraint, a set will be slower than a vector
08:49kwladykaanyway... i will do algorithm and if it will be to slow i will change data structure
08:49justin_smithkwladyka: runnint criterium now, will share the results when done
08:50crocketNow, completing doesn't seem to make a valid transducer.
08:50Wild_Catthat said, the fact that you struggle with understanding the very basic performance profiles of these data structures tells me that you're not writing something performance-critical enough to care about the difference. Just use whatever is the most logical for your use case and disregard the performance aspect.
08:51kwladykaWild_Cat, but it is always good occasion to learn something more, like a basic performance :)
08:52justin_smithvectors are about 10x faster for appending https://www.refheap.com/106778
08:53kwladykai also see very good side of not mutable data, all things should take less memory
08:53kwladykajustin_smith, thank you
08:56justin_smithit's really sad that I can tell from the noise floor on my monitors when criterium is done running
08:56justin_smithhaha
08:56justin_smithwhen the CPU is not working as hard the timbre changes
08:58justin_smithkwladyka: paste updated, the ratio gets closer with smaller collections (because some of the shared constant time costs become a bigger part of the resulting runtime I guess) https://www.refheap.com/106778
09:37crocketjustin_smith, I figured out that completing is not meant to produce a transducer.
09:37crockethttps://groups.google.com/forum/#!topic/clojure/6cnVMUe5ALE
09:39crocketThis is really ugly.
09:39diyfupecothanks wasamasa
09:41crocketIs there a macro for writing a transducer concisely?
09:42crocketor a function for doing so?
09:43snowellcrocket: Leaving out the final argument to a sequence function call (map, filter, etc) returns a transducer
09:43snowellYou can comp transducers together to create one that does multiple things
09:46crocketsnowell, Is there a transducer that drops key-val pairs with nil vals in a map?
09:47snowellI would think (remove #(nil? (val %))) should work
09:49snowellHeh, or even better… (filter val)
09:49snowell,(filter val {:a 1 :b 2 :c nil :d 4 :e 5 :f nil})
09:49clojurebot([:a 1] [:b 2] [:d 4] [:e 5])
09:50snowellIf you want it to be a map, which of course you would, you could (comp (filter val) (into {}))
09:54crocketsnowell, On https://www.refheap.com/106782 , I rewrote assoc-in-cond2 as assoc-in-cond with transduce.
09:57snowellAnd it's not working?
09:57crocketIt does work.
09:57crocketCan you think of a more concise way to write assoc-in-cond?
09:58crocketsnowell, ^^
09:59crocketI think the function in completing could be written more conscisely.
09:59snowellI'm a relative newb compared to others here, so no I can't :D
10:00snowellI doubt I'd have gotten it THAT concise to begin with!
10:07crocketIs there a function that detects non-sequential value and turns it into a sequence?
10:07crocketA transducer is even better.
10:07crocketAh
10:08crocketmap is a transducer.
10:08crocketlike (seqify 3) == '(3)
10:08crocket(seqify '(3)) == '(3)
10:10crocket,(seq :3)
10:11clojurebot#error {\n :cause "Don't know how to create ISeq from: clojure.lang.Keyword"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Keyword"\n :at [clojure.lang.RT seqFrom "RT.java" 528]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 528]\n [clojure.lang.RT seq "RT.java" 509]\n [clojure.core$seq__4126 invoke "core.clj" 135]\n [sand...
10:14sveriHi, I want to insert something like {%if toread.done = 1 %}checked{% endif %} into a hiccup form, is there a way to do that?
10:16hyPiRionsveri: (if (= (:done toread) 1) "checked") ?
10:16hyPiRionI have no idea what toread is, might want to use (.done toread) instead
10:17sverihyPiRion: no, I mean the string: "{%if toread.done = 1 %}checked{% endif %}" into a hiccup form which generates <input ... {%if toread.done = 1 %}checked{% endif %} />
10:17sverisorry for being unclear
10:17justin_smithsveri: hiccup forms are just clojure data structures, so there's as many ways to generate that as you like
10:18justin_smithsveri: so you have a post-processor over your hiccup output?
10:19sveriyea, I generate selmer html templates with hiccup
10:21sverijustin_smith: one way would be enough for me :D I am using hiccup like this now [:input {:key "val"} "string"] which generates <input "key"="val">string</input> but as "{%if toread.done = 1 %}checked{% endif %}" is no key value pair I am a bit stuck
10:22justin_smithsveri: yeah, when I said that I thought you were talking about generating html
10:22justin_smithand of course that's not html
10:23crocketIs there a way to map over only values in a map?
10:23sverijustin_smith: true
10:23sveriok, so I generate selmer templates
10:23crocket,(map #(update % 1 name) {:a :b :c :d})
10:23clojurebot([:a "b"] [:c "d"])
10:23justin_smithsveri: my sad suspicion is you won't be able to do that because hiccup was never intended to be a general purpose renderer that could do non-html output
10:24sverijustin_smith: that's my assumption too after reading the docs, just wanted to make sure I am not missing anything
10:24justin_smith,(map name (vals {:a :b :c :d :e :f})
10:24clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
10:24hyPiRionsveri: I've tried to unescape html into hiccup in the past without luck
10:24justin_smith,(map name (vals {:a :b :c :d :e :f}))
10:24clojurebot("b" "d" "f")
10:24justin_smith,(into {} (map #(update % 1 name) {:a :b :c :d :e :f}))
10:25clojurebot{:a "b", :c "d", :e "f"}
10:25crocket,(into {} (map #(update % 1 name)) {:a :b :c :d})
10:25clojurebot{:a "b", :c "d"}
10:26crocketI can't find a way to write it more concisely.
10:28crocketIs there a way to write https://www.refheap.com/106785 more concisely?
10:30sverithanks everyone
10:39crocket,(reduce #(+ %2) nil [1 2 3])
10:39clojurebot3
10:39crocketHow does it return nil?
10:39crocketoops
10:42perplexa¯\_(ツ)_/¯
10:42justin_smithperplexa: I really wish it was possible to name a function that
10:42perplexahaha
10:42perplexaisn't it?
10:43oddcullyyou cant?
10:43justin_smithit has parens in it
10:43justin_smithone moment, faking it
10:43oddcullythere are for sure some utf-8 parens out there in the wild
10:43perplexamy repl strips the ツ :(
10:44justin_smiththe harder part is the \ I think
10:45justin_smithI guess you could just fake the \ and the ( ) with unicodes
10:45blkcat#clojure, solving the important problems :P
10:45justin_smiththe result should be (defmacro \_(ツ)_/¯ [& boxy] `(try ~@body (catch Throwable t :WHATEVER)))
10:46justin_smitherr, body, whatever
10:47kavkazhey justin_smith
10:48justin_smithyes?
10:50kavkazjust saying hello
10:50justin_smithoh, hi
10:53wasamasajustin_smith: now we know what's on your mind
11:04justin_smith,(defmacro ¯\_❨ツ❩_/¯ [& bo `(try ~@body (catch Throwable t# :ok)))
11:04clojurebotjustin_smith: Pardon?
11:04justin_smith:P
11:04justin_smiththe unicode I used messes with my terminals
11:05Bronsa(defmacro (╯°□°)╯︵ ┻━┻ [& body] `(throw (Exception.)))
11:06gfredericks`,(defmacro (╯°□°)╯︵ ┻━┻ [& body] `(throw (Exception. ~(pr-str &form))))
11:06clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
11:06Bronsaah, the open paren :(
11:06gfredericks`the sideways one?
11:07justin_smithyeah, I used a doppleganger
11:07Bronsa,(defmacro ❨╯°□°)╯︵ ┻━┻ [& body] `(throw (Exception. ~(pr-str &form))))
11:07clojurebot#error {\n :cause "Don't know how to create ISeq from: clojure.lang.Symbol"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol, compiling:(NO_SOURCE_FILE:0:0)"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6644]}\n {:type java.lang.IllegalArgumentException\n :message "Do...
11:07justin_smithor are those already doppleganger parens?
11:07Bronsa,(defmacro ❨╯°□°)╯︵┻━┻ [& body] `(throw (Exception. ~(pr-str &form))))
11:07clojurebot#'sandbox/❨╯°□°)╯︵┻━┻
11:07Bronsathere
11:08gfredericks`,(❨╯°□°)╯︵┻━┻ whatever I don't even)
11:08clojurebot#error {\n :cause "(❨╯°□°)╯︵┻━┻ whatever I don't even)"\n :via\n [{:type java.lang.Exception\n :message "(❨╯°□°)╯︵┻━┻ whatever I don't even)"\n :at [sandbox$eval96 invoke "NO_SOURCE_FILE" -1]}]\n :trace\n [[sandbox$eval96 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6792]\n [clojure.lang.Compiler eval "Compiler.java" 6755]\n [clojure.core$eval invoke "core.clj
11:08gfredericks`perfect
11:08Bronsaheh
11:08justin_smithsweet
11:08gfredericks`(clojure.string/join " " (map pr-str &form)) might be slightly better
11:23crocketCan anyone write https://www.refheap.com/106785 more concisely?
11:24crocketCan I write (fn [m [keys val]] (assoc-in m keys val)) more concisely?
11:31crocket#(apply assoc-in %1 %2) can be done, but this is confusing.
11:35gfredericks`I am using node with cljs and I don't know what I'm doing
11:35gfredericks`debugging is hard
11:37gfredericks`I don't know how to get a cljs repl
11:40crocketgfredericks`, Are you writing a command line app?
11:43justin_smithgfredericks`: you can get a cljs repl with the cljs standalone jar
11:45gfredericks`justin_smith: does that use rhino?
11:45gfredericks`crocket: developing a library
11:45gfredericks`it's not a webby library so I want to avoid browsers if I can
11:49crocketwebby?
11:52gfredericks`has nothing to do with doms or ajax
11:55justin_smithgfredericks`: hmm, not sure actually
11:56csd_Hello-- If I have two successive calls to >! or >!! to the same channel, is order of delivery guaranteed?
11:56justin_smithgfredericks`: https://github.com/clojure/clojurescript/wiki/REPL-Options
11:57justin_smithcsd_: in terms of control flow in your block of code, it will go start to end. I am not sure if there are strong guarantees of channels being ordered?
11:58gfredericks`yep looks like `lein test` can't find .cljc files
11:58gfredericks`to the githubmobile!
11:59justin_smithgfredericks`: yeah, I ran into this a few times (same issue with eastwood)
11:59csd_justin_smith: yeah so if one >! is called before another, is it guaranteed to be delivered first too?
11:59justin_smithgfredericks`: I linked to the wrong page before, this is the right one https://github.com/clojure/clojurescript/wiki/Running-REPLs
11:59csd_curious about both >! and >!!
11:59gfredericks`justin_smith: no github issue for lein yet that you know of?
12:00justin_smithcsd_: it will be delivered first because the next one won't be run until the first one is
12:00justin_smithgfredericks`: definitely an issue, I forget the details
12:00justin_smithsomething about bultitude?
12:00csd_ok thanks
12:01justin_smithgfredericks`: that wiki page shows separate config for node repl, rhino repl, etc.
12:01Legendary_LinuxHey so I'm entirely new to clojure and clojurescript, but I want to learn. Anyone know of some good tutorials to help me learn? A syntax guide would be awesome to start.
12:02justin_smithsyntax? we don't need no stinking syntax!
12:02justin_smithLegendary_Linux: clojure.org has great docs for a start
12:02justin_smithfor the super basic stuff
12:03Legendary_LinuxI did find this, which was sort of helpful. http://clojurescriptkoans.com/
12:03justin_smithLegendary_Linux: for exercises, 4clojure is great too
12:03justin_smithhttp://www.4clojure.com/
12:03Legendary_Linuxjustin_smith: Thanks.
12:04justin_smithjust be aware the difficulty is not all in numeric order, feel free to start skipping eventually
12:04justin_smithit will suggest "try X next" and X isn't always the best next puzzle to try
12:05gfredericks`justin_smith: this repl stuff looks promising, thanks
12:05justin_smithLegendary_Linux: depending on how much programming experience you have, there is also clojure from the ground up by aphyr, and clojure for the brave and true
12:05justin_smithgfredericks`: yeah, thankfully dnolen realized how tangled the world of cljs tooling got and prioritized making some (relatively) simple options available. Which is awesome.
12:05justin_smith(inc dnolen)
12:05lazybot⇒ 23
12:08Legendary_LinuxI have history with C, C++, and Java. That was a few years ago, though. More recently I've been doing PHP, JS, and Node.js
12:09justin_smithyeah, clojure from the ground up would likely be a bit too introductory then
12:10justin_smiththough clojure for the brave and true might be OK, if you can handle how "twee" it can be sometimes
12:10Legendary_LinuxTwee?
12:10justin_smithLegendary_Linux: kinda cute, silly
12:11blkcati enjoyed clojure for the brave and true
12:11Legendary_LinuxHow much difference is there between Clojure and ClojureScript?
12:11blkcatbut you definitely have to be OK with a great deal of levity :p
12:12justin_smithLegendary_Linux: they both use host interop a lot. Aside from the host interop they are very similar.
12:12Legendary_LinuxI can deal with that. Thanks for the suggestions, all.
12:12justin_smiththe host interop will be very familiar based on your java / javascript experience
12:12justin_smiththough the syntax is different of course
12:19dnolennot sure of ATXers hang out here but https://twitter.com/swannodette/status/623527687932481536
12:29crocketIs there a build-in function for (map #(update % 1 fn) {:a :b ...})?
12:29crocketIt is map-val.
12:35gfredericks`there is no built-in map-vals
12:35gfredericks`the easiest is (into {} (for [[k v] m] [k (f v)]))
12:36gfredericks`prismatic/plumbing has it; I'm sure other util libs do too
12:36TimMccrocket: clojure.algo.generic.functor/fmap
12:37gfredericks`oh dear
12:37crocketTimMc, Is it part of core?
12:37TimMcnope
12:37TimMcNo lie, we have pulled in that entire lib just for fmap on maps. It's kind of silly.
12:37crocketI have (into {} (map #(update % 1 name) m))
12:37TimMc[org.clojure/algo.generic "0.1.2"]
12:38gfredericks`TimMc: that's kind of silly
12:38TimMccrocket: (zipmap (keys m) (map f (vals m)))
12:38TimMcthere are so many ways to write this
12:39crocketSo many ways to confuse users
12:39TimMcfmap is written (into (empty m) (for [[k v] m] [k (f v)]))
12:39TimMcbut maybe for perf it should use transients?
12:48justin_smithTimMc: I thought into used transients
12:48justin_smithoh wait no it uses transducers, my bad
12:48crockettransducers win over transients
12:49justin_smithbut trans* beats everything
12:49crocketOh my god, iterate creates a recursive data structure!!!
12:50justin_smithum, it can
12:50justin_smithit doesn't have to
12:50justin_smith,(iterate inc 0)
12:50clojurebot(0 1 2 3 4 ...)
12:50blkcatthey were clearly overwhelmed by this revelation
12:50justin_smithnothing recursive about that data structure
13:08xemdetiaand then they died
13:11scriptorwonder what they meant by recursive data structure
13:35mmeixshort question:
13:35mmeixI have in a let:
13:36mmeix(let [sw1 (if (< s e) 1 0), sw2 (if (= 1 sw1) 0 1)])
13:36mmeixthere must be a more elegeant way to say this
13:37gfredericks`sw2 (- 1 sw1)
13:38mmeixah, silly me ... thanks!
13:39mmeix(inc gfredericks)
13:39lazybot⇒ 142
13:44gfredericks`mmeix: there's also (bit-xor 1 sw1)
13:44mmeixwow
13:44mmeixok ...
13:45mmeixwould be much faster, I guess ...
13:45gfredericks`hypothetically
13:45justin_smith,(bit-xor 1 1)
13:45clojurebot0
13:45justin_smith,(bit-xor 1 0)
13:45clojurebot1
13:45TimMcblkcat: "My god, it's full of cons cells!"
13:45mmeixthe wise are thinking alike :-)
13:47mmeixaha, this is a function of clojure.lang.Numbers in source, interesting
13:47scriptornot sure if bit-xor would be that much faster
13:48mmeix(in my case speed doesn't matter much)
13:49mmeix(just flipping a flag in a SVG path)
13:49gfredericks`yeah do whatever is the clearest to you
14:01gfredericks`omg I think I have to implement bit-count for 64-bit integers in cljs
14:01justin_smithgfredericks`: how do you even do a 64 bit integer in cljs? where do you get the extra bits to make that work?
14:04gfredericks`justin_smith: gclosure has a Long
14:04TimMcjustin_smith: Store them as properties on the number.
14:04gfredericks`lol
14:05TimMc(function(x) { x.foo = "bar"; console.log(x.foo); })(3)
14:05TimMc^ Prints undefined, but does not error.
14:05gfredericks`erroring would be hostile to developers
14:05gfredericks`nobody likes to see error messages
14:08TimMcI think 3 is getting boxed as a Number, but I don't know why Number silently throws away property writes.
14:10gfredericks`what does it mean for a js number to be boxed?
14:11amalloyTimMc: (function(x) {console.log(x.foo="bar");})(3) // quick hack TODO figure out why this is needed
14:11TimMcamalloy: :-)
14:12TimMcgfredericks`: new Number(3) + 5 //= 8
14:12TimMctypeof new Number(3) //= "object"
14:13TimMctypeof Number(3) //= "number"
14:14amalloyTimMc: actuall new Number(3) + 5 == 8 in my browser
14:14amalloybut here is a funny thing i just found in the ecmascript spec: Number is the inverse of new Number
14:24justin_smithamalloy: did you see my hilarious destructuring pitfall the other day?
14:24amalloyuh
14:25amalloyoh, the keyword and some sort of not-actually-space space?
14:25justin_smith,(let [{:keys {a b c d}} {:a 0 :b 1 :c 2 :d 3}] [a b c d])
14:25clojurebot[nil nil nil nil]
14:25amalloyhah
14:25justin_smithof course the keys arg should have been a vector
14:25justin_smithbut it just silently gives you nil
14:26justin_smithamalloy: led to a hilarious wild goose chase
14:26amalloy,(let [{:keys #{a b c d}} {:a 1 :b 2 :c 3 :d 4}] [a b c d])
14:26clojurebot[1 2 3 4]
14:26amalloy,(let [{:keys #{a b c d e f g h i}} {:a 1 :b 2 :c 3 :d 4}] [a b c d])
14:26clojurebot[1 2 3 4]
14:26amalloyhmmmph, i was hoping for some sort of rearrangement from the conversion to hashset
14:27justin_smithanother fun one (which I found much faster) ##(let [{:keys [a b c :a all]} {:a 0 :b 1 :c 2}] all)
14:27lazybot⇒ nil
14:27justin_smithof course the :as all needs to be moved out of the vector
14:27justin_smitherr, I didn't even do the :as right this time
14:27justin_smithanother fun one (which I found much faster) ##(let [{:keys [a b c :as all]} {:a 0 :b 1 :c 2}] all)
14:27lazybot⇒ nil
14:28Bronsac.c/destructure is just awful
14:29Bronsaunreadable, unmaintainable and accepts lots of bad inputs
14:29amalloyBronsa: has anyone tried to rewrite it? it seems like it shouldn't be *that* hard to redo from scratch, even if reading the existing one is impossible
14:29Bronsaamalloy: have fun trying to get a refactoring commit into clojure
14:30justin_smithBronsa: on top of that, also it can be slow, and it can undermine laziness
14:30amalloyoh, sure
14:30justin_smiththose might be harder to fix
14:30amalloyjustin_smith: you mean because of the nth calls?
14:30justin_smithamalloy: I think so, it's actually something that came to my attention via yourself. I just superstitiously avoid destructuring when I need maximal laziness now :P
14:31Bronsaamalloy: I think the big issue with the current version is that it tries too hard to be super generic and reuse one code-path to do all the nested destructuring
14:31amalloyoh, i meant the slowness. that's not what causes laziness issues
14:31Bronsajustin_smith: it can also mess with locals clearing!
14:31justin_smithahh, I just know that from benchmarking. Probably the extra collection making and such? not sure
14:31justin_smithwow
14:31Bronsa(because of a bug in locals clearing though)
14:32TimMcamalloy: //= was supposed to be a comment followed by an equals sign, like ;;=
14:32Bronsajustin_smith: it will sometimes bind unused and unreachable locals which the compiler can't clear. I have a ticket w/ patch in jira but..
14:32amalloyjustin_smith: well because it calls nth a lot
14:33amalloy,(#'clojure.core/destructure '[_ _ _ _ _ _ _ _ _ _ x])
14:33clojurebot[_ _ _ _ _ ...]
14:33amalloy,(#'clojure.core/destructure '[[_ _ _ _ _ _ _ _ _ _ x] y])
14:33clojurebot[vec__128 y _ (clojure.core/nth vec__128 0 nil) _ ...]
14:33justin_smithahh
14:33amalloyso if y is a seq it calls nth 0, nth 1, nth 2...
14:33justin_smithnice
14:33amalloywhere instead it could be using nthnext and first
14:35Bronsaamalloy: uh, are you saying walking a seq of a vector is faster than accessing each element?
14:36amalloyBronsa: for a vector it's not, and for a seq itis
14:36TimMc&(let [{:keys {AAAAA BBBBB}} {(keyword "[AAAAA BBBBB]") [5 6]}] AAAAA) ;; amalloy, another result from justin_smith's discovery
14:36lazybot⇒ 5
14:36kwladyka_How to transform (1 2 3 4) into (4 1 2 3)?
14:36kwladyka_in elegant way
14:36Bronsaamalloy: right, I guess vector destructuring is optimized for vector access
14:36TimMckwladyka_: (constantly (list 4 1 2 3))
14:36amalloyright, but an awful lot of the time we actually have lists
14:37hiredmanno, it is sequential destructuring
14:37Bronsaah
14:37amalloyand it's not hard to check whether the thing you're destructuring supports nth via whatever interface
14:37Bronsayeah, true that
14:37kwladyka_TimMc, ?
14:37amalloyor to make nthnext and first be fast on vectors (like subvec)
14:37TimMckwladyka_: (cons (last xs) (butlast xs)) perhaps
14:37TimMckwladyka_: You didn't explain the relationship between the two, so I had to guess.
14:38TimMcMaybe you want all inputs to become (4 1 2 3), for example!
14:38amalloyTimMc: that was the one i guessed when he asked me
14:38kwladyka_TimMc, you have strange intuition :)
14:38kwladyka_TimMc, anyway thx for solution
14:38amalloyalthough since i wasn't reading it at the time i mis-guessed the cause
14:38chouser(->> xs cycle (drop 3) (take 4))
14:39TimMckwladyka_: Did I guess right, then?
14:39kwladyka_TimMc, (cons (last xs) (butlast xs))
14:40chouserkwladyka_: depending on the other operations you intend to do, a persistent queue might work well
14:41kwladyka_chouser, can you give me an example?
14:43chousera persistent queue is fast for conj'ing on one end and peek/pop'ing from the other, so you could efficiently take an item (4) from one end and put it back on the other end.
14:44chouserif you do that a lot, or on a large collection, it might be more efficient than a vector or list which has to be rebuilt every time you do that "rotate" operation you asked about
14:44chouseron the other hand, it may then be hard to access the full contents of the collection in the order you want for whatever else you're doing with it.
14:45kwladyka_chouser, are you talking about http://clojuredocs.org/clojure.core/persistent! ?
14:45chousernope.
14:46chouser,(-> clojure.lang.PersistentQueue/EMPTY (into [1 2 3 4]))
14:46clojurebot#object[clojure.lang.PersistentQueue 0x22125a58 "clojure.lang.PersistentQueue@e93c3"]
14:47kwladykaoh... thx
14:47chouser,(let [q (into clojure.lang.PersistentQueue/EMPTY [1 2 3 4])] (-> q (conj (peek q)) pop seq))
14:47clojurebot(2 3 4 1)
14:48gfredericks`conj-peek-pop-seq would be a good name for *something*
14:48kwladykagenerally i need do from (1 2 3 4 2 3 53 23 932 2) all possible configurations
14:48chouser,(let [q (into clojure.lang.PersistentQueue/EMPTY (reverse [1 2 3 4]))] (-> q (conj (peek q)) pop reverse))
14:48clojurebot(4 1 2 3)
14:48kwladyka*all possible unique configurations
14:49chouserso, those 'reverse' operations are relatively expensive, but if you can do the things you need to in-between them, or figure out how to never need them, you'd be winning.
14:50amalloy"all possible configurations?"
14:50amalloyyou are looking for the function named permutations, or what?
14:51kwladykaamalloy, i have chess pieces and i have to try them in all possible unique configurations from first to the last one
14:51amalloywhat is a unique configuration?
14:52amalloythis is getting back to TimMc's answer
14:52kwladykaso (:king :king :queen) (:king :queen :king) (:queen :king :king:) <- this is easy one.
14:52gfredericks`sounds like permutations
14:52kwladykaas you can see :king is 2 times there
14:53kwladykabut i am not doing (:king :queen :king) twice because it doesn't make sense
14:53kwladykagfredericks`, but there is no function like permutation in Clojure as i seee
14:55kwladykahmm but maybe http://clojure.github.io/math.combinatorics/#clojure.math.combinatorics/permutations
14:56gfredericks`,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m))))))
14:56clojurebot#'sandbox/unique-permutations
14:56gfredericks`,(unique-permutations [:king :king :queen])
14:56clojurebot#error {\n :cause "Unable to resolve symbol: unique-permutations in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: unique-permutations 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 r...
14:56gfredericks`what
14:56gfredericks`,sandbox/unique-permutations
14:56clojurebot#error {\n :cause "No such var: sandbox/unique-permutations"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: No such var: sandbox/unique-permutations, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "No such var: sandbox/unique-permutations"\n :at [cl...
14:56gfredericks`,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m))))))
14:56clojurebot#'sandbox/unique-permutations
14:56gfredericks`,(unique-permutations [:king :king :queen])
14:56clojurebot#error {\n :cause "Wrong number of args (0) passed to: sandbox/unique-permutations/self--71"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: sandbox/unique-permutations/self--71"\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" 28]\n [sandbox$unique_...
14:57kwladykagfredericks`, i guess clojurebot doesn't remember function from query before
14:57gfredericks`,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m))) m)))
14:57clojurebot#'sandbox/unique-permutations
14:57gfredericks`,(unique-permutations [:king :king :queen])
14:57clojurebot((:king :king :queen) (:king :queen :king) (:queen :king :king))
14:57gfredericks`hey yay
14:57gfredericks`only two tries
14:57gfredericks`,(unique-permutations [:king :rook :queen])
14:57clojurebot((:king :rook :queen) (:king :queen :rook) (:rook :king :queen) (:rook :queen :king) (:queen :king :rook) ...)
14:57gfredericks`,(unique-permutations [:king :king])
14:57clojurebot((:king :king))
14:58amalloythat's a cute way to handle duplicates, gfredericks`
14:58gfredericks`amalloy: thanks!
14:58kwladykagfredericks`, respect
14:58gfredericks`I like to think of frequencies as returning a multiset
15:07TimMcclojurebot: I like to think |of| frequencies
15:07clojurebot'Sea, mhuise.
15:09snowellJust when I think I understand these bots...
15:11rhg135Heh
15:14kwladykadamn... i killed intellij using permutation in REPL
15:18gfredericks`hey snapchat I just successfully ported the immutable RNG to cljs
15:18gfredericks`it gives identical results
15:19dnolengfredericks`: cool did you end up using goog.math.Long for this?
15:19gfredericks`dnolen: oh absolutely
15:19dnolengfredericks`: cool!
15:19gfredericks`dnolen: I had to write bit-count myself but everything else was there
15:19dnolengfredericks`: excellent
15:19gfredericks`dnolen: next comes the part where I find out it's unsalvageably slow
15:20dnolengfredericks`: haha, I suspect it will be OK, I think test.check would dominate not goog.math.Long ops
15:20gfredericks`I hope so
15:20dnolengfredericks`: last I checked it as something like 4X perf hit over regular arithmetic
15:21dnolenand the biggest time sink in test.check is GC
15:21kwladykaoh god... it produce so many results from so small collection
15:21gfredericks`dnolen: makes me want to rewrite the generators with transducers
15:21gfredericks`kwladyka: the maybe good news is that it's lazy
15:21dnolengfredericks`: def
15:22justin_smith,(defn get-name [] (->> 'clojure.core ns-publics keys shuffle (take 3) (clojure.string/join \-) symbol))
15:22clojurebot#'sandbox/get-name
15:22justin_smith,(repeatedly get-name) ; gfredericks`
15:22clojurebot(spit-nnext-*command-line-args* char?-subs-dissoc! comment-completing-read-string apply-keys-int print-method-case-drop ...)
15:23gfredericks`(inc justin_smith)
15:23lazybot⇒ 279
15:23kwladykagfredericks`, yes but i am scare of time needed to run whole algorithm from start to the end
15:24gfredericks`kwladyka: yeah combinatorial stuff can be tricky that way
15:24kwladykawhich each permutation i need check all possible configuration on chess
15:24kwladyka*with
15:25gfredericks`kwladyka: is it a permutation of 8 pieces?
15:25kwladykahmm but as i see 99% of time it was time to show me text on screen not counting
15:25gfredericks`,(defn unique-permutations [xs] (let [m (frequencies xs)] ((fn self [m] (if (empty? m) [[]] (mapcat (fn [[x n]] (map #(cons x %) (self (if (= 1 n) (dissoc m x) (update m x dec))))) m))) m)))
15:25clojurebot#'sandbox/unique-permutations
15:25gfredericks`,(count (unique-permutations '(R N B K Q B N R)))
15:25clojurebot5040
15:25kwladykagfredericks`, no... as many as user want on board size as user want
15:25justin_smith,defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take 3) (clojure.string/join \-) symbol))
15:25clojurebot#error {\n :cause "Can't take value of a macro: #'clojure.core/defn"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/defn, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Can't take value of a macro: #'clojur...
15:25justin_smith,(defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take 3) (clojure.string/join \-) symbol))
15:25clojurebot#'sandbox/get-name
15:26justin_smith,(repeatedly get-name)
15:26clojurebot(update-count-seq *1-min-ctor condp-with-*print byte-chars-history boolean-vector-vary ...)
15:26kwladykaanyway... i have to finish algorithm and we will see how long it will take
15:26kwladykathere is no other way :)
15:34TimMc(inc justin_smith)
15:34lazybot⇒ 280
15:35TimMc,(meta #'completing)
15:35clojurebot{:arglists ([f] [f cf]), :doc "Takes a reducing function f of 2 args and returns a fn suitable for\n transduce by adding an arity-1 signature that calls cf (default -\n identity) on the result argument.", :added "1.7", :line 6560, :column 1, ...}
15:35gfredericks`heck yeah it generates identical doubles as well
15:35TimMcthat's great!
16:39riogrIn my program, I have the state in a variable I call `current-buffer`. It has an atom, that is swap!-ed and reset!-ed at certain times. Should you in clojure *earmuff* such variables? They never change (always point to the atom) but the value from deref-ing the atom _is_ changing. To *earmuff* or not to earmuff?
16:42justin_smithriogr: in clojure earmuffs are for dynamic bindings, not atoms
16:43riogrI see. Thank you justin_smith for clearing it up! Back to the hacking...
16:43justin_smithriogr: there's even a message about it
16:43justin_smith,(def *foo* (atom nil))
16:43clojurebot#error {\n :cause "denied"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6740]}\n {:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__835 invoke "sandbox.clj" 69]}]\n :trace\n [[clojureb...
16:43riogrjustin_smith: saw that, but didn't really understand..
16:43justin_smitherr... that's not the usual message
16:44justin_smithriogr: OK. there's a good section on dynamic bindings on clojure.org where vars are documented
17:12DocSolverHi all! I'm trying to teach myself clojure with a book and the REPL and I have two questions:
17:13DocSolverMy first question: when I start a REPL outside a project I get an outdated Clojure version (1.6.0), even though I made a project.clj in the ~/.lein folder with a dependency on 1.7.0. Am I doing something wrong?
17:14DocSolver('m on MacOSX)
17:17justin_smithDocSolver: lein doesn't use a project.clj from .lein
17:18justin_smithDocSolver: you'll need to wait for a newer lein version before non-project repls use the brand new clojure version (it's only been official for a few weeks at most)
17:18DocSolverok, then I must have misread that somewhere.
17:18DocSolverthank you for the clarification!
17:18justin_smithnp
17:19justin_smithDocSolver: in practice it's not so hard to just use projects
17:19justin_smithsince they are so easy to generate
17:19DocSolverk, will do
17:20DocSolveralso, another thing I was wondering is about the syntax: it is mostly quite clear but I am confused by the cases where a keyword has a specific meaning. For example the :keys speical keyword to destructure a hashmap. Why is this a keyword and not a function?
17:20justin_smithI have a "just experimenting" project that pulls in clojure 1.7 plus some of my favorite libs like core.async (which I use often, but not ubiquitously to put in my profiles.clj)
17:20justin_smithDocSolver: because that keyword is handled specially by that reader - you can think of it like command line args on a *nix system
17:21justin_smithDocSolver: the function is clojure.core/destructure
17:21justin_smithand it uses things like :keys and :as to guide its execution
17:21DocSolverdoes that mean that these keywords are reserved? Or only in that specific context?
17:21justin_smiththere's a macro that grabs that binding vector, then feeds it to destructure, then uses the result
17:22justin_smithno, they are not reserved, they just have a special meaning in that context, similar to command line switches
17:22justin_smithDocSolver: really it's not much different than how a vector is used by defn / fn
17:23justin_smithit's not that the vector is special, it's that fn / defn treat a vector in that position in a special manner
17:23DocSolverbut it does matter that the keyword is named :keys right?
17:23justin_smithDocSolver: sure, other keywords mean other things in that context
17:23justin_smithDocSolver: like :strs
17:24DocSolverI haven't stumbled upon that one in the book I'm reading yet... but I will keep it in mind
17:24DocSolverThanks for the clarifications Justin, really appreciate!
17:24justin_smithDocSolver: yeah, :strs is practically secret, it gets used so rarely :)
17:24justin_smithnp
17:25justin_smith,(let [{:strs [a]} {"a" 41}] (inc a))
17:25clojurebot42
17:27DocSolverjustin_smith: so what is the added value of using :strs ?
17:27justin_smithDocSolver: same as for keys, avoids repetition when destructuring
17:28justin_smithDocSolver: often a hash-map coming from a database or an http API will come back with strings as keys rather than keywords
17:29justin_smithwhat most people do is do a tree-walk converting the strings to keywords (or at least walking and converting the top level, or converting while parsing with a json parser). Really you can just use the strings.
17:30DocSolverYou managed to confuse me a bit with the :str :-) I don't really see the difference with :keys. I assume it's not an alias?
17:30justin_smithDocSolver: :keys works with keywords, :strs works with strings
17:31justin_smiththese are different datatypes, they are not equivalent when used as hash-map keys
17:31justin_smith,(get {"a" 0} :a)
17:31clojurebotnil
17:31justin_smith,(get {"a" 0} "a")
17:31clojurebot0
17:31DocSolverThe example about :keys in the book I'm reading is:
17:31DocSolver,(let [{:keys [flower1 flower2]} {:flower1 "red" :flower2 "blue"}] (str "The flowers are " flower1 " and " flower2))
17:31clojurebot"The flowers are red and blue"
17:32DocSolverIt obviously doesnt work if I replace :keys with :strs but your example seems really similar
17:32justin_smithDocSolver: I bet you could translate that to use :strs, by changing the keys in the map
17:32DocSolverIs it because you're extracting only one key?
17:32justin_smithDocSolver: it is because :a is not equal to "a"
17:32justin_smiththey are different data types
17:32DocSolverAaaah, now I see: your key is a string
17:32justin_smith:a is not a special syntax for map keys, it is a type of data
17:33DocSolverOkay, it's good that you point that out because I practically only see :keys being used as... erm... keys in objects
17:33justin_smithDocSolver: objects != hash-maps
17:33justin_smithhash-maps are one class of objects
17:34justin_smithbut we have Objects via the jvm too, entirely different beast usually...
17:34justin_smithDocSolver: but stick to hash-maps now, and use them as you would usually use objects, and you can sort out the rest when you are more experienced
17:35DocSolverOkay; I did mean hash maps but I'm still too much in Javascript lingo...
17:36DocSolverActually the :keywords system in Clojure kind of reminds me of symbols in the new Ecmascript 6 which are provided as a means to avoid collisions that might occur with string keys. Or is this not a good comparison?
17:36justin_smithDocSolver: heh, if you ever use cljs, you can use js Objects and cljs hash-maps (which are a kind of js object...)
17:36justin_smithDocSolver: well, keywords can be namespaced, and we use the namespacing to avoid collisions
17:37DocSolverbut what is the added value of keywords, as opposed to using strings instead?
17:37justin_smithbut we also use keywords in literal source code because it helps differentiate a string used as a data type representing human readable text, as opposed to keys in a map or other usage of tokens
17:37justin_smithalso keywords can be called like functions, they look up a value in a hash-map
17:38justin_smith,(:foo {:foo 0})
17:38clojurebot0
17:39DocSolverokay, that's clear.
17:40DocSolverSo it's actually other languages which use strings for both purposes and clojure separates these uses by creating a separate data type...
17:41justin_smithDocSolver: right. I saw a comical version of this the other day from a haskell user on twitter: "should the type be string? I dunno, would the complete works of shakespeare translated to mandarin be a valid value?"
17:42DocSolver:two_households_both_alike_in_dignity_In_fair_Verona_... no that doesn't feel right :-)
17:42justin_smithhaha
17:43DocSolveractually, the fact that a leyword can't contain spaces is a clear indicator of what you wrotr
17:43justin_smithDocSolver: right. Well a literal can't. As you learn more clojure you find out all kinds of evil terrible bad things you shouldn't do that are actually quite easy.
17:44DocSolverI don't wanna know :-)
17:45DocSolverAlright Justin, you helped me a lot. Now I'm returning to the book and the REPL :-) This was a nice first experience with the Clojure community!
17:45justin_smith,(keyword "OK I won't tell you how.")
17:45clojurebot:OK I won't tell you how.
17:46justin_smithDocSolver: awesome, thanks
17:47DocSolver,(keyword "Two households, both alike in dignity, In fair Verona, where we lay our scene, From ancient grudge break to new mutiny, Where civil blood makes civil hands unclean. From forth the fatal loins of these two foes A pair of star-cross'd lovers take their life; Whose misadventured piteous overthrows Do with their death bury their parents' strife. The fearful passage of their death-mark'd love, And the continuance of their p
17:47clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading string>
17:47DocSolvereven romeo and julia doesnt fit...
17:48justin_smithit's an irc limitation, lol
18:05sdegutisHelp.
18:06sdegutisThis works from `lein run`, but not from inside a jar: (->> (resource "public/assets") (file) (file-seq))
18:06sdegutisIt complains with an illegal argument exception saying "not a file".
18:07sdegutisSo in Clojure, whether in a .jar or not, how do you get a list of files in a directory within your ./resources/ dir?
18:10justin_smithsdegutis: things inside jars are not files
18:10justin_smithsdegutis: if you want to access things inside jars, don't use file, use resource
18:10justin_smithsdegutis: jars do not contain directories
18:11sdegutisOkay.
18:11sdegutisSo then, in Clojure, whether in a .jar or not, how do you get a list of "files" in a "directory" within your ./resources/ dir?
18:13justin_smithwell, "resources" itself won't be in the jar
18:14Cr8there's not really a good way to do it it -- (resource) will pull a file out of any jar on the classpath
18:14justin_smithbest you can do is list things under some relative path on the classpath
18:14Cr8so you have to use the ZIP apis to check every jar on the classpath
18:14justin_smithanswer to that, I am working on
18:14hiredmanthere is a large assumption there
18:14hiredmanthat things can only come out of jars on the classpath
18:15Cr8also dirs on classpath
18:15hiredmanresource, and resources actually load things from classloaders
18:15hiredmanwhich can, for example, magic up stuff out of no where, or load things from random urls, etc
18:15Cr8yeah, could have a magic classloader that you can't actually ask for a list
18:15Cr8like some http server you dont control -- you cant necessarily get a listing
18:17amalloyjustin_smith, Bronsa: in case anyone is interested i wrote up a version of destructure that isn't just one giant function, and uses first/next on vectors instead of nth: https://www.refheap.com/de3767810a33dd855f0bc803e
18:17sdegutisThanks. I'll do this outside Closure.
18:17justin_smithamalloy: cool
18:17sdegutisAppreciated much.
18:18amalloydoesn't have all the error handling but i think it has all the features
18:44justin_smithjust found an apt quote from a 20th century music composer: "now that things are simple, there's so much to do"
18:44justin_smith(Morton Feldman)
21:47slaterrmap returns a lazy sequence. what does a lazy sequence mean exactly? is it like iterators in C++? or sequence in python
21:49amalloyit is a thing you can get an iterator on. but it stays valid when you do, and future calls cache the already-computed values. it's not like an iterator that gets mutated as you request elements from it and can only use once
21:49slaterryeah I see
21:50slaterrwhat if I only iterate it once? how much memory will it use
21:52celwellHello, does anything like this already exist? (defmacro unless [pred x y] `(if (not (~pred ~x)) ~x ~y))
21:52celwellEx. usage: (unless Double/isNaN (Double. "0.75") 0)
21:52celwellOr, is there a better pattern?
21:53amalloycelwell: why would that be better than using when-not?
21:53amalloyoh, you're not returning nil, but rather y
21:54celwellYeah, it's an if but i don't want to rewrite 'x'
21:55celwellMy name unless is kind of misnomer
21:56amalloyi don't think there's anything very good built-in. with flatland/useful you could write (-> x (fix pred y))
21:56slaterror, to repharse, if I iterate through a lazy sequence with a million elements only once will they all be stored in memory or will it just use memory required to store a single element?
21:56amalloyslaterr: i mean the GC is nondeterministic so it could run whenever, but when the GC *does* run, only one element wll be kept
21:58celwellamalloy: huh... seems like it would be a common pattern for data validation w/ defaults
21:58slaterri thought maybe clojure compiler is smart enough to notice that it does not need to cache all those results, since they are not used again
21:59amalloyactually maybe cond-> does that now. i don't remember how that works
21:59amalloy,(doc cond->)
21:59clojurebot"([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."
21:59amalloy,(cond-> 2 even? inc)
21:59clojurebot3
21:59amalloy,(cond-> 2 odd? inc)
21:59clojurebot3
22:00amalloyright, thought so. it wants a bool, not a predicate, so it doesn't help you avoid repeating x
22:03celwellThanks a cool function though, might be useful for other things. Thanks
22:39namrahm is there no way to ask leiningen for verbose output
22:39namracause it's kinda frustrating when compilling something and it just hangs somewhere
22:39namrawithout ever finishing
22:46justin_smithnamra: that's caused by top level side effects
22:47justin_smithnamra: all your namespaces get run at the top level when compiling, the only way to make it not hang is to have no side effects at the top level of the file
22:47justin_smithanything that "does anything" should be in functions called by your -main
22:48justin_smithnamra: you can use jstack (it's a command line tool that comes with the jdk) to see where the clojure process is hanging
22:49namrajustin_smith: thanks
22:50namracurrently i solved it by removing :aot :all from the uberjar profile
22:50namrabut like to know why it doesn't work on the new dev machine cause on the old one the compiliation works
22:50justin_smithoh, that's interesting
22:51justin_smithin my experience a hanging compile is almost always some small thing I didn't notice, like launching a core.async go block in a def
22:52justin_smith(which means the core.async threads spin up, which means the compiling vm does not exit)
22:55namrajustin_smith: thanks that was the issue
22:55justin_smithcore.async?
22:55clojurebotcore.async is 100% imperative
22:57namrahad code that connected to a server outside of main
22:57justin_smithahh
23:27namraah how i'd like to do more with clojure :/
23:28blkcati'm dreadfully tempted to use om for an upcoming work project
23:28namraom?
23:29justin_smithnamra: clojurescript library that uses react.js (but actually performs better thanks to immutable data structures last I heard)
23:29justin_smithnamra: from the brilliant dnolen
23:29justin_smith~om
23:29clojurebotTitim gan éirí ort.
23:29namraah thanks
23:30blkcatit looks absolutely brilliant
23:30TEttingerclojurebot: om is a clojurescript library that uses react.js . Om is so hot right now!
23:30clojurebotIk begrijp
23:31justin_smithTEttinger: I improved my clojure.core name generator
23:31TEttingeroh?
23:33justin_smithTEttinger: digging it up
23:33justin_smith,(defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take (inc (rand-int 3))) (clojure.string/join \-) symbol))
23:33clojurebot#'sandbox/get-name
23:34justin_smith(repeatedly get-name)
23:34justin_smith,(repeatedly get-name)
23:34clojurebot(re send-dorun object-with-drop defmulti-keep-aset >Vec-key-dec' ...)
23:34justin_smith,(repeatedly get-name)
23:34clojurebot(sig-make class?-run! read->>-memfn var?--inc filter ...)
23:34justin_smithoh wait
23:34amalloyread->>-memfn
23:34amalloysolid name
23:34amalloyvar?--inc
23:34justin_smith,(defn get-name [] (->> 'clojure.core ns-publics keys (mapcat (fn [s] (clojure.string/split (name s) #"-"))) shuffle (take (+ 2 (rand-int 3))) (clojure.string/join \-) symbol))
23:34clojurebot#'sandbox/get-name
23:34justin_smith,(repeatedly get-name)
23:34clojurebot(identity-at-defprotocol biginteger-remove eval-min macroexpand-class-coll-complement map?-unreduced-int ...)
23:35justin_smithamalloy: one I just got in my repl here - >Vec-vec->>
23:35justin_smith,(repeatedly get-name)
23:35clojurebot(pop-ref-next-repeat >=-ctor find-bit-find-method set->-matcher-array proxy-reader ...)
23:36amalloycomputer-generated babble is always strangely compelling
23:37justin_smithfor me I think it's cathartic because I have spent so much time cramming things made of those tokens into my brain already
23:38justin_smith,(repeatedly get-name)
23:38clojurebot(error-transient list-set-unsigned-errors deref-groups not-biginteger subtract-re-int-underive ...)
23:39amalloynot-biginteger. a useful function indeed
23:39justin_smithindeed, should be a predicate, of course
23:40justin_smith,(repeatedly get-name)
23:40clojurebot(unchecked-in-set-send type-min-in fn*-filterv string-create->map-not satisfies?-shift-aset-with ...)
23:41tmtwdis there something like hiccup for css?
23:42justin_smithtmtwd: garden
23:42tmtwdjustin_smith, is it often used by clojure developers?
23:42justin_smithtmtwd: the only reason I haven't used it is designers would rather just use regular css, or maybe sass/less
23:43amalloythat's true of hiccup too
23:44justin_smithamalloy: yeah, we have an unusual division of labor now, which lets us use reagent stuff which is basically hiccup syntax, but before we had to use a more conventional templating engine