#clojure logs

2015-03-03

00:00h_how might I serialize a function such that I could write it to a file and recall an identical function from that file at a later time?
00:00puredangerhttps://github.com/technomancy/serializable-fn
00:01h_hooray! thank you friend
00:04puredangerenjoy!
00:08h_`3`3
00:08h_<3<3 even!
02:36jeis there a way from the repl to "inspect" data to explore all the interfaces it implements and all the classes it inherits from
02:36amalloy&(ancestors clojure.lang.PersistentVector)
02:36lazybot⇒ #{clojure.lang.IMeta java.lang.Comparable clojure.lang.Indexed clojure.lang.IPersistentVector java.lang.Iterable java.util.List clojure.lang.Associative clojure.lang.IObj clojure.lang.APersistentVector clojure.lang.Reversible java.lang.Object clojure.lang.Seqable clo... https://www.refheap.com/98040
02:37jeI want to identify commonality for dispaching in a multimethod
02:38jeamalloy: nice thanks
02:42TEttinger(inc amalloy)
02:42lazybot⇒ 231
03:34dm3hello
03:34daniel`hi
03:34dm3is there an "approved" way to detect if a sequence is lazy?
03:35dm3I know there's a clojure.lang.LazySeq, but does it cover all cases?
04:15justin_smithdm3: it's the only lazy type in clojure. Though they can hide.
04:15justin_smith,(type (cons :a (range)))
04:15clojurebotclojure.lang.Cons
04:15justin_smiththat's a cons, but it's tail is lazy
04:15justin_smith,(type (range))
04:15clojurebotclojure.lang.LazySeq
04:18dm3I'm trying to enforce stricter semantics for an fn which operates in a dynamic scope
04:18dm3know that there'll be trouble with nested lazy sequences, but forcing the outer one should cover 95% of use cases
04:18godd2*opens lein repl* (reduce + (range)) ; oh god what have I done
04:19dm3guess just checking if it's a sequence and doall'ing would be enough
04:19justin_smithdm3: if you know you won't get (range) or (iterate ...)
04:19dm3yes
04:20justin_smithyou could also do a clojure.walk/postwalk, which will hit every subtree, and try to fully descend every subtree
04:20justin_smithhmmm. maybe just a (dorun (tree-seq ...))
04:27dm3justin_smith: thanks
04:29justin_smith,(tree-seq coll? seq [:a [:b {:c 0 :d 1 :e #{1 2 3}}]])
04:29clojurebot([:a [:b {:e #{1 3 2}, :c 0, :d 1}]] :a [:b {:e #{1 3 2}, :c 0, :d 1}] :b {:e #{1 3 2}, :c 0, :d 1} ...)
04:35TEttinger&(tree-seq coll? seq [:a [:b {:c 0 :d 1 :e #{1 2 3}}]])
04:35lazybot⇒ ([:a [:b {:e #{1 3 2}, :c 0, :d 1}]] :a [:b {:e #{1 3 2}, :c 0, :d 1}] :b {:e #{1 3 2}, :c 0, :d 1} [:e #{1 3 2}] :e #{1 3 2} 1 3 2 [:c 0] :c 0 [:d 1] :d 1)
04:35justin_smithaint no room for a lazy seq to hide in there
04:35TEttingerI have no idea how tree-seq works
04:36justin_smithTEttinger: it returns every sub tree
04:36justin_smithand every sub-tree of each sub-tree
04:36justin_smiththe first arg is the function which tells you if a thing has sub-trees
04:36justin_smiththe second arg is the thing that returns the sub-trees, if it has them
05:40dysfunwhat do i need to do to correctly inflate a ns-qualified symbol in an edn file to a value? let's assume for now that the code is in the classpath
05:43dysfunaha, find-var
05:58ggherdov,(->> '([1 :a] [2 :c]) (sorted-map-by <))
05:58clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: ([1 :a] [2 :c])>
05:58ggherdov,(->> '([1 :a] [2 :c]) (apply (sorted-map-by <)))
05:58clojurebot[2 :c]
05:58ggherdov,(->> '([1 :a] [2 :c]) flatten (apply (sorted-map-by <)))
05:58clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (4) passed to: PersistentTreeMap>
05:59ggherdovyou have a list of keyvals (as vectors), and want to build a sorted-map-by. How do you do?
05:59Glenjamin(doc into)
05:59clojurebot"([to from] [to xform from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined. A transducer may be supplied."
06:00TEttinger,(into (sorted-map-by <) '([1 :a] [2 :c]) )
06:00clojurebot{1 :a, 2 :c}
06:00ggherdovthanks TEttinger Glenjamin
06:00TEttingernp
07:35razum2umdnolen: what's the status of cljs support of promise/deliver/deref ?
07:35dnolenrazum2um: no support is planned, JS is single-threaded
07:50razum2umdnolen: yes, but what king of abstraction should we use to "fix" callback hell?
07:50dnolenrazum2um: core.async
07:50razum2umbesides of core.async :)
07:50razum2umsay, setTimeout
07:51dnolenrazum2um: core.async is the best solution
07:52razum2umdnolen: but there is a lot of promise-solutions as libraries (besides ES6 promisses) - why not to map them and choose one of the polyfill for older browsers?
07:53dnolenrazum2um: I don't really have anything else to say on this topic than what I've already said. Sorry.
07:53razum2umdnolen: ok then, thanks :)
07:54sverirazum2um: I guess you are free to create your own abstractions over one of the existing libraries
07:54sveriIf you feel the need for them
07:55razum2umsveri: yes, native calls to js/.. work, but I just worder why promise is not implemented
07:57sveriI see :-)
08:03dnolenrazum2um: if it wasn't clear earlier, JS promise abstractions are nothing like the Clojure promise abstraction which has blocking semantics for deref. This would imply duplicating core.async but would require whole program transform.
08:04dnolenrazum2um: it hasn't been done because the semantics can't be preserved
08:04dnolenwithout too a big tradeoff
08:27piranhahey all! I'm trying to call Java method with spread arguments (...): http://cr.openjdk.java.net/~sundar/jdk.nashorn.api/8u40/javadoc/jdk/nashorn/api/scripting/NashornScriptEngineFactory.html#getScriptEngine-java.lang.String...-
08:27piranhars-example.server.render> (.getScriptEngine f "-pcc" "-ot=true")
08:27piranhajava.lang.ClassCastException: Cannot cast java.lang.String to [Ljava.lang.String;
08:27piranhaand it fails with this ^
08:27piranhaam I doing something wrong?
08:28piranhaah! (into-array String ["a", "b"]) helps
08:46sveriHi, anyone knows how to properly handle umlaute with transit? transit converts umlaute wrong and makes weird chars of it, see this: http://pastebin.com/7Z8x3C5d
08:47EremoxHow do i stop cider from swapping to error-buffer and set it to just print the error message in the repl instead?
08:49dnolensveri: I don't think transit-clj will handle that for you by default, http://stackoverflow.com/questions/15356716/how-can-i-convert-unicode-string-to-ascii-in-java
08:50dnolensveri: perhaps worth opening an enhancement issue w/ transit-java
08:51sveridnolen: thank you, I will do that. Not sure exactly, but this is something I would expect to be handled by the library
08:51dnolensveri: perhaps, not sure about the perf implications though
08:52sveridnolen: maybe it can be made optional, however, thank you, I open an issue :-)
09:23borkdudeI might be brainnumbed, but is there an easier way to update the val in a map? (update-in {:foo "bar"} [:foo] count)
09:23borkdudeof a collection of maps that is
09:23borkdudeso (map #(update-in ....))
09:24gfredericksborkdude: clojure 1.7 has update
09:24borkdudegfredericks yes, I heared.
09:24borkdudegfredericks when is it out?
09:25gfredericksdunno; prismatic/plumbing also has it in the meantime
09:25borkdudek
09:26gfredericks,(defmacro map-> [& exprs] `(map #(-> % ~@(butlast exprs)) ~(last exprs)))
09:26borkdudehttps://github.com/clojure/clojure/blob/2e76c57d3b7672ce5eca096ed2059d9a1dd379d0/src/clj/clojure/core.clj#L5909
09:26clojurebot#'sandbox/map->
09:27gfredericks,(->> [{:foo 12} {:foo 13} {:foo 92}] (map-> (* 2) (inc)))
09:27clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Number>
09:27gfrederickswhoopsiedoodle
09:27gfredericks,(->> [{:foo 12} {:foo 13} {:foo 92}] (map-> (update :foo * 2)))
09:27clojurebot({:foo 24} {:foo 26} {:foo 184})
09:28gfredericksno idea if map-> is defined in some lib somewhere
09:28borkdudegfredericks thanks ;)
09:29gfredericksnp
09:51borkdudegfredericks I found reduce-kv also handy
09:53gfredericksborkdude: for your original question?
09:53borkdudegfredericks yes
09:53borkdudegfredericks it was a little bit different than I asked, but eventually this is what I needed. didn't know about this one yet
09:54jcromartie.
09:56gfredericks,
09:56jcromartieexcuse me
09:56clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
09:56jcromartieI was cleaning my keyboard
09:56jcromartie:P
09:56jcromartie,(((
09:56clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
09:56gfredericks,())))
09:56clojurebot()
09:56jcromartieI have a recipe for pain
09:57jcromartiea Clojure app that depends on Ruby gems to be available at runtime
09:57jcromartieI think binstubs may be the answer
09:57jcromartieI dunno
09:58jcromartieit's particularly troublesome with Emacs and Cider launching the REPL process
09:58jcromartieI can't figure that one out
10:01loliveiraI would like to run java -jar my_uber.jar —repl and get a repl. Do you know how to do that?
10:03jcromartiewhat was that cider-related channel?
10:05katratxololiveira: https://github.com/clojure/tools.nrepl#embedding-nrepl-starting-a-server
10:14justin_smithloliveira: java -cp my_uber.jar clojure.main
10:14justin_smithor that
10:14justin_smithbut clojure.main will give you a repl
10:15loliveirakatratxo: justin_smith: thank you!
10:15loliveirait worked. =)
10:17justin_smithloliveira: if you prefer the nrepl repl to the clojure one, you can launch the nrepl server from your own app (or even from the clojure repl) as described in katratxo 's link, and then connect to it with "lein repl :connect N" where N is the port number it opens
10:19loliveirajustin_smith: I will try the nrepl approach.
10:19loliveirajustin_smith: I will put the follow up.
10:23justin_smithloliveira: a trick I often use is to have an optional environment variable, which if set, I turn on an nrepl server from my process
10:23loliveirajustin_smith: good idea.
10:23justin_smithbut the java -cp ... clojure.main is useful for if I want to just run some code with exactly the setup that would be available on the server
10:24justin_smithnot running the app, but just running some code that I think might have failed in production for example
10:25justin_smith(I used this recently to verify that tomcat was making the serving of resources inside the jar with unusual names 404)
10:33loliveiraaggred
10:34loliveirajustin_smith: I have the same need that you had.
10:36justin_smithloliveira: another trick that I needed in that case, because this was a war file and not a jar file, I needed to also explicitly add the clojure.core to the class path because of how wars are packed up
10:36justin_smithprobably not an issue in your case
10:37loliveirai used to deploy wars.
11:21timvisherwhat's the state of clojure servers at this point? last i heard you really weren't supposed to serve out of embedded jetty in prod using `lein ring server`, but people weren't thrilled with tomcat, some people were using application servers (way heavier than i need), and some people were thrilled with http-kit (which is embedded in the app so you can just `lein run`?)
11:22justin_smithtimvisher: I think http-kit and aleph are great options, and using lein to run in prod is a bad idea
11:22justin_smithbetter to create an uberjar and use java -jar ... or java -cp ...
11:23justin_smithlein is a great dev tool, but it doesn't help you much in production
11:23schmirthe boot people advertise using boot in production
11:23timvisherjustin_smith: indeed. :) i've heard that over the years but never dove into why. is there a good doc somewhere that expresses that?
11:23justin_smiththat's a choice I wouldn't be likely to make, but I know that a lot of people use lein in prod too
11:24justin_smithtimvisher: for starters, lein starts up an extra vm you don't need. It also sets jvm options that optimize startup time at the expense of performance (turning down the JIT options)
11:25justin_smithtimvisher: but even if it wasn't actively reducing performance, it's functionality I don't need, a program I don't need to install, and an extra place for things to break that can be removed from the prod environment
11:25timvisherjustin_smith: all good points
11:25michaelr`anything out there which converts html to clean, formatted hiccup?
11:25timvisherdo you also embed an nrepl server?
11:26timvishermichaelr`: bet you pandoc could do it! (or at least get you stupid close) :)
11:26timvisherbut i haven't heard of anything
11:26justin_smithtimvisher: I use an environment variable to optionally start nrepl (local host only, ssh tunnel to connect)
11:26timvishermichaelr`: actually, i take that back. doesn't enlive get you very close?
11:26timvisheri suppose it wouldn't pretty print, but that's why clojure.pprint is a thing
11:26bjamichaelr`, I think I've used hickory for that before
11:27timvisherhttps://github.com/cgrand/enlive
11:27timvisherguess it depends what you mean by clean
11:27justin_smithtimvisher: the nrepl optionally being started in it's own thread from the function that starts the web server
11:27timvisherjustin_smith: and then start up the nrepl server internal to the app?
11:27timvishernice
11:27michaelr`hickory give hiccup but it's full of empty strings and empty attribute maps
11:27justin_smithright, the app's logic turns on the server if the env var is set
11:28justin_smithtimvisher: one caveat that doesn't affect most of us: don't run nrepl on a machine that is actually multi-user, because anyone on the machine can access the nrepl port and get the full permissions of the user running the clojure process
11:28justin_smithbut who uses multi user machines for anything nowadays anyway
11:28michaelr`i need to import html which the designer built into my om views
11:29michaelr`which are written in hiccup (sablono)
11:29michaelr`so I thought that I must not be the first to do that :)
11:29justin_smithmichaelr`: the reason hickory gives you empty strings (or strings with spaces) is that this ensures that the rendering gives you an identical document to the intial input, whitespace and all
11:30michaelr`justin_smith: that's fine by me, but it doesn't help with my use case :)
11:30justin_smithrihgt
11:30justin_smithI think enlive's html-resource likely gives you a cleaner data structure
11:31justin_smithor whatever the function is that gives you a data structure from an html file - forgetting the name
11:31Glenjaminthere's a list here: https://github.com/weavejester/hiccup/wiki/Converting-html-to-hiccup
11:32justin_smithGlenjamin: nice!
11:32michaelr`Glenjamin: a list!? cool
11:32justin_smith(inc Glenjamin)
11:32lazybot⇒ 16
11:32Glenjaminit's a fairly short list
11:32bjamichaelr`, this solution on stack overflow seems to work in my repl pretty well: https://stackoverflow.com/questions/11094837/is-there-a-parser-for-html-to-hiccup-structures
11:32bjait uses enlive
11:32justin_smithstill, we can assume weavejester will update it occasionally
11:33justin_smithbja: yeah, that's what I use (or very close to it)
11:34michaelr`bja: thanks, let me check that too..
13:11daGrevishi! how is lein test finding tests? i would like to split my core_test.clj into many files
13:11daGrevisalso, are new kids using lein test or there's another better testing framework out there?
13:12gfredericksdaGrevis: `lein test` looks through all the namespaces under /test, I think
13:12gfredericksso it sounds like you just want to make more namespaces
13:12gfredericksnormally namespaces <--> files are 1-to-1, with corresponding names
13:13gfredericksclojure.test is fine for a lot of people; depends on your taste
13:14daGrevisgfredericks, okay, thanks! clojure.test works fine for me too :P
13:15emaczenI'm trying to update two lazySeqs in an atom with swap!
13:16emaczen(swap! state update-in [:waste :foundation] rest conj (first waste))
13:16emaczenThe keywords have the same name as the arguments passed into the method
13:17gfredericksI'm having trouble figuring out what you're going for there
13:17emaczenThis swap form should do the same thing as (push (pop waste) foundation)
13:17hiredmanemaczen: that is a race condition
13:17emaczenI want to update the lazySeqs given by :waste and :foundation in atom state
13:18emaczenI want the function rest applied to the waste (to remove the first element) and I want to put the first element of waste at the front of foundation
13:19gfredericks(swap! state (fn [{:keys [waste] :as current-state}] (-> current-state (update-in [:waste] rest) (update-in [:foundation] conj (first waste)))))
13:20gfredericksI think that's basically what you're describing; I have no idea what race condition hiredman is referring to
13:20emaczengfredericks: Thanks very much!
13:20hiredman(swap! state update-in [:waste :foundation] rest conj (first waste)) is grabing the first of waste out side of the swap, so it isn't part of the case, so waste in the atom could change
13:21hiredmancas
13:22hiredmanassuming this is in some kind of let like (let [{:keys [waste]} @state] ....)
13:25gfredericksah yeah; I tripped up on passing conj to rest and didn't bother interpreting the code any further :)
13:25gfredericksemaczen: hiredman is right you definitely want to be careful to do all the reading inside the update function
13:25gfrederickswhich my code does
13:43gfredericksanybody know of anything similar to clojure.core/format but that accepts names instead of positional args?
13:44gfredericksI'm imagining another throwing helper (macro?) for catch-data that lets your errmsg strings reference values in your ex-data map
13:45gfredericksI know about strint in the incubator lib; that could sort of be twisted into the role but it's arbitrary eval so a little different
13:49daGrevisi'm trying to make a test setup that creates two browser instances and passes them to test each time. this is what i have so far, but it seems that deftest have no mechanism to accept params. :( https://gist.github.com/b072e75c3a3453723a5d
14:17crack_userhello guys
14:26cap10morgangiven that clojure.lang.Keyword is not part of the public API, what is the idiomatic way of converting a clojure.lang.Keyword into a java.lang.String *from Java code*?
14:27jjttjjI have a bunch of data i need to pull from various APIs and store somewhere persistant and query somehow with clojure. It's just to figure out my taxes and i want it to be quick/easy/hacky as possible. Does this sound like a case for mongo or is there anything better? Anything that lets me just persist clojure structures without dealing with file io?
14:32hiredmanfilesystems are a thing these days
14:35delaneyso i've been learning a bit of clojure in my spare time. something that I can't quite grok. is there a way to de/serialize persistent data structures? for example have a map, add/remove keys and store both versions to edn/fressian/etc. how do you deserialize back to the shared/persistent state where they share most of the same memory space?
14:36LauJensenGents - Ive updated to the most recent version of cider, and now C-M-x no longer drops the result of eval in the repl. Is that intentional or have I borked a setting?
14:36chouserdelaney: generally, you don't.
14:37delaneyhmm, i was a afraid of that
14:37delaneyonce you save/load you lose a lot of the benefits it seems
14:37chouserif you use normal serialization (edn, fressian, transit) you'll get *one* version, and when you read it back in you'll get a whole new unshared data structure
14:37delaneyright
14:38delaneyis there (not 'normal)?
14:38delaney:P
14:38delaneylike a memory dump
14:38chousersure, you can serialize the operations applied to a value instead
14:38delaneyso a transaction log
14:38chouseryup
14:40chouserthen you could tag various versions in the transaction log, and when deserializing grab references to those tagged version. Once thats done, those tagged versions would share the memory for their common sub-values.
14:40delaneyi work mostly in C# and trying to justify time towards clojure, but in practice having a hard time. i love the theory of it but most of the concrete examples seem easier there. sure part of it is familiarity.
14:41chouserimmutable values have benefits, even in contexts where you don't get structural sharing
14:41delaneywell yeah, but i already do that in C#
14:41chouserin fact, structural sharing isn't really a benefit so much as an attempt to reduce the cost
14:41delaneybut more from convention than lang level granted
14:42chouserah, well, if you've already got immutability and high-order functions, that is indeed a couple of major talking points removed in an argument for clojure
14:42delaneybut there is no D in stm's acid beyond things like datomic it seems
14:42chouserlet's see, what's left -- immutable locals, s-expressions (macros), ...
14:43delaneyyeah i like the idea of Om, which is what got me interested in clojure (already using react from js land)
14:45agarman_C# is a good language, especially as unnecessary syntax keeps getting pruned away each release
14:46delaneyagarman_: right. if it was a while ago then yeah there is a big diff (and being tied to jvm for sure). maybe its also when looking at the clojure examples or tutorials it just is crazy terse to grok
14:46delaneythe syntax is simple, the complexity moves into the function calls
14:47delaneyagain hopefully that melts away with time
14:47delaneyi love the idea of having the same lang server and client side for sure, and edn seems slicker than json for my wants
14:49agarman_if you have an opportunity to learn F#, and force yourself to not use mutable (mostly records, tuples & object expressions) you'll have most of the big benefits of Clojure.
14:51delaneywell i've always loved the jvm's speed, just not the root lang. the clojurescript and even closure-clr makes it seem like there is something there i just don't quite see yet. in no way was it trying to avoid clojure, if anything seeing if i'm just approaching it wrong.
14:51agarman_Clojure's atoms & refs are nice though. core.async is great too.
14:55agarman_Even though C# & F# have syntax trees, reflection emit & reified generic containers these are poor substitutes for a good macro system.
14:59delaneyi sounds dumb but i can't see my need for macros. i know there are canonical examples like (what if you want to write 'if')
14:59delaneyi see they help you basically write compilers, but for the stuff i do it seems weird
14:59LauJensenGents - Ive updated to the most recent version of cider, and now C-M-x no longer drops the result of eval in the repl. Is that intentional or have I borked a setting?
15:00delaneylike you can't write a macro that does matrix math faster by preprocessing
15:02agarman_delaney: C# delegates are all syntactic sugar put in by the special logic in the compiler. If you had macros in C#, you could write that.
15:03agarman_delaney: C# async methods, dynamics, var & many many other items are written as changes to the C# compiler. These could all be done via a library if C# supported macros.
15:04delaneyi get that, but those constructs are there now. could you write a macro that does that transaction log thing i was talking about before.
15:04delaneytake every map/array function and throw into a transact log?
15:06amalloydelaney: for one thing, the compiler would be a lot simpler if it *didn't* have to include that stuff, and could let macros do it instead
15:06amalloybut if you are looking for a simple useful example, i offer https://github.com/amalloy/useful/blob/96f665/src/flatland/useful/map.clj#L6
15:06amalloyso that you can write (keyed [x y z]) instead of {:x x, :y y, :z z}
15:07agarman_delaney: you can do a write to transact log in Clojure but you'd usually do it by wrapping the vars that make the changes rather than writing macros
15:10agarman_but that logs operations on map/vector functions instead
15:13delaneyso why wouldn't you do as a macro?
15:18agarman_it may be implemented with macros, but the better usage would be to (transact-log/start) and have that rewrite the vars for the functions that are relevant. So when someone calls (conj ...), (map ...), etc you get your transaction log written without having to change existing calls. It's like AoP but with all of your language already in an IOC container
15:18amalloyi don't know that a mass modification of vars is really such a great solution either...
15:19agarman_amalloy: It would terrify me.
15:20agarman_for debugging purposes, not so scary.
15:20amalloyi disagree. conj and map are called *a lot*. i'd be surprised if you could even get meaningful debug output by modifying their vars, given how much they're called by the standard library
15:20amalloylike, map calls map
15:21agarman_true
15:22amalloywell, at least java's logging libraries let you turn on debug logging for particular classes/packages individually
15:23agarman_yep
15:23agarman_that was an accident of trying to use matthias's inspect library on a piece of clojure in the big Java app
18:25emaczencan you multi-method dispatch on just keywords?
18:26arrdemsure if your dispatch operation is clojure.core/identity
18:26emaczenI'm thinking if my user clicks on two places, then I can make a set of functions for each two-combination
18:27emaczenarrdem: can you give me an example?
18:28emaczenI'm very new to this
18:28arrdemyeah sure one minute
18:31arrdememaczen: https://www.refheap.com/98087
18:31arrdememaczen: is that helpful?
18:31emaczenarrdem: Thanks, I will try this out
18:32emaczenhow will this work for pairs?
18:32emaczenpairs of keywords?
18:33arrdememaczen: the dispatch-fn is applied to all arguments.
18:33arrdememaczen: so try invoking that function with a pair [:foo :bar]
18:34emaczenFor this line: (defmethod identity-dispatch :foo [foo] "Got a foo!")
18:35emaczenwhat is the type of foo inside the [] ?
18:35arrdememaczen: foo is simply a symbol naming the value of the 1st and in this case only argument.
18:41emaczenarrdem: I keep getting 'No method in multimethod 'pop-pushable?' for dispatch value: [nil
18:41emaczen nil];
18:41emaczenhow do I call these methods exactly?
18:41emaczenI'll try wrapping them in a vector first
18:42emaczenThat didn't work either
18:42arrdememaczen: can you give me a sample input pair?
18:43arrdememaczen: (pop-pushable :foo :bar) or (pop-pushable [:foo :bar])
18:43emaczenI tried both of those
18:44arrdememaczen: in the form (defmethod identity-dispatch :foo [foo] "Got a foo!") the keyword :foo is the dispatch value for which the method tail returning the strung (fn [foo] "Got a foo!") will be invoked.
18:44arrdememaczen: when you invoke a dispatch identity multimethod with the pair [:foo :bar], you need to have a method registered for that pair.
18:45arrdembah I'm sorry I'm doing this wrong.
18:45arrdememaczen: can you refheap what you have now?
18:46emaczenarrdem: Sure, I am trying to make a klondike solitaire game
18:46emaczenCan you look at a pastebin?
18:46arrdemsure
18:49emaczenarrdem: http://paste.lisp.org/+34P1.
18:50emaczenarrdem: do you get the idea?
18:50arrdememaczen: yeah.
18:51arrdememaczen: (waste @state) could be :waste, unless there's more code you didn't paste.
18:51justin_smithemaczen: the args to your defmulti and your defmethod don't agree in arity
18:52justin_smitharrdem: based on the dispatch it would have to be (::waste @state), which looks like it would always be nil
18:53arrdemAh. @justin_smith yeah I see the arity missmatch.
18:53emaczenWhat is the arity mismatch?
18:54justin_smithemaczen: your multi takes one arg, the method you create for it takes two
18:54justin_smithidentity isn't a two argument function, but your defmethod is
18:54emaczenI'm not even sure why the multi takes one.... All I did was make the dispatch function be identity
18:54arrdememaczen: if you dispatch on the _pair_ [::waste ::foundation], you have only given the body one argument.
18:54justin_smithemaczen: and identity takes two arguments
18:55justin_smithemaczen: you could change your dispatch function to be vector
18:55justin_smithand then the arities would work
18:55justin_smith(defmulti pop-pushable? vector)
18:55justin_smithbecause you can call vector on two args, and it returns the two args such that you can dispatch on them
18:56justin_smithor maybe list would be better, it would work the same either way
18:57arrdemjustin_smith: dispatching on first should be fine...
18:57arrdemjustin_smith: in case you want non-constant args elsewhere :P
18:57justin_smitharrdem: he matches on two args though
18:57emaczengive me a few seconds/minutes -- I am following, but I know this is going to take me a little bit of time to get to work
18:57arrdemjustin_smith: (foo [dispatch-a dispatch-b] . args)
18:57amalloyarrdem: (first x y) doesn't return x
18:58arrdemamalloy: correct me if I'm wrong, but I thought that multimethods did (<dispatch-fn> (seq args))
18:58arrdemnot (apply <dispatch-fn> args)
18:58amalloyarrdem: that is wrong
18:59amalloythe dispatch fn receives exactly the same args as the method does
19:00justin_smitharrdem: emaczen: https://www.refheap.com/98090
19:00justin_smiththat's how you dispatch on two arguments
19:00arrdem"This function will be applied to the arguments to the multimethod in order to produce a dispatching value."
19:00arrdemgotcha.,
19:00arrdemon clojure.org/multimethods but not in the docstring. right.
19:00emaczenjustin_smith: cool!
19:01emaczenI have a new question now...
19:01emaczenI want to dispatch on these two keywords and an integer
19:01emaczenerr wait
19:01emaczensorry
19:02justin_smith(fn [a b & optional] [a b])
19:02justin_smithit will dispatch on the first two, and the multi itself will get all the args
19:02emaczenI just want the integer to be an argument to the function
19:02justin_smiththey are all arguments
19:03justin_smithfor clarity, when I said "the multi itself" I mean the form defined in defmethod, that was badly worded
19:03emaczenWait, (defmethod foo [:a :b] [a b i] ... )
19:03justin_smithright
19:04emaczencool!
19:04justin_smiththat would work with the dispatch function I shared above
19:04justin_smithbecause the dispatch just checks the first two args, ignoring the rest
19:04dfletcherAhhh sweet. UI editable with WindowBuilder, main program logic in Clojure. This is what I was after, thanks for the help earlier channel :)
19:05justin_smithemaczen: updated the paste to show optional args on a defmulti https://www.refheap.com/98090
19:06justin_smithdfletcher: sounds cool, I would like to read it
19:07emaczenjustin_smith: sweet
19:10emaczenhow do I remove a defmulti definition from the REPL
19:10rufoayou can use interop to do (.addMethod
19:10rufoaso perhaps similar
19:11rufoalook in clojure.lang.MultiFn
19:11arrdem$grim clojure.core/remove-all-methods
19:11lazybothttp://grimoire.arrdem.com/1.6.0/clojure.core/remove-all-methods
19:11justin_smithemaczen: it is a def, you can do (def multi-fn-name nil)
19:11arrdem$grim clojure.core/remove-method
19:11lazybothttp://grimoire.arrdem.com/1.6.0/clojure.core/remove-method
19:11dfletcherheh oops justin_smith wrong chan. #eclipse helped me figure out how to make this work ;)
19:11justin_smithhaha
19:11justin_smithOK
19:11justin_smithdfletcher: is it a clojure thing at all?
19:12emaczenarrdem: doesn't that just remove all the methods of the multi?
19:12arrdememaczen: remove-method can remove the method associated with a specific dispatch value.
19:12dfletchermy main program logic is in clojure and i pass a window to my clojure main (that was built using some nice gui tools in Eclipse [WindowBuilder])
19:12justin_smithemaczen: arrdem: to remove the mutli altogether just do (def your-multi nil)
19:13justin_smith*multi
19:13dfletcheractually heh maybe I don't even want to pass the window here. but as a test (.show window) is working nicely :>
19:13emaczenthanks!
19:13justin_smiththis is needed in order to redefine multis, because they are defonce
19:14justin_smiththat's a trick I learned from technomancy, hope he joins us here again some day
19:15emaczenisn't technomancy on #emacs a lot?
19:15justin_smithyeah, he seems to be taking a break from this channel
19:16amalloy$karma technomancy
19:16lazybottechnomancy has karma 162.
19:16godd2I just ordered his keyboard a week and a half ago. can't wait to solder that together
19:18godd2This one, if anyone's interested: http://atreus.technomancy.us/
19:23emaczenjustin_smith: I'm still struggling and I'm following your example practically to a tee
19:23justin_smithemaczen: is there a specific thing that isn't working?
19:24emaczenI'll make a paste
19:26emaczenhttps://www.refheap.com/98091
19:26emaczenI am calling the method like: (pop-pushable? [::waste ::foundation] 2)
19:27justin_smithemaczen: why the vector?
19:27justin_smith(pop-pushable? ::waste ::foundation 2)
19:27justin_smithshould work with the definitions you have there
19:27emaczenI tried it like that too and it still says wrong number of args
19:28emaczenI'm going to try restarting my repl
19:28justin_smithdid you do (def pop-pushable? nil) before redefining the defmulti?
19:29justin_smithbecause just running defmulti again will not replace the old dispatch
19:29justin_smithit's varargs, it should only complain about argument count if you provide less than 2 args
19:29emaczenjustin_smith: yeah, I didn't set it to nil
19:30justin_smith$source defmulti
19:31lazybotdefmulti is http://is.gd/nhS5dG
19:31justin_smithemaczen: look at the when-not near the bottom of the definition of defmulti
19:31justin_smithit doesn'
19:31justin_smitht do anything if the multi is already a multi
19:31justin_smithso assigning to nil explicitly is needed in order to redefine the dispatch
19:32justin_smithwell, asigning to anything that is not a multimethod, or deleting the var itself from the namespace
19:32justin_smithbut the former is easier
19:33emaczenI get a null pointer exception now
19:34justin_smithyou need to redefine the multifn and it's methods after assigning to nil
19:34emaczenjustin_smith: I think this is actually in the definition of my multi-method... lol
19:34emaczenI'll keep playing with it
19:34justin_smithoh, OK then :)
19:35justin_smithhere's a funny one:
19:35blake_Can map return a map? =P
19:35justin_smith,(nth nil 2)
19:35clojurebotnil
19:35justin_smith,(nth () 2)
19:35clojurebot#<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>
19:36justin_smithblake_: you can use (into {} (map ...))
19:36justin_smiththat makes the map eager of course, because {} cannot be lazy
19:36blake_justin_smith: Sure, I was just noting the lexical oddity.
19:36justin_smithahh, OK
19:36justin_smithyeah, that bugs me sometimes
19:37blake_Homophones, man. How do they work?
19:37amalloyobviously we should just call them dictionaries
19:37amalloyi think these are actually hononyms, right, not just homophones
19:37justin_smith,(def territory {})
19:37clojurebot#'sandbox/territory
19:37blake_Yes. There's also "associative arrays", though 'tis cumbersome.
19:37justin_smithamalloy: homonym
19:38justin_smithoh, they are homophones too
19:38justin_smithas many homonyms are
19:38blake_justin_smith: All homophones are homonyms. No, strike that, reverse it.
19:38blake_ALl homonyms ar ehomophones.
19:38amalloyblake_: injective cartesian relations
19:38justin_smiththere are homophones that are not homonyms
19:38justin_smiththere are homonyms that are not homophones
19:38justin_smithlike read
19:38blake_amalloy: That's good jargon!
19:38justin_smiththat is homonym but not homophone
19:39blake_justin_smith: Well, but not at the same time.
19:39emaczenclojure.core/swap!
19:39emaczen([atom f] [atom f x] [atom f x y] [atom f x y & args])
19:39amalloyblake_: huh?
19:39blake_justin_smith: If you're saying "red" and "reed", they're no longer homonyms (or homophones).
19:39justin_smithI'm just saying, all four options are available: a, b, both a and b, neither a nor b
19:39emaczenWhat do the the different vectors [atom f] [atom f x] mean?
19:40justin_smithblake_: I mean "I read it" and "I will read it"
19:40emaczendifferent possible inputs?
19:40emaczenmethod overloading I mean?
19:40justin_smithemaczen: possible arities of a function
19:40blake_amalloy: lol, sorry, I thought you were suggesting "injective cartesian relations" as a new way of saying "map".
19:40justin_smithemaczen the only kind of overloading we have is argument count
19:40amalloyblake_: i was
19:40amalloyi'm objecting to your homonym/homophone claims
19:41amalloyjustin_smith: lead and lead are probably a better example, since read and read have similar origins/meanings
19:41justin_smithmuch better example, thanks
19:41blake_amalloy: Homophones include homonyms, if I'm not mistaken. Homonyms are homophones that are spelled the same.
19:41amalloyblake_: no. homophones are pronounced the same (as the -phone suffix suggests)
19:41justin_smithblake_: no, I already explained
19:42amalloyhomonyms are spelled the same
19:42justin_smithsome homophones are homonyms, but not all, some homonyms are homophones, but not all
19:43amalloywhat i don't quite get is the difference between a homonym and homograph
19:43blake_Mmmmmm. OK, we're using different definitions. "lead" and "lead" are homographs.
19:43justin_smithblake_: these words are in the dictionary
19:44blake_Sorry, this is my default:
19:44blake_In non-technical contexts, the term "homonym" may be used (somewhat confusingly) to refer to words that are either homographs or homophones.
19:44blake_http://en.wikipedia.org/wiki/Homonym
19:44justin_smithblake_: homograph is a synonym for homonym
19:44blake_I recommend that page there.
19:45emaczenwhat does {:keys [some variable]} do?
19:45justin_smithemaczen: argument destructuring by keyword
19:45justin_smith,(let [{:keys [a b]} {:a 1 :b 2}] (+ a b))
19:45clojurebot3
19:46justin_smithblake_: fascinating, I didn't realize that more technical definition existed
19:47blake_justin_smith: Yeah. It actually is a lot better than the common definition, which causes much confusion.
19:47justin_smith(inc blake__
19:47justin_smitherr
19:47justin_smith(inc blake_)
19:47lazybot⇒ 1
19:47blake_(Or, when some jackass uses the non-common definition without quailfying.)
19:47justin_smithwat
19:47blake_lol
19:47blake_I lost my braces.
19:47blake_(inc {blake})
19:47lazybot⇒ 2
19:47blake_lol
19:47blake_THE LOOPHOLE!
19:48justin_smithwhat was that unicode? I am in a tty and I just got a replacement character
19:48justin_smith(identity blake_)
19:48lazybotblake_ has karma 1.
19:49emaczen,(def m {:a 1 :b 2 :c 3})
19:49clojurebot#'sandbox/m
19:49emaczen(update-in m :a (fn [x] (+ x 1)))
19:49emaczen,(update-in m :a (fn [x] (+ x 1)))
19:49clojurebot#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Keyword>
19:50emaczenwhy doesn't that work?
19:50justin_smithemaczen: [:a]
19:50amalloyemaczen: you are forgetting the brackets again
19:50emaczenthanks guys!
19:56blake_For finding all the unique keys in a sequence of maps "(keys (apply merge x1))". Tacky?
19:59emaczenI need to update two lazySeqs in an atom -- I want to remove the first element of one of the lazySeqs and conjoin it to the front of the other.
19:59emaczenCan you guys give me some advice?
20:00emaczenswap! only takes one function
20:00amalloyemaczen: write a pure function that takes in two lazy seqs and returns two new ones
20:00amalloyforgetting about the atom entirely
20:00amalloythen, once that works, adapt it to your atom
20:04emaczenamalloy: I made my function, now how do I correctly pass the arguments?
20:04justin_smithit should have exactly one argument
20:05emaczen(defn pop-push [l1 l2] [(rest l1) (conj l2 (first l1))])
20:05emaczenThat is my function
20:05amalloyemaczen: what is in your atom, and what does your function look like?
20:06emaczenamalloy: there are two lazySeqs (lists) in the Atom that are relevant for pop-push
20:06amalloyemaczen: write your function so that it takes as input exactly whatever object is currently in the atom. like, how are you storing two things in one atom? as a list? then your function should take a list and return a list. as a map? then your function should take a map and return a map
20:07emaczenamalloy: The atom is a map
20:12vasHi. I want to have short-ids for a bunch of posts that live in a datomic database. I am thinking maybe I can devise a hash function that will figure out the entity ID from the letters and numbers of the short ID (for example, 17592186045438 would map to a667qq2 or some such). Is this a reasonable approach?
20:13justin_smithvas: what would you do to handle collisions?
20:14emaczenamalloy: The two lazySeqs (lists) are values in the map?
20:14emaczen(defn pop-push [l1 l2] [(rest l1) (conj l2 (first l1))])
20:14vasjustin_smith: excellent point. does it make more sense to add a unique identifier "on the fly" to the datomic entities?
20:14vas(and maybe just go incrementally?)
20:15justin_smithvas: that would likely be simpler
20:15vasyou got some good words in them fingers. thanks yet again friend
20:16justin_smithunless there is some clever scheme for short IDs that handle collisions elegantly (for all I know there might be), in which case use that of course
20:16justin_smithI try
20:16emaczenamalloy: should pop-push take a map? Or should it take two lists?
20:16amalloyemaczen: it should take exactly what is in your atom
20:16justin_smithemaczen: if you want to update a map, have it take a map
20:18emaczenI'm trying to use swap!
20:18emaczenSo I am trying to make the function that swap! takes
20:18justin_smithin that case, have it take a map, and return one
20:19emaczenjustin_smith: I will try that
20:22emaczen(defn pop-push [m]
20:22emaczen (update-in m [:waste] (fn [] (conj (first (:deck @state)) (:waste @state))))
20:22emaczen (update-in m [:deck] rest))
20:22emaczenOops
20:22justin_smithemaczen: that would work if you chained it using ->
20:22emaczenI'll make a paste for this
20:22amalloyemaczen: remember, this is a pure function. it doesn't take in an atom of a map, but a map
20:23amalloyjustin_smith: no, there are at least two other things wrong
20:23justin_smithyes, you are right
20:24amalloyemaczen: try what i was suggesting: forget about the atom entirely. (def sample-map '{:waste (1 2 3) :deck (4 5 6)}), and then write a function that takes in sample-map and returns a new map the way you want it
20:24emaczenso I removed, the dereferencing
20:24amalloyonce you have that, the atom will be super-easy to add
20:25justin_smithemaczen: you want no reference to the state global
20:25justin_smithjust use the map that gets passed in
20:25emaczenOkay, let me try this again
20:25ludbekdoes anyone here know how to use clojurescript for meteor development?
20:26godd2ludbek quick google leads to meteor-clojurescript: https://github.com/mystor/meteor-clojurescript
20:27emaczen(defn pop-push [m]
20:27emaczen {:waste (conj (:waste m) (first (:deck m)))
20:27emaczen :deck (rest (:deck m))})
20:27emaczenHow about that?
20:27ludbek@godd2, i tried it, but the compiled code some 27k big
20:27ludbek@godd2 is it supposed to be so?
20:28justin_smithemaczen: if you use -> chained update-in, (or at least a merge) it would work even if you added more keys to the map
20:28amalloyemaczen: that looks pretty good to me
20:28godd2ludbek No clue. You might be able to tweet ben orenstein and ask him. I know he does a lot of clojurescript as of late
20:28justin_smithemaczen: it's really common to add keys to a map, so code that needs to be edited to add the extra keys is often regretted
20:28amalloyemaczen: that function should now just work: (swap! some-atom pop-push)
20:29emaczenjustin_smith: I'll try the chained variant once this works
20:30emaczenamalloy: Thanks so much! This should take me pretty far :D
20:32ludbek@godd2 thanks
20:45emaczenjustin_smith: the other function that I was asking about first works too :)
20:45emaczenthanks so much guys!
20:46gfredericksdoes anybody know of an approach to using schema or something similar to describe coersions as well as vanilla schemas?
20:49justin_smithemaczen: it shouldn't, unless the update-ins are chained with ->
20:49justin_smithemaczen: or is that what you mean?
20:50emaczenI'm not using update-ins.
20:51justin_smithoh, I thought that was what you meant by the other function
20:51emaczen (fn [m]
20:51emaczen {:waste (conj (:waste m) (nth n (:deck m)))
20:51emaczen :deck (nthrest (:deck m) n)})))
20:51emaczenI'm doing that
20:51emaczenother function refers to the multi-method questions I had earlier
20:51justin_smithoh, OK
21:02emaczenhow can I get the first 3 elements of a list?
21:02emaczenIs there a function like nthrest?
21:02justin_smith(take 3 l)
21:03emaczencool!
21:04amalloynthrest is the opposite, it would remove the first 3
21:04justin_smithwhen would you use nthrest instead of drop?
21:05amalloyprobably never. but they have different laziness characteristics
21:05justin_smithwhere drop is lazier?
21:05amalloyso in theory you might have situations where you'd prefer nthrest
21:05amalloyyeah
21:15xapakHello.
21:17xapakI’m new to Clojure (I may have tried it before, but this time is for real), and I’d like to know what projects do you recommend to check their source code for “elegantness” and “succinctness”. I’ve been tasked to do a CLI, but also the library part of it (functional), so I’d like to follow some code guideliness besides just the Best Practices on “paper”.
21:20emaczenjustin_smith: how can I define two optional paramters to a multi?
21:21emaczenI tried just adding another argument as well placing another &
21:34justin_smithall the args after the first two are put in one collection
21:35justin_smith,((fn [& args] args) 1 2 3 4)
21:35clojurebot(1 2 3 4)
21:35emaczenis it treated as var args or as a list inside the function?
21:36justin_smithit is var args, which means that inside the function it is a list
21:36emaczenThere isn't another way to do it?
21:36justin_smithyou can use destructuring
21:36justin_smithbut that's just destructuring the list
21:37justin_smith,((fn [& [a b c]] c) 1 2 3)
21:37clojurebot3
21:37emaczenjustin_smith: cool! I'm happy with that
21:51skynet9001is there a good way to see out of date dependencies in a lein project?
21:52gfrederickslein ancient
21:52gfrederickswhich might be a plugin
21:52skynet9001thanks
21:52gfredericksnp
21:53xapakI’ll ask again in case it was missed:
21:53xapakI’m new to Clojure (I may have tried it before, but this time is for real), and I’d like to know what projects do you recommend to check their source code for “elegantness” and “succinctness”. I’ve been tasked to do a CLI, but also the library part of it (functional), so I’d like to follow some code guideliness besides just the Best Practices on “paper”.
21:55justin_smithxapak: flatland/useful, the various ring libraries, pretty much anything from prismatic
21:56xapakPrismatic... I seem to have heard or something from them before.
21:56xapakjustin_smith, awesome, thanks. :)
21:56justin_smithxapak: they make schema, plumbing, and graph
22:05skynet9001anyone here use the chestnut webapp template?
22:20skynet9001I'm getting "ReferenceError: goog is not defined" after using lein ring uberwar on a chestnut project and deploying on tomcat, any ideas?
22:21justin_smithskynet9001: how are you building your cljs? are you turning on optimizations?
22:22skynet9001justin_smith: looks like :optimizations :none
22:23justin_smithtry running 'lein with-profile -dev,+uberjar cljsbuild once' before making the uberwar
22:26skynet9001will try that, thanks
22:31skynet9001so that didn't work, but I'm looking at the /public/js/ directory and it's missing the out.js.map file, although I have :sourcemap "resources/public/js/out.js.map" defined in the cljs build
22:32skynet9001I don't see the resources/public/js/out.js.map file in the project, how do I create it?
22:42justin_smithcljsbuild should create that. maybe cljsbuild clean then build again?
23:03skynet9001still nothing, weird
23:03skynet9001I had it working on another machine earlier today, maybe something's misconfigured on this vm
23:04skynet9001this is all just the base chestnut template
23:07justin_smithI don't see what vm config could break chestnut
23:08skynet9001I think on this one I had installed openjdk 8 before installing 7, maybe that had something to do with it
23:08skynet9001gonna try a fresh start
23:20GuthurHi, I'm trying to create my own leningen template standard-project. I created the project with lein new template standard-project editted it and then ran lein install
23:20Guthurthere were no errors but when I try to use my template with lein new standard-project foo it gives the following...
23:20GuthurFailed to resolve version for standard-project:lein-template:jar:RELEASE
23:21Guthurany suggestions?
23:27ddellacostais there a reason to use atoms vs. dynamic vars for configuration of libs?
23:27ddellacostaor even something else?
23:33justin_smithddellacosta: a global atom will usually limit how a lib can be used
23:35ddellacostajustin_smith: so, if I make configuration an atom, that's going to ensure that/restrict it so that the configuration is accessible across threads, no?
23:35ddellacostavs. dynamic vars being thread-local--that's the big distinction, am I right?
23:35justin_smithI think the cleanest is the c.j.jdbc approach of a configuration arg, that a client can esaily partially apply
23:38justin_smithyeah, an atom means a global config, dynamic vars, thresd local, configuration argument is lexically scoped
23:38ddellacostajustin_smith: trying to understand what you mean here--you're talking basically about config always getting passed in as fn args, basically?
23:38ddellacostajustin_smith: in reference to c.j.j being ideal
23:38ddellacosta(if that's the case would agree)
23:38justin_smitha map ad the first arg, yeah
23:39justin_smiththe first, because we have partial
23:43justin_smiththe atom and dynamic var versions can be implemented by the end user in two lines of code
23:43justin_smith(given the explicit argument version existing, and taking the config as the first arg)
23:44justin_smiththe others are not so flexible