2014-10-05
| 00:02 | dbasch | amalloy: still, with an array long-to-hash only becomes 10% faster |
| 00:07 | dbasch | amalloy: actually it becomes significantly faster, encode overall still takes 4x as long as the java version |
| 00:07 | amalloy | sure, but you're getting there |
| 00:07 | amalloy | you should be able to get it to at most 1.5x |
| 00:08 | amalloy | if you're inclined to keep pushing |
| 00:11 | dbasch | amalloy: well, I could rewrite the entire thing in java from clojure :) |
| 00:12 | dbasch | the initial question was, what was the point of writing a clojure implementation of something for which there is a very performant java library |
| 00:26 | alexyz | is there a way to get from a Java array to a Clojure seq? |
| 00:31 | dbasch | alexyz: (seq the-array) |
| 00:34 | dbasch | btw, if you change the-array, the seq changes so don’t do it |
| 00:35 | dbasch | (the sequence is backed by the array directly) |
| 00:36 | alexyz | dbasch thanks |
| 00:37 | alexyz | meanwhile I have found a "native" Clojure function so no need to convert |
| 00:38 | alexyz | still reading about multimethods... if the dispatch function returns a sequence how should I define a defmethod? I've tried '("text" "html") and it doesn't seem to match --- everything going to :default |
| 00:39 | alexyz | http://pastie.org/9621536 |
| 00:51 | dbasch | alexyz: why do you need a multimethod there? it seems like you just want a case |
| 00:52 | amalloy | alexyz: multimethods are sneaky buggers, greatly opposed to being redefined. i bet if you (def my-multi nil) and then re-run that code it works fine |
| 00:53 | dbasch | I still think that’s an unnecessary usage of a multimethod though |
| 00:54 | alexyz | dbasch I asked earlier and was told about multimethod which seems to fit pretty well. I didn't know about case though |
| 00:55 | alexyz | amalloy unfortunately I'm not following you. I have found a bug in that code though and now it seems to work fine |
| 00:56 | dbasch | or not even a case, a map would do just fine |
| 00:57 | alexyz | dbasch in what sense a map? |
| 00:57 | dbasch | alexyz: you have a mapping of mime types to titles, right? |
| 00:58 | alexyz | dbasch nope... for each mime type I plan to apply a different approach for finding out the real title |
| 00:58 | alexyz | so basically it's a mapping from mime types to functions |
| 00:58 | dbasch | alexyz: ok, in that case a case |
| 00:58 | alexyz | that's why multimethods sounded like exactly what I needed |
| 00:59 | dbasch | multimethods are more useful when you have things of different types, and you don’t want to be figuring out what something is |
| 00:59 | dbasch | but in your case you always have two strings |
| 01:00 | alexyz | but the processing is rather different... and this sounds a lot like polymorphism |
| 01:01 | alexyz | I mean I'm pretty sure I can achieve the same results with either multimethods or a case so the real question here is more about what's the idiomatic way |
| 01:01 | dbasch | alexyz: in this situation it’s a matter of taste I guess. If you like it that way, why not |
| 01:01 | alexyz | I'll actually give it a try to both to learn how each of them feels |
| 01:03 | dbasch | I guess the other reason for multimethods is when you don’t know all your cases in advance and you want to be able to add dispatch methods without touching the existing logic |
| 01:04 | alexyz | dbasch in this particular case I thought that having the :default matcher around could prove quite useful |
| 01:05 | dbasch | alexyz: see also cond |
| 02:13 | sineer | Anyone knows how to use use .appendChild with Om dom/div ? |
| 03:03 | borkdude | bbloom what's the difference between union and sum types? |
| 03:05 | julienmarie | Hello all. I'm quite of a newbie here. I got troubles to swap! a nested atom. I feel a bit lost about it for now ( first week on clojure / clojurescript ) http://pastebin.com/bwSqBLxW .Been scratching my head for a day on that now… |
| 03:16 | borkdude | julienmarie I suggest you add a println to set-active to see what you are calling it with |
| 03:16 | julienmarie | @borkdude I'll do that |
| 03:19 | julienmarie | @borkdude this is what I'm getting [:menu [{:name Dashboard, :path /, :icon dashboard} {:name Analytics, :path /analytics, :icon analytics}]] |
| 03:19 | julienmarie | but I need to iterate under the :menu symbol |
| 03:19 | borkdude | julienmarie I suggest you now look at the update-in function |
| 03:20 | julienmarie | instead of assoc ? |
| 03:20 | borkdude | julienmarie or assoc-in |
| 03:20 | borkdude | just take a look at those functions |
| 03:23 | julienmarie | @borkdude thanks! |
| 03:24 | borkdude | np |
| 03:31 | borkdude | question about core.typed: when I define a function in namespace a and also have the annotation there, and this function is called from namespace b incorrectly typewise, lein typecheck a b doesn't find it |
| 03:31 | borkdude | question is: what am I doing wrong |
| 03:34 | borkdude | cfleming renaming via filename refactors namespaces name, but not the other way around |
| 03:37 | borkdude | hmm, lein typed says: "Not checking ringapp.other (tagged :collect-only in ns metadata)" |
| 03:37 | borkdude | while I called it with lein typed ringapp.api ringapp.other |
| 04:14 | H4ns | i'm using http-kit+ring+compojure and my static resources are not found. i've looked at the system class loader (java.lang.ClassLoader/getSystemClassLoader) path and found that it contains the right directories. it seems, though, that a different class loader is used. |
| 04:14 | H4ns | any ideas how i could debug this further? |
| 04:16 | H4ns | in fact, the context class loader path seems to not contain anything |
| 04:23 | H4ns | apparently, a restart of my application helped with this. |
| 05:14 | cfleming | borkdude: Yeah, there's a few cases I need to fix there - the namespace code is old and crufty unfortunately |
| 05:15 | cfleming | borkdude: How's the core.typed support in Cursive BTW? It's pretty new and I haven't used it in anger yet. |
| 05:15 | cfleming | borkdude: I'd like to start using core.typed for some of the Cursive code but I haven't yet. |
| 05:54 | SagiCZ1 | is there any way to take a string and compile it as a C code in java? |
| 05:55 | martinklepsch | I just wrote a bit of code that feels complicated, would be happy if someone could take a look: https://gist.github.com/mklappstuhl/60b061d749f0c0c12275 |
| 05:59 | dysfun | Hi. what interface do i have to implement to support conj? |
| 06:00 | SagiCZ1 | dysfun: Sequential? |
| 06:00 | dysfun | tuy |
| 06:36 | dysfun | is there a nice clojurescript dom library that might work under clojure with a webkit open? |
| 06:37 | dysfun | the api is basically the same |
| 06:42 | dysfun | dommy looks interesting. i'm not sure if i approve or disapprove of the gross abuse of macros in that way |
| 06:48 | mbac | how do i make a plot of a sequence of [x y] appear on my screen with minimum effort |
| 06:48 | mbac | (clojure.magic/plot data) isn't working :P |
| 06:49 | mbac | is it loom? |
| 06:50 | borkdude | cfleming I have the following issue with core.typed in general now: https://www.refheap.com/91197 |
| 06:50 | borkdude | cfleming it's not entirely clear what happens when you just check 1 ns... what happens if the annotations are in another namespace? or when annotations are in "this" namespace, but calls in another? |
| 06:51 | cfleming | borkdude: Hmm, interesting - I'm not sure, I must admit. I implemented the Cursive support modelling it on the calls that the Emacs/Vim support makes, but like I say I still haven't used it myself other than to test it. |
| 06:52 | cfleming | borkdude: So I'm still not sure about a lot of the core.typed details. |
| 06:52 | borkdude | cfleming me neither. I started using it because it was present in the REPL menu :) |
| 06:52 | cfleming | borkdude: Haha - so you'll try all the libraries I add support for? |
| 06:52 | borkdude | cfleming maybe |
| 06:53 | borkdude | cfleming if I get a free license :P |
| 06:53 | cfleming | borkdude: I'll run it by my CFO |
| 06:54 | borkdude | cfleming how big is your team/company? |
| 06:54 | borkdude | cfleming I thought you were the only one |
| 06:54 | cfleming | borkdude: It's just me. |
| 06:54 | borkdude | hehe ok |
| 06:54 | cfleming | borkdude: My CFO is either me, or my wife |
| 06:54 | borkdude | cfleming lol ok. |
| 06:57 | borkdude | cfleming I actually had a use case for core.type to find possible null pointers in some code which uses bigints extensively, but until I can work this namespace problem out, it won't be of much use |
| 06:57 | borkdude | cfleming it's more a core.typed thing than cursive |
| 06:57 | cfleming | borkdude: Try the core.typed mailing list, ambrosebs is very responsive on there |
| 06:57 | cfleming | borkdude: When he's not around here, that is. |
| 06:58 | borkdude | cfleming I already pinged him on twitter, so I think he'll respond soon |
| 06:58 | cfleming | borkdude: Ok cool |
| 07:00 | cfleming | borkdude: Speaking of null pointers, check this out: http://t.co/qTbnjiXwpg |
| 07:01 | borkdude | cfleming yeah, I saw it via your twitter |
| 07:01 | cfleming | borkdude: I have a total geek crush on jetbrains |
| 07:02 | dysfun | that is pretty cool |
| 07:02 | dysfun | shame i hate IDEs |
| 07:02 | cfleming | dysfun: That is a shame :-) |
| 07:03 | borkdude | cfleming do I understand correctly you would have to add annotations in order for it to detect possible NPEs? |
| 07:03 | borkdude | it's still cool though |
| 07:04 | cfleming | borkdude: No, they've had that for ages. This infers what and where the annotations should be. |
| 07:04 | cfleming | borkdude: Depending on how well it works, it might completely eliminate NPEs in Java |
| 07:06 | borkdude | cfleming so you have a program in java with possible NPEs, intellij warns that you should add annotations? |
| 07:09 | mbac | oh wait maybe it's incanter |
| 07:09 | borkdude | cfleming "infer annotations" means you wouldn't have to add them, so why speak of annotations - isn't that more of an implementation detail? |
| 07:09 | mbac | wait maybe i should just write text to a file and use gnuplot |
| 07:11 | cfleming | borkdude: Right, that's a little confusing, I think they're talking about what their algorithm actually infers. As I understand it it'll infer what those annotations should be in SDK/library code. |
| 07:11 | cfleming | borkdude: I'm assuming it can also tell you where they should go in your own code. |
| 07:12 | cfleming | borkdude: I'm guessing this analysis is independent of the actual NPE checking |
| 07:13 | cfleming | borkdude: But if it can use the inferred ones, you're right, the annotations themselves become a little redundant except as documentation. |
| 07:21 | mbac | i find myself doing (map (fn [i x] [i x]) (range (count xs)) xs) a lot |
| 07:21 | mbac | is there something more idiomatic |
| 07:21 | Bronsa | ,(map-indexed vector '[a b c]) |
| 07:22 | clojurebot | ([0 a] [1 b] [2 c]) |
| 07:22 | Bronsa | mbac: ^ |
| 07:23 | mbac | thank you! |
| 08:03 | clj-learner | whats the difference between (resolve 'first) and #'first |
| 08:18 | dysfun | oh excellent, i made java segfault |
| 08:21 | rweir | gold star! |
| 08:21 | rweir | unless it involved JNI |
| 08:25 | dysfun | well, only JNI written by oracle |
| 08:25 | dysfun | (javafx) |
| 08:25 | rweir | silver star then ;p |
| 08:25 | dysfun | javafx is certainly interesting |
| 08:26 | dysfun | i had no idea an api could be made this infuriating |
| 08:26 | rweir | worse than jdbc? |
| 08:26 | dysfun | but i think being able to crash a browser by loading a webpage with a simple javascript loop is quite special |
| 08:44 | gfredericks | ,`````````x |
| 08:44 | clojurebot | #<StackOverflowError java.lang.StackOverflowError> |
| 09:36 | hyPiRion | oh, you. |
| 09:46 | noncom | how do i in clojure better find the constructor for a class that I need and pass the required parameters to it? i cannot make (.getConstructors) with (.newInstance) to work with it.. |
| 09:51 | gfredericks | noncom: you're asking about how to find documentation on java classes, or just call a constructor, or something else? |
| 09:51 | gfredericks | ,(BigInteger. "42") ;; calling a constructor |
| 09:51 | clojurebot | 42 |
| 09:53 | gfredericks | ,(.newInstance BigInteger "42") |
| 09:53 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: newInstance for class java.lang.Class> |
| 09:53 | justin_smith | dysfun: SagiCZ1: hash-maps and sets support conj but are not sequential |
| 09:53 | gfredericks | ,(.newInstance BigInteger) |
| 09:53 | clojurebot | #<InstantiationException java.lang.InstantiationException: java.math.BigInteger> |
| 09:53 | dysfun | *sigh* i wonder what we could achieve with something similar to html but with an immutable DOM |
| 09:55 | gfredericks | noncom: the docs for newInstance state that it won't work if the class doesn't have a zero-arg constructor |
| 10:09 | rubberduck | anyone familiar with core.async.impl.protocols ? in particular what's the procedure for implementing ReadPort in clojure ? |
| 10:09 | rubberduck | from what I can tell you get passed a handler and you must lock it then check if it's active and call commit with the value |
| 10:10 | rubberduck | ManyToManyChannel implementation isn't very straightforward :( |
| 10:12 | kungi | Can I somehow create a globally unique symbol? |
| 10:13 | justin_smith | ,(symbol (java.util.UUID/randomUUID)) |
| 10:13 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.util.UUID cannot be cast to java.lang.String> |
| 10:13 | justin_smith | err |
| 10:13 | justin_smith | ,(symbol (str (java.util.UUID/randomUUID))) |
| 10:13 | clojurebot | 906eafe8-36c2-4cb7-b035-65d39983413c |
| 10:13 | kungi | justin_smith: Hmm ok this is possible. |
| 10:14 | justin_smith | globally unique (or at least pretty damned close to it) |
| 10:14 | kungi | justin_smith: thanks |
| 10:21 | noncom | gfrederics: say i have a class with 2 constructors - 1) parameterless, 2) with some params. i want to be able to call the parametrized one, passing the parans |
| 10:22 | noncom | gfredericks: sorry, misspelled the nick :) |
| 10:25 | noncom | gfredericks: actually, my ultimate goal is to be able to find a class by its name, so that i use (Class/forName) and then call a parametrized constructor on it to get the instance... what would be the best approach for that ? |
| 10:26 | gfredericks | ,(.getConstructors BigInteger) |
| 10:26 | clojurebot | #<Constructor[] [Ljava.lang.reflect.Constructor;@1b91ad7> |
| 10:26 | noncom | ,(.getConstructors (Class/forName "BigInteger")) |
| 10:26 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: BigInteger> |
| 10:27 | gfredericks | ,(map #(seq (.getParamaterTypes %)) (.getConstructors BigInteger)) |
| 10:27 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: getParamaterTypes for class java.lang.reflect.Constructor> |
| 10:27 | gfredericks | ,(map #(seq (.getParameterTypes %)) (.getConstructors BigInteger)) |
| 10:27 | clojurebot | (([B) (int [B) (java.lang.String int) (java.lang.String) (int java.util.Random) ...) |
| 10:27 | noncom | hmmm... thats giving some signatures ! |
| 10:27 | gfredericks | ,(def my-string-constructor (->> BigInteger (.getConstructors) (filter #(= [String] (seq (.getParameterTypes %)))) (first))) |
| 10:27 | clojurebot | #'sandbox/my-string-constructor |
| 10:28 | gfredericks | ,(.newInstance my-string-constructor (into-array ["42"]) |
| 10:28 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 10:28 | gfredericks | ,(.newInstance my-string-constructor (into-array ["42"])) |
| 10:28 | clojurebot | 42 |
| 10:28 | gfredericks | so that does it I think |
| 10:28 | gfredericks | you might also find a helper in the clojure.lang.Reflector class |
| 10:28 | gfredericks | or something to that effect |
| 10:29 | gfredericks | noncom: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java#L150 |
| 10:29 | gfredericks | ,(clojure.lang.Reflector/invokeConstructor BigInteger (into-array ["42"])) |
| 10:29 | clojurebot | 42 |
| 10:29 | gfredericks | rather easier |
| 10:32 | noncom | gfredericks: wow! |
| 10:32 | noncom | gfredericks: that's it, thanks! :) |
| 10:32 | gfredericks | np |
| 11:49 | john________ | Can ask a datomic question here? |
| 11:50 | AeroNotix_ | john________: don't ask to ask, ask. |
| 11:52 | john________ | I hope it is not unpolite to paste in serveral lines of a datomic query code: |
| 11:52 | john________ | [:find ?e ?name |
| 11:52 | john________ | :where |
| 11:52 | john________ | [?e :item/name ?name] |
| 11:52 | john________ | [?e :item/values ?ref] |
| 11:52 | justin_smith | use a pastebin |
| 11:52 | john________ | [?ref :value/attribute ?a] |
| 11:52 | john________ | [?a :attribute/ident “12009”] |
| 11:52 | john________ | ] |
| 11:52 | justin_smith | use refheap.com next time |
| 11:52 | john________ | allright thanxs I do that from now on! |
| 11:53 | justin_smith | I'm guessing you are fairly new to IRC |
| 11:54 | john________ | yes! quite just used it so far only a couple of times for short questions |
| 11:54 | john________ | https://www.refheap.com/91206 |
| 11:55 | justin_smith | thanks |
| 12:04 | bbloom | borkdude: i explained it to gfredericks |
| 12:14 | viktar | (+ 2 2) |
| 12:14 | clojurebot | 4 |
| 12:15 | mbac | so, it's kind of a drag that for toplevel scopes you need to use def but inside of defs you need to use let |
| 12:17 | gfredericks | mbac: they're pretty different |
| 12:19 | gfredericks | it's not just about positioning |
| 12:20 | mbac | what's different about them? |
| 12:20 | mbac | or, rather, why would you want them to be different? |
| 12:20 | gfredericks | def is for things that can be referenced from anywhere, and they are also mutable (e.g., for code reloading) |
| 12:20 | AeroNotix_ | mbac: let is scoped |
| 12:20 | gfredericks | so there's more indirection involved |
| 12:20 | mbac | can't you just think of the top-level scope as the body of function that wraps the module |
| 12:21 | AeroNotix_ | mbac: def can be accessed from outside the namespace it's being defined as well |
| 12:21 | gfredericks | mbac: that kind of hand-waves around how code reloading works |
| 12:21 | mbac | oh. hmm. |
| 12:21 | justin_smith | mbac: you can't, because the body of a function is immutable, and global bindings are not |
| 12:22 | mbac | wait so (def x 0) (def y (based-on x)) (def x 1) is a thing? |
| 12:23 | justin_smith | it's terrible, but it's a thing |
| 12:23 | mbac | :'( |
| 12:23 | mbac | i guess that's super useful sometimes... |
| 12:24 | justin_smith | mostly for development workflows, but yeah, I get pretty damn suspicious when I see it being done in code |
| 12:26 | borkdude | bbloom I'll have to dig up the logs then |
| 12:29 | justin_smith | ,(name "name") |
| 12:29 | clojurebot | "name" |
| 12:30 | justin_smith | it's handy, but it surprised me |
| 12:32 | bbloom | yeah, especially because ##(keyword :keyword) doesn't work, nor does ##(symbol 'symbol) |
| 12:32 | lazybot | (keyword :keyword) ⇒ :keyword |
| 12:32 | lazybot | (symbol (quote symbol)) ⇒ symbol |
| 12:32 | bbloom | oh wow, maybe it does |
| 12:32 | bbloom | nevermind |
| 12:33 | bbloom | &*clojure-version* |
| 12:33 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 12:33 | bbloom | huh |
| 12:35 | justin_smith | ,(keyword :keyword) |
| 12:35 | clojurebot | :keyword |
| 12:35 | justin_smith | ,(symbol 'symbol) |
| 12:35 | clojurebot | symbol |
| 12:36 | justin_smith | yeah, these facts just simplified some of my code immensely |
| 12:36 | bbloom | justin_smith: oh, i remember now: |
| 12:36 | bbloom | ,(symbol 'namespace 'name) |
| 12:36 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String> |
| 12:36 | bbloom | yeah |
| 12:36 | bbloom | :-/ |
| 12:36 | justin_smith | ahh |
| 12:36 | bbloom | ,(keyword 'ns 'n) |
| 12:36 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String> |
| 12:36 | bbloom | ,(keyword 'ns "n") |
| 12:36 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String> |
| 12:36 | bbloom | no good |
| 12:37 | justin_smith | luckily I don't need that version for my code |
| 12:47 | bbloom | hmm so core.async gos get GC-ed if they are waiting on channels for which nobody holds the other end... but what about threads created with clojure.core.async/thread ? |
| 12:47 | dysfun | is there anywhere i can read about things planned for future versions of clojure? |
| 12:48 | bbloom | dysfun: http://dev.clojure.org/display/design/Home |
| 12:48 | dysfun | thanks |
| 12:56 | allenj12 | how does this work if conj never gets a coll? (def foo [x] (when (> x 0) (conj (foo (dec x)) x))) => (foo 5) -> (5 4 3 2 1) |
| 12:57 | gfredericks | ,(defn foo [x] (when (> x 0) (conj (foo (dec x)) x))) |
| 12:57 | clojurebot | #'sandbox/foo |
| 12:57 | gfredericks | ,(foo 5) |
| 12:57 | clojurebot | (5 4 3 2 1) |
| 12:58 | gfredericks | ,(conj nil 1) |
| 12:58 | clojurebot | (1) |
| 12:58 | gfredericks | allenj12: ^^ nil is treated as an empty collection sometimes |
| 12:59 | allenj12 | gfredericks: why do i feel like thats a bad thing? |
| 12:59 | allenj12 | kinda goes against the philosophy nothing is nothing, an empty list is something |
| 12:59 | bbloom | allenj12: industry wide brainwashing? |
| 13:00 | bbloom | i kid though, i go back and forth on my feelings about nil :-P |
| 13:00 | dysfun | because you'd like it to not error out and a lot of things that return sequences may also return nil |
| 13:00 | allenj12 | eh i have mixed feelings about this aswell |
| 13:01 | bbloom | in general, clojure handles nil reasonably sanely |
| 13:02 | justin_smith | allenj12: things silently returning nil are pretty pervasive in clojure |
| 13:02 | justin_smith | ,(+ nil) |
| 13:02 | clojurebot | nil |
| 13:02 | justin_smith | ,(+ :a) |
| 13:02 | clojurebot | #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.Keyword to java.lang.Number> |
| 13:03 | bbloom | justin_smith: (+ nil) is just garbage in garbage out |
| 13:03 | bbloom | + is defined for numbers only |
| 13:03 | allenj12 | huh |
| 13:03 | justin_smith | sure, but notice that it catches it with :keword |
| 13:03 | justin_smith | but not with nil, that was my point |
| 13:04 | bbloom | justin_smith: that's b/c nil can be a Number |
| 13:04 | justin_smith | sure, the pervasiveness of nils is related to the underlying jvm |
| 13:04 | justin_smith | not accusing clojure here, just describing |
| 13:04 | allenj12 | i see |
| 13:06 | bbloom | yeah, that's a good point: null is pervasive on the jvm already, so shouldn't fight it |
| 13:07 | justin_smith | for comparison, we can look at how scala handels it http://blog.sanaulla.info/2009/07/12/nothingness/ |
| 13:07 | justin_smith | which to me reads like a language designed by Heidegger or something |
| 13:09 | aaelony | justin_smith: (and "being" t |
| 13:09 | aaelony | justin_smith: (and "being" "time") |
| 13:10 | justin_smith | hehe |
| 13:10 | aaelony | hehe ;) |
| 13:17 | justin_smith | john_______: did you ever get any help with your datomic question |
| 13:18 | justin_smith | or, more to the point, did you ever actually ask it? |
| 13:19 | john_______ | @justin_smith: yes but nobody answered. I asked why this query https://www.refheap.com/91206 performs so bad. I also posted a question to the datomic user group |
| 13:20 | john_______ | but as always I think I just have to read and learn more about how datomic handles queries |
| 13:46 | dpathakj | ,(and “being” “time”) |
| 13:46 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: “being” in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 13:46 | justin_smith | dpathakj: inc clojure, smart-quotes aren't quotes |
| 13:46 | justin_smith | ,(and "being" "time") |
| 13:46 | clojurebot | "time" |
| 13:47 | dpathakj | Yeah. Looks like I just found out that my irc client is smart-quoting on me. |
| 13:47 | justin_smith | *in clojure |
| 13:47 | borkdude | cfleming namespaces that don't require core.typed won't be type checked |
| 13:47 | borkdude | cfleming sais ambrose |
| 13:48 | john_______ | justin_smith Somebody helped me on the datomic IRC thanxs alot |
| 13:49 | justin_smith | borkdude: I can see how that would be useful actually. |
| 13:49 | borkdude | justin_smith tell me |
| 13:50 | viktar | exit |
| 13:50 | justin_smith | borkdude: if I am adapting a codebase to use core.typed, that means I can work throught it one ns at a time. |
| 13:51 | borkdude | justin_smith then what is the point of calling lein typed with specific namespaces |
| 13:51 | justin_smith | borkdude: and if I have a feature that turns into a terrible rabbit hole when I try to strictly type it, I can still typecheck all the other namespaces, even if that one would never survive the check. |
| 13:51 | justin_smith | borkdude: sorry, I know nothing about "lein typed" |
| 14:23 | michaelr524 | hey |
| 14:24 | pellis | hi all |
| 14:24 | pellis | is this the proper place for clojurescript q's? |
| 14:24 | michaelr524 | here is an excersize, how would you split a constant length string to 5 parts of a given length |
| 14:24 | michaelr524 | pellis: yeah, why not |
| 14:25 | pellis | well i just tried deep diving into om and clojurescript |
| 14:25 | pellis | given around 1 month experience with clojure (but i do learn fast) |
| 14:25 | pellis | my last clojure code was around a year ago |
| 14:26 | michaelr524 | [8, 4, 4, 4, 12] <- these lengths |
| 14:26 | pellis | i came to the conclusion that i can't really do something complex - I need some background in clojurescript first. |
| 14:26 | pellis | so my question is - what would be a good place to slowly introduce clojurescript into existing javascript projects? |
| 14:26 | pellis | is that even wise? |
| 14:27 | pellis | for example - a clojurescript coffeescript hybrid ? or clojurescript on node.js? |
| 14:28 | michaelr524 | pellis: i think the best way to start would be to build a clojurescript only project |
| 14:28 | justin_smith | ,,(reduce (fn [[acc s] n] [(conj acc (subs s 0 n)) (subs s n)]) [[] "this is the input string, is it long enough?"] [8 4 4 4 12]) |
| 14:28 | michaelr524 | pellis: why mix in javascript? |
| 14:28 | clojurebot | [["this is " "the " "inpu" "t st" "ring, is it "] "long enough?"] |
| 14:28 | justin_smith | michaelr524: see above |
| 14:28 | pellis | michaelr524: what if i feel too insecure there? should i go back to square one and invest time in learning first? |
| 14:28 | michaelr524 | justin_smith: one sec, let me parse that |
| 14:28 | justin_smith | exercise for the reader: error checking for when the string runs out |
| 14:29 | michaelr524 | pellis: just build one simple project in clojurescript - this should cure your problems :) |
| 14:29 | pellis | michaelr524: i can't build anything simple enough :( |
| 14:32 | michaelr524 | pellis: why not? |
| 14:33 | michaelr524 | justin_smith: cool, i like your solution |
| 14:33 | justin_smith | thanks |
| 14:33 | pellis | michaelr524: i guess i can't think simple enough. i've been doing complex problems for too long, that i consider everything trivial |
| 14:33 | justin_smith | it errors out if the input string is too short |
| 14:33 | michaelr524 | justin_smith: i was thinking in the same direction actually.. but maybe there is a way to make it more efficient? |
| 14:33 | michaelr524 | i wonder |
| 14:34 | justin_smith | more efficient? yeah, use a transient |
| 14:34 | michaelr524 | justin_smith: the string will always be the same size. it's an rfc compliant uuid without the '-'s |
| 14:34 | justin_smith | error checking? maybe assert that the length of the string is longer than the sum of all the sizes, and if not, bail |
| 14:34 | michaelr524 | justin_smith: i want to bring the '-' back |
| 14:35 | justin_smith | oh, never mind that part then :) |
| 14:36 | seangrove | Any way to destructure the last item in a seq? |
| 14:36 | michaelr524 | justin_smith: it's kinda surprised me actually, i've never seen the acc in (reduce) abused in such a nice way :) |
| 14:37 | Bronsa | seangrove: nope |
| 14:37 | seangrove | Bronsa: Didn't think so, but thought it might be worth it to ask - thanks |
| 14:40 | justin_smith | ,(map identity (second (reduce (fn [[index acc s] n] (aset acc index (subs s 0 n)) [(inc index) acc (subs s n)]) [0 (make-array String 5) (str (java.util.UUID/randomUUID))] [9 5 5 5 12]))) |
| 14:40 | clojurebot | ("d1d7a603-" "e9c3-" "4c5a-" "8b27-" "65aef1b44629") |
| 14:41 | justin_smith | the map identity is because arrays don't print very readably :) |
| 14:41 | Bronsa | seq? |
| 14:41 | takemikazuchi | Hi guys, is this a good place to ask some basic questions? I'm a little confused about string equality in Clojure. |
| 14:41 | justin_smith | Bronsa: ahh, of course :) |
| 14:41 | justin_smith | takemikazuchi: go for it |
| 14:42 | hiredman | yes |
| 14:42 | takemikazuchi | justin_smith: Thanks. Here's the gist: https://gist.github.com/Takemikazuchi/04d2db23a0d6437296c9 |
| 14:42 | michaelr524 | justin_smith: nice.. but think further about it, i think i'll just maybe go for the crazy stupid solution and concat the result of 5 (subs) :) |
| 14:43 | takemikazuchi | I mean this works like I expect: ,(= "E" (clojure.string/capitalize "E")) |
| 14:43 | takemikazuchi | But the behavior changes when I'm iterating over a string, I suppose? |
| 14:44 | justin_smith | michaelr524: or even construct it directly from 5 calls to subs, since it's always five elements :) |
| 14:44 | justin_smith | takemikazuchi: when you iterate on a string you get characters, not strings |
| 14:44 | clojurebot | Excuse me? |
| 14:44 | hiredman | takemikazuchi: you are comparing characters to strings |
| 14:44 | takemikazuchi | Thanks makes sense. |
| 14:45 | takemikazuchi | so capitalize is returning a string |
| 14:45 | hiredman | I suspect so |
| 14:45 | takemikazuchi | Yup that was it! |
| 14:45 | justin_smith | ,(clojure.string/capitalize \e) |
| 14:45 | clojurebot | "E" |
| 14:45 | justin_smith | yup |
| 14:46 | takemikazuchi | Just needed to add (str x) |
| 14:46 | justin_smith | ,(first (clojure.string/capitalize \e)) ; second option |
| 14:46 | clojurebot | \E |
| 14:47 | michaelr524 | justin_smith: exactly, that's what I was trying to communicate in my last sentence hehe |
| 14:47 | justin_smith | michaelr524: ahh, OK. We have a concat function so it was ambiguous |
| 14:48 | justin_smith | though in context concat would not actually make any sense... |
| 14:48 | cfleming | borkdude: ok, so for external annotations you'd type check the ns containing the annotations, not the actual code? Makes sense. |
| 14:49 | cfleming | borkdude: I should really test that! |
| 14:49 | borkdude | cfleming well, that wasn't what I meant. say I have a call in a namespace "other" to function f that is called with the wrong type |
| 14:50 | justin_smith | michaelr524: bonus, the version with five calls of subs in a collection will be more readable too |
| 14:50 | borkdude | even when I have an annotation in namespace "other2" and typecheck "other2", it won't detect the wrong call in "other" if it didn't require core.typed |
| 14:51 | borkdude | cfleming If I would add the require to "other" and type check other, it will detect |
| 14:51 | borkdude | cfleming so that's all you have to do I think |
| 14:51 | borkdude | cfleming checking "current ns" doesn't work if you haven't got the require, that's what it boils down to |
| 14:53 | takemikazuchi | justin_smith, hired_man, thanks guys. |
| 14:54 | cfleming | borkdude: But if other doesn't have the require, then it can't be annotated, right? |
| 14:54 | takemikazuchi | Got to question 30 of 4Clojure |
| 14:54 | borkdude | cfleming the annotation can be in a different namespace |
| 14:56 | cfleming | I see. And this restriction is from core.typed itself, right? |
| 14:56 | borkdude | cfleming for example, this works with the require, not without: https://www.refheap.com/91211 |
| 14:56 | borkdude | cfleming yes |
| 14:57 | borkdude | cfleming "works" -> "type checks" |
| 14:59 | borkdude | cfleming you could add a warning when someone calls "type check current namespace" when the require isn't present |
| 15:00 | michaelr524 | justin_smith: https://www.refheap.com/91212 |
| 15:00 | michaelr524 | justin_smith: could have used a vector of the calls + join of course |
| 15:01 | michaelr524 | justin_smith: but maybe this is more efficient :) |
| 15:01 | justin_smith | michaelr524: ahh - why not a StringBuilder? |
| 15:01 | justin_smith | StringBuilder would be more efficient by far, I didn't realize what you were doing |
| 15:01 | michaelr524 | justin_smith: well, there is a roumor that java automatically creates a StringBuilder when you try something like that |
| 15:01 | rubberduck | anyone here familiar with clojure.core.async.impl.protocols ? I'm having trouble figuring out the required semantics for ReadPort implementation since it's not documented |
| 15:02 | rubberduck | and the only implementation (chan) is cluttered with buffer stuff which is hard to follow |
| 15:02 | justin_smith | michaelr524: I had no idea, but really using a StringBuilder directly would not be that much more complex |
| 15:02 | borkdude | doesn't clojure have transient strings for that? ;P |
| 15:02 | michaelr524 | justin_smith: I think that's the latest recommendation from the java people, instead of using a StringBuilder just concatenate your strings aways with that + operator |
| 15:03 | justin_smith | if java does it (as in the compiler), that doesn't help at all |
| 15:03 | justin_smith | clojure does not use the java compiler except when building the clojure jar |
| 15:03 | michaelr524 | justin_smith: there is a point in what you are saying here |
| 15:03 | michaelr524 | hmm |
| 15:04 | hyPiRion | ,(time (do (reduce str "" (range 100000)) nil)) |
| 15:04 | michaelr524 | then probabaly a StringBuilder would be better |
| 15:04 | clojurebot | eval service is offline |
| 15:04 | hyPiRion | oh, uh |
| 15:04 | michaelr524 | eval service went out of bussiness |
| 15:04 | justin_smith | hyPiRion: but that's not using concat calls |
| 15:04 | borkdude | insert coin |
| 15:04 | hyPiRion | justin_smith: oh, so it's concat vs. stringbuilder? |
| 15:05 | justin_smith | yeah, that's what we are comparing |
| 15:06 | hyPiRion | &(let [s (mapv str (range 10000))] (time (do (reduce #(.concat %1 %2) "" s) nil))) |
| 15:06 | lazybot | Execution Timed Out! |
| 15:06 | hyPiRion | oh whoah, you shouldn't timeout on that |
| 15:07 | hyPiRion | lazy bugger |
| 15:07 | hyPiRion | &(let [s (mapv str (range 10000))] (time (do (apply str "" s) nil))) |
| 15:07 | lazybot | ⇒ "Elapsed time: 8.555949 msecs" nil |
| 15:07 | hyPiRion | str is using stringbuilder internally |
| 15:07 | mbac | (defn save-sexp [d f] (with-open [w (clojure.java.io/writer f)] (.write w (binding [*print-dup* true] (prn d))))) |
| 15:08 | mbac | is that no longer the right way to serialize stuff? |
| 15:09 | justin_smith | hyPiRion: oh, cool |
| 15:11 | michaelr524 | ok then |
| 15:11 | michaelr524 | I've updated the paste |
| 15:11 | michaelr524 | https://www.refheap.com/91212 |
| 15:11 | dbasch | amalloy justin_smith I got that geohash code to be “only” 1.8x as slow as the java version |
| 15:11 | justin_smith | dbasch: awesome, what did it take? |
| 15:12 | dbasch | turns out bit-flip and bit-test are pretty inefficient |
| 15:12 | justin_smith | wow, I had no idea |
| 15:14 | dbasch | justin_smith: in my benchmark (bit-flip x n) takes twice as long as (bit-xor x (bit-shift-left 1 n)) |
| 15:41 | dbasch | justin_smith: plus there was some random sillines, e.g. (+ lo (/ (- hi lo) 2)) instead of (/ 2 (+ hi lo)) |
| 15:41 | dbasch | silliness |
| 15:43 | dbasch | this is what I have so far https://www.refheap.com/91217 |
| 15:44 | dbasch | it has room for improvement |
| 16:10 | arrdem | dbasch: isn't locate [double double double long] -> long? |
| 16:10 | arrdem | clojure.lang.IFn$DDDLL exists |
| 16:10 | arrdem | could be worth something |
| 16:11 | dbasch | I’ll try |
| 16:13 | dbasch | not sure if that type hint makes a difference, it seems to get lost in the noise |
| 16:14 | arrdem | dbasch: yeah looking at that it should get lost in the noise. |
| 16:14 | arrdem | dbasch: hinting the return type would only help if it were called in a tight loop, and it isn't. |
| 16:15 | dbasch | as it is it takes about 700ns on my machine, compared to 11us for the original function and 400ns for the java version |
| 16:17 | dbasch | the one thing I don’t understand is why bit-flip seems so slow compared to the hand-rolled alternative. |
| 16:18 | Bronsa | dbasch: it's not inlined so it always gets compiled to flipBit(Object,Object) |
| 16:19 | Bronsa | dbasch: replacing (bit-flip x n) with (clojure.lang.Numbers/flipBit x n) should make it fast |
| 16:20 | dbasch | Bronsa: I’ll try that, it would make that code more clear |
| 16:20 | dbasch | but that’s the kind of function that should be inlined |
| 16:20 | Bronsa | it's unfortunate that not all the stdlib has :inline metadata where it would make a difference |
| 16:20 | Bronsa | yeah |
| 16:21 | dbasch | (inc Bronsa) |
| 16:21 | lazybot | ⇒ 53 |
| 16:21 | Bronsa | I have a ticket that adds :inline metadata to most of the predicate functions in core, but I doubt it's ever going to make it in |
| 16:22 | arrdem | story of jira... |
| 16:23 | Bronsa | arrdem: not as much as jira as the Rich deciding :inline will no longer be used |
| 16:24 | Bronsa | arrdem: Alex told me that :inline is deprecated and will no longer be added to functions in core |
| 16:24 | Bronsa | deprecated in favour of compiler macros -- which don't exist yet. |
| 16:24 | arrdem | sounds about right |
| 16:25 | Bronsa | I really don't understand why we can't leverage :inline and replace it later with those, when they'll actually be a thing |
| 16:25 | arrdem | what's the word on those. 1.8 ish? not even seeing anything on google or in the logs for em. |
| 16:26 | Bronsa | arrdem: they're in the Release.Next page so maybe they'll make it in for 1.7, but who knows |
| 16:27 | Bronsa | arrdem: http://dev.clojure.org/display/design/Inlined+code |
| 16:29 | arrdem | Bronsa: hum... could probably do that in like... a week for Oxcart/TEJVM |
| 16:31 | Bronsa | I would experiment with them if I saw the need for them, but I fail to see the limitation of :inline. I get that definline sucks because it requires eval, but :inline is fine for me. w/e |
| 16:32 | arrdem | :inline/definline is a hack IMO due to lack of a real constant folder/partial evaluation engine. It works, but it's just a hacky implementation of a special case that Rich decided was worth caring about. |
| 16:33 | Bronsa | actually if I have to be honest :inline kinda sucks too because it requires metadata to be evaluated at analysis time. |
| 16:34 | arrdem | 'tbaldridge was ... pursuasive that a partial application engine probably wasn't worthwhile generally but you're right in primitive type cases like this it really can pay off |
| 16:34 | arrdem | idk |
| 16:34 | arrdem | I was planning on doing one and it didn't happen |
| 16:34 | arrdem | down that path lies loop unrolling and inlining heuristics. and madness. |
| 16:36 | gfredericks | clojurebote: down that path |lies| loop unrolling and inlining heuristics. and madness. |
| 16:37 | gfredericks | hwhoops. |
| 16:37 | gfredericks | clojurebot: down that path |lies| loop unrolling and inlining heuristics. and madness. |
| 16:37 | clojurebot | Ok. |
| 16:37 | cfleming | Bronsa: don't get me started on definline - I still don't understand why there's so much resistance to supporting/using it |
| 16:37 | cfleming | Bronsa: Especially now that there's a fix to the main known problem - many thanks for that! |
| 16:38 | Bronsa | cfleming: yeah I really don't get it either |
| 16:39 | Bronsa | cfleming: TBH I thought that by fixing that AOT compilation bug clojure/core would reconsider its stance on definline, I was kind of baffled when they didn't change stance on it |
| 16:39 | arrdem | Bronsa: hum so CL's DEFINE-COMPILER-MACRO defines/allows a second round of declinable form rewriting before code gen? |
| 16:40 | justin_smith | ~down that path |
| 16:40 | clojurebot | down that path lies loop unrolling and inlining heuristics. and madness. |
| 16:40 | cfleming | Bronsa: Yeah, me too. At least I can use it in my own code now though. |
| 16:40 | arrdem | justin_smith: good thing I'm already mad then |
| 16:40 | Bronsa | arrdem: yeah something like that |
| 16:41 | Bronsa | arrdem: in t.a speak, it's just extending the -analyze multimethod for 'function-name |
| 16:41 | ustunozgur | hi there, a java interop question: (new (.getClass "test1") "test2") doesn't work. is there a way to achieve something like this without reflection? |
| 16:41 | Bronsa | cfleming: so you're using a patched clojure? |
| 16:41 | arrdem | Bronsa: ehrm... yeah because this occurs at the form level not at the analyzed AST level |
| 16:42 | gfredericks | ustunozgur: your example seems inherently reflective |
| 16:42 | Bronsa | arrdem: yep |
| 16:42 | arrdem | Bronsa: which actually makes this less powerful because you aren't exporting all the analysis stuff. |
| 16:42 | arrdem | Bronsa: you can't look at closed overs and soforth |
| 16:42 | ustunozgur | yes, gfredericks (assert (= String (.getClass "Test"))) (new String "test") works though. |
| 16:42 | Bronsa | arrdem: uh? you get &env and nobody prevents you from calling analyze on &body |
| 16:42 | ustunozgur | maybe because it's a special form. |
| 16:43 | Bronsa | arrdem: cljs does something like this already |
| 16:43 | ustunozgur | not sure where I would need this though, just tinkering. |
| 16:43 | gfredericks | ustunozgur: yeah new is a special form; if you don't have the class name at compile time, it's inherently reflective |
| 16:43 | Bronsa | arrdem: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L260-L276 as an example |
| 16:43 | cfleming | Bronsa: Yeah, although I haven't applied that patch yet. I will do as soon as the patch stabilises - I've been running with the patch from http://dev.clojure.org/jira/browse/CLJ-1315 since it came out. |
| 16:43 | arrdem | Bronsa: I guess. I'd just lean towards exposing the analyzed AST for user definable transforms because almost anything interesting is gonna try to get tha tinformation anyway. |
| 16:44 | ustunozgur | gfredericks: OK, thank you. |
| 16:44 | arrdem | cfleming: how's the patched verison of Clojure thing working for you? it's been tempting me for a while now. |
| 16:44 | Bronsa | I've done that, it gets old really fast |
| 16:44 | Bronsa | commits in clojure master break everything |
| 16:45 | gfredericks | what are we patching for? |
| 16:45 | cfleming | arrdem: It's working well for me, I'm still running 1.5.1. |
| 16:45 | Bronsa | and you're left trying to manually merge everything |
| 16:45 | arrdem | gfredericks: rabble rabble rabble |
| 16:45 | cfleming | arrdem: Everyone using Cursive is using a patched version. |
| 16:45 | Bronsa | cfleming: ssssh they don't need to know |
| 16:45 | arrdem | Bronsa: interesting example. thanks. |
| 16:46 | gfredericks | ah |
| 16:46 | cfleming | Bronsa: Hehe, yes, my lips are sealed. |
| 16:46 | arrdem | lol @ ninja patched version |
| 16:46 | gfredericks | how do you convince leiningen to use a patched version? do you have to exclude clojure from every dep? |
| 16:46 | gfredericks | is there a global exclude feature? |
| 16:46 | cfleming | gfredericks: I use Ant. It doesn't take much convincing. |
| 16:46 | Bronsa | arrdem: that's a really nice example actually, I've tried moving that transformation to the AST level as a pass, and it's way easier to do it this way |
| 16:46 | gfredericks | cfleming: that is the first time anybody has told me that. |
| 16:47 | Bronsa | gfredericks: just exclude org.clojure/clojure and include my.clojure/clojure |
| 16:47 | gfredericks | Bronsa: so leiningen *does* have a global exclude? |
| 16:47 | arrdem | gfredericks: not that I'm seeing. you have to roll it manually. |
| 16:47 | gfredericks | I guess a plugin could do the dirty work |
| 16:47 | arrdem | this is actually the primary reason why I've never used org.oxlang/clojure for anything... |
| 16:48 | Bronsa | gfredericks: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L63-L66 |
| 16:48 | arrdem | (inc Bronsa) |
| 16:48 | lazybot | ⇒ 54 |
| 16:48 | gfredericks | (inc Bronsa) ;; semiprimes are cool |
| 16:48 | lazybot | ⇒ 55 |
| 16:48 | Bronsa | let them rain |
| 16:49 | arrdem | (dec Bronsa) ;; karma/minute rate exceeded |
| 16:49 | lazybot | ⇒ 54 |
| 16:49 | johnwalker | (inc Bronsa) |
| 16:49 | lazybot | ⇒ 55 |
| 16:49 | gfredericks | Bronsa is going to win an award for karma thrashing |
| 16:49 | Bronsa | I know how a rubberband feels now |
| 16:50 | arrdem | he's got a loooong way to go before catching up with amalloy.. |
| 16:50 | gfredericks | ~amalloy |
| 16:50 | clojurebot | try that; it won't work |
| 16:51 | gfredericks | clojurebot: clojurebot is a jukebox for amalloy's greatest hits |
| 16:51 | clojurebot | Ik begrijp |
| 16:52 | m1dnight_ | Dutch \o/ |
| 17:00 | arrdem | I guess the issue is when if ever does a patched verison of Clojure pay for itself... |
| 17:01 | gfredericks | ...when you get the feature you need? |
| 17:01 | gfredericks | which is immediately? |
| 17:01 | arrdem | no as in what features could not be added as libraries. |
| 17:01 | arrdem | so.. lets say I wanted a library that adds clojure.core/seqable? |
| 17:01 | gfredericks | some of them |
| 17:02 | gfredericks | probably mods to the compiler mostly? |
| 17:02 | arrdem | probably... |
| 17:02 | arrdem | but even then TEJVM is almost good enough, just drag that in and mod it |
| 17:04 | gfredericks | $google TEJVM |
| 17:04 | lazybot | [CPU count confusion | VMware Communities] https://communities.vmware.com/message/2334874 |
| 17:04 | arrdem | $google clojure.tools.emitter.jvm |
| 17:04 | lazybot | [clojure/tools.emitter.jvm · GitHub] https://github.com/clojure/tools.emitter.jvm |
| 17:05 | gfredericks | oh hey right |
| 17:05 | arrdem | that thing that Bronsa and I were working on. all summer. |
| 17:05 | gfredericks | worked on so hard you needed some seriously optimized acronyms |
| 17:06 | arrdem | that's actually the dev.clojure.org/jira name :/ |
| 17:06 | gfredericks | oh I like those acronyms actually |
| 17:06 | gfredericks | I just don't know them all |
| 17:07 | gfredericks | I've been working on TCHECK and NREPL lately |
| 17:10 | takemikazuchi | Anyone wanna give me some feedback? I'm working through 4clojure problems: Problem: https://4clojure.com/problem/31 My solution: https://www.refheap.com/91221 |
| 17:11 | justin_smith | takemikazuchi: conj takes varargs, so you don't need to wrap a call to conj in another call to conj |
| 17:11 | justin_smith | ,(conj [] :a :b) |
| 17:11 | clojurebot | [:a :b] |
| 17:12 | gfredericks | ,(conj [] conj conj (conj)) |
| 17:12 | clojurebot | [#<core$conj clojure.core$conj@d4f698> #<core$conj clojure.core$conj@d4f698> []] |
| 17:12 | justin_smith | lol |
| 17:12 | gfredericks | actually |
| 17:12 | gfredericks | ,(conj (conj) (conj) (conj) (conj)) |
| 17:12 | clojurebot | [[] [] []] |
| 17:13 | arrdem | rofl |
| 17:14 | takemikazuchi | justin_smith: in that case I believe I need to as last of x is a collection that I want to insert y into. |
| 17:16 | justin_smith | ahh, I misread, you are right |
| 17:17 | justin_smith | well, style wise, if you are using pop, then use peek and not last |
| 17:17 | justin_smith | peek/pop butlast/last |
| 17:17 | justin_smith | (first/rest) |
| 17:18 | gfredericks | +/-, *//, concat/deconcat swap!/unswap! |
| 17:19 | justin_smith | heh |
| 17:19 | justin_smith | we need unswap! |
| 17:19 | gfredericks | launch-missiles/return-missiles |
| 17:19 | takemikazuchi | justin_smith: That makes sense, peek does seem more natural there. |
| 17:20 | justin_smith | gfredericks: deconcat is clearly (rand-nth [partition partition-all partition-by]) |
| 17:20 | gfredericks | split-at |
| 17:21 | gfredericks | split-with |
| 17:21 | justin_smith | oh yeah, those too |
| 17:21 | gfredericks | (juxt take drop) |
| 17:27 | dbasch | deconcat randomly partitions a sequence so that all possible partitions are equally likely |
| 17:28 | arrdem | you could actually define a Concat type and a sane deconcat operator... |
| 17:28 | gfredericks | ,(defn deconcat [coll] ((juxt take drop) (rand-int (inc (count coll))) coll)) |
| 17:28 | clojurebot | #'sandbox/deconcat |
| 17:28 | gfredericks | ,(deconcat (range 10)) |
| 17:28 | clojurebot | [(0 1 2 3 4 ...) ()] |
| 17:28 | gfredericks | ,(deconcat (range 10)) |
| 17:28 | clojurebot | [(0 1 2) (3 4 5 6 7 ...)] |
| 17:29 | dbasch | gfredericks: that’s all splits, I mean all possible partitions from all n elements to a single collection |
| 17:34 | arrdem | so looks like we define concat in terms of a lazy sequence of cons... |
| 17:34 | arrdem | could probably have a Concat type with a seq of subsequences |
| 17:34 | arrdem | then deconcat is trivially the sequence of subsequences |
| 17:38 | justin_smith | a version of deconcat https://www.refheap.com/91223 |
| 17:38 | takemikazuchi | Anyone who knows ruby here, is it safe to say Ruby's foo(*bar) and Clojure's (apply foo bar) are functionally equivalent? |
| 17:40 | dbasch | justin_smith: but the empty subsequences… |
| 17:40 | amalloy | takemikazuchi: yes, they are the same general idea |
| 17:40 | justin_smith | dbasch: they are all valid inputs that return the original sequence if you apply concat |
| 17:41 | justin_smith | feel free to change the (rand-int n) to (inc (rand-int (dec n))) of course |
| 17:42 | takemikazuchi | amalloy: Thanks. Any significant differences I should keep in mind? |
| 17:43 | amalloy | takemikazuchi: not really. some nice stuff like apply is a function, so you can do something silly like ##(map apply [+ -] [[1 2 3] [21 7 2]]) |
| 17:43 | lazybot | ⇒ (6 12) |
| 17:44 | amalloy | i suppose (partial apply +) would be a more common example |
| 17:44 | amalloy | (def sum (partial apply +)) |
| 17:47 | hiredman | partial apply + 0 |
| 17:52 | gws | takemikazuchi: can the splat be used on something akin to ##(apply + (range 10)) |
| 17:52 | lazybot | ⇒ 45 |
| 17:53 | gws | e.g. a hypothetical sum function that takes a variable number of arguments: sum(*[0..9]) |
| 17:53 | H4ns | in compojure, is there a way to pass both the body-params and a url param to a handler? apparently, if i use vector syntax, i can only access the url parameters (/bar/:foo), whereas when i use map syntax, i can't access the url parameters. |
| 17:53 | H4ns | (i want to have a PUT handler which has the ID in the url and the updated data in the request body) |
| 17:54 | amalloy | gws: yes, that is like the only thing that splat can do |
| 17:56 | dbasch | justin_smith: check this one out https://www.refheap.com/91226 |
| 17:56 | gws | amalloy: i don't know ruby that well, but i created a vararg sum function and it works when i pass multiple args but with *[0..9] i get "Range can't be coerced into Fixnum" on ruby 2.1.0, so that's why i asked |
| 17:56 | dbasch | lazy, uniform random partition |
| 17:59 | justin_smith | interesting, so it has 50% chance of size 1, 25% of size 2, 12.5% of size 3 etc. (modulo the bail out if size is greater than remaining contents) |
| 18:00 | justin_smith | whereas mine was even within range of size of coll (with same bailout condition) |
| 18:00 | amalloy | gws: that's not the syntax for rangers. it's just a really weird number |
| 18:00 | amalloy | *ranges |
| 18:00 | justin_smith | amalloy: time for the ad&d based dsl for sequences |
| 18:00 | takemikazuchi | gws: Yeah I mean the analogy starts to break down at that point I supppose |
| 18:00 | dbasch | justin_smith: and mine doesn’t even care about the seq size, or if it’s finite |
| 18:01 | justin_smith | right |
| 18:01 | dbasch | e.g. (take 10 (random-partition (range))) |
| 18:01 | takemikazuchi | lol you end up with something like this: lambda{|*x| x.inject(:+) }.call(*(1..9).to_a) |
| 18:01 | amalloy | gws: you want (1...9) |
| 18:01 | amalloy | takemikazuchi: eh? you don't need the to_a |
| 18:01 | takemikazuchi | amalloy: yeah just noticed that. |
| 18:02 | amalloy | def sum(*xs) xs.inject(:+) end; sum(1...9) |
| 18:02 | amalloy | or something like that |
| 18:02 | amalloy | there. def sum(*xs) xs.inject(:+) end; sum(*(1..9)) |
| 18:03 | dbasch | justin_smith: the 1/2 chance is to guarantee uniformity |
| 18:04 | dbasch | can’t think of a better way off the top of my head |
| 18:04 | justin_smith | right, just observing the behavior |
| 18:05 | justin_smith | could have as easily been thirds (1/3 chance of size 1, 1/6 of size 2, 1/12 of size 3, etc.) |
| 18:05 | dbasch | justin_smith: but then it wouldn’t be uniform |
| 18:06 | dbasch | I wanted all possible partitions to be equally likely |
| 18:09 | dbasch | that would be an awful interview question btw |
| 18:11 | dbasch | I should create a library called useless, in the spirit of amalloy’s useful |
| 18:12 | dbasch | this could go in there |
| 18:13 | dbasch | along with a macro that makes code fail randomly |
| 18:13 | dbasch | actually that’s not useless |
| 18:16 | amalloy | dbasch: the classic backwards-mode macro belongs there |
| 18:17 | amalloy | (defmacro backwards [& body] (cons `do (postwalk (fn [x] (if (seq? x) (reverse x) x)) body))) |
| 18:19 | gfredericks | without-redefs |
| 18:20 | dbasch | with-open-or-dev-null |
| 18:20 | dbasch | maybe-off-by-one-loop |
| 18:21 | dbasch | thread-somewhere |
| 18:21 | dbasch | -???> |
| 18:22 | dbasch | aka as the magical mystery arrow |
| 18:23 | dbasch | also aka as |
| 18:24 | justin_smith | dbasch: how is 50% chance of size 1 etc. more uniform than 33% chance of zie 1 etc. ? |
| 18:24 | dbasch | justin_smith: because there are 2^n partitions |
| 18:25 | dbasch | so for example the one with all the elements must occur when you get n tails in a row |
| 18:25 | dbasch | technicall 2^(n-1) |
| 18:26 | justin_smith | dbasch: clearly there is something I don't yet get about statistics underlying all this |
| 18:26 | dbasch | try for example (frequencies (take 10000 (repeatedly #(random-partition (range 4))))) |
| 18:27 | dbasch | e.g. for (0 1 2) you have four possibilities |
| 18:27 | dbasch | you want to choose ((0 1 2)) with 1/4 chance |
| 18:28 | cfleming | arrdem: Without running the patch that I'm running, I can't compile my project |
| 18:28 | cfleming | arrdem: So for me the payoff was pretty immediate. |
| 18:29 | cfleming | arrdem: That said, technically I only need my patched version to actually compile, not at runtime. |
| 18:38 | gfredericks | ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2)) |
| 18:38 | clojurebot | ((0 1) (2)) |
| 18:38 | gfredericks | ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2)) |
| 18:38 | clojurebot | ((0) (1) (2)) |
| 18:38 | gfredericks | ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2)) |
| 18:38 | clojurebot | ((0 1) (2)) |
| 18:38 | gfredericks | ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2)) |
| 18:38 | clojurebot | ((0) (1) (2)) |
| 18:38 | gfredericks | ,(partition-by (fn [_] (rand-nth [true false])) '(0 1 2)) |
| 18:38 | clojurebot | ((0 1) (2)) |
| 18:38 | gfredericks | o_O |
| 18:39 | gfredericks | ,(repeatedly 8 (fn [] (partition-by (fn [_] (rand-nth [true false])) '(0 1 2)))) |
| 18:39 | clojurebot | (((0) (1 2)) ((0 1 2)) ((0 1) (2)) ((0) (1 2)) ((0) (1 2)) ...) |
| 18:39 | gfredericks | looks legit |
| 18:40 | justin_smith | (inc gfredericks) |
| 18:40 | lazybot | ⇒ 91 |
| 18:40 | justin_smith | that's the one |
| 18:41 | tuft | anyone know how to do a "where in" style query in datomic? i.e. get entities where an attribute value is one of several |
| 18:41 | dbasch | yes, that’s nicer |
| 18:53 | AeroNotix_ | does/can timbre rotate log files? |
| 18:57 | lodin | Anyone know how to restart an nrepl server so that all defs etc are gone? I tried (do (stop-server s) (start-server)) but that didn't help. |
| 18:58 | justin_smith | lodin: defs are not local to the nrepl server |
| 18:58 | justin_smith | they are global to the clojure process |
| 18:58 | lodin | Oh. |
| 19:02 | lodin | That actually makes a lot of sense. :-) |
| 19:07 | lodin | Is there any tool to start/stop isolated clojure processes easily (which I then can access using nrepl)? I think I've read about such a tool. |
| 19:09 | justin_smith | http://leiningen.org/grench.html there is grench, I don't know isolated it is |
| 19:10 | truebuddi | quick question here at http://pastebin.com/hpFqRFJ7 |
| 19:13 | jkj | working with clojure and sampling large data objects, i'd be happy if i had a ide and a repl that wouldn't choke on a few kilobytes of text |
| 19:14 | jkj | wonder if there is a middleware to protect emacs from accidentally printint something that takes all the cpu for couple of minutes |
| 19:15 | justin_smith | jkj: iirc the issue is that it applies regexes per line, so lack of line breaks make it freak out |
| 19:15 | jkj | ok |
| 19:16 | jkj | justin_smith: good to know |
| 19:18 | jkj | hmm. maybe the trick would be to redirect all the output to something that can take it. web browser maybe |
| 19:19 | justin_smith | jkj: you could set debug-on-signal, and then send a signal to emacs via kill in a command line |
| 19:20 | justin_smith | jkj: then in the debugger you can see what the hell it was doing |
| 19:20 | jkj | justin_smith: thx |
| 19:20 | justin_smith | sending problematic output to a text file and opening it in emacs in auto-tail-mode is another option |
| 19:20 | justin_smith | it will scroll down as new content is created, but not do the CPU heavy shit it does in the repl buffer |
| 19:21 | justin_smith | sorry it's called auto-revert-tail-mode |
| 19:21 | justin_smith | or something like that - it is like tail -f but in an emacs buffer |
| 19:21 | justin_smith | watches the file and reloads every time it sees a change |
| 19:22 | justin_smith | you could use proper logging, and then open the log file using auto-rever-tail-mode |
| 19:22 | alexbaranosky_ | bbloom :snapshot sounds like a good idea |
| 19:23 | lodin | justin_smith: I found https://github.com/projectodd/shimdandy. Unfortunately I can't use it via clojure itself. :-) |
| 19:23 | jkj | oops. HUP was a bad idea :D |
| 19:23 | justin_smith | jkj: oops |
| 19:28 | bbloom | alexbaranosky_: it certainly is :-) works out nice too if your variable is a map, which is a good idea anyway so you can assoc/update-in on each recur, rather than muck with positional arguments |
| 19:28 | jkj | i'm not quite sure if printing huge amounts of data slowly or lagging when handling big buffers is really a problem or just trying to misuse emacs |
| 19:29 | justin_smith | jkj: it's a problem with the repl buffer, that won't come up in a buffer in plain text mode |
| 19:29 | jkj | justin_smith: ok |
| 19:29 | justin_smith | do you mean it is lagging for big non-repl buffers? |
| 19:29 | tuft | any ideas on testing set membership for an attribute value in datomic? searched all over with no luck |
| 19:30 | justin_smith | jkj: if so, in clojure mode or in general? |
| 19:30 | cfleming | jkj: if you're an IDE sort of person, Cursive handles lots of output pretty well. |
| 19:31 | jkj | cfleming: haven't tried that. |
| 19:33 | arrdem | cfleming: fair |
| 19:34 | cfleming | arrdem: I had a hideous Rube Goldberg machine hooked up just to be able to compile until I applied that patch. |
| 19:35 | jkj | Debugger entered--Lisp error: (wrong-type-argument symbolp [object ede-project-autoload .... |
| 19:35 | jkj | quite strange place where it hits after signilng |
| 19:36 | arrdem | cfleming: what patch did you need that badly? |
| 19:36 | arrdem | cfleming: I have a list of bugbears with Clojure, but nothing that actually stops me getting work done |
| 19:36 | jkj | it seems to finish the print and then give backtrace of something else |
| 19:36 | jkj | so doing what is does does not stop on signal |
| 19:36 | cfleming | arrdem: http://dev.clojure.org/jira/browse/CLJ-1315 |
| 19:37 | arrdem | cfleming: gotcha |
| 19:37 | cfleming | arrdem: Without that patch, I had to bring up the IntelliJ test infrastructure (~45 secs) and compile inside it. |
| 19:38 | jkj | now i have stuff in repl buffer and pushin any key takes about 1,5 sek for the character to appear |
| 19:38 | arrdem | cfleming: lol |
| 19:38 | cfleming | arrdem: And then shower afterwards, which also takes time. |
| 19:38 | jkj | any ideas on seeing what it does? |
| 19:38 | truebuddi | sorry if already replied .. disconnected earlier but was asking about splitting (-> .... ) into multiple forms.. http://pastebin.com/hpFqRFJ7 |
| 19:39 | bobpoekert | What are people using for single-machine k-means clustering these days? |
| 19:39 | bobpoekert | Still Weka? |
| 19:39 | cfleming | arrdem: What's the status of TEJVM these days? |
| 19:40 | cfleming | arrdem: Is it realistic to use it to compile? |
| 19:40 | arrdem | truebuddi: you need to be threading that request. right now you ignore it. line 19 |
| 19:40 | arrdem | truebuddi: in future please use refheap, because Raynes made it, it's awesome and it doesn't have ads. |
| 19:41 | truebuddi | googling refheap |
| 19:41 | arrdem | cfleming: TEJVM totally works, Oxcart is sketchy at best however |
| 19:41 | truebuddi | arrdem: thank you will do |
| 19:42 | arrdem | cfleming: the main restrictions with TEJVM are either actual bugs in core (incorrect annotations) or just performance. Bronsa has gotten it down to ~15x clojure.core/compile from ~25x but it's still slow. |
| 19:43 | arrdem | cfleming: I never had issues when building Oxcart that weren't of my own doing. |
| 19:43 | cfleming | arrdem: That's probably ok for a production build if it makes a different though. |
| 19:43 | cfleming | s/different/difference/ |
| 19:43 | arrdem | cfleming: oh. TEJVM can't do AOT yet. Oxcart can, but I never backported the infrastructure for Bronsa |
| 19:43 | cfleming | arrdem: Ah. |
| 19:43 | arrdem | cfleming: that's another killer |
| 19:44 | bobpoekert | Searching around for clustering implementations there's a bunch of stuff that hasn't been updated in years and isn't in maven, adn Weka |
| 19:44 | bobpoekert | and stuff like MALLET which is NLP-specific |
| 19:44 | arrdem | one of these days I'll have free time and PR it... but not today |
| 19:44 | cfleming | arrdem: Did you look at skummet at all? It looked interesting as well and sounds like it was quite successful. |
| 19:44 | truebuddi | arrdem: I changed it to https://www.refheap.com/91230 but still getting cemerick.friend$authenticate$fn__379 cannot be cast to java.util.Map |
| 19:45 | arrdem | truebuddi: you have a type error somewhere. you are passing a function where it expects a map. more than that I cannot trivially surmise. |
| 19:46 | kenrestivo | ~tejvm |
| 19:46 | clojurebot | It's greek to me. |
| 19:46 | kenrestivo | me too |
| 19:46 | arrdem | truebuddi: I would guess line 12 |
| 19:46 | arrdem | truebuddi: check your arguments order with -> |
| 19:46 | arrdem | cfleming: meh totally not biased in this or anything but I think that skummet is a hack/wrong approach |
| 19:47 | arrdem | cfleming: have you seen my end of summer blag post? |
| 19:47 | cfleming | arrdem: Sure, but it's one that might produce decent gains with relatively little work. |
| 19:47 | cfleming | arrdem: No, got a link? |
| 19:48 | arrdem | cfleming: http://arrdem.com/2014/08/05/of_oxen,_carts_and_ordering/ |
| 19:48 | arrdem | cfleming: https://groups.google.com/forum/#!topic/clojure-dev/dSPUNKSaV94 |
| 19:48 | arrdem | cfleming: those two pretty well capture my takeaway from this summer |
| 19:49 | cfleming | arrdem: Ah, I lie, I did see the mailing list post. I think the proposal to split out core sounds good. |
| 19:50 | arrdem | no way it's gonna happen.. but it would be nice |
| 19:50 | arrdem | ^ one line summary of my summer :/ |
| 19:51 | cfleming | arrdem: I didn't realise that one of the main benefits of Oxcart was to remove var indirection - nice. |
| 19:53 | truebuddi | arrdem: converting the defn to a def worked ... https://www.refheap.com/91230 thanks! |
| 19:54 | arrdem | cfleming: as I argued in the clj-dev post, skummet and "lazy loading" can only approximate an actual tree shaking compiler, and do so at the cost of creating a difficult to maintain fork of Clojure. |
| 19:55 | arrdem | cfleming: if the world were flat and I had my way, we'd do lib-clojure and then Mikera and I would be free to build crazy clojure-like fast languages |
| 19:55 | arrdem | but it isn't |
| 19:55 | cfleming | arrdem: Yeah, no doubt. I'd love to be able to make a totally static production build of Cursive for deployment though. |
| 19:55 | cfleming | arrdem: I guess there's nothing stopping you doing it except time and money, right? :-) |
| 19:56 | justin_smith | jkj: not sure actually, if just seeing where it was when you interrupted did not help |
| 19:56 | justin_smith | jkj: #emacs could have some ideas |
| 19:57 | arrdem | cfleming: basically. mainly money as it can buy time... if someone wanted to foot the bill for this I'd be delighted to say fuckit, maintain my lib-clojure fork and keep working on Oxcart but GSoC is over |
| 19:57 | arrdem | cfleming: that and I think if you're gonna statically compile Clojure may as well take the time to clean up some warts |
| 19:58 | arrdem | I have a project that's my sketch of doing so, but it doesn't work and I'm not sure it'll ever exist so I'll refrain from advertising it here. |
| 20:00 | cfleming | arrdem: I'd be interested in hearing about it - are you going to the conj? |
| 20:01 | arrdem | cfleming: I probably will but I don't have plans yet. |
| 20:01 | cfleming | arrdem: Ok, I'll buy you a beer if you make it and you can tell me about it. |
| 20:01 | arrdem | cfleming: haha you're on |
| 20:02 | arrdem | after seeing all the cool stuff from strangeloop I'd be crazy to miss the conj... but classes and stuff |
| 20:03 | cfleming | arrdem: Yeah, I have to make it to strangeloop one of these days, it looks amazing. |
| 20:04 | cfleming | arrdem: Almost more interesting than the conj actually, more eclectic |
| 20:04 | arrdem | cfleming: yeah it was really interesting to see all the hot stuff from different languages and communities. I've been looking at the conj schedule and due to having a single track there's something for everone |
| 20:17 | bobpoekert | I found a library that was updated this year! The documentation is all in japanese. |
| 20:18 | bobpoekert | oh, and it only works on 2d vectors :( |
| 20:18 | TEttinger | (inc Japanese) |
| 20:18 | lazybot | ⇒ 1 |
| 20:19 | TEttinger | what are you looking for, bobpoekert? something in core.matrix? |
| 20:19 | bobpoekert | something that can take 27-dimensional |
| 20:19 | bobpoekert | vectors of reals |
| 20:19 | bobpoekert | and turn them into a k-means tree |
| 20:19 | bobpoekert | whether it's in core.matrix or not I don't really care |
| 20:21 | justin_smith | (inc 日本の) |
| 20:21 | lazybot | ⇒ 1 |
| 20:22 | TEttinger | I saw a japanese version of https://github.com/joshuaeckroth/clj-ml |
| 20:23 | justin_smith | bobpoekert: this looks a little dated, but it does look like what you are looking for http://www.informatik.uni-ulm.de/ni/staff/HKestler/parallelkmeans/ |
| 20:24 | justin_smith | it's not really idiomatic as a clojure project, but it is doing k-means and has source code you can start with |
| 20:24 | bobpoekert | TEttinger: I was referring to https://github.com/satoh-disk/k-means |
| 20:29 | TEttinger | there seem to be a bunch of leads. https://github.com/elben/k-means |
| 20:30 | bobpoekert | that's 2d |
| 20:30 | bobpoekert | justin_smith's suggestion might work |
| 20:30 | TEttinger | I am not familiar with k-means at all, so I'd go with justin_smith's then. I also found https://github.com/codyrioux/kmeans-clj |
| 20:31 | bobpoekert | numeric processing with core.async??? |
| 20:31 | lazybot | bobpoekert: Oh, absolutely. |
| 20:34 | bobpoekert | it should really be more common knowledge that (apply min-key …) is argmin |
| 20:34 | bobpoekert | took me a long time before I found that out |
| 20:34 | bobpoekert | min-key and max-key are really confusingly names |
| 20:34 | bobpoekert | named |
| 20:37 | justin_smith | yeah, I wonder what the origin of the current names is? |
| 20:49 | gfredericks | min-by and max-by would be less surprising I guess? |
| 20:54 | justin_smith | or argmin and argmax, which is what they are called in math |
| 20:54 | hodlr | in order to pull in java libs into my project what do i need to enter into project.clj from the pom.xml ? |
| 20:54 | justin_smith | hodlr: [group/project "version.id"] |
| 20:55 | justin_smith | err, that was sloppy |
| 20:55 | justin_smith | [groupId/artifactID "version"] |
| 20:56 | hodlr | justin_smith: thanks :) |
| 20:56 | gfredericks | justin_smith: I'm kind of surprised I never noticed those names in math |
| 20:57 | justin_smith | gfredericks: http://en.wikipedia.org/wiki/Arg_max |
| 20:58 | justin_smith | it's the only standard name for the function I know of |
| 20:58 | justin_smith | I guess technically arg-min and arg-max could be like min-key / max-key but take collections and return sets |
| 20:59 | justin_smith | (the set of all items returning the minimum value) |
| 20:59 | justin_smith | (or maximum) |
| 20:59 | gfredericks | HUH. |
| 20:59 | gfredericks | (inc justin_smith) |
| 20:59 | lazybot | ⇒ 85 |
| 21:00 | justin_smith | actually planet math is usually a better source than wikipedia http://planetmath.org/argminandargmax |
| 21:02 | justin_smith | actually, to be most mathematically correct, we could (intern 'clojure.core (symbol "arg max") #(hash-set (apply max-key %))) |
| 21:02 | justin_smith | but it would be a pain in the ass to use something with a name like that in actual code |
| 21:03 | justin_smith | ,(intern *ns* (symbol "arg max") #(apply max-key %&)) |
| 21:03 | clojurebot | #'sandbox/arg max |
| 21:04 | gfredericks | somebody at work was asking about the behavior of ##(keyword "foo bar") and why it doesn't throw |
| 21:04 | lazybot | ⇒ :foo bar |
| 21:04 | gfredericks | does anybody know if the answer is A) only backwards compatibility, B) speed (from not checking), C) something else? |
| 21:04 | justin_smith | we've had similar discussions around here |
| 21:05 | TEttinger | ,((keyword "Oh yeah: I heard the best news!") {(keyword "Oh yeah: I heard the best news!") "Oh really?"}) |
| 21:05 | clojurebot | "Oh really?" |
| 21:05 | TEttinger | they certainly are valid |
| 21:06 | justin_smith | ,(intern *ns* (symbol "arg max") (fn [key sq] (apply max-key key sq))) |
| 21:06 | clojurebot | #'sandbox/arg max |
| 21:06 | justin_smith | ,((resolve (symbol "arg max")) #(* % %) [-10 1 2 3 4]) |
| 21:06 | clojurebot | -10 |
| 21:06 | gfredericks | sure but there are uses where they don't |
| 21:07 | gfredericks | e.g., if you like to just blindly parse your json into keywords, that might work okay most of the time, but as soon as you start using cascalog or storm things break |
| 21:07 | gfredericks | since they're serializing things behind the scenes |
| 21:07 | justin_smith | right. and the blindly parsing json into keywords thing may just be the source of the permissive behavior? |
| 21:08 | gfredericks | "source of"? |
| 21:08 | justin_smith | maybe "a justification for" |
| 21:08 | justin_smith | sloppy wording |
| 21:09 | gfredericks | well it certainly sets up the "changing this would break lots of code" argument |
| 21:10 | gfredericks | which I figured is a good enough explanation for not expecting anything to change at this point; but I wasn't sure if it was universally regretted or not. |
| 21:13 | justin_smith | tangentially, I wonder if something related to this (any string becoming a symbol / keyword) couldn't have been exploited to make gensyms a bit stronger (eg. rendering them unreadable) |
| 21:13 | justin_smith | I think I meant ie. |
| 21:17 | gfredericks | haha that's clever |
| 21:17 | gfredericks | so they're guaranteed to not clash |
| 21:17 | gfredericks | could make some fringe uses more difficult though |
| 21:18 | justin_smith | yeah |
| 21:18 | bbloom | gfredericks: it's speed / not bothering to do error checking b/c it's hard |
| 21:18 | bbloom | and of course can't change now b/c ppl depend on broken behavior |
| 21:18 | bbloom | but keywordizing strings when parsing json is a universally bad idea without a known schema |
| 21:19 | bbloom | and a marginally bad idea with a schema too :-P |
| 21:22 | gfredericks | bbloom: error checking isn't hard in this case, is it? just arm thyself with a decent regex? |
| 21:22 | bbloom | gfredericks: problem isn't "this case" it's universally |
| 21:23 | bbloom | if you make a promise to check your arguments for validity, you get in to the whole type systems, contracts, schemas, etc etc etc forever |
| 21:23 | bbloom | seems the line for clojure was drawn: "only check arguments when there's a high likelihood that somebody will fuck up AND it doesn't slow the whole thing down" |
| 21:24 | bbloom | "but mostly only when a macro will eat the line numbers of your stack trace" |
| 21:24 | bbloom | :-P |
| 21:30 | Wild_Cat | while we're on that topic, I'm curious, why was the decision taken to keywordize strings? |
| 21:31 | gfredericks | bbloom: coolthx |
| 21:31 | gfredericks | Wild_Cat: in what case? |
| 21:32 | Wild_Cat | gfredericks: JSON deserialization. |
| 21:32 | justin_smith | that's optional |
| 21:32 | justin_smith | always has been |
| 21:32 | Wild_Cat | wait, it is? |
| 21:32 | bbloom | there's a keywordize? argument |
| 21:32 | Wild_Cat | hrmm. I'm misremembering. Disregard my question and carry on, then. |
| 21:33 | Wild_Cat | it's been too long since I got the occasion to write actual Clojure code. |
| 21:33 | bbloom | the argument is discussed in the api docs |
| 21:33 | bbloom | but not the readme |
| 21:33 | bbloom | but it should be :-P |
| 21:36 | gfredericks | bbloom: I'm looking for such an argument in the cheshire docstrings but can't find it; is that where you were referring to? |
| 21:37 | bbloom | core.data.json |
| 21:37 | bbloom | i assumed that's what Wild_Cat was referring to |
| 21:37 | bbloom | sorry |
| 21:37 | Wild_Cat | bbloom: it was. |
| 21:37 | bbloom | oh then NOT sorry :-) |
| 21:41 | bbloom | gfredericks: the read-json function |
| 21:44 | gfredericks | bbloom: oh dear I think I misinterpreted the word "argument" |
| 21:44 | bbloom | gfredericks: ha! seems you need some sleep my friend |
| 21:44 | gfredericks | this morning I slept in till 6:30 |
| 21:44 | hugoduncan | in cheshire you can pass in an arbitrary function to apply to keys |
| 21:50 | justin_smith | hugod: which could as easily be a validator as a keywordizer :) |