#clojure logs

2015-07-30

02:22ddellacostaso, finally giving Stuart Sierra's component a shot, and I'm having trouble replicating the basic functionality in the repl
02:23ddellacostaI suspect it's actually a referring-to-records problem vs. a problem with how I'm using component, but it seems like none of the behavior I've added to the record is actually getting performed--for example, just doing a basic assoc with 'this' similarly to how he does it in the README doesn't work
02:24ddellacostaI just get the record back as it was
02:24ddellacostaand printlns don't do anything either
02:24ddellacostawhich makes it seem like there is a no-op running vs. my actual protocol implementation
02:24ddellacostaanyone seen this kind of behavior using component (or types/records in general) in the repl?
02:31ddellacostathis gist shows what I'm trying to do, and how it's failing: https://gist.github.com/ddellacosta/07be4db31425f4827f1a
02:32noididdellacosta, try running lein clean before you start the repl
02:32ddellacostanoidi: I've restarted the repl and run lein clean a few times, don't believe that's it
02:33ddellacostawill try it again once more to make sure though
02:36ddellacostayep, no luck with that (again). It's also suspicious because I've never implemented my record with no-ops--I've always had it at least printing. So I would assume that if there is some old instance of my record in memory it would be using that--but it's clearly just doing nothing.
02:57crocketHow do I specify datetime in edn?
03:00crocketOh, there is https://github.com/edn-format/edn#inst-rfc-3339-format
03:01crocketedn is good as a wire format.
03:01crocketAlthough it could be slower than other wire formats.
03:02crocketDo you use edn as your wire format?
03:18seangroveIs there any way to check if a value is a core.async channel?
03:20seangroveNooooooope http://dev.clojure.org/jira/browse/ASYNC-74
03:34arrdemcrocket: no, don't do that, use parquet or avro or protobuffs or transit or something else
03:34crocketarrdem, Why?
03:34crocketperformance?
03:35clojurebothttp://clojure.org/java_interop#toc46
03:35arrdemit is possible to use edn as a wire protocol, as it is possible to use json, it's just encoding inefficient
03:35arrdemarguably gzip streams get around some of this, but it's still a thing
03:36arrdemat work we've reaped a huge performance win from using parquet to store lots and lots of what were previously EDN records on disk / move em over wire
03:38arrdemBut maybe you don't care, try em and see
03:38arrdemOnly You Can Profile Your Code
03:39crocketHow do you document your wire format?
03:39crocketDid you document your API interface independent of wire format and wire protocol?
03:40arrdemShort answer is we don't, we're using parquet to move a lot of data which fits a single uniform schema and use a (could be thinner) Java layer to interact with it from Clojure
03:41arrdemso this may not be a great datapoint for you if you're interested in a message protocol of some sort
03:41crockethmm...
03:41crocketProbably, it is not a public API.
03:41crocketIt's ok to not document at all if it is an internal thing.
03:42arrdemI mean it is documented in so much as parquet is a versioned, schema based compiled encoding and ther exist docs for the Java classes that wrap parquet encoded "objects".
03:43arrdembut being internal and an implementation detail such docs are languishing
03:44arrdemI thin a reasonable approach would be to design your procol first and prototype it with an EDN encoding, get that working, and then rework it to use some tighter format for performance once you have documentation and desired behavior.
03:44arrdembut that's also Brooks' plan to throw one away which you may not be game for
03:48ddellacostahmm, is it possible component isn't working for me as advertised because of Clojure 1.7?
03:48crocketarrdem, Is parquet for storage or wire?
03:48ddellacostaI just realized he says he's only tested with 1.6 and below
03:48arrdemcrocket: it's just a data encoding you can do both with it.
03:48arrdemsocket.write(parquet.getBytes())...
03:49arrdemcrocket: we're using it for on disk (HDFS) data storage
03:51crocketDo you send parquet on the wire, too?
03:51arrdemno, that I can't speak directly to
03:52arrdemI mean we do in so much as HDFS does it magically for us
03:52arrdembut I'm not piping parquet data over sockets if that's the goal
03:57crocketWhat goes over the wire?
04:36tgoossensI have to do doseq over a possible large array (millions). Is there an easy way to parallelize this?
05:05arrdemGrimoire 0.4.23 live now with 1.7 special forms (issue 213/214) not broken and a minor fix or two.
05:05arrdemsleep now
05:31dabdI have small app that writes some files to the filesystem. I packaged it with lein uberjar. If I call -main from the REPL it works fine, however if I run it from the cmd line it won't write anything. Anything I am missing?
05:34Kneivadabd: how do you run it from command line?
05:34dabdwith java -jar <standalone jar> arg1 arg2 ...
05:36dabdI think I found the problem. The side effects were being called inside a 'map' which is lazy and probably the repl forces the evaluation which won't happen when I call it from the cmd line. I switched the map to run! and now it works
05:36Kneivagreat
05:36dabddoes this make sense?
05:36Kneivayes
05:37dabdsupposing I wanted to use map how do I force the evaluation?
05:38MasseRdabd: haven't written clojure for a while, but wasn't there something like doseq which forces evaluation?
05:38MasseRUse map for pure computations and doseq for side-effects
05:40dabdyes makes sense
05:58cflemingSomewhat OT: I just know enough IRC to get connected and then not touch anything. Recently for some reason I started receiving private messages from *status every time I connect to my ZNC instance. Does anyone know how to disable that? I'm using Textual on OSX.
07:07perplexagfredericks: didn't you put up some black magic 'timestamps' created only with the java math lib? can you gimme a link pls?
07:20Cka3Hello, can someone help me? I need to figure out how to get from two collections e.g. [2 8 6] [8 5 1] one collection of collections like this ([2 8 6][3 7 5][4 6 4][5 5 3][6 5 2][7 5 1][8 5 1]) ?
07:21alexyakushevCka3: Where are the other elements coming from?
07:21zphdsCka3: you could flatten the source coll and use permutations
07:21zphdshttp://clojure.github.io/math.combinatorics/
07:22alexyakushevzphds: It doesn't look lke permutations, more like reducing the last number and increasing the first one, but still unclear
07:22Cka3here is my first step
07:22zphdsalexyakushev: yes, you're right
07:22snowellLooks like it's showing intermediate steps to transform the first one into the second one
07:22snowellUsing inc and dec
07:22Cka3(let [from-color [2 8 6]
07:22Cka3 to-color [8 5 1]
07:22Cka3 step 1
07:22Cka3 direction (fn [a b] (map #(if (> %1 %2) - +) a b))
07:22Cka3 crange (fn [a b c] (conj (vec (range a b (c step))) b))
07:22Cka3 ]
07:22Cka3 (map crange from-color to-color (direction from-color to-color)))
07:23Cka3=> ([2 3 4 5 6 7 8] [8 7 6 5] [6 5 4 3 2 1])
07:23Cka3I'm very new to programming)
07:24Cka3([2 8 6][3 7 5][4 6 4][5 5 3][6 5 2][7 5 1][8 5 1])
07:24Cka3this what I need to get)
07:28Cka3Any ideas? ))
07:29Cka3Rich? )
07:29justin_smithCka3: don't do multiple line pastes, please. Use a site like refheap.com for that
07:30Cka3Sorry
07:31justin_smithCka3: your "c" argument to crange needs to be a function you can call, and direction does not return a function
07:32justin_smithactually to be correct, direction would have to return a sequence of functions
07:32justin_smithor you would have to do something with c other than calling it
07:33Cka3it returns collection of functions + or -
07:33justin_smithoh, wait, never mind, it does return a sequence of functions
07:33justin_smithright
07:33Cka3but I having problem with the next steps
07:34Cka3how I can go from this ([2 3 4 5 6 7 8] [8 7 6 5] [6 5 4 3 2 1]) to this ([2 8 6][3 7 5][4 6 4][5 5 3][6 5 2][7 5 1][8 5 1])
07:34justin_smithCka3: (apply mapv vector) will give you your answer
07:35justin_smith,(apply mapv vector '([2 3 4 5 6 7 8] [8 7 6 5] [6 5 4 3 2 1]))
07:35clojurebot[[2 8 6] [3 7 5] [4 6 4] [5 5 3]]
07:35justin_smithexcept one of your sequences is too short, you need to fix that
07:35Cka3no I don't)
07:35justin_smithOK, then don't use the simple solution
07:35justin_smithand fix it some other way
07:37justin_smithCka3: the straightforward solution would be to fill the short inputs by repeating the last element until they are equal in length to the longest
07:37justin_smithfollowed by mapv vector
07:37Cka3so I need to check which collection is longest and then for other two collections fill missing items with last element of themselves?
07:38justin_smithor you could use a loop
07:43justin_smiththe loop version is a lot uglier
07:48justin_smithCka3: this gives the right answer, but it is ugly I think https://www.refheap.com/107264
07:56justin_smithCka3: I updated the paste above, maybe the second version is a bit better
08:02Cka3thank you!
08:04gfredericksperplexa: I think what you're remembering was just some tweets, and I can't search twitter effectively enough to find them; but this is related https://gist.github.com/gfredericks/96e284ce2d52b91d481e
08:05gfredericksoh just kidding, searching for "Math/cbrt" worked: https://twitter.com/gfredericks_/status/517622176821043200
08:06justin_smithgfredericks: OH, I remember when we were mucking with that stuff!
08:07justin_smithmaking arbitrary doubles using only java.lang.Math and no literals
08:11perplexagfredericks: thanks
08:13gfredericksjustin_smith: I don't think I succeeded in getting arbitrary doubles; I got pretty close though
08:13gfredericksI think arbitrary integers for sure
08:14gfredericksthough I guess in the 2^53 range that's about the same problem
09:06jonathanjuser=> "\003"
09:06jonathanj""
09:07jonathanji'm assuming that the \003 is elided from the REPL output there because it's not printable, but how can i actually be sure?
09:14opqdonutjonathanj: try (seq "\003") to look at the characters in the string
09:15opqdonut,(seq "\012\141") -- like this
09:15clojurebot(\newline \a)
09:15opqdonut,(seq "x\003x")
09:15clojurebot(\x \ \x)
09:16opqdonutwell that looks weird
09:17justin_smith,(first "\003")
09:17clojurebot\
09:17justin_smithhaha
09:17opqdonut,(seq (.getBytes "\003"))
09:17clojurebot(3)
09:17opqdonutso it really is there
09:18opqdonut,\o003
09:18clojurebot\
09:18opqdonut,\o004
09:18clojurebot\
09:18opqdonuthrmph
09:19opqdonut,[\o010 \o016]
09:19clojurebot[\backspace \]
09:19opqdonutright, clojure probably just prints \<the character> when you don't hit one of the \tab \newline etc. special cases
09:19opqdonutor rather, tries to print
09:20justin_smith,(apply str [\a \backspace \b])
09:20clojurebot"a\bb"
09:20justin_smithhrmph
09:20justin_smith,(print (apply str [\a \backspace \b]))
09:20clojurebotab
09:41tgoossensgiven a map m , how can i update the values of m (for all keys) given a transform fn
09:41justin_smith,(into {} (map (fn [[k v]] [k (inc v)]) {:a 0 :b 1 :c 2}))
09:41clojurebot{:a 1, :b 2, :c 3}
09:42tgoossens<3 destructuring, justin_smith thanks!
09:42justin_smithor ##(reduce-kv (fn [m k v] (assoc m k (inc v))) {} {:a 0 :b 1 :c 2})
09:42lazybot⇒ {:a 1, :b 2, :c 3}
09:44snowellIs using `for` more/less efficient than map/reduce?
09:44snowellAh, he did say "given a transform fn"
09:45snowellTurns out the best way for me to read something is to hastily reply to it :/
09:45justin_smithsnowell: for should be pretty much equivalent to map
09:45i-blissnowell, I think the difference might come from into vs .kvreduce
09:46i-blisinto uses transients (and I guess reduce doesn't use mutation)
09:47justin_smiththe reduce-kv version could easily be updated to use transients, of course
09:48justin_smith(persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (tansient {}) {:a 0 :b 1 :c 2})
09:48justin_smith,(persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (tansient {}) {:a 0 :b 1 :c 2})
09:48clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
09:48justin_smitherr
09:48i-blisyeap, one could wrap it in persistent!
09:48justin_smith,(persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (tansient {}) {:a 0 :b 1 :c 2}))
09:48clojurebot#error {\n :cause "Unable to resolve symbol: tansient in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: tansient in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6611]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: tansien...
09:48justin_smithhmm
09:48justin_smith,(persistent! (reduce-kv (fn [m k v] (assoc! m k (inc v))) (transient {}) {:a 0 :b 1 :c 2}))
09:48clojurebot{:a 1, :b 2, :c 3}
10:23csd_Is it possible to have `lein repl`, when run inside a project dir, *not* execute the project's top level forms?
10:24justin_smithcsd_: you can not specify a :main, you can use lein run -m clojure.main to launch a vanilla repl that does not load your project
10:24justin_smithbut that's not going to be an nrepl, of course
10:24csd_justin_smith: would that still allow access to the project deps as needed?
10:24justin_smithcsd_: via require, yes
10:25csd_cool thank you
10:26justin_smithcsd_: lein is hella convenient, but I think there's something to be said for knowing how to set things up by hand too
10:26csd_another unrelated question-- my coworkers are telling me that an uberjar can only package up clojure deps, and not java deps. so instead we're using an eclipse package that does this but its really clunky. do you know of any alternatives?
10:27justin_smithcsd_: :provided in project.clj should prevent the dep from being packed into an uberjar
10:27csd_no we want to have an uberjar that has every dependency in it, whether clojure or java based
10:28justin_smithcsd_: oh, they are claiming a clojure uberjar is unable to contain java deps? that's patently false
10:28justin_smithjust add the java dep to your dependencies, it just works
10:28justin_smithI thought they were saying those deps should be excluded
10:28csd_hrm i don't know then
10:29clgvcsd_: uberjar it is then ;)
10:30justin_smithcsd_: well anyway, if your uberjar was including a thing erroneously, you can use the :provided {:dependencies [things you want but not in uberjar]} thing, and for java deps you do want in an uberjar, you just convert the maven coordinates to lein notation, which is easy, and put them under :dependencies
10:30TimMccsd_: Every uberjar I've ever made disagrees with their claim.
10:30csd_i see
10:30csd_would this still work for java dependencies that are accessed locally and which arent hosted on maven/etc?
10:31justin_smithcsd_: you would need to at least run lein install, or put them in resources/ or something
10:31justin_smith(or mvn install or whatever)
10:31justin_smithit's really not hard to make a maven accessible jar of something
10:31clgvjustin_smith: putting them in resources requires some serious weight lifting to load them afterwards ;)
10:32justin_smithcsd_: like adding resources/foo.jar to your classpath?
10:32justin_smitherr, that was for clgv
10:32csd_ok well idk what they're talking about then
10:32clgvjustin_smith: would work from leiningen but not from the uberjar afaik
10:33justin_smithclgv: but yeah, the better solution is to put the jar into a maven repo
10:33justin_smithclgv: resources end up in your uberjar
10:33clgvcsd_: for repeatable builds from different dev machines you should host those dependencies anyway
10:33csd_yeah
10:33clgvjustin_smith: that's true but there is no eays way to add a jar within a jar to the classpath
10:33csd_just a lot of other things need doing too :-P
10:33justin_smithyeah, we use s3-wagon-private, but I think we should upgrade to a regular private maven server
10:34clgvcsd_: but broadcasting new deps is annoying as well, isnt it?
10:34csd_it really only applies to two things, and one of them is fairly stable
10:34clgvcsd_: not to mention potential inconsistencies
10:35csd_we have a hacked version of one serialization library, and the other is our java platform code which we export some of into a jar
10:35csd_the serialization library has been fairly stable
10:35clgvsetting up a repository is not that hard
10:37csd_do you know of a good guide?
10:38clgvcsd_: those repository tools usually have their guide. I checked archiva and nexus where that is the case
10:38justin_smithcsd_: iirc nexus has a good walkthrough
10:42clojurehelp me ? "Cannot cast clojure.lang.PersistentVector to [Ljava.lang.Class;" my code: (def ctor (-> clazz (.getDeclaredConstructor [String, String, int])))
10:43clojure help me ? i got a exception: "Cannot cast clojure.lang.PersistentVector to [Ljava.lang.Class;" here is my code: (def ctor (-> clazz (.getDeclaredConstructor [String, String, int])))
10:43csd_How do I refer to a Java compiled class (Foo.class) in clojure? I'm getting a class not found error. Specifically this is to mimic something like Guice's Key.get(Thingie.class, annotation) syntax
10:46clgvclojure: read that blog post (or tutorial) more carefully
10:48noncom|3speaking of idiomatic clojure.. if you have some program or a script, big enough to be spread over several namespaces, and which conducts some process, do you prefer to pass the state among all the functions in the program or do you reside to storing it in an atom?
10:49noncom|3i find storage in atom far more convenient in most occasions, however, i wonder what others think..
10:49TimMcclojure: Do you need help understanding the exception?
10:49TimMcOr what?
10:51noncom|3clojure: i think you need (into-array [String, String, int]) ... ?
10:51noncom|3coz [] is not [Ljava.lang.*
10:52noncom|3csd_: even better - push you library to clojars and enjoy the eternal benifits of repeatability right away!
10:54clgvcsd_: use only the class name itself
11:00jonathanjso there was no real consensus as to how i get \003 to usefully display in a REPL?
11:01jonathanjit would be nice if non-printables were just printed in their escaped octal form
11:03opqdonutjonathanj: indeed it would
11:03jonathanjcan i file a bug somewhere?
11:03noncom|3in jira?
11:04opqdonutjonathanj: you could just use StringEscapeUtils to get the escaped string back, but yeah, file a bug
11:04noncom|3or maybe in the issue tracker of the particular repl you're using...
11:05jonathanjdoes the REPL itself construct the representation?
11:22noncom|3jonathanj: not sure what you mean... repl is the one who presents you the data
11:22noncom|3i think that you can sorta change this data before it presents it to you
11:23noncom|3other details depend on the particular repl you use
11:23clgvjonathan: prn
11:23clgv,(prn \003)
11:23clojurebot#<RuntimeException java.lang.RuntimeException: Unsupported character: \003>
11:23tmtwdAre there any libraries for putting in html and spitting out hiccup?
11:24clgvhuh?
11:24clgv,(prn (char 3))
11:24clojurebot\\n
11:26jonathanji'm not sure how it works with Clojure, but with Python presenting a representation of data is generally up to the data type via the repr() API
11:26clgvjonathan: clojure has the print-method multi method
11:27jonathanjcan i determine whether there is a method defined for a particular type?
11:28jonathanjanyway, is it truly solely up to the REPL to determine how best to display the result of every value?
11:29clgvjonathan: as I said, that is the task of the print-method
11:30jonathanjokay, so filing the bug against the REPL i'm using is probably not the right course of action
11:30clgvjonathanj: indeed.
11:31clgvjonathanj: you can look up the types via ##(keys (.getMethodTable print-method))
11:31lazybot⇒ (nil java.lang.Boolean clojure.lang.Var java.lang.Character clojail.testers.ClojailWrapper clojure.core.Iteration java.util.Date java.lang.Class java.util.RandomAccess java.util.regex.Pattern java.util.UUID :default clojure.lang.ISeq java.sql.Timestamp clojure.lang.... https://www.refheap.com/107273
11:33clgvjonathanj: you can override as follows: (defmethod print-method Character [x, w] (.write w (format "char: %s" (long x))))
11:34clgvjonathanj: though that only handles single characters
11:41tmtwdI meant if there are any libraries that let you input raw html and outputs hiccup-html
11:41tmtwdthat way I can paste templates from bootstrap and use hiccup instantly
12:20csd_is there any other magic i need to do to get slamhound.el working other than jacking in with cider? It looks like it's having trouble talking to the nrepl
13:08dabdanyone has an idea what the function parse-opts from tools.cli expects as first argument? (parse-opts ["-h"] ["-h" "--help"])
13:08dabdthrows an exception
13:09dabdI meant (parse-opts ["-h"] [["-h" "--help"]])
13:32TimMclgtm
13:46slesterIs there accepted style for using (cond->)? Do I just use a space after each condition or do I line up conditions and functions?
14:07kwladykaI am so confuse... i have my own algorithm in Clojure and i have not my algorithm in Scala. This one in Scala run in 1 sec, but my don't stop after 30 minuts. As i see they do exactly the same.... somebody is able to help me understand why is that?
14:08bjaare you sure they are the same?
14:08bja(i.e. not using mutable ops in scala)
14:08kwladykaif i see good they do the same
14:09bjado you have an example somewhere (maybe a gist)?
14:09kwladykahttps://github.com/VlachJosef/scalac-chess-problem/tree/master/src/main/scala/vlach/josef <- scala super fast
14:10kwladykamy, the most important part https://www.refheap.com/76772dd5a7946a727450d76bb
14:10kwladykascala use bfs and my use dfs but as i know there is no difference
14:11kwladyka*no difference in complexity
14:11justin_smithI wonder why clojure-mode wants to highlight "handle" as if it were special...
14:12kwladykai have maybe a little mess in code because i was changing it so many times and still looking right one
14:12kwladykajustin_smith, can i please you to look on my question? i am fighting with this so long
14:13kwladykado you see any mistake in my code which can make it slow?
14:13kwladykaor why scala code is so fast?
14:13kwladykait doesn't make sense
14:15justin_smithkwladyka: for starters your recursive-solutions is not tail-recursive, unlike the scala version
14:16justin_smiththe only way to do tail-recursion in clojure is recur, though you could also use loop or trampoline to the same effect
14:17kwladykajustin_smith, but is it changing anything if i will use recur instead of name of function?
14:17kwladykain performance
14:17kwladykabut ok, i can change the name to recur, it should works without changing anything else
14:18kwladykabut still it is slow
14:18justin_smithkwladyka: no, "changing the name to recur" doesn't do it
14:18kwladykaok, i can't change it so easy
14:19justin_smithand yeah, you can't just swap out the self call - you have to change how the stack is being managed
14:19kwladykabefore i was using recur with loops and it was also slow
14:19justin_smithalso, eventually you would want something other than doseq anyway, because otherwise your function will always return nil
14:19justin_smith,(doseq [i (range 10)] i)
14:20clojurebotnil
14:20kwladykajustin_smith, because the solutions is only on the end of tree i am using ref variable
14:20kwladykaand change it only if i am on the end of tree
14:21kwladykaso i dont have to return anything
14:21justin_smithOK
14:21kwladykaso... am i using something what is slow?
14:21justin_smithbtw, a ref-set that uses the existing value should be replaced with alter (see line 10)
14:22justin_smithkwladyka: yes, primitive recursion is slower than a loop or tail recursion via recur. Using a ref is slower than passing a value along to hold results
14:23kwladykajustin_smith, ref is not exaclty a problem, there is only 92 call this in example what i am trying do faster
14:24kwladykajustin_smith, hmm but loop and recur is not lazy?
14:24justin_smithno, it is not
14:24justin_smithnor is self call
14:24justin_smithwhich is what you do now
14:24justin_smithneither is lazy
14:25justin_smiththe only thing that is lazy is lazy-seq (or one of our many helpful functions that use lazy-seq)
14:25justin_smithkwladyka: that doseq on line 64 is not lazy, it will call the function again for every result, eagerly
14:25kwladykajustin_smith, so do you think if i will rewrite it with loop and recur it will change it from 40 minuts to 1 second? ;)
14:26justin_smithkwladyka: I have no idea, but I suspect that you are wasting CPU cycles in that eager doseq with self calls on line 64
14:26justin_smithbecause that is driving your algorithm, and it is not in any way lazy
14:26justin_smithnor is it fast - you want one or the other at least
14:27kwladykawhat else can i check?
14:28justin_smithkwladyka: I have no idea, I've got other stuff I need to attend to at work, sorry
14:28kwladykajustin_smith, ok, thank you for help
14:28kwladykajust.... i cant live with this problem, i am spending hours on that why it is so slow..
14:29kwladykaeveryday
14:29kwladyka:)
14:29justin_smithkwladyka: I suspect the solution will involve replacing the doseq with something lazy
14:31kwladykai was trying do this in so many ways... but i will try again, each time i am clever :)
14:31justin_smithalso the concat on line 22, you'd get a faster result by replacing all those filters with one group-by followed by some key lookups
14:32justin_smithwait, no, just use frequencies
14:32justin_smith,(frequencies [:queen :queen :rook :rook :rook :bishop :knight :bishop :knight :king])
14:33clojurebot{:queen 2, :rook 3, :bishop 2, :knight 2, :king 1}
14:34justin_smithif you really need that format ##(sort-by (zip-map [:queen :rook :bishop :king :knight] (range)) [:queen :queen :rook :rook :rook :bishop :knight :bishop :knight :king])
14:34lazybotjava.lang.RuntimeException: Unable to resolve symbol: zip-map in this context
14:34justin_smith,(sort-by (zipmap [:queen :rook :bishop :king :knight] (range)) [:queen :queen :rook :rook :rook :bishop :knight :bishop :knight :king])
14:34clojurebot(:queen :queen :rook :rook :rook ...)
14:34justin_smithmuch faster than 5 filters and a concat
14:38slesterjustin_smith, my game is coming along slowly. Still trying to parse/determine what you were saying about passing along snapshots of the game state as a lazyseq
14:39TEttingerslester: ah!
14:40TEttingerI had an idea for that
14:40TEttingerhttps://github.com/tommyettinger/infinite-raid/blob/master/src/infinite_raid/state.clj
14:40TEttingerpretty simple state tracking, it needs an RNG with a highly visible state, so you can get and reseed the RNG to earlier states
14:42justin_smithslester: in a functional language, you can replace any global state with a sequence of values, which each value is a snapshot in time
14:43justin_smithTEttinger: what's the reasoning for repeated swap! calls on the same atom? why not one assoc with multiple keys and vals?
14:44justin_smithTEttinger: the order is guaranteed ##(assoc {} :a (doto 1 pr) :b (doto 2 pr) :c (doto 3 pr))
14:44lazybot⇒ 123{:c 3, :b 2, :a 1}
14:44TEttingerjustin_smith: http://i110.photobucket.com/albums/n86/MCRfreek92/i-have-no-idea-what-im-doing-dog.jpg
14:45justin_smithhaha
14:45kwladykathx
14:45kwladykajustin_smith, thx
14:45justin_smithTEttinger: the reason I ask, is atoms have a relatively high overhead for modification, so if you reduce the number of swap! calls you'll usually see a benefit
14:45hellofunkjustin_smith: doesn't that replacement of values kinda depend on persistent data structures? not all functional languages actually implement their data in the way Clojure does
14:45TEttingeryah, I haven't touched that code in a while
14:46justin_smithhellofunk: you could do a full tree copy in a language that doesn't have immutable values
14:47justin_smithhellofunk: the only difference is that it's up to the programmer to be disciplined and not touch the history (rather than enforced fairly strongly by the language itself)
14:47hellofunkthat's one of the things that really bugs me about Swift. they have all these seductive functional idioms everywhere, but the data is fully copied when you actually "change" anything
14:47TEttingerI was wondering about using in-memory file serialization to mimic clojure in lua
14:48justin_smithyeah, and what's worse, they lead naive users to think that functional programming implies that kind of slow deep copying everywhere
14:48hellofunkit's awful.
14:48justin_smithso they try fp in swift and are like "never mind, fp is too slow"
14:48hellofunki'm saddened that apple didn't do more under the hood. but that's probably why they are open sourcing the language, they want the community to fix it
14:48TEttingerhttps://github.com/torch/torch7/blob/master/doc/file.md#serialization-methods
14:54slesterTEttinger, thanks, I'll look at it! I'm still a newbie to clojure/functional programming so it's taking me a while to process things.
14:56gfrederickshello
14:56kwladykajustin_smith, can you recommend me something to watch / read about how to write algorithm with good performance. I mean for example to use recur instead of primitive recur and use lazy instead of eager, but with explanation why and what is happening inside? to better understand how to write fast code?
15:00justin_smithslester: what I had in mind was somthing much simpler - imagine a game where :a and :b repeatedly flip a coin and keep a tally ##(iterate #(update % (if (> 0.5 (rand)) :a :b) inc) {:a 0 :b 0})
15:00lazybotjava.lang.RuntimeException: Unable to resolve symbol: update in this context
15:00justin_smith,(iterate #(update % (if (> 0.5 (rand)) :a :b) inc) {:a 0 :b 0})
15:00clojurebot({:a 0, :b 0} {:a 1, :b 0} {:a 2, :b 0} {:a 2, :b 1} {:a 2, :b 2} ...)
15:01justin_smithan immutable lazy seq containing every state the game reaches, in order
15:01justin_smith,(iterate #(update % (if (> 0.5 (rand)) :a :b) inc) {:a 0 :b 0})
15:01clojurebot({:a 0, :b 0} {:a 0, :b 1} {:a 1, :b 1} {:a 2, :b 1} {:a 3, :b 1} ...)
15:03slesterjustin_smith, ah! I'm kind of going to be doing that in a way. I have state, and I just recur until the state's "over" flag is set to true
15:04justin_smithslester: right, you could even use take-while with iterate if you wanted the full history instead of just the final state
15:04slesterI'm hesitant to show code because it's probably awful
15:04slesterah, nice idea
15:04justin_smithheh, remember it's a great way to learn if your ego can handle the bruising
15:04slesterit can, I just don't want to waste people's time
15:06justin_smithkwladyka: sorry about the delay - that is a huge subject and I can't think of something simple off the top of my head - it's likely covered in a functional way in SICP? https://mitpress.mit.edu/sicp/full-text/book/book.html which is a great textbook, available for free online, in a language very similar to clojure
15:07justin_smithhmm maybe that doesn't cover run time complexity actually...
15:09justin_smithkwladyka: you could check out using clojure.tools.trace to see how much each of your functions is getting called
15:10slester|lunchjustin_smith, https://github.com/slester/amiss is the code if you're interested. I'll be back after lunch!
15:10slester|lunchmaybe PM would be best?
15:10slester|lunchappreciated if you do have time
15:12justin_smithslester|lunch: on line 66, you don't need partial ##(apply + 1 [2 3])
15:12lazybot⇒ 6
15:13justin_smith,(map (comp {-1 false 0 nil 1 true} compare) [1 2 3 4 5] [5 4 3 2 1])
15:13clojurebot(false false nil true true)
15:14justin_smithslester|lunch: ^ suggestion for compare-cards
15:15justin_smithslester|lunch: on line 106 the two assoc-in calls could be replaced with a single assoc
15:17justin_smith,(< 1 2 5) ; slester|lunch - suggestion for line 168
15:17clojurebottrue
15:28amalloyBronsa: re clj-1460 it may be helpful to know that clojure.core/case macroexpands to something involving a sorted-map
15:30amalloyor maybe an array-map? i forget. at any rate if you macroexpand a case statement yourself and then eval it, and that case has "too many" clauses, stuff breaks because the cases are no longer in the right order
15:31Bronsaamalloy: yeah that's how I discovered that bug actually
15:31amalloyi wonder if you heard about it from me complaining about that issue in here, ages ago
15:32Bronsaamalloy: i wish i had. I remember spending hours trying to figure out why t.e.jvm was bugged.
15:33amalloyah. for me, it came up trying to use c.t.macro/macrolet
15:33amalloywhere i wound up let'ing a macro that involved a 10-clause case
15:33Bronsafun times debugging that stuff I bet
15:35amalloyi've been bitten by macrolet like 5 different times in 5 different ways, and yet the siren song of macrolet always calls me back
15:38sdegutisMy intuition about partition-by at some recent point became no longer in sync with reality.
15:39sdegutisI assumed (partition-by (partial = :z) [:a :b :z :c :d :z :e]) would give '((:a :b) (:c :d) (:e)) but it's actually giving '((:a :b) (:z) (:c :d) (:z) (:e))
15:48justin_smithsdegutis: so you were imagining it to behave like string/split does
15:48sdegutisI suppose yes.
15:49sdegutisIn fact the first function I Dash'd was split-with.
15:49sdegutisThen I realized I probably wanted something more like partition-by.
15:49sdegutis(Since I wanted it to happen multiple times, not just once.)
15:51sdegutisRight now I'm just combining that `partition-by` with (remove (partial = [:z]) ...)
15:51sdegutisSeems to work, but feels sloppy and careless.
15:51tear-------------------------------------------------
15:56wasamasasmooth
16:05Bronsaamalloy: looks like it is documented that (eval (sorted-map 1 1)) is allowed to return a PAM :/
16:10slesterjustin_smith, thanks, looking at those now
16:12sdegutiswasamasa: I don't get it.
16:13slester,(compare 1 5)
16:13clojurebot-1
16:13slesterjustin_smith, I think I was under the impression that it returned like, -4
16:14wasamasasdegutis: I guess you didn't see that /quit
16:15sdegutiswasamasa: I have them hidden. Much quieter this way: https://www.dropbox.com/s/8qh22b5vn6x5e6f/quieterirc.png?dl=0
16:15wasamasasdegutis: smart filter ftw
16:16sdegutiswasamasa: what was it?
16:16wasamasasdegutis: tear got immediately k-lined after posting
16:17sdegutisHa.
16:24sdegutisHow do you get the current year. Thanks.
16:25justin_smith,(.getYear (java.util.Date.))
16:25clojurebot115
16:25justin_smithyou probably want to add 1900
16:25justin_smith,(+ 1900 (.getYear (java.util.Date.)))
16:25clojurebot2015
16:26Bronsasdegutis: you keep asking questions not related to clojure that you could answer yourself with 20 seconds of google, could you try doing that next time before asking?
16:27sdegutisThanks, I used the Clojure library chee.datetime.
16:27sdegutis,(do (require '[chee.datetime :as dt]) (str (dt/year (dt/now))))
16:27clojurebot#error {\n :cause "Could not locate chee/datetime__init.class or chee/datetime.clj on classpath."\n :via\n [{:type java.io.FileNotFoundException\n :message "Could not locate chee/datetime__init.class or chee/datetime.clj on classpath."\n :at [clojure.lang.RT load "RT.java" 456]}]\n :trace\n [[clojure.lang.RT load "RT.java" 456]\n [clojure.lang.RT load "RT.java" 419]\n [clojure.core$load$fn__...
16:29justin_smithsdegutis: lol top google hit for chee.datetime https://github.com/slagyr/joodo/issues/27
16:31jsabeaudryIs there a csv library for clojurescript ?
16:31sdegutisMost likely.
16:32Bronsajsabeaudry: https://cljsjs.github.io/ looks like there are a few
16:33Bronsaah nevermind, those are js libraries
16:33Bronsahttps://github.com/testdouble/clojurescript.csv this seems what you need otoh
16:33sdegutisjustin_smith: how is that lol?
16:34jsabeaudryBronsa, thanks for the first link
16:34jsabeaudryBronsa, that second one cannot read csvs haha
16:34sdegutisBronsa: Sometimes #clojure surprises me with very excellent pure-Clojure answers that aren't in the top Google results.
16:35Bronsasdegutis: "how to get the current year" is hardly a question you'd expect to get such an answer
16:35sdegutisBronsa: You never know!
16:35sdegutis:)
16:52slesterit's why I try to google and understand things before I ask here, and why I'm afraid to actually post code snippets until I've tried to vet them myself heh
17:01phyzomeslester: As long as it's clear you're putting in some effort of your own it's fine to ask questions and link to snippets!
17:09jsabeaudrySomehow the cljsjs does not get compiled when I run my project? Is there anything I need to do when a lein project has boot dependencies?
17:17justin_smithBronsa: in fact, people fear, mistrust, and commonly misuse java.util.Date, and will go through all kinds of silliness to avoid the simplest answer if the simplest answer is to use Date
17:19justin_smithlike a wrapper library that makes a calender out of a data and pulls the year out of the calendar
17:27oddcullyand because Date is so awesome, there is a new api in each major java version
17:35numbertenis there a place you can add let variables in a prop/for-all with test.check?
17:35numberteninstead of recomputing a constant for every test
17:36sdegutisjustin_smith: on the other hand, an API that is easy to misuse is poorly designed
17:48TimMcI've certainly never heard someone claim that Date was well-designed. :-)
17:54sdegutisIs there a way that I can make (require 'foo.bar) look in "src/foo/bar/[something].clj" instead of "src/foo/bar.clj" ?
18:04sdegutisThanks.
18:09numbertenis there something like clojure.test's 'thrown?' that you can use in test.check?
18:16sdegutisWhy isn't this true? &&(= {:a 2} {:a 2 :b nil})
18:16sdegutisOops I forgot the bot notation.
18:17Cr8,[(:b {:b nil} :missing) (:b {} :missing)]
18:17clojurebot[nil :missing]
18:17sdegutisOh.
18:17sdegutisStill, it seems that in the general case, nil and absent should be equivalent.
18:18Cr8,(mapv seq [{} {:b nil}])
18:18clojurebot[nil ([:b nil])]
18:19Cr8,(map (partial contains? :b) [{} {:b nil}])
18:19clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.Keyword>
18:19Cr8ok i got something wrong there but you get the idea
18:19Cr8lots of respects in which containing a k-nil pair is different than not having an entry for k
18:20Cr8you couldn't even roundtrip JSON through if that were the case
18:21sdegutisI assumed for maps that (= m1 m2) would be equivalent to (every? #(= (% m1) (% m2)) (distinct (concat (keys m1) (keys m2))))
18:21sdegutisThat seems like the most common-sense meaning of = for maps.
18:22Bronsaequality on maps uses contains?, not get
18:22Bronsawhich is the reasonable thing to do
18:22justin_smith,(= {Double/NaN Double/NaN} {Double/NaN Double/NaN})
18:22clojurebotfalse
18:22Cr8https://github.com/clojure/clojure/blob/b926222fbdbd866806d441fa362e3ac0cf0afafa/src/jvm/clojure/lang/APersistentMap.java#L52-L71
18:23Bronsasdegutis: would you have two maps be equal when their `count` differs?
18:23Cr8checks pair count is the same, checks contains for each key, then checks get equivalence
18:23Bronsa,[(count {:b 1 :a nil}) (count {:b 1})]
18:23clojurebot[2 1]
18:23sdegutisBronsa: because (= (get m1 :b) (get m2 :b))
18:23Bronsaso what?
18:23Bronsa(not= (contains? m1 :b) (contains? m2 :b))
18:23Bronsawhat's your point?
18:24sdegutisBronsa: so it seems intuitive to me that they're equal when (get) for all keys produce equal results
18:24justin_smithsdegutis: so (= {:a 0} {:a 0 :b 1 :c 2}) by that argument
18:24Cr8if (get) was the only thing on the map interface that would make sense
18:24Cr8it's not
18:24Bronsasdegutis: and contains? does not.
18:24Bronsanor does count on the map
18:24sdegutisjustin_smith: No, that would be false.
18:24Bronsaa nil key is not a non-present key
18:24Cr8plus also there's get of other arities that isn't the same
18:24sdegutisjustin_smith: either you're completely misunderstanding what I said, or I completely butchered saying it.
18:25Cr8,[(get {:b nil} :b :missing) (get {} :b :missing)]
18:25clojurebot[nil :missing]
18:25Cr8or:
18:25Cr8nil doesn't mean "not present", it's just the default default value
18:26justin_smith,((juxt = list) (hash-map Double/NaN Double/NaN) (hash-map Double/NaN Double/NaN Double/NaN Double/NaN))
18:26clojurebot[false ({NaN NaN} {NaN NaN, NaN NaN})]
18:26sdegutisThe fact that the /default/ for get on a map with an absent key is nil seems to suggest that the :missing key is an exception for special circumstances, and that in the general case, you shouldn't care whether the key pointed to a literal nil or missing.
18:26sdegutisAnd = should assume the general case, not the exception.
18:27Bronsathat's not how equality works.
18:27sdegutisBronsa: Honestly I think you just want to defend whatever Clojure currently does without regard to what it ought to do.
18:27Bronsasdegutis: lol.
18:29justin_smith,(iterate #(assoc % Double/NaN Double/NaN) {})
18:29clojurebot({} {NaN NaN} {NaN NaN, NaN NaN} {NaN NaN, NaN NaN, NaN NaN} {NaN NaN, NaN NaN, NaN NaN, NaN NaN} ...)
18:29Cr8:missing isnt special
18:29Cr8,[(get {:b nil} :b :bob) (get {} :b :bob)]
18:29Bronsasdegutis: I've given you at least two reasons why `=` behaves correctly with regards to nil values
18:29clojurebot[nil :bob]
18:29Bronsawhich you seem to have ignored
18:31sdegutisBronsa: Were your reasons about contains? and :missing?
18:31Bronsaread the backlog
18:31sdegutisBecause I responded to both of those.
18:31Cr8,(doc get)
18:31clojurebot"([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."
18:32bmay_in Ring, how do i get the file content from a file submitted with enctype multipart/form-data
18:34sdegutisThis is how = should be defined for maps `ms`: (every? (fn [k] (apply = (map #(get % k) ms))) (distinct (mapcat keys ms)))
18:34sdegutisBronsa: reading now
18:34Cr8that would make it impossible to represent nil as a value of a kv pair in a map
18:34Cr8why is that better
18:34sdegutisCr8: how so?
18:35Cr8if {:b nil} and {} are equivalent then you can't safely truck {:b nil} around
18:35sdegutisCr8: It makes {:a 1} indistinguishable from {:a 1, :b nil}, but for the general case that doesn't matter.
18:35Cr8yeah and it breaks *every case where it does*
18:35sdegutisCr8: in what situation?
18:35Cr8say you're sticking those in a cache
18:35Cr8you put in {:b nil} and you get back {} when you ask for it back
18:35Cr8that's a problem
18:35Bronsasdegutis: you seem to think that your general case is everybody's general case
18:36sdegutisA cache sounds like a highly specific problem where nil values probably have a special meaning.
18:36sdegutisBronsa: Yep. Pretty darn sure it is.
18:36Bronsagood. implement your own = and use that then
18:37sdegutisBronsa: I'm pretty sure you have just as little code to back up your assertion that it's not as much as you think I have to support that it is.
18:37Cr8thing is {:b nil} and {} are -different data-, and if = considered them the same I couldn't use huge parts of the stdlib
18:37Cr8if i cared about it
18:37Bronsai'd rather have my maps be not= when `keys` or `count` than for them to be =
18:37Cr8and i might not *know* if I don't care about it, i might be a library author
18:37justin_smith(apply merge (repeat 9 {Double/NaN Double/NaN}))
18:37Bronsawhen `keys` or `count` are not=
18:37justin_smith,(apply merge (repeat 9 {Double/NaN Double/NaN}))
18:37clojurebot{NaN NaN, NaN NaN, NaN NaN, NaN NaN, NaN NaN, ...}
18:37justin_smith,(apply merge (repeat 10 {Double/NaN Double/NaN}))
18:37clojurebot{NaN NaN}
18:38sdegutisCr8: I fundamentally disagree, considering almost every single time you use a map is with (get) or some variation that uses (get).
18:38hiredmanhuh
18:38Bronsajustin_smith: is spamming NaN your subtle way to stop a flame? :)
18:38justin_smithBronsa: I found the difference between the 9 map and 10 map result amusing
18:38Bronsaoh wait
18:38BronsaI didn't even notice that
18:39Cr8example: passing a param map to something than generates a url query string
18:39Cr8example: serializing json to pass to some api that expects a key to be present and null
18:39Bronsajustin_smith: one is a PAM and the other is a PHM, but I have no idea how they can compare equal :|
18:40Cr8really anything that consumes an entire map, or might care about the presence of a key
18:40Bronsasdegutis: I couldn't undertand your last sentence.
18:40justin_smithclearly they are hashing or comparing differently - probably no differences that actually matter to code that is not insane
18:42sdegutisBronsa: The highest priority driving forces of a data structure is how you use it, not how it's implemented. And even then, it's how they're most often used, not the few niche situations.
18:42sdegutisBronsa: So the most important driving features of maps are assoc, merge, and get.
18:42Cr8how is it useful to make it not workable to put nil in your collection
18:42Bronsajustin_smith: ah, it is possible that PAM doesn't use pointer identity checks while the PHM does, I guess
18:43sdegutisBronsa: contains? is lower priority than these, since you usually just want to know the value of a key, not whether it's there or not.
18:43Bronsasdegutis: and they are more important because you decided so?
18:43Bronsasdegutis: what about count, keys, vals?
18:43justin_smithfind even
18:43Cr8or even (seq)
18:43sdegutisBronsa: Because in my 4 years of experience writing Clojure full-time professionally, this is what I have encountered in my own code, the code of my colleagues, and code I have seen written in third party libs.
18:44Cr8a map is a collection of kv pairs, why would you throw some out because you don't like what the .val portion is
18:44sdegutisBronsa: I've rarely if ever seen count or contains? used, but sometimes keys and vals used by programmer-centric libraries.
18:44sdegutis(like a testing framework)
18:44Bronsasdegutis: functions must return the *right* value not some opinionated result based on what is more generally used in your experience
18:45Bronsasdegutis: and in your 4 years of experience writing clojure full-time professionally it just now occurs to you that (not= {:a 1} {:a 1 :b nil})? I'm sorry but if that's the case you might have some serious misunderstanding of the philosophy behind some design clojure design choices
18:46Cr8if you are going to argue that (= {:b nil} {}) you need to argue {:b nil} shouldn't compile
18:46Cr8otherwise the whole type would by maddeningly inconsistent
18:47Bronsajustin_smith: gah now you got me curious to see if there's actually a PAM/PHM bug hidden in there
18:50sdegutisBronsa: Actually no, it came up years ago, resulting in me writing a special equality function for maps for our own use.
18:51sdegutisBronsa: But I fully agree with you, it should do /the right thing/, not some opinionated thing. And I believe the right thing is the definition I provided, and that your suggestion of it being fine the way it is is just your incorrect opinion.
18:51sobelhow can i make string/replace match case-insensitive?
18:51justin_smithsobel: with a case-insensitive regex?
18:51sdegutisBronsa: Because you tend to agree with rhickey simply because he's rhickey rather than to think of how functions should work.
18:51Bronsasdegutis: that's insulting and ignorant
18:52sdegutiscontains? is a stupid function and works stupidly and is stupidly named.
18:52justin_smithsdegutis: I've seen Bronsa complain a lot about clojure internals
18:52sobeljustin_smith: i'm sure it's obvious when you already know how to do it
18:52sdegutisjustin_smith: but the public-facing API is another story
18:52justin_smithsobel: clojure regexes are java regexes, there is a ?i key
18:52sdegutiscontains? should work completely differently, it should tell you whether a collection contains an element
18:52Bronsasdegutis: I complain about the public API just aswell
18:53justin_smith,(matches #"WORD" "word")
18:53clojurebot#error {\n :cause "Unable to resolve symbol: matches in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: matches in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6611]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: matches i...
18:53justin_smith,(re-matches #"WORD" "word")
18:53clojurebotnil
18:53sobeljustin_smith: thx, think i found the relevant doc bits now
18:53justin_smith,(re-matches #"?iWORD" "word")
18:53clojurebot#<SecurityException java.lang.SecurityException: denied>
18:54justin_smith,(re-matches #"(?i)WORD" "word")
18:54clojurebot"word"
18:54justin_smithfinally
18:54Bronsa"Dangling meta character '?' near index 0" is an awesome error message
18:55justin_smithBronsa: dangling off the front, heh
18:59Bronsa,(let [a (hash-map Double/NaN 1)] [(assoc a Double/NaN 2) (assoc a (key (first a)) 2)])
18:59clojurebot[{NaN 1, NaN 2} {NaN 2}]
18:59Bronsawtf
19:00justin_smithwow
19:00Bronsaisn't that suppoosed to be impossible? I thought NaN returned false for pointer equality
19:00hiredman(hash Double/NAN)
19:00hiredman,(hash Double/NAN)
19:00clojurebot#error {\n :cause "Unable to find static field: NAN in class java.lang.Double"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to find static field: NAN in class java.lang.Double, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6611]}\n {:type java.lang.RuntimeException\n :message "Unable to find st...
19:01hiredman,(hash Double/NaN)
19:01clojurebot2146959360
19:01hiredman,(hash Double/NaN)
19:01clojurebot2146959360
19:01hiredmanhmmmm
19:01Bronsahiredman: yeah but they still have to compare =
19:01hiredmanBronsa: doesn't matter
19:01hiredmanfor hash maps equality only kicks in after hashing
19:02hiredman,(hash (Double. Double/NaN))
19:02clojurebot2146959360
19:03hiredmanbut I guess I was wrong
19:03hiredmanI assumed some kind of boxing thing created boxed NaN's with different hashes
19:03Bronsauhmm
19:03Bronsaif my printlns are correct the value always gets assoc'd
19:04hiredman,(let [a (hash-map (Object.) 1)] [(assoc a (Object.) 2) (assoc a (key (first a)) 2)])
19:04clojurebot[{#object[java.lang.Object 0x17334611 "java.lang.Object@17334611"] 1, #object[java.lang.Object 0x273d11fd "java.lang.Object@273d11fd"] 2} {#object[java.lang.Object 0x17334611 "java.lang.Object@17334611"] 2}]
19:04Bronsa,(let [a (hash-map Double/NaN 1)] (identical? (assoc a Double/NaN 2) a))
19:04clojurebotfalse
19:05hiredmanhard to see, but you get the same looking thing with objects that have identity
19:05Bronsaoh well obviously, the value is different mhh
19:05Bronsauhm weird
19:06Bronsano wait, not really?
19:06Bronsahiredman: in the object case it's supposed to pass the pointer check
19:06BronsaNaN is not
19:06hiredmansure, but in the second case it short circuits on the identity check
19:06Bronsa,(let [a Double/NaN] (identical? a a))
19:06clojurebotfalse
19:07Bronsa,(let [a (Object.)] (identical? a a))
19:07clojurebottrue
19:07hiredmanhmmm
19:07Bronsalike, it'd look like someplace in PHM it's using just the hashCode rather than doing equality checks
19:08Bronsabecause there's no way for NaNs to compare equal or identical?, just the hash
19:16Bronsawhat the
19:16Bronsa,(let [a (hash-map Double/NaN 1)] (= (key (first a)) (key (first a))))
19:16clojurebottrue
19:16Bronsa,(let [a Double/NaN] (= a a))
19:16clojurebotfalse
19:16hiredmanah hah
19:17hiredmanit has to be some kind of boxing issue
19:18hiredman,(= (Double/valueOf Double/NaN) (Double/valueOf Double/NaN))
19:18clojurebotfalse
19:18hiredman,(let [a (hash-map Double/NaN 1)] (identical? (key (first a)) (key (first a))))
19:18clojurebottrue
19:18Bronsais this some jvm weirdness I'm not aware of
19:19hiredman,(let [a (hash-map Double/NaN 1)] (identical? (double (key (first a))) (double (key (first a)))))
19:19clojurebotfalse
19:19hiredmanhah
19:19justin_smith,(let [a [Double/NaN]] (= (first a) (first a)))
19:19clojurebottrue
19:19Bronsahiredman: how can you laugh, I'm having some serious identity crisis over here
19:20hiredmanyou have to laugh
19:20hiredmanfloating point
19:20hiredman,(let [a (hash-map Double/NaN 1)] (identical? (double (key (first a))) (double (key (first a)))))
19:20clojurebotfalse
19:21hiredman,(let [a (doto (java.util.HashMap.) (.add Double/NaN 1))] (= (key (first a)) (key (first a))))
19:21clojurebot#error {\n :cause "No matching method found: add for class java.util.HashMap"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "No matching method found: add for class java.util.HashMap"\n :at [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]}]\n :trace\n [[clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 53]\n [clojure.lang.Reflector invokeInstanceMe...
19:21hiredman,(let [a (doto (java.util.HashMap.) (.put Double/NaN 1))] (= (key (first a)) (key (first a))))
19:21clojurebottrue
19:22Bronsahere we go
19:22Bronsa,(let [a (Double/valueOf Double/NaN)] (identical? a a))
19:22clojurebottrue
19:22Bronsaboxed NaNs compare identical
19:23hiredmanah, well, there you go
19:25Bronsabut now the question is why if they compare identical? PAM doesn't behave like PHM :P
19:27Bronsa,(let [a (Double/valueOf Double/NaN)] (clojure.lang.Numbers/equal a a))
19:27clojurebotfalse
19:27Bronsaand here's the answer
19:31Bronsalooks like Numbers/equal doesn't do pointer any pointer check but just unboxes the values and compares them
19:31Bronsa,(let [a (Double/valueOf Double/NaN)] (identical? a a))
19:31clojurebottrue
19:31Bronsa,(let [a (Double/valueOf Double/NaN)] (identical? (.doubleValue a) (.doubleValue a)))
19:31clojurebotfalse
19:32hiredmanoh jvm
19:32Bronsano idea why PAM uses Util.equivPred
19:34Bronsawell that was fun
19:38Bronsa,(.equals Double/NaN Double/NaN)
19:38clojurebottrue
19:38BronsaTIL
19:53elvis4526I have troubling understanding the difference between core.match and core.unify
19:53hiredmanunification can be two way, pattern matching tends to be one way
19:54elvis4526I have trouble seeing where matching the other way around could be useful
19:54elvis4526Do you have an example ?
19:54hiredmanit is useful for various tree searching things
19:55hiredmanlogic programming tends to be built on unification
19:56hiredmanso core.logic's ==
19:56hiredmanit doesn't use unify, but it has its own unifier
19:57hiredmana unifier lets you say, I don't know what they two values are, but they are the same
19:58elvis4526interesting its like algebra
19:59hiredmanexactly
19:59hiredmansome logic programming guys prefer to refer to it as relational programming
20:00hiredmanbecause you specify relations between things (and then maybe search for a set of things with those relations)
20:01hiredmanyou often end up getting some like a unifier when implementing type inference, because you may not kow the types of terms in certain scopes, but you know how they relate
20:01hiredmansomething
20:14numbertencan you add to prismatic schemas? for ex: take the json-coercion-matcher and add a datetime coercion rule to it?
21:07gfredericksnumberten: there's no thrown?, you just have to catch things
21:08numbertengfredericks: that's what I ended up doing, thanks
21:08numbertenfigured I would check to see if there was an idiomatic nicer way :)
21:08gfredericksnumberten: and you can write your own matchers with schema, you just have to study the code they used for json-coercion-matcher; it's a bit abstract/trippy
21:08numbertengfredericks: haha yeah.. I ended up just doing some manual coercion
21:09numbertenif it becomes a pattern I'll see if I can abstract it out
21:09gfredericksnumberten: I did a custom one to do keywordization and kebabization and UUIDization and DateTimeization and I love it
21:10numbertenyeah it seems like it would be nifty
21:11gfredericksnumberten: as for the let-bindings question, if it's constant why not put the let outside the for-all?
21:11numberteni wanted it out of local scope
21:11numbertensomething inbetween file-wide private and the for-all itself
21:12gfredericks(let [...] (prop/for-all [...] ...))?
21:13numbertenI didn't realize you could do that
21:13numbertenthanks :)
21:14gfredericksno problem, that's what I was trying to suggest at first
21:15numbertenah, I see
21:48slesterDo most Clojurists seem to use OS X for development or Linux? I'm in the market for a new laptop... and yes, it's a weird question to ask, but just curious. I see a lot of MacBooks during talks on youtube.
21:50TEttingerslester: I think if you're doing JVM clojure dev, OS doesn't matter that much
21:50TEttingerJVM runs pretty much the same everywhere
21:51TEttingerclojurescript some tools may be better for server-y stuff if you are using an OS that has oriented itself for that, like Linux, but I don't know how much that matters. also linux drivers are, depending on brand, sometimes not good on laptops
21:52TEttingergenerally smaller not-big-name parts are slower to get drivers
21:53TEttingeras in, if your hardware contains a name that has no english translations anywhere, expect english-speaking linux devs to be slower to release support for it, heh
21:54slesterhaha
21:54slesteryeah, I know. I was just curious if there was a large leaning to OS X, or Windows, or *nix
21:56TEttingerhowever, if you're living in an island nation like new zealand, far away from major markets, your best bet for reasonable prices on laptops may be an online marketplace like, say, AliExpress, where many laptops are made in the same or similar factories as HP or Lenovo or whatnot but for whatever reason are unbranded with a major name
21:57TEttingerI've had surprisingly good experience buying tv sticks from AliExpress, the quality has been fine. one box came with a dead bug that had slipped in during transit, haha, but the device worked perfectly
21:58TEttingerfor a long time that was the only place to buy them if they just came out
21:58slesterI'm in the US, so that shouldn't be an issue, but ... yikes!
21:58TEttingerhaha
21:58TEttingeryeah it was a silverfish, which seems like it slipped in on the american side
21:59TEttingerI don't know if they have the same kinds across the pacific
21:59TEttingerthey eat paper and glue, bane of books
22:00Jaoodslester: I would say most do dev in OS X and deploy to linux, they don't leave OS X because of the nice integration with hardware(macbooks) and a more polished desktop, some use linux VMs in OS X
22:00slesteroh! silverfish aren't so bad, they're everywhere
22:00Jaoodslester: depends on your preferences and what you are doing
22:01TEttingeralso, reliable build quality from apple
22:01TEttingerand reliably higher prices
22:01slesterI'm thinking just for sturdiness and dependability. My current laptop (3.5 years old now) was a 'gaming' one that feels pretty... flimsy? I don't know. It has a strange feel.
22:01slestermacbooks and thinkpads have the kind of solid feel I like
22:02Jaoodslester: If I recall well lein doesn't play nice in windows
22:02slesterI'm on linux
22:02slesterwell I have windows 10 on a partition I only use if I need windows-specific apps
22:03Jaoodslester: dell has some ubuntu certified laptops
22:03TEttingerI'm very very happy with the build quality on this MSI gaming laptop
22:03slesterthe thing I hate about my current linux setup is that switching languages/keyboards is awful
22:03slesterI still haven't figured out how to get it to work
22:03slesterOS X it's 3 clicks
22:04atomislester, have you tried Cinnamon?
22:04slesteratomi, nope, I haven't
22:04slesterI'm on KDE5
22:04atomiit's good imo
22:04slesterI may look into it
22:04TEttingerI had a lenovo Y series that had just awful build quality, but once I 1) disabled the GPU by 2) installing windows server 2008 R2 as the OS, fresh install, and 2) disabled the windows audio driver because the sound card gets messed up on every lenovo it seems, it works fine. very long uptime, I use it as a server on a cooling pad.
22:05TEttingerhttp://www.techbargains.com/apple-macbook-pro-retina-deals#newsID441241 I have no idea if these are good deals for macs
22:05TEttingerconsidering there are 1/3 the price laptops elsewhere on there running win10
22:06slesterTEttinger, I'll check that out, but yeah, even a deeply discounted macbook is way expensive
22:06TEttingerhttp://www.techbargains.com/dell-inspiron-15-deals#newsID457636
22:06slesterplus I don't really like apple as a company
22:06slesterbut that's neither here nor there
22:07slesteroh nice, they have 4k laptops :O
22:07slesterclojuring in so many pixels!!!
22:22slesterAndddd Linux just broke. Haha.
23:02nicolai have a list of actions to perform, each one being executed only on the success of the previous one (otherwise exit with some return message); is there an idiomatic way to write this in clojure without lots of nesting? i'm thinking something along the lines of the Maybe monad in haskell if it helps ...
23:05johannbestowrousyou can do assertions at every action
23:05johannbestowrousand wrap the actions in a try catch
23:06nicolathat would be very similar to what i'm doing right now
23:06gfredericksnicola: the maybe monad is a lot like some->; it's when you want the either monad that options get sparser
23:07nicolagfredericks: i'm not familiar with this, i'll look into it, thanks
23:08nicola(i mean i'm familiar with either monad in haskell, not sure about the clojure equivalent)
23:18slesterany nice function to remove one matching value from a list?
23:18slester,'(:a :a)
23:18slesterfor instance
23:18clojurebot(:a :a)
23:18slesterto just remove one of those
23:18johannbestowrousyou mean the first equality?
23:19slesterJust one matching :a -- like disj but for a list, and just one element
23:19slester(= (some-fn '(:a :b) :a) '(b)) and also (= (some-fn '(:a :a) :a) '(:a))
23:21johannbestowroushaha watch out some-fn is actually a core function just saw it today https://clojuredocs.org/clojure.core/some-fn
23:21slester... whoops
23:21slesterhaha
23:22slesterI meant generic function I am wanting :P
23:23gfredericksslester: it doesn't exist, probably because it would be inefficient for lists; e.g., should you be using a map instead?
23:26TEttinger,(defn remove-first [coll] (let [sp (split-with (partial = :b) coll)] (concat (butlast (first sp)) (second sp))))
23:26clojurebot#'sandbox/remove-first
23:26TEttinger,(let [ls '(:a :b :a :b :a)] (remove-first ls))
23:26clojurebot(:a :b :a :b :a)
23:27TEttingerdamn
23:27johannbestowrousnoice
23:27TEttingernot work
23:27slesterI talk about getting a new laptop today, and then my computer crashes 3 times in a row. What'd I miss haha
23:28TEttinger,(defn remove-first [coll item] (let [sp (split-with (partial not= item) coll)] (concat (butlast (first sp)) (second sp))))
23:28clojurebot#'sandbox/remove-first
23:28TEttinger,(let [ls '(:a :b :a :b :a)] (remove-first ls :b))
23:28clojurebot(:b :a :b :a)
23:28TEttingerright.
23:28TEttinger,(defn remove-first [coll item] (let [sp (split-with (partial not= item) coll)] (concat (first sp) (rest (second sp)))))
23:28clojurebot#'sandbox/remove-first
23:28TEttinger,(let [ls '(:a :b :a :b :a)] (remove-first ls :b))
23:28clojurebot(:a :a :b :a)
23:29TEttingerit's highly inefficient but if you need that behavior, sure
23:29slesteroh awesome! here's my use case, maybe there's a better way
23:29slesterin this game, we have a hand of 1-2 cards. cards can be duplicates.
23:30slesterIf I want to play a knight and the hand is '(:knight :knight), it doesn't matter which one I pick, and order doesn't matter either
23:31TEttinger(you may want to prefer vectors over quoted lists when using clojure for a few reasons, I'll get back to that later)
23:31gfredericksslester: you could keep a frequency map
23:31gfredericks,(frequencies [:knight :knight])
23:31clojurebot{:knight 2}
23:31gfredericks^ that data structure
23:31TEttinger,(frequencies [:knight :knight :dammit :gfredericks :ninja])
23:31clojurebot{:knight 2, :dammit 1, :gfredericks 1, :ninja 1}
23:32TEttingerif using frequencies, this does become easier
23:32TEttinger,(def hand {:knight 2 :king 1 :pawn 4})
23:32clojurebot#'sandbox/hand
23:33slesterhow would I push a card into that?
23:33gfredericks(update m card-name inc)
23:33gfredericks,(update hand :TEttinger (fnil inc 0))
23:33clojurebot{:knight 2, :king 1, :pawn 4, :TEttinger 1}
23:33TEttingergod, 1.7 helps with that stuff a lot
23:33gfredericksforgot the fnil
23:33slesterI thought I was being so good and choosing the right data type but I was so wrong
23:34TEttingerwell it's interesting
23:34TEttingerquoted lists are really common in other lisps
23:34TEttingeralong with using the behavior of quoting everything inside them
23:34johannbestowroushttps://gist.github.com/jobez/27edc10dfe867deed82f here's a remove-first
23:34TEttinger,'(I love pie)
23:34clojurebot(I love pie)
23:35TEttingerbut they start having trouble with nesting and when you don't actually want to quote stuff
23:35TEttinger,'(I love (+ 1 2))
23:35clojurebot(I love (+ 1 2))
23:35gfredericksslester: related vocabulary are "multiset" and "bag"
23:36slestergfredericks, as in 'things clojure doesn't have'? hehe
23:36gfredericksno things related to frequency maps
23:37TEttingervectors work very well for data that needs random access, and are otherwise similar to seqs (IIRC if you call "(list 1 2 3)" it actually runs as its body "(seq 1 2 3)"). they conj at the end instead of at the beginning for seqs.
23:39slesterTEttinger, seems reasonable
23:39TEttingera multiset is, basically, a subcategory of associative maps
23:39TEttingerit has what would be the set's items as keys, so they are still unique, but has counts for values
23:39slestercool, I didn't make the connection until gfredericks made that comment
23:39slester:D
23:40TEttingerso if you have a non-strictly typed map implementation, you have multisets already, which is nice
23:40TEttinger(if you have a strictly typed one, you can do multisets for one kind of set entry)
23:40gfredericksyou could imagine a multiset API similar to a set API instead of exposing it as a map
23:41gfredericksI'm sure there's a clojure library for this somewhere
23:41TEttingerflatland curates a number of useful libs, some for data structures. I love ordered collections myself, and I believe either flatland/ordered or amalloy/ordered is the most recent
23:42TEttingerI recently encountered a bizarre bug with a java demo I wrote for a gamedev lib to be used from clojure at some point
23:42TEttingerit generated the same dungeon layout in terms of walls, every time, with the same seed used every time
23:43TEttingerbut on java 7, the water was in a different place than on java 8
23:43virmundihello
23:43TEttingerI couldn't figure it out...
23:43TEttingerhey virmundi
23:43virmundidoes anyone know how to split a string on a hex value? I have a CSV style file where the split is 0x1F
23:44TEttingervirmundi: the string or the char?
23:44virmundiwithin the row. Rows are new line split
23:44virmundithe char
23:44sdegutisWhy doesn't this work? (-> #(prn :hi) ())
23:44TEttinger,(clojure.string/split "\u001F" "hey\u001Fvirmundi\u001fhow is it going?")
23:44clojurebot#error {\n :cause "java.lang.String cannot be cast to java.util.regex.Pattern"\n :via\n [{:type java.lang.ClassCastException\n :message "java.lang.String cannot be cast to java.util.regex.Pattern"\n :at [clojure.string$split invoke "string.clj" 217]}]\n :trace\n [[clojure.string$split invoke "string.clj" 217]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Compiler eval "Compile...
23:45TEttinger,(doc clojure.string/split)
23:45clojurebot"([s re] [s re limit]); Splits string on a regular expression. Optional argument limit is the maximum number of splits. Not lazy. Returns vector of the splits."
23:45sdegutis,(-> #(prn :hi) ())
23:45clojurebot#error {\n :cause "Can't call nil"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.IllegalArgumentException: Can't call nil, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6798]}\n {:type java.lang.IllegalArgumentException\n :message "Can't call nil"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6783]}]\n :t...
23:45virmundiThanks. I always forget about \u
23:45gfredericks,(macroexpand-1 '(-> #(prn :hi) ())
23:45clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
23:45gfredericks,(macroexpand-1 '(-> #(prn :hi) ()))
23:45clojurebot(nil (fn* [] (prn :hi)))
23:45TEttinger,(clojure.string/split "hey\u001Fvirmundi\u001fhow is it going?" #"\u001f")
23:45clojurebot["hey" "virmundi" "how is it going?"]
23:45gfrederickssdegutis: ^
23:46gfredericksI think the simple answer is the macro wasn't written to handle that case
23:46gfredericksI rewrote -> a couple years ago, am not sure if it did anything different before
23:46TEttinger,()
23:46clojurebot()
23:46sdegutisgfredericks: oh ok
23:47gfredericksit's calling first on the empty list and getting nil and just going ahead with that
23:47sdegutisBut it should in principle handle that case, right?
23:47sdegutisLike, it makes sense semantically as calling a function, right?
23:47gfredericksyeah you could certainly argue that
23:47TEttinger,(-> #(prn :hi) (apply))
23:47clojurebot#error {\n :cause "Wrong number of args (1) passed to: core/apply"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/apply"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 412]\n [sandbox$eval188 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang....
23:47sdegutisOkay.
23:47gfredericksI think deliver might work
23:47TEttinger,(-> #(prn :hi) (apply ()))
23:47clojurebot:hi\n
23:47gfredericks,(-> #(prn :hi) (deliver))
23:47clojurebot#error {\n :cause "Wrong number of args (1) passed to: core/deliver"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/deliver"\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" 32]\n [sandbox$eval240 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang.Com...
23:48gfredericksoh right
23:48gfredericksonly for one-arg functions
23:48TEttingerTEttinger solved a weird thing! I'm happy
23:48sdegutisAlthough then again, the guiding purpose I have for wanting that probably doesn't extend very far beyond this one thing, and probably breaks more assumptions than it wins.
23:48sdegutisTEttinger: hahaha
23:48TEttingerand it works, which is kinda crazy.
23:49virmundihanks
23:49virmundithanks
23:50gfredericksconsarnit I think I found another bug in goog.math.Integer
23:50sdegutis,(-> #(prn :hi) (apply))
23:50clojurebot#error {\n :cause "Wrong number of args (1) passed to: core/apply"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: core/apply"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 412]\n [sandbox$eval266 invoke "NO_SOURCE_FILE" 0]\n [clojure.lang....
23:51sdegutisClojure is closer to Common Lisp than Haskell.
23:51sdegutis:'(
23:54scriptorsdegutis: because it doesn't have function currying?
23:55scriptorthat's because they chose to favor multi-arity function definitions
23:55sdegutisscriptor: sorry that's not what I meant
23:56sdegutisI meant, because Clojure favors exposing low-level implementation details as public APIs rather than high-level abstractions
23:56sdegutisMany functions in clojure.core are designed the way they are because efficiency and speed are considered more important than abstraction and purity to the Clojure team
23:56sdegutisBy purity I don't mean in the FP sense, I meant in the cleanliness sense.
23:57scriptorcan you give an example of low-level implementation leaking through the public API?