2015-02-22
| 00:00 | julianleviston | ddellacosta: yeah, it’s just creating a copy with bits missing, effectively… so should be roughly that. |
| 00:00 | justin_smith | ddellacosta: if you are removing n keys out of m, the into solution is N=(m-n), the select-keys solution is N=n |
| 00:00 | ddellacosta | I guess it's O(n) where n is the set of keys you are removing |
| 00:00 | ddellacosta | right |
| 00:00 | justin_smith | ddellacosta: so the number of keys being removed, and the initial count, are going to affect things a lot |
| 00:00 | julianleviston | now I have my beautiful function thanks guys… you really do rock… (defn filter-on-keys [pred coll] (select-keys m (filter pred (keys m)))) |
| 00:00 | ddellacosta | right, right |
| 00:01 | julianleviston | haha coll !- m |
| 00:01 | julianleviston | good work justin_smith |
| 00:01 | julianleviston | I mean good work julianleviston |
| 00:01 | justin_smith | heh |
| 00:08 | tomjack | If I cared about performance I think I would write (fn [pred m] (reduce-kv (fn [m k v] (if (pred k) m (dissoc m k))) m m)) |
| 00:08 | tomjack | ,(time (let [m {:a "hey" :b "yes" "string-key" "should not include"} pred #(keyword? %)] (reduce-kv (fn [m k v] (if (pred k) m (dissoc m k))) m m))) |
| 00:08 | clojurebot | "Elapsed time: 1.471779 msecs"\n{:b "yes", :a "hey"} |
| 00:09 | justin_smith | ten times faster than the select-keys |
| 00:09 | tomjack | (for no good reason besides superstition) |
| 00:09 | justin_smith | *slower |
| 00:09 | ddellacosta | I'm not sure we can determine much from testing on such a small set of values |
| 00:09 | tomjack | right :) |
| 00:09 | justin_smith | that's true |
| 00:10 | tomjack | I guess the point of the reduce-kv is that you're seq-free |
| 00:10 | justin_smith | you've still got a seq on the last arg |
| 00:10 | tomjack | no |
| 00:10 | justin_smith | no? |
| 00:10 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 00:10 | ddellacosta | I would think the main thing is to reduce (ha) the number of linear scans over the same set of data |
| 00:11 | tomjack | well, I thought not |
| 00:11 | tomjack | but maybe you're right |
| 00:12 | justin_smith | tomjack: this seems relevant https://github.com/clojure/clojure/blob/96e8596cfdd29a2bb245d958683ee5fc1353b87a/src/clj/clojure/core/protocols.clj#L180 |
| 00:12 | tomjack | PHM and PAM's kvreduce are seq-free |
| 00:12 | ddellacosta | what does having a seq vs. not do for you? Doesn't it still end up being the same amortized time? |
| 00:12 | tomjack | eh, not really |
| 00:12 | tomjack | I mean, not really seq-free I guess |
| 00:12 | tomjack | ddellacosta: oh, yeah, absolutely |
| 00:12 | julianleviston | is there a reject-keys? or should I just comp not my pred? |
| 00:13 | justin_smith | ddellacosta: the difference is you have lower constant cost |
| 00:13 | julianleviston | complement* |
| 00:13 | tomjack | but if that's all we cared about, we wouldn't have PHM at all, would we? |
| 00:13 | ddellacosta | justin_smith: sorry, can you explain? I'm not getting it |
| 00:13 | tomjack | :) |
| 00:13 | justin_smith | ddellacosta: same rationale as transducers - same time complexity, less time spent generating garbage |
| 00:13 | julianleviston | erm.. that was a silly question… is there a reject keys? |
| 00:13 | ddellacosta | justin_smith: dissoc ? |
| 00:13 | ddellacosta | er, sorry, that was for julianleviston |
| 00:13 | ddellacosta | see tomjack reduce above |
| 00:14 | ddellacosta | tomjack's * |
| 00:14 | julianleviston | ddellacosta: oh yeah, apply dissoc…stupid me! |
| 00:14 | tomjack | justin_smith: it looks like kvreduce for PHM ends up going through a NodeSeq in PersistentHashMap.java |
| 00:14 | ddellacosta | justin_smith: still not quite getting it |
| 00:14 | justin_smith | right, you need a linear view of the keys no matter what |
| 00:14 | tomjack | but looks to be less overhead than a normal seq, I think |
| 00:14 | julianleviston | apply makes me somewhat anxious... |
| 00:14 | tomjack | (anyway I think it hardly ever matters :)) |
| 00:14 | ddellacosta | justin_smith: so it's about space considerations? |
| 00:15 | justin_smith | ddellacosta: two ops with the same time complexity can take a different amount of time due to overheads that are linear |
| 00:15 | justin_smith | it's about time constraints |
| 00:16 | tomjack | ddellacosta: binary trees often can get O(log_2(n)) operations. We get O(log_32(n)) stuff for our 32-ary trees. But O(log_2(n)) and O(log_32(n)) are the same -- O(log(n)) -- because log_2(n) = 5 * log_32(n) |
| 00:16 | justin_smith | reductio ad absurdum: consider an operations that takes 1 ms per element and is O(n) vs. an op that takes 1 year per input and is O(n) |
| 00:16 | justin_smith | ddellacosta: ^ |
| 00:16 | tomjack | yet, for some reason, we still care about the difference |
| 00:16 | ddellacosta | tomjack, justin_smith, okay, I think it's getting through my thick skull now--thanks |
| 00:17 | justgreg | I was walking through this tutorial: http://clojure-doc.org/articles/tutorials/vim_fireplace.html and I can't get cpr to run properly even though I have classpath.vim in my pathogen .vim/bundle/ folder. |
| 00:17 | ddellacosta | justin_smith: did you mean constant above vs. linear though? "two ops with the same time complexity can take a different amount of time due to overheads that are linear" |
| 00:17 | justin_smith | ddellacosta: linear as in their cost is multiplied by the side of the input |
| 00:18 | justin_smith | rather than being constant for the algo regardless of input size |
| 00:18 | justgreg | I'm using vim in the terminal, executing from the correct path, with $lein repl running in a separate GNU screen terminal |
| 00:18 | justin_smith | justgreg: are you sucessfully connected then? |
| 00:18 | justgreg | justin_smith, no, that's exactly the problem. |
| 00:20 | justgreg | justin_smith, it was working, then I removed a line related to autocomplete from my .vimrc -- because autocomplete wasn't working properly. |
| 00:20 | justin_smith | OK - I don't know enough about fireplace to help beyond that, sorry. Thought maybe it was an issue where my clojure knowledge would help. |
| 00:21 | justin_smith | hopefully someone else knows more about fireplace and can help you out |
| 00:21 | justgreg | justin_smith, thanks anyway. #vim sent me here. |
| 00:21 | justin_smith | I find it odd that the tutorial does not mention any explicit "connect to a repl" step |
| 00:22 | justin_smith | I would think such a command would exist |
| 00:22 | justgreg | It mentions the :connect command, but it also ought to connect automatically. |
| 00:23 | justin_smith | I would try figuring out how to run connect manually |
| 00:24 | justgreg | (nod) I'm just annoyed because it was working previously, and pathogen.vim appears to be working erratically. |
| 00:24 | swarthy | When I was using vim 'Vundle' was a much simpler package manager |
| 00:24 | swarthy | I had vim + fireplace working with that |
| 00:25 | justgreg | swarthy, really? pathogen claims to just require putting everything in .vim/bundle |
| 00:26 | swarthy | Vundle you just add the github repo as a line, plus two other lines to your vimrc |
| 00:26 | swarthy | then when you start vim |
| 00:26 | swarthy | it does it all automatically |
| 00:26 | swarthy | to connect though |
| 00:27 | swarthy | just open two terms |
| 00:27 | swarthy | in one do $ lein repl |
| 00:27 | swarthy | look at the port number it shows |
| 00:27 | swarthy | then in the other term with vim |
| 00:27 | swarthy | do ':connect' |
| 00:27 | swarthy | follow the prompts using default for everything |
| 00:27 | swarthy | except port |
| 00:27 | swarthy | enter that from before |
| 00:27 | swarthy | Alternatively, if everything is working you just open vim in the directory where there is a running repl |
| 00:28 | swarthy | and a subsequent |
| 00:28 | swarthy | '.nrepl-port' file |
| 00:28 | swarthy | Not to start a flame war, but I've found emacs + prelude + evil-mode a better experience. |
| 00:28 | justgreg | run :connect as a vim command or enter it in the file? |
| 00:28 | swarthy | command |
| 00:28 | swarthy | it might be :Connect |
| 00:28 | swarthy | if that doesn't work |
| 00:30 | justgreg | I'm starting to get fed up w/ vim and liking lisps more and more. I might just try to deal w/ my c-ish scripting langauges in emacs rather than lisps in vim. |
| 00:32 | swarthy | justgreg: I had a hard time getting emacs going with evil mode on my own |
| 00:32 | swarthy | prelude makes it really easy to get up and running after being a vim user |
| 00:32 | swarthy | http://batsov.com/prelude/ |
| 00:32 | swarthy | I recommend that, turning on evil mode is one line |
| 00:32 | swarthy | a lot of vim stuff works |
| 00:33 | swarthy | not 100% but enough |
| 00:33 | swarthy | I used vim for several years, but I'm not die hard about it. |
| 00:34 | swarthy | honestly I use vim for stuff still plenty, do the c stuff there. No reason to only use one thing, use whatever is best. |
| 00:34 | justgreg | I never learned it especially well. I treat it more or less like a nano with syntax highlighting and indenting. I've also never genuinely tried emacs outside of learning sml in it, which was how I learned basic fp. |
| 00:34 | julianleviston | prelude? haha I thought I was in the wrong channel there for a second :) |
| 00:34 | swarthy | oh like Prelude in haskell? |
| 00:34 | swarthy | might be where he got the name |
| 00:35 | julianleviston | swarthy: yeah :) |
| 00:35 | swarthy | justgreg: well prelude makes the barrier to entry basically 0. After two days I was flying around. |
| 00:36 | justgreg | Sweet. I was mostly looking for music-making in a language I could claim was making me a better programmer. There's a very good livecoding environment called Overtone. |
| 00:36 | swarthy | Yeah, I've seen it & I tried their emacs thing a while back. It was a bit complicated and I gave up. |
| 00:36 | swarthy | Might be easier now. |
| 00:36 | julianleviston | I really like stuff that bridges things. Clojure is very bridgy, obviously. |
| 00:39 | julianleviston | So I ended up with a “better” thing for selecting parts of a map… (defn select-filter [pred coll] (select-keys coll (keys (filter pred coll)))) |
| 00:39 | justgreg | I was *trying* to use a scheme dialect, but it's not very well-maintained. |
| 00:40 | julianleviston | it makes things like this so much more readable: (let [expired-items (select-filter #(time-expired? (:timestamp %)) chan-maps)] …) |
| 01:30 | wenshan | I have two lists A: (1 2 3 4) and B (2 4 5 6), how do I do (- A B) to get (-1 -2 -1 -2)? |
| 01:34 | kriyative | wenshan: (map - '(1 2 3 4) '(2 4 5 6)) |
| 01:36 | tomjack | (map - '(1 2 3 4) '(2 4 5 6) '(0 0 -1 0)) ? ;) |
| 01:37 | kriyative | ah, didn't see that ... I presume the second -1 was a typo? |
| 01:48 | wenshan | kriyative: yes, that was a typo, (map - A B) works, thank you |
| 01:51 | kriyative | wenshan: as tomjack indicated, `map` extends to (map - A B C ...) etc. |
| 01:53 | tomjack | ,(apply map vector [[1 2 3] [4 5 6] [7 8 9]]) |
| 01:53 | clojurebot | ([1 4 7] [2 5 8] [3 6 9]) |
| 01:54 | awwaiid | Question for any overtone folks who might be here: (apply eval ['(piano)]) works, but (apply-at (+ (now) 1000) eval ['(piano)]) does not; it appears to have some issue that it is silently discarding. Any pointers? |
| 01:54 | awwaiid | (note that the eval is because the '(piano) is actually dynamically generated) |
| 02:28 | wenshan | hmm, I have a single file (not within a project) opened and started a REPL with cider-jack-in. Now how can I use the math functions (e.g. round)? Simply evaluating (use 'clojure.contrib.generic.math-functions) returns "java.lang.ClassNotFoundException: clojure.contrib.generic.math-functions" |
| 02:30 | kriyative | wenshan: try (Math/round 3.14) |
| 02:30 | kriyative | I'm pretty sure clojure.contrib.generic.math-functions is deprecated |
| 02:45 | wenshan | kriyative: thanks again, (Math/round 3.14) works, but (Math/round (/ 1 20)) does not work, I guess this is because (/ 1 20) is a ratio, not a number? |
| 02:48 | TEttinger | wenshan: to import a file without being in a project, you would still need some amount of lein usage. I think lein imports some of its dependencies into the REPL by default, one of which lets you download a dep in the repl |
| 02:48 | TEttinger | pomegranate maybe? |
| 02:48 | TEttinger | aether? |
| 02:48 | TEttinger | I can't remember |
| 03:06 | rritoch | Is anyone here skilled with regular expressions? |
| 03:06 | amalloy | ~anyone |
| 03:06 | clojurebot | anyone is anybody |
| 03:09 | rritoch | I wrote a blog/tutorial on reverse engineering regular expressions, and was hoping someone could review it to see if there is anything I've missed, or if there are any technical errors. |
| 03:16 | TEttinger | rritoch, post away |
| 03:16 | TEttinger | I like em, I wouldn't say I'm that skilled with them |
| 03:16 | rritoch | --> http://www.ritoch.net/2015/02/22/the-exorcism-of-regular-expressions/ |
| 03:16 | TEttinger | wasn't someone making a regex prover or something? |
| 03:17 | rritoch | It is a little themed to sorcery, but other than that it should be fairly easy to read. |
| 03:17 | TEttinger | or a type checker for regexes? |
| 03:18 | rritoch | Hmm, I don't know. I made some code to ungreedy a regular expression using clojure, but I'm not aware of the projects your mentioning. This is more a manual process for reverse engineering a regular expression, though much of it can be automated. |
| 03:19 | rritoch | I'm also making the suggestion that programmers document their regular expressions, as if that would ever happen, lol |
| 03:21 | TEttinger | nice article, rritoch |
| 03:21 | TEttinger | I scanned the second page, didn't read in depth, but it's sound advice |
| 03:22 | rritoch | TEttinger: Thanks. I have to be honest, it took me 4 hours to write the blog and reverse engineer the example, but I think the end result is at least helpful. |
| 03:22 | amalloy | rritoch: are you really recommending documenting regexes by adding a commented-out verrsion with newlines and indentations, rather tahn recommending use of the /x flag? |
| 03:23 | rritoch | amalloy: No, that is just a middle step of the reverse engineering process |
| 03:24 | rritoch | amalloy: The final result is in the last code block. |
| 03:24 | TEttinger | ambrosebs might have been? |
| 03:25 | rritoch | amalloy: The final result is an approximation of BNF |
| 03:27 | TEttinger | rritoch: since such a big part of programming is giving names to things, the fact that regexes don't have much in the way of naming by default makes them hard to understand when they get large |
| 03:27 | TEttinger | I like your named component parser-style approach |
| 03:33 | rritoch | TEttinger: Well, the idea came to me while manually translating a BNF language definition into Java code. After translating enough entries it occured to me that the process was somewhat reversable, so this is what I came up with to extract the functionality of a complex regular expression. |
| 04:29 | the-kenny | Hm. Why is creating leiningen templates so painful? Copying all files over & then creating entries manually is cumbersome |
| 04:33 | rritoch | the-kenny: Leiningen is open source and can be extended with plugins. If your finding the process repetative you could probably make a plugin to automate the process. You would probably end up with a lot of users of the plugin. |
| 04:44 | the-kenny | rritoch: I know I know :/ |
| 05:09 | julianleviston | the-kenny: or you could use that new thing instead of lein |
| 05:09 | the-kenny | julianleviston: doing that right now. It's still pretty cumbersome |
| 05:09 | julianleviston | the-kenny: what’s it called again? |
| 05:09 | the-kenny | newnew |
| 05:09 | julianleviston | the-kenny: why’s it cumbersome? |
| 05:09 | the-kenny | oh no, wait |
| 05:10 | the-kenny | it's [lein-create-template "0.1.1"] |
| 05:10 | the-kenny | julianleviston: still many manual steps. Cleaning up, etc. It creates a flat folder structure in resources/leiningen/new/ which is confusing in some situations. |
| 05:10 | julianleviston | the-kenny: I was talking about Boot |
| 05:10 | the-kenny | oh |
| 05:11 | julianleviston | the-kenny: sozzy :) |
| 05:11 | the-kenny | actually I'd like to be able to just specify a "normal" leiningen project as source and rename the namespaces. Like forking a git repository |
| 05:12 | julianleviston | the-kenny: make it so, captain :) |
| 05:12 | the-kenny | haha :) |
| 05:43 | wenshan | b |
| 08:48 | AeroNotix | Can anyone recommend a websocket library for ClojureScript? The one that appears the most is Sente, but my god is it bloody complex |
| 08:49 | dnolen | AeroNotix: Google Closure Library has some stuff you can use if you want something more minimal. |
| 08:50 | AeroNotix | dnolen: all I really need is something that returns perhaps channel and has no huge opinions on what the message format should be |
| 08:50 | AeroNotix | https://github.com/james-henderson/chord seems reasonable at first glance. |
| 08:51 | AeroNotix | dnolen: if I were to use the google library, I wonder how easily I can map the JS docs into Cljs. Is that something you think is a barrier? |
| 08:52 | AeroNotix | (or perhaps some enterprisin' individual has converted the docs, I wouldn't be surprised) |
| 08:52 | dnolen | AeroNotix: the docs haven't been converted but there's really no need, CLJS interop is pretty simple after all. |
| 08:53 | AeroNotix | dnolen: I'm not really familiar with javascript at all tbh |
| 08:53 | dnolen | AeroNotix: it will be difficult to be as productive as possible with ClojureScript if you don't know JavaScript basic. |
| 08:53 | dnolen | s/basic/basics |
| 08:53 | AeroNotix | I know the basics-ish |
| 08:53 | AeroNotix | lets say |
| 08:54 | dnolen | AeroNotix: then you probably won't have a problem |
| 08:54 | AeroNotix | cool, I'll persevere |
| 08:54 | justin_smith | AeroNotix: dude wrote the lang in a week, you shouldn't take long to get up to speed |
| 08:55 | AeroNotix | lol |
| 08:55 | AeroNotix | https://github.com/swannodette/om-async-tut oh this is nice |
| 10:32 | sol__ | what does it mean if i have ^bytes in the signature? (defn foo [x ^bytes payload])? |
| 10:33 | sol__ | oh, java type hints :) |
| 10:36 | frzn | oskarth: is breakfast running live anywhere? Couldn't see it running in http://breakfast.clojurecup.com/ |
| 10:40 | AeroNotix | frzn: what the hell is that webpage haha :) |
| 10:41 | frzn | AeroNotix: no idea! haha. But the oskarth project looks nice. I'm planning to use it, if I can get it to work. |
| 11:10 | gfredericks | happy 10:10am to everybody in my time zone |
| 11:12 | devll | it is 10:00 pm here,but Happy to you too. |
| 11:12 | gfredericks | must be one of those weird off-by-ten-minutes time zones |
| 11:13 | devll | lol. 10:12 |
| 11:13 | devll | Any recommendations for scheduling libraries? |
| 11:14 | gfredericks | ~this one weird time zone |will destroy| your faith in humanity; programmers hate it! |
| 11:14 | clojurebot | c'est bon! |
| 11:14 | devll | quartzite , at-at |
| 11:15 | devll | I am not sure which to pick. |
| 11:17 | frzn | AeroNotix: #clojurecup-breakfast |
| 11:17 | frzn | now is running nice :) |
| 11:17 | frzn | (local) |
| 11:17 | frzn | oskarth: nice job. |
| 11:59 | irctc__ | I don't know if it's okay to ask here but quick question guys: why does (for [a (range 4), b (range a)] [a b]) give the same result as (for [a (range 1 4), b (range a)] [a b]) even though `a` should be starting from 0? It's giving me ([1 0] [2 0] [2 1] [3 0] [3 1] [3 2]) as the result. And I'm expecting it to start from [0 0]. |
| 12:01 | aroemers | devll: Depends on your usecase. I find at-at nice and simple. Quartzite has more features. |
| 12:05 | vas_ | ,(for [a (range 1 4)] [a]) |
| 12:05 | clojurebot | ([1] [2] [3]) |
| 12:06 | vas_ | ,(for [a (range 4)] [a]) |
| 12:06 | clojurebot | ([0] [1] [2] [3]) |
| 12:06 | subhashgo | irctc__ : (range 0) -> () |
| 12:07 | irctc__ | ,(for [a (range 4) b (range a)] [a b]) |
| 12:07 | clojurebot | ([1 0] [2 0] [2 1] [3 0] [3 1] ...) |
| 12:08 | irctc__ | oh |
| 12:08 | irctc__ | subhashgo: ok thanks, it just hit me. |
| 12:08 | subhashgo | No worries |
| 12:08 | irctc__ | :) |
| 12:13 | vas_ | irctc_: i think this is an appropriate place to ask that stuff, by the way, as it always helps me out when i try and provide an answer, so everyone wins :] |
| 12:17 | irctc__ | vas_: that's good to know :) thanks for helping out too |
| 12:38 | kras | Hi, why is this code hanging http://pastebin.com/yru9TzKx |
| 12:38 | kras | I am just trying out a basic loop recur |
| 12:39 | kras | Any hints will really help |
| 12:41 | hyPiRion | ,(next '(1)) |
| 12:41 | clojurebot | nil |
| 12:41 | raek | kras: use 'empty?' instead of 'nil?', and use 'conj' instead of 'concat' |
| 12:42 | raek | or, instead of changin the 'nil?', you could change the let to [e (seq v), res []] |
| 12:43 | hyPiRion | kras: what does (next v) return? :) |
| 12:44 | kras | ,(next [1 2 3 4 5 |
| 12:44 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 12:45 | kras | ,(next [1 2 3 4 5]) |
| 12:45 | clojurebot | (2 3 4 5) |
| 12:45 | hyPiRion | kras: Eventually, a better hint: What's the difference between (next v) and (next e)? |
| 12:45 | raek | kras: the propblem using 'concat' here is that it expects to sequences, but you are giving it a vector and an element |
| 12:45 | kras | :-| |
| 12:45 | kras | Got it thanks hyPiRion |
| 12:46 | hyPiRion | np, was confused for a bit too |
| 12:46 | kras | I should be using the binded e inside the loop |
| 12:46 | kras | raek: thanks for the suggestions |
| 12:50 | kras | raek: concat works on two colls, whereas I am giving it one coll and one Long, so had to change it to conj |
| 12:55 | kras | what is an idiomatic way of checking an element's presence in a collection? Equivalent of "in" operator in python |
| 12:57 | kras | ,(some #{2] [1 2 3 4]) |
| 12:57 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]> |
| 12:57 | kras | ,(some #{2} [1 2 3 4]) |
| 12:57 | clojurebot | 2 |
| 12:57 | kras | this seems like an overkill |
| 13:00 | the-kenny | kras: yes, that's the idiomatic way |
| 13:00 | the-kenny | If your collection is a set, you can use contains? |
| 13:07 | oskarth | frzn: thanks! It's currently not running live (the free server clojurecup offered expired afaik) |
| 13:07 | oskarth | frzn: curious, how did you find it? |
| 13:08 | frzn | oskarth: I found one project from clojurecup in hackernews, looked for others and found yours. |
| 13:08 | oskarth | oh cool |
| 13:09 | oskarth | hope it's useful! |
| 13:09 | oskarth | meant to extend it and clean it up, but never happened :p |
| 13:09 | frzn | I'm planning to create a integrated chat with IRC to put in a sidebar in my webapp. |
| 13:09 | frzn | oskarth: I now how it is! haha |
| 13:09 | frzn | but it will be useful, for sure. |
| 13:10 | oskarth | awesome :) |
| 13:10 | imanc_ | what's the best way to write gui apps in clojure? |
| 13:32 | justin_smith | imanc_ seesaw makes it pretty easy, people like the way javafx looks though |
| 14:15 | vas_ | what's a good approach for caching database results between queries? |
| 14:19 | justin_smith | vas_: I've used a wrapper where an atom maps from queries to results, and insertions remove keys from the hash (so you don't get stale results) |
| 14:20 | justin_smith | vas_: also, eg. datomic is cached for you automatically |
| 14:24 | gfredericks | anybody know why clojure seems to name its functions one package level up? |
| 14:25 | gfredericks | e.g. (ns foo.bar) (defn baz []) creates the class foo.bar$baz |
| 14:25 | vas_ | justin_smith: well i have not used atoms before, so i will have some researching to do ... I was trying to naievely just memoize the function that connects to the DB, but I can't invoke "nth" on the result set .. dunno why |
| 14:25 | justin_smith | vas_: atoms are pretty straightforward, it's worth taking a few hours to figure them out |
| 14:26 | justin_smith | ,(let [a (atom {}] (swap! a assoc :a 0) (swap! a assoc :b 1)) |
| 14:26 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]> |
| 14:26 | justin_smith | er |
| 14:26 | justin_smith | ,(let [a (atom {})] (swap! a assoc :a 0) (swap! a assoc :b 1)) |
| 14:26 | clojurebot | {:b 1, :a 0} |
| 14:28 | vas_ | justin_smith: cool. arigato |
| 14:30 | vas_ | by the way, some things just clicked for me the other day with enlive. was able to clean up my code immensely |
| 14:30 | justin_smith | vas_: for what you want atom / swap! (with assoc or dissoc) / @ should be all you need |
| 14:30 | justin_smith | cool |
| 14:30 | vas_ | @? |
| 14:30 | clojurebot | @ is like the macro version of apply |
| 14:30 | vas_ | lol thank you clojurebot! =D |
| 14:31 | justin_smith | ,(let [a (atom "hello")] [a @a]) |
| 14:31 | clojurebot | [#<Atom@267038a5: "hello"> "hello"] |
| 14:31 | justin_smith | notice the difference between the two elements of that vector |
| 14:31 | justin_smith | that's what @ does |
| 14:31 | justin_smith | it's a reader shortcut for deref |
| 14:49 | gfredericks | oh clojurebot was trying to talk about ~@ |
| 14:50 | justin_smith | oh, that makes much more sense, yeah |
| 14:50 | justin_smith | ~@? |
| 14:50 | clojurebot | @ is forget @ |
| 14:50 | justin_smith | hahaha |
| 14:52 | justin_smith | ~~@? |
| 14:52 | clojurebot | ~@ is splicing unquote |
| 14:52 | justin_smith | there we go |
| 14:53 | kaplan_ | justin_smith, what is difference between unquote and splicing unquote? |
| 14:53 | justin_smith | ,`(a b ~(+ 1 2 3)) |
| 14:53 | clojurebot | (sandbox/a sandbox/b 6) |
| 14:54 | justin_smith | ,`(a b ~@(+ 1 2 3)) |
| 14:54 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 14:54 | justin_smith | err |
| 14:54 | justin_smith | ,`(a b ~@[1 2 3]) |
| 14:54 | clojurebot | (sandbox/a sandbox/b 1 2 3) |
| 14:54 | justin_smith | ,`(a b ~[1 2 3]) |
| 14:54 | clojurebot | (sandbox/a sandbox/b [1 2 3]) |
| 14:54 | justin_smith | it splices |
| 14:55 | kaplan_ | justin_smith, that went over my head |
| 14:57 | justin_smith | ~ unquotes |
| 14:57 | clojurebot | Pardon? |
| 14:57 | justin_smith | ~@ inserts a collection, unquoted |
| 14:57 | clojurebot | Cool story bro. |
| 14:58 | justin_smith | I think I have a clearer way to show it |
| 14:58 | justin_smith | ,(def a 42) |
| 14:58 | clojurebot | #'sandbox/a |
| 14:58 | justin_smith | ,`(a ~a) |
| 14:58 | clojurebot | (sandbox/a 42) |
| 14:58 | justin_smith | see how ~ made it unquote? |
| 14:59 | justin_smith | ,`(a ~[a a a]) |
| 14:59 | clojurebot | (sandbox/a [42 42 42]) |
| 14:59 | kaplan_ | justin_smith, ah, I see |
| 14:59 | justin_smith | ,`(a ~@[a a a]) |
| 14:59 | clojurebot | (sandbox/a 42 42 42) |
| 14:59 | justin_smith | notice the differencebetween what ~[] did and what ~@[] did |
| 14:59 | kaplan_ | yep |
| 14:59 | kaplan_ | no vector around ~@ |
| 14:59 | justin_smith | right, it gets spliced in to the parent |
| 15:00 | kaplan_ | justin_smith, can you give a practical example of a macro? |
| 15:01 | justin_smith | ,(defmacro spy [form] `[~'form ~form]) |
| 15:01 | clojurebot | #'sandbox/spy |
| 15:01 | justin_smith | ,(spy a) |
| 15:01 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: form in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:01 | justin_smith | hrm |
| 15:02 | justin_smith | right |
| 15:02 | justin_smith | ,(defmacro spy [form] `['~form ~form]) |
| 15:02 | clojurebot | #'sandbox/spy |
| 15:02 | justin_smith | ,(spy a) |
| 15:02 | clojurebot | [a 42] |
| 15:02 | justin_smith | ,(spy (+ 1 2)) |
| 15:02 | clojurebot | [(+ 1 2) 3] |
| 15:03 | justin_smith | the macro returns a vector containing the original input quoted, and what it evaluates to |
| 15:03 | kaplan_ | justin_smith, ah, I see |
| 15:04 | justin_smith | the general idea with a macro, is you return the form that should be evaluated |
| 15:04 | kaplan_ | justin_smith, but I still can't think of anything where I might find this useful |
| 15:04 | justin_smith | def is a macro |
| 15:04 | benmoss | is there a decent way to access the version number of a lib from within the lib itself |
| 15:04 | justin_smith | that's why you can just give the name you are defining, and don't have to quote it or anything |
| 15:04 | kaplan_ | justin_smith, ah, I see |
| 15:05 | justin_smith | kaplan_: in general, you should rarely need to write macros. But they are very useful when you need them. |
| 15:05 | justin_smith | they are for when you need to change the evaluation rules, or introduce a new syntax |
| 15:07 | justin_smith | "the first rule of macro club, is don't write macros" |
| 15:07 | kaplan_ | justin_smith, are all of clojure's built in keywords like def built with macros? |
| 15:07 | justin_smith | kaplan_: there are a lot of macros in the language |
| 15:07 | justin_smith | actually, it's possible to build a list |
| 15:08 | justin_smith | ,(filter (comp :macro meta) (vals (ns-publics 'clojure.core))) |
| 15:08 | clojurebot | (#'clojure.core/when-first #'clojure.core/cond->> #'clojure.core/gen-class #'clojure.core/while #'clojure.core/import ...) |
| 15:08 | justin_smith | in your repl, that will list all the things in clojure.core that are macros |
| 15:08 | justin_smith | &(filter (comp :macro meta) (vals (ns-publics 'clojure.core))) |
| 15:08 | lazybot | java.lang.SecurityException: You tripped the alarm! ns-publics is bad! |
| 15:09 | justin_smith | blergh |
| 15:18 | crazydiamond | Hi. In CIDER, when *cider-error* buffer displayed, can I automatically jump to line/char where error happened? |
| 16:05 | devll | Hi,in mf Compojure appindex.htm is a valid url. I want to trim "index.htm/". |
| 16:05 | devll | *my |
| 16:07 | devll | but Compujure treats "index.htm" and "index.htm/" the same way |
| 16:07 | devll | It never reaches my wrapper function. |
| 16:09 | devll | I can manage to trim urls like "/music/" to "/music",but not the "htm" files. |
| 16:09 | devll | How can I trim this? |
| 16:12 | justin_smith | why is it not reaching your wrapper? |
| 16:15 | devll | none of the static resources reach wrappers. |
| 16:16 | devll | I think "index.htm/" is treated as static. |
| 16:16 | justin_smith | oh, because your middleware is shortcircuiting the request |
| 16:17 | justin_smith | yeah, having a route that should be the same as a static resource is a bad idea, you should move one of the two |
| 16:18 | justin_smith | why does the file "index.htm" need to be in the static resources folder? |
| 16:18 | devll | it is in the public folder. |
| 16:18 | justin_smith | why? |
| 16:18 | clojurebot | http://clojure.org/rationale |
| 16:19 | AeroNotix | ~why |
| 16:19 | clojurebot | http://clojure.org/rationale |
| 16:19 | AeroNotix | ,why |
| 16:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: why in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:19 | AeroNotix | THERE IS NO WHY |
| 16:19 | AeroNotix | :) |
| 16:19 | justin_smith | devll: if you want something to be a route with a handler etc. then it shouldn't be a static resource, and visa versa |
| 16:19 | devll | I am just serving the file. |
| 16:19 | justin_smith | because one of the two is not going to work if you try to use both |
| 16:20 | devll | "index.htm" is not a route |
| 16:20 | AeroNotix | so you have a static file handler/middleware? |
| 16:20 | AeroNotix | and you have a 'chop-off-the-trailing-slash-middleware' |
| 16:20 | AeroNotix | ? |
| 16:20 | AeroNotix | show your routing code. |
| 16:20 | devll | I dont have static file mw |
| 16:21 | justin_smith | devll: sorry, I misunderstood. In this case you need to switch the ordering of the static wrapping mw and the drop-slashes one |
| 16:21 | AeroNotix | justin_smith: yeah^ Was thinking this was the case. |
| 16:21 | justin_smith | devll: if the file is getting served, you do, it is likely hidden in the default ring middleware |
| 16:21 | devll | (route/resources "/") |
| 16:21 | devll | (ANY "*" [] |
| 16:21 | devll | "404")) |
| 16:22 | devll | and I have many route like "/music"... |
| 16:22 | devll | OK |
| 16:23 | justin_smith | OK, so you explicitly serve resources |
| 16:23 | justin_smith | and you want to remove trailing slashes before that gets hit? |
| 16:23 | devll | yes. |
| 16:24 | justin_smith | do you have a middleware that does this already? |
| 16:24 | devll | I have one chops trailing slashes |
| 16:24 | devll | It does the jobs for "/music/" |
| 16:25 | justin_smith | but you still get a 404 for /index.htm/ |
| 16:26 | devll | in my case ,it is a file download |
| 16:26 | devll | I guess I should add a static mw and reorder it. |
| 16:26 | devll | am I right? |
| 16:26 | justin_smith | that sounds right, yes |
| 16:27 | devll | OK. thanks. (inc justin_smith) |
| 16:28 | devll | (inc justin_smith) |
| 16:28 | lazybot | ⇒ 192 |
| 18:42 | chr15m | Hello! I have been beating my head against the externs file requirement of Google's closure for days. I finally found this project, which fixed all of my problems by generating an externs file from my cljs code directly: https://github.com/ejlo/lein-externs - how come it only has two stars? Has everybody moved on from this? What do people use to handle the externs file situation? |
| 20:06 | JavaDog | Could anyone give me a quick hand? I'm doing this for a code gold thing: |
| 20:06 | JavaDog | golf* |
| 20:06 | JavaDog | (drop iterator (remove #(.contains (take-nth (nth collection iterator) collection) %) collection))) |
| 20:07 | JavaDog | However, I get a "java.lang.IndexOutOfBoundsException: null" on this line. I think it's related to lazy sequences, and I've tried using (doall thatSeq), but I'm not sure whether I'm doing that right. |
| 20:17 | irctc__ | is there an atom? equivalent in clojure |
| 20:34 | gfredericks | nope |
| 20:34 | gfredericks | ,clojure.lang.IAtom |
| 20:34 | clojurebot | clojure.lang.IAtom |
| 20:34 | gfredericks | can check against that |
| 20:35 | gfredericks | there's a ticket somewhere about this I think |
| 20:35 | gfredericks | ,atom? |
| 20:35 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:35 | cfleming | gfredericks: Yeah, IIRC it might be for 1.7 |
| 20:39 | gfredericks | ,*clojure-version* |
| 20:39 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 20:39 | crazydiamond | Hi. Is there ability to define functions like = for certain classes created with deftype? |
| 20:42 | gfredericks | I think overriding Object#equals will accomplish that |
| 20:42 | gfredericks | not sure what other functions are "like =" that you're referring to |
| 20:43 | amalloy | gfredericks: people who ask for an atom? equivalent usually mean it in the common lisp sense |
| 20:44 | crazydiamond | I'mhaving code like this: (deftype MyType [...] ...) (MyType. x [...]) (MyType. y [...]) (are_equal x y) |
| 20:44 | crazydiamond | and there I have almost everything in class definitions |
| 20:44 | crazydiamond | but standalone function are_equal |
| 20:45 | crazydiamond | and I want it to be associated with types |
| 20:45 | crazydiamond | though, everything works |
| 20:45 | crazydiamond | but I still think it would be better to do association |
| 20:47 | gfredericks | amalloy: oh that sense of "equivalent" |
| 20:58 | amalloy | gfredericks: i'm curious what other sense of equivalent you're thinking of |
| 21:00 | TEttinger | ,atom? |
| 21:00 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:00 | TEttinger | ,promise? |
| 21:00 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: promise? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:00 | TEttinger | hm |
| 21:00 | TEttinger | ,ref? |
| 21:00 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ref? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:00 | TEttinger | are there any type checks for stuff like atoms? |
| 21:01 | gfredericks | amalloy: "equivalent to this thing from another language that actually exists" vs "equivalent to this imaginary clojure function" |
| 21:01 | gfredericks | TEttinger: what's a "type check"? you mean a function like the ones you're searching for? |
| 21:01 | gfredericks | ,(->> (ns-publics 'clojure.core) keys (filter #(= \? (last (str %)))) shuffle) |
| 21:01 | clojurebot | [nil? fn? var? thread-bound? ifn? ...] |
| 21:02 | TEttinger | I guess, kinda like float? or something like it |
| 21:02 | gfredericks | ,(->> (ns-publics 'clojure.core) keys (filter #(= \? (last (str %)))) shuffle) |
| 21:02 | TEttinger | ,float? |
| 21:02 | clojurebot | #<core$float_QMARK_ clojure.core$float_QMARK_@3ee8c23e> |
| 21:02 | clojurebot | [future-done? odd? future? bound? zero? ...] |
| 21:02 | gfredericks | ,(->> (ns-publics 'clojure.core) keys (filter #(= \? (last (str %)))) shuffle) |
| 21:02 | clojurebot | [pos? identical? every? future-cancelled? ifn? ...] |
| 21:02 | TEttinger | whatcha doing gfredericks? |
| 21:03 | TEttinger | imaginary clojure, from the makers of invisible bike and high-performance INTERCAL |
| 21:04 | TEttinger | &(->> (ns-publics 'clojure.core) keys (filter #(= \? (last (str %))))) |
| 21:04 | lazybot | java.lang.SecurityException: You tripped the alarm! ns-publics is bad! |
| 21:04 | TEttinger | haha |
| 21:05 | TEttinger | ,(->> (ns-publics 'clojure.core) keys (filter #(= \? (last (str %)))) #(clojure.string/join " ")) |
| 21:05 | clojurebot | #<sandbox$eval195$fn__196 sandbox$eval195$fn__196@5cdc4aaa> |
| 21:05 | TEttinger | ,(->> (ns-publics 'clojure.core) keys (filter #(= \? (last (str %)))) (clojure.string/join " ")) |
| 21:05 | clojurebot | "decimal? contains? every? satisfies? seq? fn? vector? thread-bound? isa? char? some? future-done? pos? sequential? neg? reduced? float? set? reversible? bound? map? volatile? var? empty? string? associative? keyword? even? extends? counted? future? zero? not-every? class? future-cancelled? sorted? nil? instance? record? identical? true? integer? special-symbol? ratio? delay? ifn? chunked-seq? dis... |
| 21:05 | TEttinger | so we have var? |
| 21:06 | TEttinger | and delay? |
| 21:06 | TEttinger | very odd |
| 21:07 | gfredericks | there's a ticket for it |
| 21:16 | gfredericks | ,(defmacro defmulti! [name & args] `(do (def ~name nil) (defmulti ~name ~@args))) |
| 21:16 | clojurebot | #'sandbox/defmulti! |
| 21:20 | TEttinger | gfredericks, what... I'm slightly nervous to use that |
| 21:22 | rhg135 | what is the point of this defmulti! i wonder |
| 21:22 | gfredericks | TEttinger: defmulti refuses to redefine things the second time you use it; defmulti! tricks it into doing so |
| 21:22 | rhg135 | ah i see |
| 21:23 | TEttinger | that's... devious |
| 21:23 | gfredericks | also racey since the function is temporarily nil |
| 21:24 | rhg135 | i don't think it's racey since do is guaranteed to run them in order |
| 21:25 | gfredericks | another thread could call it while it's nil |
| 21:26 | gfredericks | I bet you could fix that by setting it to a proxy function instead |
| 21:28 | rhg135 | oh I see |
| 21:30 | gfredericks | amalloy: oh I just figured out how to throw that dynamic var exceptoin |
| 21:31 | gfredericks | it looks like it is only possible with futures and agents |
| 21:32 | amalloy | binding conveyance? i sorta expected that to prevent it, not cause it, but okay |
| 21:32 | gfredericks | TIL that what futures and agents do is different from what bound-fn does |
| 21:32 | gfredericks | which is different from what starting a raw thread does, which was your original suggestion |
| 21:33 | gfredericks | dynamic vars what are you gonna do. |
| 21:35 | crazydiamond | Hi. Is there a way to clean session in REPL? I'm using fireplace.vim and doing series of updates followed by %Eval. So, next time I hit eval, old things that I might deleted are still alive. Is there a way to start clean, each time I'm doing %Eval? (This effect makes Clojure sooo stateful for me). |
| 21:43 | justin_smith | crazydiamond: clojure.tools.namespace has a namespace recet |
| 21:43 | justin_smith | *reset |
| 21:43 | crazydiamond | justin_smith, thanks |
| 21:44 | crazydiamond | (clojure.tools.namespace.repl/refresh) works for me now |
| 21:44 | TEttinger | (inc justin_smith) |
| 21:44 | lazybot | ⇒ 193 |
| 21:44 | TEttinger | almost to 200 |
| 21:44 | justin_smith | there is also stuartsierra's component for doing modular restarting of state |
| 21:44 | justin_smith | getting close |
| 21:48 | gfredericks | is tonight the night that justin_smith gets to 200? |
| 21:48 | gfredericks | justin_smith: quick start telling jokes |
| 21:49 | justin_smith | I've been lambda lifting all night, and boy are my arms tired! |
| 21:49 | rhg135 | *crickets* |
| 21:50 | gfredericks | tonight is not going to be the night |
| 21:53 | justin_smith | My wife, lemme tell ya folks, I try to explain to her, Liskov's substitution principle says I could just trade her in for a mentally disabled donkey... |
| 21:56 | gfredericks | a mentally disabled monkey is a subtype of your wife? |
| 21:56 | justin_smith | it's quite unfortunate |
| 21:57 | justin_smith | (not even dating not to mention married) |
| 21:57 | rhg135 | ok... |
| 21:57 | justin_smith | sorry, I will stop making intentionally cringeworthy CS themed jokes |
| 21:58 | justin_smith | it was my "best" interpretation of henny youngman groaners |
| 21:58 | justin_smith | https://www.youtube.com/watch?v=i7gg8GGP79w |
| 22:05 | gfredericks | I listened to that entire thing and now I'm older |
| 22:06 | justin_smith | hehe |
| 22:07 | chr15m | does anyone else find this passive aggressive: |
| 22:07 | chr15m | $ git rebase --continue |
| 22:07 | chr15m | No rebase in progress? |
| 22:08 | chr15m | maybe i just need more sleep |