2014-11-08
| 00:15 | rritoch | I'd love to switch to Mac but they're so overpriced, Lenovo Flex 2 (15-Inch) $700, Mac (15-inch) $2000, does Tin Cook really think we're that stupid? |
| 00:16 | justin_smith | there's offices full of people with office supplied macbooks saying yes |
| 00:17 | rritoch | I've noticed, many of my clients use Mac, I just don't get it |
| 00:18 | rritoch | My server with 4 Teraflops of computing power via 2 Radeon 280X's cost me less than that Macbook |
| 00:22 | rritoch | It was the first time I've seriously looked at Mac's in 25 years, not because Mac has improved, but because Microsoft has devolved. |
| 00:26 | catern | switch to Linux |
| 00:26 | catern | holy crap freenode spammers everywhere |
| 00:26 | catern | kickban kirloo, is spammer |
| 00:29 | rritoch | Well, I am running Ubuntu (rooted) on my server, but Linux still requires a lot of complex maintenance and configuration to set it up properly. |
| 00:30 | catern | that's not true |
| 00:30 | catern | also what |
| 00:30 | catern | Ubuntu (rooted), as in you have root? |
| 00:30 | catern | on a server you administrate, it would be highly unusual if you did not |
| 00:30 | catern | (have root) |
| 00:30 | justin_smith | if it was complex, would we really be using it on servers? |
| 00:32 | rritoch | justin_smith: Once it's configured it's stable for the most part, but getting the AMD drivers and OpenCL to work properly is a nightmare |
| 00:32 | justin_smith | rritoch: I bought this box with linux pre-installed. Compared to installing windows or mac from scratch it was a breeze to set up (but let's compare apples to apples - pre-installed to pre-installed, install from scratch to install from scratch) |
| 00:32 | rritoch | It still isn't working properly |
| 00:32 | rritoch | I can't get any video-out on the second video card |
| 00:33 | justin_smith | rritoch: as soon as I first powered up this machine I had full accelerated video |
| 00:33 | justin_smith | just like with a mac or windows box, the factory set it up for me |
| 00:33 | justin_smith | comapre apples to apples |
| 00:33 | rritoch | I can run dual screen on the one card, but if I connect screens to the second card they don't display anything |
| 00:33 | justin_smith | rritoch: I am using three screens right now, I can potentially use up to five, it just works |
| 00:34 | rritoch | From separate AMD cards? |
| 00:34 | justin_smith | one card |
| 00:34 | justin_smith | like I said, it was pre-configured by the folks who built my laptop |
| 00:34 | rritoch | multi-monitor works fine from my first video card, I just can't get any output on the second video card |
| 00:34 | justin_smith | just as your windows box was pre-configured by the folks who built your machine |
| 00:35 | rritoch | At least not from Linux, I have a dual-boot to windows and both cards function properly from windows |
| 00:35 | justin_smith | and who configured that? I expect it worked when you first bought the machine. |
| 00:36 | rritoch | It is a problem with the AMD catalyst driver, but I"m not sure what |
| 00:36 | rritoch | I configured it myself, it only came with Windows. |
| 00:37 | catern | rritoch: yes, but someone configured the Windows for you |
| 00:37 | rritoch | No, I just installed the Catalyst driver and it worked out of the box |
| 00:39 | catern | yes |
| 00:39 | catern | that's what we're saying |
| 00:39 | catern | anyway |
| 00:40 | rritoch | It worked on windows out of the box |
| 00:40 | rritoch | It doesn't work on Ubuntu out of the box |
| 00:40 | rritoch | that is what I"m saying |
| 00:41 | catern | yes, that's because someone already (mostly) configured it for you on Windows |
| 00:41 | catern | anyway |
| 00:41 | rritoch | Windows doesn't have any effect on linux in a dual-boot situation |
| 00:41 | catern | yes, justin_smith was just being competitive |
| 00:42 | justin_smith | catern: I just think it is unfair that people compare the experience installing an OS from scratch, to the experience with an OS that was pre-installed and pre-configured |
| 00:42 | catern | you seemed to be bashing Linux and praising Windows, so he was pointing out the seeming superiority of Windows in this regard is just a result of your laptop coming preinstalled and preconfigured with Windows |
| 00:42 | catern | justin_smith: i agree |
| 00:43 | justin_smith | "I tried to build a mercedes from parts, but just driving my kia is easier" |
| 00:43 | justin_smith | (an exageration, of course0 |
| 00:44 | rritoch | justin_smith: I've installed windows from scratch literally hundreds of times, and linux from scratch dozens of times, windows is always easier to install. |
| 00:44 | rritoch | I suppose if you have garbage generic hardware linux is easy to use, but if you have good/modern hardware, linux is a nightmare. |
| 00:45 | catern | see justin_smith that's why you don't jump so far ahead in the conversation |
| 00:45 | rritoch | I have a 5th gen motherboard and 2X GPU's, so the setup was far from simple. |
| 00:45 | justin_smith | rritoch: I have a laptop with a top of the line video card that supports four simulaneous external displays, 32 gigs of ram installed, and 8 cores. The machine is over a year old but it is not trash. |
| 00:46 | rritoch | I can't compare any of this to Mac, as I said I haven't used an apple product in over 25 years, unless you count virtual machines, but I just used a prepared VM drive for that so I really don't know what the install is really like. |
| 00:46 | catern | well, anyway, on Windows you *STILL* have to look around for drivers, which is ridiculous, so Linux is superior there at least. you do have an unconventional setup so some configuration is to be expected |
| 00:48 | justin_smith | this is all pretty off topic, I'm sorry I went off like that. |
| 00:48 | rritoch | Well, clojure needs an OS, and needs a good one |
| 00:49 | rritoch | I wish oracle would bring back sparc, I bet clojure would run like a sportscar on a sparc server. |
| 00:51 | rritoch | I've been toying with the idea of a clojure OS, but I think that would be a brutal nightmare. |
| 00:51 | razum2um | is there any best practice to override map->MyRecord with a function with preconditions? or do I need to stick with another fn name? |
| 00:51 | justin_smith | razum2um: why override? just write your own and use it |
| 00:52 | justin_smith | don't steal the name, I think that would inevitably lead to confusion |
| 00:52 | razum2um | justin_smith: but ideally not about to override it, just add precondition |
| 00:53 | razum2um | ok, is there any semantic under fn* names, would it be ok for such cases? |
| 00:54 | justin_smith | razum2um: just write a function that validates the arguments and constructs the structure |
| 00:56 | razum2um | justin_smith: ok, but I think it good if such cases have traditionaly approved names, e.g. map->Record* means it behaves just like map->Record but may check args and fill in defaults |
| 00:56 | razum2um | i think convention over configuration is always good |
| 00:56 | justin_smith | there is no such tradition that I know of |
| 00:57 | justin_smith | adding a * at the end typically means "don't use this one" |
| 00:57 | justin_smith | see fn*, let* |
| 00:57 | razum2um | perhaps adding a bang will be good such in rails it means that fn may raise an exception |
| 00:58 | razum2um | but agian, I think absence of convention is very bad for understanding other's people code |
| 00:58 | justin_smith | razum2um: in clojure a bangh usually means that a function is not safe in a transaction, or it does some extreme mutation |
| 00:59 | razum2um | justin_smith: yeah, naming and cache invalidation are hard :) |
| 00:59 | justin_smith | ,(clojure.string/join \space (filter (comp #(.endsWith % "!") name) (keys (ns-publics 'clojure.core)))) |
| 00:59 | clojurebot | "vswap! vreset! set-error-mode! set-agent-send-executor! disj! conj! pop! compare-and-set! reset-meta! set-error-handler! set-agent-send-off-executor! dissoc! assoc! reset! alter-meta! persistent! run! set-validator! swap! volatile! io!" |
| 01:00 | razum2um | yes, they deal with mutation |
| 01:01 | razum2um | e.g. will you recognize map->>Record without looking into source of fn? |
| 01:03 | justin_smith | I would expect construct-Record or make-Record to do something that map->Record does not |
| 01:09 | razum2um | justin_smith: ok, but how you think, is there any sense to turn it and perhaps some other similar cases into a survey? just not to invent convention, but collaborately define it |
| 01:16 | rritoch | Does clojure provide any means of namespace inheritance? I'm thinking of changing the MVC framework I'm using to be more pure clojure (without the gen-class) but I'd like common functions available, like view-ns/render which can be overridden but have a default functionality "imported". |
| 01:17 | rritoch | My issue is that use/require doesn't actually "import" the functions into the current namespace, it just makes them available for use |
| 01:26 | akhudek | rritoch: you can refer either some of the symbols or all of the symbols when you require |
| 01:26 | razum2um | rritoch: I suggest to wirite a macro generating defn's which call original fn |
| 01:26 | akhudek | rritoch: or do you mean you want a copy essentially? |
| 01:27 | rritoch | Yes, I want a local copy, or better yet, reference |
| 01:27 | rritoch | Probably similar to what akhudek suggested |
| 01:27 | rritoch | But some means of bringing in all of the symbols |
| 01:28 | akhudek | e.g. you if you import into foo into namespace b, you want to be able to call it as b.foo |
| 01:29 | akhudek | I think there was a thread on the clojure list about that |
| 01:29 | akhudek | don’t remember any good solutions sadly |
| 01:30 | rritoch | Something like (map #(def (second %1)) (ns-publics 'some-other-ns)) |
| 01:31 | rritoch | But of course it would need to be much cleaner than that, I suppose a macro could be used |
| 01:32 | godd2 | I have (map #(vector %1 %2) (range 10) (range 10)) but I want to pass that second (range 10) -as the collection itself- to the anonymous function. Is there a way to stop map from sending the individual elements? |
| 01:33 | rritoch | I guess ... (map #(def (first %1) (second %1)) (ns-publics 'some-other-ns)) is closer though I don't think that would work... A macro may |
| 01:37 | rritoch | ,(map #(vector %1 %2) (range 10) (take 5 (repeatedly #(range 10)))) |
| 01:37 | clojurebot | ([0 (0 1 2 3 4 ...)] [1 (0 1 2 3 4 ...)] [2 (0 1 2 3 4 ...)] [3 (0 1 2 3 4 ...)] [4 (0 1 2 3 4 ...)]) |
| 01:37 | rritoch | godd2: Is that ok with you? |
| 01:37 | rritoch | err |
| 01:37 | rritoch | ,(map #(vector %1 %2) (range 10) (take 10 (repeatedly #(range 10)))) |
| 01:37 | clojurebot | ([0 (0 1 2 3 4 ...)] [1 (0 1 2 3 4 ...)] [2 (0 1 2 3 4 ...)] [3 (0 1 2 3 4 ...)] [4 (0 1 2 3 4 ...)] ...) |
| 01:37 | TEttinger | tbaldridge: nice work with https://github.com/pixie-lang/pixie |
| 01:41 | godd2 | yes! thank you rritoch |
| 01:42 | TEttinger | ,(map (partial vector (range 10)) (range 10)) |
| 01:42 | clojurebot | ([(0 1 2 3 4 ...) 0] [(0 1 2 3 4 ...) 1] [(0 1 2 3 4 ...) 2] [(0 1 2 3 4 ...) 3] [(0 1 2 3 4 ...) 4] ...) |
| 01:42 | TEttinger | that does put it in reverse order though |
| 01:43 | godd2 | TEttinger that will nicely produce the list rritoch made, but I wanted to pass the collection to the anon function so I could do more work on it |
| 01:43 | TEttinger | ah, ok |
| 01:43 | TEttinger | you can have it as a variable, or other bound name |
| 01:45 | TEttinger | ,(let [roll (fn [] (repeatedly 5 #(rand-int 100)))] (map (partial vector (roll)) (range 10)) |
| 01:45 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 01:45 | TEttinger | ,(let [roll (fn [] (repeatedly 5 #(rand-int 100)))] (map (partial vector (roll)) (range 10))) |
| 01:45 | clojurebot | ([(53 29 24 43 64) 0] [(53 29 24 43 64) 1] [(53 29 24 43 64) 2] [(53 29 24 43 64) 3] [(53 29 24 43 64) 4] ...) |
| 01:45 | TEttinger | weird |
| 01:46 | TEttinger | ,(let [roll (fn [] (repeatedly 5 #(rand-int 100)))] (map #(vector % (roll)) (range 10))) |
| 01:46 | clojurebot | ([0 (51 59 8 71 10)] [1 (45 46 53 29 55)] [2 (60 10 97 46 57)] [3 (67 78 25 26 55)] [4 (80 40 53 14 9)] ...) |
| 01:48 | godd2 | awww I cant do repeated #() ?? |
| 01:48 | lazybot | godd2: Uh, no. Why would you even ask? |
| 01:48 | rritoch | ? It's repeatedly |
| 01:49 | godd2 | sorry, nested |
| 01:49 | godd2 | I can't do nested #() |
| 01:50 | rritoch | No but #() is just a reader macro, you can resort to an anony function via (fn [...] ....) |
| 01:51 | godd2 | ah okay awesome |
| 01:51 | godd2 | yay it worked! (map #(map (fn [x y] (vector x y)) %2 (repeat %1)) (range 10) (repeatedly #(range 10))) |
| 01:51 | godd2 | I hope that's not an entirely stupid way of making a list of vector pairs of the cartesian product of (range 10) with itself |
| 01:54 | TEttinger | kinda |
| 01:55 | TEttinger | ,(map #(map vector %2 (repeat %1)) (range 10) (repeatedly #(range 10))) |
| 01:55 | clojurebot | (([0 0] [1 0] [2 0] [3 0] [4 0] ...) ([0 1] [1 1] [2 1] [3 1] [4 1] ...) ([0 2] [1 2] [2 2] [3 2] [4 2] ...) ([0 3] [1 3] [2 3] [3 3] [4 3] ...) ([0 4] [1 4] [2 4] [3 4] [4 4] ...) ...) |
| 01:56 | godd2 | I added (apply concat ...) to get rid of the list of lists |
| 01:56 | TEttinger | remember, fns are first-class in clojure, so (fn [x y] (vector x y)) is almost the same as vector |
| 01:57 | godd2 | TEttinger but then I couldn't rely on map passing the elements of the colls from %2 and (repeat %1) |
| 01:58 | godd2 | are you saying I could just pass (vector) |
| 01:58 | TEttinger | no |
| 01:58 | TEttinger | the function vector |
| 01:58 | TEttinger | like in the example I just posted |
| 01:58 | godd2 | ahh okay I was making it more complicated than I needed to |
| 01:59 | godd2 | ,(apply concat (map #(map vector (repeat %1) %2) (range 10) (repeatedly #(range 10)))) |
| 01:59 | clojurebot | ([0 0] [0 1] [0 2] [0 3] [0 4] ...) |
| 01:59 | TEttinger | vector, instead of an anon fn calling vector, should be ever so slightly faster, and simpler to write |
| 01:59 | dbasch | &(for [x (range 10) y (range 10)] [x y]) |
| 01:59 | lazybot | ⇒ ([0 0] [0 1] [0 2] [0 3] [0 4] [0 5] [0 6] [0 7] [0 8] [0 9] [1 0] [1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [2 0] [2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [2 8] [2 9] [3 0] [3 1] [3 2] [3 3] [3 4] [3 5] [3 6] [3 7] [3 8] [3 9] [4 0] [4 1] [4 2] [4 3] [4... https://www.refheap.com/92893 |
| 01:59 | TEttinger | and yeah, for is good for this :P |
| 01:59 | dbasch | ^ godd2 is that what you want? |
| 02:00 | godd2 | dbasch that is precisely what I wanted. Ill go look at the docs for for now, thank you! |
| 02:04 | rritoch | ,(map-indexed (fn [x y] (map (partial #(vec (list %1 %2)) x) (range 10))) (range 10) |
| 02:04 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 02:05 | rritoch | ,(map-indexed (fn [x y] (map (partial #(vec (list %1 %2)) x) (range 10))) (range 10)) |
| 02:05 | clojurebot | (([0 0] [0 1] [0 2] [0 3] [0 4] ...) ([1 0] [1 1] [1 2] [1 3] [1 4] ...) ([2 0] [2 1] [2 2] [2 3] [2 4] ...) ([3 0] [3 1] [3 2] [3 3] [3 4] ...) ([4 0] [4 1] [4 2] [4 3] [4 4] ...) ...) |
| 02:06 | rritoch | ,(map-indexed (fn [x y] (map (partial #(vec (list %1 %2)) x) (range 2))) (range 3)) |
| 02:06 | clojurebot | (([0 0] [0 1]) ([1 0] [1 1]) ([2 0] [2 1])) |
| 02:20 | godd2 | Here is the completed problem. Feel free to offer any criticism of the code, including format. https://gist.github.com/nicklink483/a7ad9968a9a58c7ebf0a |
| 02:26 | arrdem | Okay. Someone convince me to learn a structural editing mode for emacs |
| 02:29 | nonuby | is there a nil loving nth? rather than IOOB exceptipn |
| 02:30 | nonuby | ah nevermind 3rd arg is default not found, fits |
| 02:33 | rritoch | ,(map #(seq (zipmap (range 10) (take 10 (repeatedly (partial identity %))))) (range 10)) |
| 02:33 | clojurebot | (([0 0] [7 0] [1 0] [4 0] [6 0] ...) ([0 1] [7 1] [1 1] [4 1] [6 1] ...) ([0 2] [7 2] [1 2] [4 2] [6 2] ...) ([0 3] [7 3] [1 3] [4 3] [6 3] ...) ([0 4] [7 4] [1 4] [4 4] [6 4] ...) ...) |
| 02:36 | rritoch | Any ideas why that isn't sorted? |
| 02:38 | rritoch | ,(map #(sort (zipmap (range 10) (take 10 (repeatedly (partial identity %))))) (range 10)) |
| 02:38 | clojurebot | (([0 0] [1 0] [2 0] [3 0] [4 0] ...) ([0 1] [1 1] [2 1] [3 1] [4 1] ...) ([0 2] [1 2] [2 2] [3 2] [4 2] ...) ([0 3] [1 3] [2 3] [3 3] [4 3] ...) ([0 4] [1 4] [2 4] [3 4] [4 4] ...) ...) |
| 02:40 | TEttinger | (doc zipmap) |
| 02:40 | clojurebot | "([keys vals]); Returns a map with the keys mapped to the corresponding vals." |
| 02:40 | TEttinger | maps aren't sorted |
| 02:42 | TEttinger | ,(map #(interleave (range 10) (repeat 10 %)) (range 10)) |
| 02:42 | clojurebot | ((0 0 1 0 2 ...) (0 1 1 1 2 ...) (0 2 1 2 2 ...) (0 3 1 3 2 ...) (0 4 1 4 2 ...) ...) |
| 02:42 | TEttinger | ,(map #(map vector (range 10) (repeat 10 %)) (range 10)) |
| 02:42 | clojurebot | (([0 0] [1 0] [2 0] [3 0] [4 0] ...) ([0 1] [1 1] [2 1] [3 1] [4 1] ...) ([0 2] [1 2] [2 2] [3 2] [4 2] ...) ([0 3] [1 3] [2 3] [3 3] [4 3] ...) ([0 4] [1 4] [2 4] [3 4] [4 4] ...) ...) |
| 02:43 | TEttinger | that closer to what you're after, rritoch? |
| 02:43 | rritoch | I see, I just assumed they maintained the order items were added to them. Scary how many bugs may be floating around because of that mistake. |
| 02:43 | TEttinger | maps are never sorted by default, you can use the collections in a lib called "ordered" if you want the behavior you describe |
| 02:44 | rritoch | I actually don't have use with this code, I was just playing with the different ways of creating a matrix of positional vectors |
| 02:44 | godd2 | in (reduce conj () "hello") is the 'magic' that reduce is treating "hello" like a sequence of characters? |
| 02:44 | TEttinger | there is the sorted-map , and you can also do sorted-map-by |
| 02:44 | TEttinger | yes |
| 02:45 | TEttinger | strings can be treated as seqs by most core clojure fns |
| 02:45 | TEttinger | they aren't actually seqs but they can be used as such |
| 02:46 | TEttinger | ,(reduce str "hello " "world") |
| 02:46 | clojurebot | "hello world" |
| 02:46 | TEttinger | ##(reductions str "hello " "world") ;; let's see how this works |
| 02:46 | lazybot | ⇒ ("hello " "hello w" "hello wo" "hello wor" "hello worl" "hello world") |
| 02:49 | godd2 | okay cool |
| 02:50 | TEttinger | godd2, you'll probably enjoy learning about destructuring, if you haven't already |
| 02:50 | TEttinger | it's one of the cooler features clojure has in regards to cleaning up code |
| 02:51 | godd2 | I have learned about destructuring. I haven't tried it out with all the different types and such, but I do know how to, say, pass a vector as if its elements were the parameters |
| 02:52 | godd2 | I come from a Ruby background, and destructuring seemed similar to passing arrays to methods and having individual params take on the elements themselves by default |
| 02:54 | godd2 | But I'm trying to learn Clojure without trying to do things the Ruby way |
| 02:58 | TEttinger | it does seem like a lot of people come to clojure from the ruby community. both are concise, expressive languages, certainly, with a focus on getting stuff done. |
| 02:59 | godd2 | Even in Rich's talks you'll see various examples of things which include Ruby in the list |
| 03:07 | godd2 | ooooh, I like this ->> thingy |
| 03:07 | arrdem | -> and ->> are awesome |
| 03:07 | arrdem | factor of at least four readability increase once I got used to it |
| 03:13 | sam122 | Hi, I'd like to contribute to Clojure and hopefully try out for gsoc 2015. Is it too late to start? |
| 03:13 | sam122 | And how much knowledge of Clojure is required? |
| 03:14 | godd2 | sam122 when you say "contribute to Clojure" do you mean Clojure itself, or something that happens to be written in Clojure? |
| 03:15 | sam122 | Clojure, Typed Clojure etc |
| 03:16 | godd2 | Is this a good way of formatting? https://gist.github.com/nicklink483/65b1801b00e7e0bfb816 |
| 03:16 | arrdem | Speaking as an ex-gsoc student, getting changes into clojure/core itself is basically impossible unless you are actually Rich |
| 03:16 | arrdem | that said anyone can propose changes with no background |
| 03:16 | arrdem | it's just that Rich'll take only what he likes |
| 03:16 | arrdem | contributing to clojure.* is easy tho |
| 03:17 | godd2 | Also, is there a go-to format guide for writing Clojure? |
| 03:17 | arrdem | ambrosebs, the core.typed maintainer and the other contrib libraries are awesome to a man |
| 03:17 | arrdem | godd2: there is a community style guide |
| 03:17 | arrdem | $google clojure style guide |
| 03:17 | lazybot | [bbatsov/clojure-style-guide · GitHub] https://github.com/bbatsov/clojure-style-guide |
| 03:18 | arrdem | there's also Eastwood, which tries to lint for unidiomatic code, |
| 03:18 | arrdem | but form the most part formatting isn't standardized |
| 03:18 | godd2 | alright, thank you |
| 03:19 | arrdem | godd2: functions on the same line as arguments, arguments broken by line only when you'd go over 80 or it'd be detrimental to readability. |
| 03:19 | arrdem | godd2: the = and seq/reverse here |
| 03:19 | arrdem | godd2: otherwise looks fine |
| 03:19 | sam122 | Would a basic knowledge be sufficient? |
| 03:19 | nonuby | i have this in my project.clj https://www.refheap.com/92897 yet running lein with-profile couchexport uberjar still produces project name version (e.g. ncdoffice-0.0.2-snapshot.jar) and not couchexport.jar, any ideas? |
| 03:20 | arrdem | sam122: well you have to convince a maintainer or two to support you for GSoC... so prior experience/interest is a huge help |
| 03:20 | sam122 | Ok :) |
| 03:20 | sam122 | Thanks! |
| 03:21 | sam122 | I hope there are more slots in 2015. |
| 03:22 | arrdem | shrug. find something to work on and seriously put some time into it ahead of time. I wouldn't say that getting accepted to GSoC is a horribly high bar for Clojure |
| 03:22 | arrdem | not that we've had a slack project I know of so... shrug |
| 03:51 | wildharvest | I'm stuck on problem #22 on 4clojure, counting a sequence without using count. It's saying I tripped the alarm when I haven't used count. |
| 03:52 | wildharvest | I'm assuming its a macro thing, but I'm not sure if its a bug or if my solution is wrong |
| 03:55 | TEttinger | ,(reduce (fn [c _] (inc c)) 0 [1 2 3]) |
| 03:55 | clojurebot | 3 |
| 03:55 | TEttinger | what's your solution so far, wildharvest? |
| 03:56 | wildharvest | My solution was (fn [s] (let [r 0] (doseq [i s] (swap! r inc)) r)) |
| 03:57 | TEttinger | well, swap! only works on atoms |
| 03:58 | TEttinger | so since r is a number, it wouldn't run anyway |
| 03:58 | arrdem | do you really need mutability here? |
| 03:58 | arrdem | ^ always ask this in Clojure |
| 04:01 | wildharvest | I knew I was headed in the wrong direction with swap! but wasn't quite sure how to do it with filter/reduce/map but your solution cleared that up for me |
| 04:03 | wildharvest | Thanks TEttinger & arrdem |
| 04:03 | TEttinger | no prob |
| 04:03 | arrdem | my pleasure |
| 04:04 | arrdem | I'll be here, with beer, telling you to do it better all night :P |
| 04:41 | ingsoc | anyone use counterclockwise, I am wondering how you can get the saved changes immediately reflected in the integrated REPL - save + load |
| 04:43 | amalloy | arrdem: another thing to always reconsider: whether you really need the integer indices of a seq |
| 04:44 | ingsoc | CTRLK+ALT+K seems to compile into REPL window |
| 05:15 | crocket | Does clojure suffer java's null pointers? |
| 05:17 | amalloy | basically |
| 05:18 | borkdude | crocket yes, but you can use core.typed to prevent some |
| 05:19 | crocket | JAva libraries throw NPEs which clojure can't prevent. |
| 05:19 | borkdude | crocket most NPEs will come from interop code. Clojure's composable functions and datastructures cope with nil in a sane way. |
| 05:19 | TEttinger | also, many of clojure's core functions handle nil better. |
| 05:19 | crocket | Can programmers write clojure codes that throw NPEs not because of java libraries? |
| 05:19 | TEttinger | ,(map inc nil) |
| 05:19 | clojurebot | () |
| 05:20 | TEttinger | crocket: of course |
| 05:20 | TEttinger | ,(+ 1 nil) |
| 05:20 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 05:20 | crocket | nil == null? |
| 05:20 | TEttinger | yes, in clojure |
| 05:20 | borkdude | ,(throw (NullPointerException.)) |
| 05:20 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 05:20 | crocket | That's no good |
| 05:20 | crocket | null is a mistake. |
| 05:21 | borkdude | crocket maybe you can try Haskell then ;) |
| 05:21 | TEttinger | not having nil would mean clojure couldn't use any java libs, which would be a worse mistake |
| 05:22 | crocket | What about clojurescript? |
| 05:22 | borkdude | crocket same thing |
| 05:22 | crocket | null in javascript is different from null in java. |
| 05:22 | TEttinger | javascript also has the concept of null, yeah |
| 05:23 | borkdude | crocket Crockford said that he only uses undefined and not null |
| 05:23 | TEttinger | you of course won't get NPE in clojurescript because that's an error defined on the Java VM |
| 05:23 | TEttinger | (technically, maybe you could if you mis-wrote a macro, but it would show up at compile time) |
| 05:24 | TEttinger | there's probably something similar in JS, though I wouldn't know what it is |
| 05:24 | crocket | javascript doesn't have NPE. |
| 05:25 | crocket | clojure looks amusing to my eyes. |
| 05:25 | crocket | JAva is too verbose. |
| 05:25 | crocket | Clojure seems to beat scala on JVM. |
| 05:25 | borkdude | crocket it is very amusing and also addicting |
| 05:25 | TEttinger | crocket, yeah, agreed about scala |
| 05:25 | crocket | Scala is becoming the next C++. |
| 05:25 | TEttinger | scala is a very large language that suffers from bloat yes |
| 05:26 | crocket | Yet, scala still has some advantages. |
| 05:26 | TEttinger | clojurescript's macros are done in clojure in the process of generating the javascript, and the clojure part of the compiler is on the JVM, so that's the only place CLJS can technically throw NPEs, at compile-time |
| 05:27 | TEttinger | never in production, which is nice |
| 05:28 | TEttinger | clojure is definitely a very succinct language, short code is common where in java it would be many lines |
| 05:28 | crocket | A fellow programmer at my company showed how beautiful clojure was compared to javascript and java. |
| 05:29 | crocket | Yet, there is one doubt. |
| 05:29 | crocket | When coding in nodejs, I needed a lot of documentations. |
| 05:29 | crocket | Do I need a lot of documenatations due to dynamic nature? |
| 05:29 | crocket | Do I need a lot of documenatations due to dynamic nature in clojure? |
| 05:30 | TEttinger | the docs are good, certainly, and there's a lot of effort to improve them further |
| 05:30 | TEttinger | once you know the core functions in the standard lib, there's a lot less to look up |
| 05:31 | crocket | TEttinger, no |
| 05:31 | crocket | I want to know if the dynamic nature of clojure requires me to attach a lot of documentations to my code. |
| 05:31 | crocket | ok |
| 05:31 | crocket | In nodejs, there was no standardized way to document codes. |
| 05:31 | crocket | because static analysis fails. |
| 05:31 | TEttinger | well if you're working with other programmers, they would appreciate docs. there is a standard here |
| 05:32 | crocket | JSDoc fails to document JS codes. |
| 05:32 | crocket | No single document lib documents JS codes well. |
| 05:34 | TEttinger | ,(defn map-indexed-2 "Runs function f on the first elements of coll1 and coll2, passing the index as the first argument, then the second elements, etc." [f coll1 coll2] (map f (range) coll1 coll2)) |
| 05:34 | clojurebot | #'sandbox/map-indexed-2 |
| 05:34 | TEttinger | ,(doc map-indexed-2) |
| 05:34 | clojurebot | "([f coll1 coll2]); Runs function f on the first elements of coll1 and coll2, passing the index as the first argument, then the second elements, etc." |
| 05:35 | ingsoc | my first impressions of clojure (an hour or so) are that the tooling leiningen and counterclockwise(eclipse plugin) are very nice and this is my first lisp and although early days I am findign the whole environment more approachable than Ocaml (which I dipped my toes into yesterday), also I like the python style documentation for functions - dosctrings? |
| 05:35 | TEttinger | ,(map-indexed-2 + [0 100 200 300] [0 10 20 30]) |
| 05:35 | clojurebot | (0 111 222 333) |
| 05:36 | TEttinger | ingsoc, yep, docstrings are nice |
| 05:36 | crocket | OCaml |
| 05:36 | crocket | The razor of Ocaml |
| 05:36 | crocket | oops |
| 05:36 | TEttinger | Occam's razor? |
| 05:36 | crocket | It's Ocam's razor. |
| 05:38 | TEttinger | OCaml is a strongly typed functional language with a very good, but very strict, compiler. technomancy wrote a faster-starting substitute for part of leiningen in OCaml, called Grenchman IIRC |
| 05:38 | TEttinger | one of the cool things OCaml can do is debug in reverse |
| 05:39 | TEttinger | not many libs for OCaml though |
| 05:40 | rritoch | Does clojure use any classloaders other than the thread's context class loader and Compiler/LOADER ? |
| 05:40 | ingsoc | well i haven't abandoned trying Ocaml, I just had a few problems early on. I had shortlisted Ocaml or Clojure to learn as a next language |
| 05:40 | TEttinger | clojure has more momentum, I'd say |
| 05:41 | TEttinger | it's definitely advancing into some rarely-found features, like the "transducers" being introduced with clojure 1.7 |
| 05:41 | TEttinger | core.async I have heard good things about |
| 05:44 | rritoch | I setup the following function to call methods on OSGi services http://pastebin.com/b7shFxXK but I'm not sure if there are any other classloaders I need to override. |
| 05:50 | ingsoc | TEttinger: the main thing that puts me off clojure is JVM being a big beast (slow startup), but on the plus side it means it has access to all of the java ecosystem. Ocaml is much lighter weight in this regard and it also has pattern matching which I have really enjoyed in erlang. |
| 05:57 | TEttinger | ingsoc, I've been curious about a new project called Pixie that runs a clojure-like lisp on PyPy's VM |
| 05:57 | TEttinger | I'm not sure if it can call python code yet https://github.com/pixie-lang/pixie |
| 05:58 | TEttinger | but it does get fast startup times from that VM |
| 05:58 | TEttinger | tbaldridge is likely asleep, but he's the guy to ask |
| 06:24 | massi` | hello * |
| 06:27 | annelies | hello |
| 06:51 | godd2 | is there a way to not print the next return value in lein repl? |
| 06:56 | hyPiRion | godd2: I usually do `(do (my-expr) nil)` to print nil instead |
| 06:57 | hyPiRion | ,(map #(throw (Exception. %)) ["foo"]) |
| 06:57 | clojurebot | #<Exception java.lang.Exception: foo> |
| 06:57 | hyPiRion | ,(do (map #(throw (Exception. %)) ["foo"]) nil) |
| 06:57 | clojurebot | nil |
| 06:58 | godd2 | okay cool, thanks |
| 07:09 | godd2 | Is there a reason that leiningen won't claim more than 4 to 4.5 GB of ram? |
| 07:10 | annelies | Running a 32-bit JVM? |
| 07:11 | godd2 | "Java HotSpot(TM) 64-Bit Server VM 1.7.0-b147" when lein repl starts up |
| 07:12 | annelies | What is the value of :jvm-opts in project.clj? |
| 07:13 | godd2 | That key isn't in the project.clj that boots with that repl |
| 07:13 | godd2 | its just the default project file from lein new app |
| 07:14 | godd2 | it's not a big deal, I was just somewhat curious. |
| 07:16 | rritoch | ,(.maxMemory (Runtime/getRuntime)) |
| 07:16 | clojurebot | #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)> |
| 07:17 | rritoch | godd2: I suspect it has something to do with that, I have 8GB ram, but my max memory is 2GB |
| 07:18 | annelies | I have 4GB and maxMemory returns 1GB. |
| 07:20 | godd2 | ah okay got it. I did the maxMemory thing before and after adding :jvm-opts ["-Xmx12G"] to the project file and got 3.5 GB before and ~10.8 GB after |
| 07:21 | annelies | GB vs GiB perhaps. |
| 07:22 | godd2 | yes /GB/GiB/g |
| 07:22 | godd2 | I divided by 1024^3 |
| 07:23 | godd2 | awesome, thanks guys. I super promise not to thoughtlessly set max ram higher :P |
| 07:25 | annelies | I wish I wrote software where memory limits were actually a thing. :( |
| 07:27 | godd2 | Oh I was just messing around in Clojure. apparently (reduce + (take 40000000 (range))) takes up around 5 gigs once it's finished |
| 07:27 | Bronsa | godd2: (take n (range)) is just (range n) btw |
| 07:28 | annelies | There is an O(1) algorithm to do that. :p |
| 07:28 | annelies | sum of integer range |
| 07:28 | godd2 | n * (n+1) / 2 I know |
| 07:28 | godd2 | I just wanted to see how far Clojure would dutifully be persistent along the way |
| 07:29 | hyPiRion | godd2: huh, that shouldn't take 5 gigs |
| 07:31 | godd2 | hyPiRion You're right, sorry. I did a (def a (take 40000000 (range))) and then (reduce + a) on a new line |
| 07:31 | hyPiRion | I'm not able to reproduce that with (reduce + (range 40000000)) actually |
| 07:31 | hyPiRion | ah, right |
| 07:31 | hyPiRion | yeah, if you retain the head, you're going to have a bad time. But if you don't, then it should either store 1 or 32 elements only |
| 07:32 | godd2 | because of the lazy eval of range? |
| 07:32 | hyPiRion | yup |
| 07:34 | ingsoc | TEttinger: "transducers" ?, also i hear protocols are raved about but i don't know much about them are they kinda like interfaces |
| 07:35 | godd2 | ingsoc: https://www.youtube.com/watch?v=6mTbuzafcII |
| 07:35 | hyPiRion | ingsoc: protocols are like interfaces, but unlike interfaces, you can implement the protocol outside the record/class |
| 07:36 | hyPiRion | this means if I have a protocol P in lib A, and a record R in lib B, and that I can implement the protocol for R in my app without changing lib B |
| 07:36 | ingsoc | Rich Hickey's hair gets wilder |
| 07:37 | ingsoc | :D |
| 07:37 | SagiCZ1 | ingsoc: i just wanted to say that |
| 07:38 | godd2 | "As time goes on his hair just gets better and better." - top comment from reddit thread of that video |
| 07:38 | ingsoc | Brian May |
| 07:39 | godd2 | It reminds me of Steven Pinker's hair |
| 07:39 | ingsoc | Hair proportional to features ? |
| 07:40 | godd2 | Hickey might be able to join The Luxuriant Flowing Hair Club for Scientists |
| 07:41 | ingsoc | Isaac Newton had a fair barnet on him also :) |
| 07:44 | ingsoc | how come clojure is so fast even with it appearing to be so dynamic ? Is this just testament to the power of JVM JIT etc. ? |
| 07:46 | Lowl3v3l | ingsoc, i believe it is primarily, yes. |
| 07:47 | ingsoc | I know you shouldn't choose a language because of the tooling counterclockwise for eclipse and leiningen are just making clojure so much easier to use than Ocaml (I don't use or have the time to invest in learning Emacs) |
| 07:47 | Lowl3v3l | ingsoc, you should take the time, it is worth. |
| 07:50 | SagiCZ1 | ingsoc: but eclipse is so horrible i cant imagine any sane person could use it |
| 07:50 | ingsoc | Lowl3v3l: I have heard this a lot |
| 07:50 | ingsoc | I have also heard that a lot |
| 07:50 | ingsoc | :D |
| 07:50 | SagiCZ1 | http://www.ihateeclipse.com/ |
| 07:51 | ingsoc | eclipse appears overwhelmingly complex (considering most people just want to code in an editor) |
| 07:51 | ingsoc | but I kinda forced myself to use it (not knowing any better) and I spose now I know my way around it i like it |
| 07:51 | ingsoc | :/ |
| 07:52 | SagiCZ1 | ingsoc: i dont think its complex, but its bloated, buggy and incredibly slow |
| 07:52 | ingsoc | version 4+ is ridiculously slow on linux atm |
| 07:52 | ingsoc | 3.7 works fine |
| 07:53 | ingsoc | I code in isolation and have never been exposed to Emacs to "see the light" |
| 07:53 | ingsoc | maybe I will have a look one day |
| 07:53 | SagiCZ1 | ingsoc: see intellij if you want a good ide for java and cant cope with emacs |
| 07:54 | ingsoc | SagiCZ1: I use intellij (Webstorm) for web dev |
| 07:54 | annelies | I once wrote a function that returned whether an editor is good or not. |
| 07:54 | ingsoc | and I like it |
| 07:54 | ingsoc | I use eclipse for python and erlang - at the time if I wanted an IDE for erlang it was the only resonably mature option |
| 07:54 | annelies | It was (partial contains? #{:emacs :vim}) |
| 07:55 | ingsoc | :) |
| 07:55 | SagiCZ1 | ingsoc: alright, cant believe you can still go back to eclipse.. its so bad :D |
| 07:55 | ingsoc | I would NOT be able to code for the web now without Webstorm |
| 07:56 | godd2 | never heard of it. what's webstorm? |
| 07:56 | annelies | IntelliJ specialised for client-side web dev. |
| 07:57 | godd2 | ah okay |
| 07:57 | ingsoc | godd2: from the intelliJ IDE guys (Jetbrains) |
| 07:57 | SagiCZ1 | annelies: well i cant say that vim or emacs is bad, but it was just too much to learn new language (clojure) and a completely new editor (emacs) |
| 07:58 | ingsoc | It is focussed for web dev and at the time i didn;t want to have all the other features confusing the IDE (like what happens with eclipse with all its different "perspectives") |
| 07:59 | ingsoc | not sure if thre is an intelliJ/Webstorm plguin for clojurescript though yet |
| 07:59 | ingsoc | plugin* |
| 07:59 | SagiCZ1 | ingsoc: i still distinctly remember the wtf moment i experienced when trying to turn debugging on in eclipse.. |
| 08:00 | SagiCZ1 | ingsoc: there is Cursive |
| 08:00 | SagiCZ1 | ingsoc: https://cursiveclojure.com/ |
| 08:00 | SagiCZ1 | it is amazing |
| 08:01 | m1dnight | ugh, i've about had it with emacs and cider |
| 08:01 | m1dnight | thing randomly "cant find file on classpath" |
| 08:01 | ingsoc | anyone using lightable |
| 08:01 | Lowl3v3l | SagiCZ1, is cursive ready to use yet? |
| 08:01 | ingsoc | light table* |
| 08:02 | ingsoc | the demos show some great promise, looks to be implementing Bret Victors demo of an interactive IDE |
| 08:04 | SagiCZ1 | Lowl3v3l: its not finished, but i use it every day without a problem |
| 08:04 | annelies | What'd you call (fn [& fs] (apply comp (reverse fs)))? pmoc? |
| 08:04 | ingsoc | http://vimeo.com/36579366 skip to 16:45 and see how he interactively develops binary search |
| 08:04 | Lowl3v3l | SagiCZ1, to sad i do not like non-open-source products |
| 08:04 | ingsoc | apparently that kind of thing is avaiulable in light table for clojure |
| 08:05 | annelies | May be better to use #(-> % ...) though I guess. |
| 08:05 | SagiCZ1 | Lowl3v3l: yeah... ive seen how open source eclipse is great.. i would rather pay a couple $$ for a good editor than tear my hair |
| 08:06 | Lowl3v3l | SagiCZ1, well. Emacs is Open Source and i like it. Vim too. |
| 08:07 | SagiCZ1 | Lowl3v3l: yeah, but those are decades old.. i guess they are polished now |
| 08:07 | Lowl3v3l | SagiCZ1, and they are still good. I just don't like closed source in general^^ |
| 08:07 | SagiCZ1 | Lowl3v3l: i understand |
| 08:13 | ingsoc | so what language did you guys use prior to clojure ?, are there a lot of java converts or from totally different environment (non JVM) |
| 08:13 | SagiCZ1 | ingsoc: for me it was mostly Java |
| 08:14 | Lowl3v3l | i use a whole couple of languages upt to now, clojure isn't even my only lisp^^ |
| 08:14 | SagiCZ1 | yeah i actually had a brief episode with Common Lisp before discovering Clojure |
| 08:14 | ingsoc | SagiCZ1: it looks WAY more concise than Java so I am guessing for you clojure has been a productivity enhancer |
| 08:14 | ingsoc | ok |
| 08:15 | ingsoc | a guy at a local tech meetup keeps telling me how clojure changed his views on programming and loves it keeps asking me to try it, I do the same to him but with erlang |
| 08:15 | SagiCZ1 | ingsoc: definitely, the only gripe with clojure i have, is not understanding it as much as i understand java, so some things which should be quicker and easier to do in clojure are actually harder.. but i am getting there |
| 08:15 | ingsoc | :) |
| 08:17 | ingsoc | my concern with clojure is do i inevitably have to learn java to become truly competent. I know I am comparing apples and oranges a bit here but I use coffeescript but in the end I had to know javascript to use it effectively |
| 08:17 | godd2 | same coming from Ruby. everything looks out of order... |
| 08:17 | hyPiRion | I started out with Java/Common Lisp. Really hard to understand how to do purely functional programming in the beginning, but with experience that feels superior in many cases. |
| 08:17 | hyPiRion | Guess coming from Erlang makes that transition a bit easier |
| 08:17 | SagiCZ1 | ingsoc: i am not sure you would have to know java, but it might help a lot |
| 08:18 | hyPiRion | ingsoc: Can't speak for Clojure/Java, but I don't know JavaScript properly and managed to create rather "sophisticated" ClojureScript programs |
| 08:19 | godd2 | But I have found a couple amazing Clojure tutorials. http://www.braveclojure.com/getting-started/ for text (you can skip the emacs part if you don't emacs) and for video: https://www.youtube.com/watch?v=9A9qsaZZefw&list=PLAC43CFB134E85266 |
| 08:19 | hyPiRion | As long as you find non-Java libraries for the things you want to do, life should be easy without Java knowledge. |
| 08:19 | ingsoc | hyPiRion: yeah, erlang was originally a bit painful as it was my first ever functional language. No loops (only recursion), single assignment, no objects or global anything etc. |
| 08:20 | ingsoc | big shift, but now i find it a better way to structure programs |
| 08:20 | ingsoc | seems to force you down the path of divide and conquer with small independent easily understood functional components |
| 08:21 | SagiCZ1 | ingsoc: i guess thats a common experience with most functional languages.. it is hard at the beginning but you can appreciate it later.. especially testing just seems so easy compared to java mutant world |
| 08:21 | ingsoc | hyPiRion: I am hoping to try clojurescript at some point as I still haven't found a nice language for client side web dev yet. Coffeecript is a nicer face to JS but it is still quite fragile |
| 08:23 | Lowl3v3l | SagiCZ1, there is a reason why i prefer teaching with functional languages. |
| 08:23 | hyPiRion | Leaky abstractions, eh |
| 08:23 | Lowl3v3l | i believe in general functional programming is, for someone who didn't program before, easier |
| 08:24 | SagiCZ1 | Lowl3v3l: i am not sure.. maybe for mathematcians.. imperative programming is easy because it is just a sequence of steps.. the computer follows it like a cooking recipe |
| 08:24 | ingsoc | one problem I find people have is recursion, it seems some people have real trouble visualising in their minds eye what is occurring |
| 08:25 | SagiCZ1 | ingsoc: it is definitely not trivial.. especially trying to visualize the call stack |
| 08:25 | godd2 | Some otherwise imperative languages offer recursive tools, so it's not all bad depending on the transition |
| 08:25 | Lowl3v3l | the problem is that imperative programming allows for constructs like x = x+1; which is kind of absurd if you think about it^^ |
| 08:25 | ingsoc | actually, do you have to be mindful in clojure of the stack or is there tail call optimisations like in erlang/Ocaml |
| 08:26 | Lowl3v3l | ingsoc, there is a possibility for tail calls |
| 08:26 | SagiCZ1 | there are ONLY tail recursions in clojure, right? |
| 08:26 | godd2 | SagiCZ1 yes but not all tail recursions are tco'd |
| 08:26 | SagiCZ1 | godd2: i see |
| 08:27 | godd2 | at least, that's my understanding |
| 08:27 | Lowl3v3l | well no. There is recur. |
| 08:27 | ingsoc | tco means that the compiler/runtime knows that to continue next recursion it doesn't need to push anything else onto stack ? |
| 08:27 | Lowl3v3l | But in general you could write a non-tail-recursion by directly calling a function generating a stack overflow with enough calls |
| 08:28 | SagiCZ1 | does functional programming imply immutable data? |
| 08:30 | godd2 | SagiCZ1 not necessarily. in Clojure you can tap into java data structures which are mutable |
| 08:30 | ingsoc | SagiCZ1: my understanding is that immutable data is a key trait of functional language |
| 08:30 | Lowl3v3l | SagiCZ1, depends on. There is up to my mind at least the theoretical possibility to do it without by not using the von-neumann-architecture... But practical i believe so. |
| 08:30 | godd2 | SagiCZ1 there' |
| 08:31 | godd2 | SagiCZ1 there's also the difference between "pure" functional and functional. a "pure" function never returns anything different given some inputs |
| 08:31 | Lowl3v3l | godd2, well, but foing that you leave the functional space, don't you? Functional means side-effect-free which is why clojure isn't strictly functional in the sense haskell, for example, is. |
| 08:31 | SagiCZ1 | godd2: i wasnt talking about clojure specifically.. its possible to write a clearly imperative code in clojure.. if you use atoms and mutate states of java objects using interop.. but it is still a functional language |
| 08:32 | godd2 | SagiCZ1 right, Clojure doesn't restrict you from not being functional, but if you want to be funcitonal, it provides every opportunity |
| 08:32 | SagiCZ1 | godd2: i see your point |
| 08:52 | oskarkv | Hm, what is going on here? https://www.refheap.com/919221bb6a9664a3485c8cb01 |
| 08:53 | oskarkv | Oh, literals... |
| 08:56 | justin_smith | oskarkv: looks like you should just match on PRIMARY / SECONDARY / MIDDLE I guess? |
| 08:56 | justin_smith | I haven't tried matching enums in a case before |
| 09:01 | justin_smith | ,(case java.time.format.FormatStyle/FULL FULL :true LONG nil MEDIUM nil SHORT nil) |
| 09:01 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: java.time.format.FormatStyle, compiling:(NO_SOURCE_PATH:0:0)> |
| 09:01 | justin_smith | oh, new in 1.8, duh |
| 09:02 | justin_smith | anyway, yeah, it seems there is no way to match on an enum (none I could figure out, at least) |
| 09:03 | oskarkv | justin_smith "The test-constants are not evaluated." So I guess Class/Something is just a symbol in the case |
| 09:03 | justin_smith | hmm |
| 09:03 | justin_smith | yeah, I guess so, I thought the reader did that, but OK |
| 09:03 | justin_smith | oh right, the reader could not do that |
| 09:10 | ingsoc | hmmm, jobs in UK are pretty thin on the ground for clojure devs . Maybe people wanting to use clojure get java jobs and introduce clojure into their workplace |
| 09:10 | ingsoc | (not that I care about popularity but it would be interesting to know if clojure IS getting more popular in industry) |
| 09:11 | annelies | Where is the transducer library? |
| 09:11 | annelies | I cannot find the functions mentioned in the talk on this page: http://clojure.github.io/clojure/ |
| 09:12 | SagiCZ1 | ~lazy-logs |
| 09:12 | clojurebot | lazy-logs is http://logs.lazybot.org/ |
| 09:14 | SagiCZ1 | ingsoc: if you want a language that is widely used and get a job with it, java is the surest way to go.. there is just so many java jobs its mind boggling.. i was looking for a java job and was employed within 5 days |
| 09:14 | Glenjamin | is anyone else seeing all the gravatars missing on github.com? |
| 09:15 | AeroNotix | Glenjamin: force refresh |
| 09:15 | Glenjamin | seems like github itself is now breaking anyway |
| 09:15 | Glenjamin | all the graphs on https://status.github.com/ just shot up |
| 09:16 | ingsoc | SagiCZ1: I was just curious as to whether clojure is becoming an employable skill and popularity increasing or has it topped out |
| 09:16 | Glenjamin | ingsoc: where in the UK are you looking? |
| 09:17 | Glenjamin | i know thoughtworks are pushing Clojure quite a bit, and there's some GDS stuff thats starting to use it |
| 09:18 | AeroNotix | uswitch are big clojure users |
| 09:18 | AeroNotix | in the UK |
| 09:18 | Glenjamin | i think mail online do a bunch of clojure as well |
| 09:19 | ingsoc | Glenjamin: currently in Manchester, and I have been to some of the their tech talks. I was just curious as to the general trend of whether companies are seeing the benefits of moving away from traditional languages like java/.net for greenfield projects |
| 09:19 | AeroNotix | The Guardian do a bit here n there, though mainly Scala. |
| 09:20 | ingsoc | Scala seems overly complicated |
| 09:20 | AeroNotix | ingsoc: you should look at the financial sector in London |
| 09:20 | Glenjamin | ingsoc: outside of London i mostly see companies playing it safe with PHP/Java/.net/Python/Ruby |
| 09:20 | ingsoc | yeah, erlang seems popular in London too in finance |
| 09:20 | Glenjamin | and really, who wants to go live in London? |
| 09:20 | ingsoc | yeah exactly |
| 09:20 | AeroNotix | meh, rough with the smooth |
| 09:21 | AeroNotix | I moved from Blackpool to Poland to write Erlang+Clojure |
| 09:21 | Glenjamin | if you fancy heading over to Sheffield we're doing some ClojureScript at the functional programming meetup on tuesday |
| 09:21 | ingsoc | whatever you extra case you earn will be absorbed by property costs, unless you want shit loads of commuting wasting your life away |
| 09:21 | Glenjamin | http://defshef.github.io |
| 09:21 | AeroNotix | Sheffield/Leeds is where I am thinking of moving back to |
| 09:21 | Glenjamin | There's a lot more jobs in Leeds unfortunately :( |
| 09:21 | ingsoc | i meant, whatever extra you earn by working in London will be absorbed by property costs |
| 09:22 | AeroNotix | Glenjamin: that's what I've heard as well |
| 09:22 | Glenjamin | I think Sheffield is much nicer, but I'm biased |
| 09:22 | justin_smith | ingsoc: that's what folks say about SF around here |
| 09:22 | AeroNotix | my brother is in Leeds at the moment |
| 09:22 | Glenjamin | Where's he working? |
| 09:22 | AeroNotix | Just at Uni |
| 09:23 | the_frey | ingsoc you looking for a clojure job in manchester? |
| 09:24 | SagiCZ1 | justin_smith: i mean... living in SF is exactly the same as anywhere else in the US.. except when you open the door outside.. you are in SF, haha |
| 09:24 | Glenjamin | the_frey: do some exist? |
| 09:24 | the_frey | our company is moving some infrastructure to it, I'm having to learn clojure for work atm :) |
| 09:24 | ingsoc | the_frey: no, I was just curious as to where the job market is heading, whether more opportunities are being created over time. I am a complete clojure noob, just started out today pretty much lol, I am an erlang and frontend web dev |
| 09:25 | the_frey | though tbf we are tiny |
| 09:25 | the_frey | right k |
| 09:25 | Glenjamin | oh neat, i could probably do some clojure in manchester |
| 09:25 | justin_smith | SagiCZ1: I meant in terms of the money you make / how much you pay for rent |
| 09:25 | the_frey | but yeah we are hiring (I think) |
| 09:25 | the_frey | lemme find the link |
| 09:25 | the_frey | http://www.swirrl.com/jobs |
| 09:26 | the_frey | our clojure yoda is the guy who runs lambda lounge in mcr, really really clever dude |
| 09:26 | SagiCZ1 | justin_smith: you make more, you spend more.. you are living in Cali.. |
| 09:26 | Glenjamin | is lambda lounge still going? i heard it had fizzled out |
| 09:27 | justin_smith | SagiCZ1: it seems like half of Cali is trying to move here |
| 09:27 | the_frey | Glenjamin: it became a lot more infrequent for a while because of the difficulty of finding speakers |
| 09:27 | the_frey | but it's got a bit more momentum of late |
| 09:27 | Glenjamin | oh cool, i should try and head across the pennines then |
| 09:28 | SagiCZ1 | justin_smith: and half of the world is trying to move to Cali ... |
| 09:28 | the_frey | I _believe_ we might be sponsoring beers at the next one because I think we might be doing one of the talks |
| 09:28 | Glenjamin | might be able to blag some (def shef) speakers out of it |
| 09:28 | the_frey | about the graph data & RDF stuff we're doing in clojure |
| 09:28 | the_frey | hence why a rubyist like me is shifting over to it :) |
| 09:29 | justin_smith | I hear many stories of folks who get hired at a ruby shop and slowly push everything into clojure |
| 09:29 | ingsoc | the_frey: Rick ? |
| 09:30 | ingsoc | I did an erlang talk there a while back |
| 09:30 | AeroNotix | ingsoc: what're jobs like in the UK for Erlang? |
| 09:30 | ingsoc | was my first tech talk so was not as smooth as i wanted |
| 09:30 | ingsoc | :) |
| 09:30 | AeroNotix | I'm writing Erlang as a dayjob at the moment |
| 09:30 | the_frey | ingsoc yeah Rick, really nice guy to work with, gotta say |
| 09:31 | ingsoc | AeroNotix: mainly London based work, but there are some companies using it outside of London but it seems to be not widely publicised |
| 09:31 | AeroNotix | hmm, ok |
| 09:33 | Glenjamin | Someone's doing an Erlang POC at the mo in the company in Leeds I'm working for |
| 09:33 | ingsoc | AeroNotix: keyword search on a local jobsite brings back 18 with clojure and 12 with erlang, there are obviously thousands of java and .net and 100's of python/ruby |
| 09:33 | Glenjamin | but I suspect hiring concerns will mean it never makes it to production |
| 09:34 | AeroNotix | ingsoc: interesting. I write Erlang and Clojure at work but I am based in Poland (blackpool originally). Thinking of coming home soon. |
| 09:34 | Glenjamin | we're having enough issues hiring people who are any good at Node.js |
| 09:34 | AeroNotix | Glenjamin: then stop using node.js |
| 09:34 | AeroNotix | Solved. |
| 09:34 | AeroNotix | That'll be my daily fee, thanks |
| 09:34 | Glenjamin | hah |
| 09:34 | the_frey | Glenjamin to be fair we have trouble hiring rubyists :) there are crap programmers in every lang |
| 09:34 | ingsoc | AeroNotix: well I think these technologies are still kinda a technical edge over the competition that use traditional languages |
| 09:35 | Glenjamin | it's not so bad really, being JS you can write it functionally |
| 09:35 | ingsoc | so maybe their use doesn't get shouted about outside of their respective tech communities |
| 09:35 | Glenjamin | supervisord + rabbitMQ + node.js processes = poor man's erlang |
| 09:35 | AeroNotix | At that point just use Erlang |
| 09:36 | Glenjamin | well yes, but that doesn't really help us deal with the the 3 years-worth of code that's running and works |
| 09:36 | annelies | Write a JavaScript-to-BEAM compiler. |
| 09:36 | ingsoc | yeah in clojure |
| 09:36 | Glenjamin | which is why someone is doing an erlang proof-of-concept |
| 09:37 | ingsoc | someone created a javascript project that can interpret beam files in browser |
| 09:37 | annelies | Speaking of writing compilers in Clojure, core.logic seems a good fit for implementing type inference. |
| 09:38 | ingsoc | AeroNotix: Funny you say you moved from UK to Poland, usually it is the other way around |
| 09:38 | AeroNotix | ingsoc: tell me about it |
| 09:38 | ingsoc | did you meet a Polish girl in UK then emigrate with her |
| 09:38 | AeroNotix | duh |
| 09:38 | AeroNotix | :) |
| 09:39 | ingsoc | lol |
| 09:39 | ingsoc | what's wrong with meeting a nice English girl on a hen do in Blackpool |
| 09:39 | ingsoc | :P |
| 09:39 | ingsoc | lol |
| 09:40 | AeroNotix | yeah and be disgusted 24/7 |
| 09:40 | ingsoc | tray of fish and chips and a couple of bacardi breezers for her |
| 09:41 | ingsoc | and you're in |
| 09:41 | AeroNotix | too easy, in my youth I took advantage of this :) |
| 09:42 | ingsoc | AeroNotix: what's the salary to living cost ration like in Poland ? |
| 09:42 | ingsoc | hoping it is better than what it appears to be for unskilled Polish workers |
| 09:42 | ingsoc | (which causes them to move here) |
| 09:43 | AeroNotix | ingsoc: I'm in a unique field so it's pretty good for me |
| 09:43 | AeroNotix | but for regular folk, it's hard. Of course. |
| 09:43 | AeroNotix | but I make 4kGBP a month so I'm not complaining. |
| 09:43 | AeroNotix | over here that's extremely good |
| 09:44 | ingsoc | how much is a tyskie over there ? |
| 09:44 | ingsoc | :) |
| 09:44 | AeroNotix | I don't drink piss |
| 09:44 | ingsoc | loool |
| 09:44 | ingsoc | well i don;t drink it, but I don;t know any other Polish beers |
| 09:44 | AeroNotix | Keep an eye out for Pinta or Ale Browar |
| 09:45 | ingsoc | i guess you would have to earn a fair bit more than that to live a similar standard in UK |
| 09:46 | AeroNotix | What are you getting? |
| 09:46 | ingsoc | sounds like you are doing pretty good then |
| 09:48 | ingsoc | I am currently taking time out to learn other things (living off investments) but when I was working it would be circa 55-60k per annum although this was not programming, I was working as operations management type role |
| 09:48 | ingsoc | I just have an interest in programming |
| 09:48 | AeroNotix | ok |
| 09:49 | AeroNotix | What're people using to generate documentation/ |
| 09:49 | AeroNotix | ? |
| 09:50 | ingsoc | AeroNotix: are you using clojure and erlang on the same system, or are these separate projects |
| 09:51 | ingsoc | just interested to how they are being used together |
| 09:52 | SagiCZ1 | ingsoc: is it rude to ask people how much they make in UK? |
| 09:52 | AimHere | It can be, yes |
| 09:52 | ingsoc | erm, possibly yeah, but obviously it depends on individual. IRC is anonymous though |
| 09:53 | AeroNotix | ingsoc: Erlang is used for maintaining a high number of connections to hardware devices |
| 09:53 | AeroNotix | ingsoc: CLojure is used because Erlang isn't a general purpose language |
| 09:53 | ingsoc | I wouldn't walk up to someone in person and say oh btw what do you earn |
| 09:53 | AeroNotix | AimHere: yes it's rude but we are anonymous |
| 09:54 | SagiCZ1 | ingsoc: i see, thanks |
| 09:54 | AimHere | Well he asked about the UK; on the Internet, the concept of 'rudeness' has long gone out of fashion |
| 09:54 | ingsoc | AeroNotix: so are you communicating with clojure over ports or some other mechanism |
| 09:54 | ingsoc | (erlang ports) |
| 09:54 | AeroNotix | ingsoc: typically HTTP |
| 09:54 | ingsoc | ok |
| 09:54 | AeroNotix | ingsoc: you could call it a microservices architecture |
| 09:54 | AeroNotix | Erlang forms the hub |
| 09:54 | AimHere | On the internet, you're a sophisticated gentleman, if you don't call people by racial or offensive epithets, or post pictures of people being beheaded more than once a day or so |
| 09:55 | ingsoc | I have used python (for certain libs not available in erlang) and communicated over port (stdio) |
| 09:55 | SagiCZ1 | off topic, i am using joda time, and i have a date [year month day], and i need to know which week in the month is the day in.. first, second, third or fourth week.. how can i do that? |
| 09:55 | AeroNotix | ingsoc: I'd prefer HTTP over ports as a first pass, optimize as necessary |
| 09:56 | ingsoc | AeroNotix: i found it useful as you get to have the processes supervised by erlang so you only have to worry about keeping the erlang node running (which is generally bullet proof) |
| 09:56 | SagiCZ1 | wait.. i could just do (quot 30 day) i guess |
| 09:57 | ingsoc | it wasn;t about optimisations |
| 09:57 | AeroNotix | ingsoc: meh, just use a proper init system which keeps processes alive |
| 09:57 | ingsoc | (OS Process running python/JVM) |
| 09:57 | ingsoc | yeah i notice ubuntu has upstart that can do that |
| 09:58 | ingsoc | restart mnechanism etc. |
| 09:58 | AeroNotix | indeed |
| 09:58 | ingsoc | (I am a windows guy originally but switched to linux as the open source ecosystem is much better) |
| 09:59 | annelies | SagiCZ1: just (quot day 7) |
| 09:59 | annelies | ,(map #(quot % 7) (range 31)) |
| 09:59 | clojurebot | (0 0 0 0 0 ...) |
| 09:59 | annelies | lol |
| 10:00 | ingsoc | does the "?" in odd? empty? have any special relevance other than it makes it visually appear as a question |
| 10:00 | AimHere | No. That's it's sole purpose |
| 10:00 | AeroNotix | ingsoc: just makes it a question |
| 10:00 | AimHere | There are no side effects |
| 10:00 | AeroNotix | some lisps use the -p suffix |
| 10:01 | AeroNotix | integerp stringp etc |
| 10:01 | AeroNotix | for predicate |
| 10:01 | SagiCZ1 | zerop? |
| 10:01 | AeroNotix | SagiCZ1: just zero? or zerop |
| 10:01 | justin_smith | ,(defn !? [a] (+ a a)) |
| 10:01 | clojurebot | #'sandbox/!? |
| 10:02 | justin_smith | ,(!? 2) |
| 10:02 | clojurebot | 4 |
| 10:02 | justin_smith | ingsoc: clojure has very few operators / special symbols. It's usually just part of a name. |
| 10:04 | justin_smith | in fact, the only things other than white space that I can think of that are contiguous with a name, but not part of it, would be () {} # . ^ [] (I may have missed one or two) |
| 10:04 | justin_smith | / of course has special meaning inside a symbol too |
| 10:05 | justin_smith | @ |
| 10:06 | justin_smith | ` and ' |
| 10:07 | annelies | You can have foo'bar as name. |
| 10:07 | justin_smith | ahh, and foo@bar too |
| 10:07 | justin_smith | ,(def foo@bar 0) |
| 10:07 | clojurebot | #<CompilerException java.lang.RuntimeException: Too many arguments to def, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:08 | justin_smith | or not |
| 10:08 | justin_smith | heh |
| 10:08 | annelies | you can with # |
| 10:08 | justin_smith | yeah, many of those are only special as the first character |
| 10:08 | justin_smith | none special as last |
| 10:08 | SagiCZ1 | clj-time uses system language for the formatter, how can i switch it to english? |
| 10:08 | annelies | Here is the exact syntax: http://clojure.org/reader |
| 10:08 | SagiCZ1 | this should give me the name of the month, but its in my local language: |
| 10:08 | SagiCZ1 | (f/unparse (f/formatter "MMMMM") (t/date-time 2010 6)) |
| 10:08 | annelies | Under "Symbols" |
| 10:09 | justin_smith | annelies: thanks |
| 10:10 | justin_smith | annelies: that's not really accurate, though, because it doesn't indicate that ' can be used (which is commonly used in symbols in practice) |
| 10:11 | annelies | SagiCZ1: eww assumptions. Anyway: (with-locale (f/formatter "MMMMM") java.util.Locale/ENGLISH) |
| 10:11 | annelies | Or Locale/ENGLAND maybe. |
| 10:12 | SagiCZ1 | annelies: where is with-locale from? is it clojure.core? |
| 10:12 | annelies | in clj-time.format |
| 10:13 | SagiCZ1 | annelies: thank you so much, works well |
| 10:13 | SagiCZ1 | (inc annelies) |
| 10:13 | lazybot | ⇒ 1 |
| 10:14 | annelies | I wish tools did away with assuming default locales and time zones and stuff like that. |
| 10:14 | annelies | s/tools/libraries/ |
| 10:14 | annelies | Such defaults are only useful in a very small set of programs. |
| 10:15 | SagiCZ1 | very true |
| 10:16 | ingsoc | Ithought clojure was single-assignment so why does the repl allow reassignment ? just for convenience ? or is there something different at work ? |
| 10:16 | justin_smith | ingsoc: not single assignment at all |
| 10:16 | justin_smith | vars are mutable |
| 10:16 | ingsoc | ok it is within a defined namespace it is single assignment |
| 10:16 | justin_smith | no, vars are mutable |
| 10:17 | justin_smith | the value in the var is usually immutible, a var itself is not |
| 10:17 | justin_smith | and every var used in practice is in a namespace (def / defn can only make namespaced global definitions) |
| 10:18 | Glenjamin | SagiCZ1: i think you can set the default JVM locale to english, and most libs will use that as their default |
| 10:19 | Glenjamin | i've got :jvm-opts ["-Duser.language=en" "-Duser.country=GB"] in my project.clj, which i think is related |
| 10:19 | m1dnight | how are macros expanded, from the outside in, or the inside out? |
| 10:19 | SagiCZ1 | Glenjamin: thanks |
| 10:19 | justin_smith | m1dnight: outside in - a macro decides how to handle each of its arguments |
| 10:19 | Glenjamin | ,(macroexpand-1 '(and (and 1 2) 3)) |
| 10:19 | clojurebot | (clojure.core/let [and__4069__auto__ (and 1 2)] (if and__4069__auto__ (clojure.core/and 3) and__4069__auto__)) |
| 10:20 | m1dnight | aha excellent :) thank you |
| 10:20 | Glenjamin | forgot about symbol expansion, that's not as clear as i was expecting it to be |
| 10:20 | justin_smith | m1dnight: otherwise things like when / and etc. couldn't short circuit |
| 10:20 | m1dnight | ah, valid point |
| 10:20 | m1dnight | hadn't thought about ti that way |
| 10:21 | Wild_Cat | hold on, why is and a macro? |
| 10:22 | justin_smith | ~source and |
| 10:22 | justin_smith | it uses if |
| 10:22 | justin_smith | if is the more fundamental |
| 10:22 | Wild_Cat | oh, because it does shortcut evaluation |
| 10:23 | justin_smith | as does or |
| 10:23 | Wild_Cat | right, makes sense. |
| 10:23 | gfredericks | if or and when, let not but-last. |
| 10:23 | Wild_Cat | I actually wouldn't have expected Clojure's boolean operators to do shortcut eval. |
| 10:23 | annelies | Why not? |
| 10:23 | gfredericks | new game - make english sentences out of clojure functions. |
| 10:24 | justin_smith | hah |
| 10:24 | gfredericks | "vector is not list." |
| 10:26 | annelies | ,is |
| 10:26 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: is in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:26 | justin_smith | ,(require 'clojure.test) |
| 10:27 | clojurebot | nil |
| 10:27 | justin_smith | ,#'clojure.test/is |
| 10:27 | clojurebot | #'clojure.test/is |
| 10:27 | justin_smith | it's a macro though |
| 10:28 | justin_smith | ,(doc future-cancel) |
| 10:28 | clojurebot | "([f]); Cancels the future, if possible." |
| 10:28 | justin_smith | my favorite bit of poetry in the clojure codebase |
| 10:28 | Glenjamin | when short reductions compare and repeatedly cycle, double key locking |
| 10:28 | annelies | Sometimes I wish I were a prn-str. |
| 10:28 | Glenjamin | there's not many nouns :( |
| 10:29 | m1dnight | not any? |
| 10:29 | m1dnight | :D |
| 10:29 | justin_smith | the hard part is the lack of articles |
| 10:29 | Glenjamin | "do reductions keep rational?" |
| 10:30 | justin_smith | haha |
| 10:30 | justin_smith | agent prefers locking intersection |
| 10:31 | justin_smith | that would be better if I could use "the" |
| 10:31 | Glenjamin | "do some parents compare distinct?" |
| 10:32 | justin_smith | aha |
| 10:32 | annelies | do not take hash |
| 10:32 | justin_smith | parernts reverse, locking intersection |
| 10:32 | justin_smith | much better |
| 10:34 | annelies | Hmm, speaking of rearranging words, I should port my Markov chain library to Clojure. |
| 10:34 | justin_smith | I did one - I was amazed how succinct I could do everything in clojure actually |
| 10:35 | justin_smith | complete with optional seed and variable memory |
| 10:35 | annelies | Here is the existing one in Scala: http://ideone.com/Do2DTU |
| 10:36 | m1dnight | oh dear, second time this week i misspell "filter" with "fitler" |
| 10:36 | annelies | (def fitler filter) and nobody will notice :) |
| 10:36 | justin_smith | annelies: ah, yourse is by word, I did mine by character - which means with a shorter memory it is prone to inventing "words" |
| 10:36 | m1dnight | :D |
| 10:37 | annelies | Oh I meant just porting MarkovChain, not NonsenseGenerator |
| 10:37 | justin_smith | annelies: oh, that will be like a four liner I bet |
| 10:38 | annelies | Yeah. :P |
| 10:38 | annelies | Well, a protocol and a function transition |
| 10:39 | annelies | Mine is bugged actually. It fails if the PRNG returns exactly 0.0. |
| 10:39 | annelies | Then it throws a NotImplementedException :v |
| 10:42 | justin_smith | annelies: I am not very good at reading scala - does yours use start / stop tokens? |
| 10:42 | annelies | No idea what those are. :P |
| 10:42 | annelies | The nonsense generator just constructs a map of (current word, set of possible next words) pairs |
| 10:43 | annelies | And then it starts at a random word. |
| 10:43 | justin_smith | annelies: when analyzing an input, a start token is inserted at the beginning, a stop token appended at the end, then "generate" will start with one of the start tokens (with a weighed probability) and stop if it reaches a stop token. |
| 10:44 | ingsoc | AeroNotix :name <- is this kinda like an atom in erlang |
| 10:44 | annelies | Oh no it just picks a random word to start with. There is no stop token, it stops when you stop calling transition. |
| 10:45 | annelies | So to construct a nonsense paragraph just reduce with transition and string concatenation |
| 10:45 | AeroNotix | ingsoc: yeah |
| 10:45 | AeroNotix | ingsoc: but there's no atom table |
| 10:45 | oskarkv | Say I want to use JavaFX or Swing or some other Java lib. And I have an idea for a new Node/Control (like Label, Image, Button). Then I would like to create a named class, that can extend a class and implement interfaces. What would you guys use for that? It almost seems like the easiest choice would be to forget about the named class thing and make a proxy for each instance. |
| 10:45 | justin_smith | annelies: an interesting side effect of using start/stop tokens is that if your input was grammatical, the output will start with a capitalized word, and end with a period / newline |
| 10:45 | AeroNotix | ingsoc: so you can make as many as you want |
| 10:45 | annelies | justin_smith: a right :p |
| 10:46 | justin_smith | oskarkv: yeah, proxy or refiy likely |
| 10:46 | justin_smith | *reify |
| 10:46 | justin_smith | time for coffee |
| 10:46 | grandy | anyone know the best practice for server side session state in compojure ? |
| 10:46 | oskarkv | but reiddraper can't extend classes, right? |
| 10:46 | oskarkv | ops |
| 10:47 | oskarkv | reify* |
| 10:47 | justin_smith | I am pretty sure reiddraper has extended quite a few classes :) |
| 10:47 | oskarkv | hehe |
| 10:47 | oskarkv | Wouldn't it make sense for clojure to be able to make new named classes for interop purposes? |
| 10:47 | justin_smith | oskarkv: reify can implement any number of interfaces |
| 10:48 | grandy | is it ring-clojure ? |
| 10:48 | oskarkv | or maybe that's what genclass does |
| 10:48 | oskarkv | justin_smith yeah but not extend classes right? |
| 10:48 | justin_smith | oskarkv: right, but swing should only care about interfaces, not classes for the most part, I would hope |
| 10:48 | justin_smith | oskarkv: maybe my optimism is misplaced |
| 10:48 | oskarkv | hehe |
| 10:49 | oskarkv | Sometimes it saves work to extend :p |
| 10:49 | justin_smith | anyway, if interfaces are sufficient (hopefully they are), with the help of defprotocol you can extend however you like - unless it actually needs you to inherit specific classes |
| 10:50 | annelies | Weighted choice is one of those things I love implementing imperatively rather than functionally. |
| 10:50 | justin_smith | heh |
| 10:50 | ingsoc | AeroNotix: ok thanks |
| 10:50 | AeroNotix | ingsoc: nw |
| 10:51 | justin_smith | annelies: my rng is of course imperative, but I actually did the weighted choice as a pure function otherwise |
| 10:51 | annelies | You can write pure functions using imperative programming. |
| 10:51 | justin_smith | of course |
| 10:51 | justin_smith | but I used standard fn / reduce and no state mutation is what I mean |
| 10:53 | grandy | ok fine |
| 10:54 | justin_smith | grandy: ring-clojure is a session state? |
| 10:54 | grandy | it has a session namespace |
| 10:54 | justin_smith | yeah - compojure is just a routing lib |
| 10:54 | justin_smith | for the other stuff, you want to look at ring middlewares |
| 10:55 | grandy | justin_smith: cool that's what i thought but wanted to make sure i hadn't missed something... there have been a few deprecated projects in this area |
| 10:55 | justin_smith | it's true |
| 10:56 | justin_smith | grandy: I've never even heard of someone using compojure without ring |
| 10:56 | justin_smith | though it may be hypothetically possible |
| 10:56 | grandy | justin_smith: cool yeah i think there have been some other libs that may do some session stuff too, also on top of ring |
| 10:57 | justin_smith | right, and they will all act as a ring middleware |
| 10:57 | annelies | Hmm, I guess I can use reductions for it. |
| 10:57 | SagiCZ1 | ,(for [i "abc"] (for [j (range 3)] (str i j))) |
| 10:57 | SagiCZ1 | i need this to return ("a0" "a1" "a2" "b0"... should i use flatten? |
| 10:57 | clojurebot | (("a0" "a1" "a2") ("b0" "b1" "b2") ("c0" "c1" "c2")) |
| 10:58 | justin_smith | grandy: I use ring.middleware.session/wrap-session |
| 10:58 | grandy | justin_smith: ahh ok perfect that looks useful |
| 10:58 | justin_smith | grandy: you can specify what sort of storage you want with that |
| 10:59 | grandy | justin_smith: cool |
| 10:59 | SagiCZ1 | nevermind, got it |
| 11:00 | justin_smith | SagiCZ1: you don't need to ever nest for calls |
| 11:00 | justin_smith | ,(for [i "abc" j (range 3)] (str i j)) |
| 11:00 | clojurebot | ("a0" "a1" "a2" "b0" "b1" ...) |
| 11:01 | SagiCZ1 | yeah i found that out, thanks |
| 11:01 | justin_smith | OK - just making sure you figured out the simple way |
| 11:05 | annelies | I think I got it: https://gist.github.com/rightfold/a2394f6d9cd785fcc990 |
| 11:05 | justin_smith | very nice |
| 11:05 | justin_smith | better than mine |
| 11:05 | justin_smith | https://github.com/noisesmith/markov-toy/blob/master/src/markov/core.clj#L14 |
| 11:08 | oskarkv | ,(for [i "abc" j (range 3)] (str i j)) |
| 11:09 | clojurebot | ("a0" "a1" "a2" "b0" "b1" ...) |
| 11:09 | oskarkv | oh, was scrolled up :p |
| 11:17 | m1dnight | guys, I'm having a brainy problem. At runtime I want to add stuff to a list and then return that list. |
| 11:17 | m1dnight | The reason is that I need the values of the expression before. |
| 11:17 | m1dnight | Is there an idiomatic way? |
| 11:18 | m1dnight | since immutability and all .. |
| 11:18 | m1dnight | wait a minute |
| 11:19 | m1dnight | yeah, still. I have a function that does a message send to a thread. But this send could contain values that are in the current lexical scope. However, I want to do those message sends during a commit. Ergo, I have to get the values out of scope to use them in a differnet one |
| 11:20 | m1dnight | So I figured I could 'cons' them to a list (to say it in lisp terms) and then return that list to the other scope |
| 11:20 | Glenjamin | m1dnight: can you provide a code sample i'm not clear why (cons) isn't enough here? |
| 11:21 | m1dnight | well, I have a meta-circular STM implementation. I also have an implementation of Erlang actors. Now in my state change of my actors (ie the body) I want to send messages to other actors. |
| 11:21 | m1dnight | But, i'm experimenting with an actor that has a dosync in his body, and inside that dosync, sends a message to another actor |
| 11:22 | m1dnight | I want to hold that message back until commit. |
| 11:22 | m1dnight | but, since the commit happens in a different scope, i need to get the values that are sent to an actor in a message out of the scope |
| 11:24 | Glenjamin | you might be able to do something with http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/add-watch |
| 11:24 | m1dnight | wait a minute, i think you gave me an idea :D |
| 11:24 | m1dnight | !è |
| 11:24 | Glenjamin | if i'm understanding, you want to queue up message sends until your current actor transaction is finished, then send them |
| 11:24 | m1dnight | yes, indeed |
| 11:25 | m1dnight | but that's easy, because a message is a keyword (e.g., :message) |
| 11:25 | m1dnight | so I can do something like (! actor :message <var> <var>..) |
| 11:25 | m1dnight | that sends the message :message to the actor and attaches the values <var> |
| 11:30 | cristian | Hi guys. I wonder what's the idiomatic way in clojure to define functions that might fail or that might return null. In Java 8, I'm mostly using Optional. In Haskell I use Maybe and Either. |
| 11:31 | cristian | How do you usually implement such functions in Clojure? |
| 11:31 | Glenjamin | generally i'd just return null |
| 11:31 | ingsoc | AeroNotix: lein repl :connect seems like a it provides some of the remsh stuff of erlang |
| 11:31 | Glenjamin | i think core.typed has a way of saying whether a function will or wont return null |
| 11:31 | ingsoc | have you sued this ? |
| 11:31 | ingsoc | used* |
| 11:31 | AeroNotix | ingsoc: it does |
| 11:32 | Glenjamin | a lot of core functions do something useful if you pass null |
| 11:32 | Glenjamin | ,(assoc nil :a 1) |
| 11:32 | clojurebot | {:a 1} |
| 11:33 | ingsoc | AeroNotix: can you reload new version of code ? |
| 11:33 | ambrosebs | cristian: do you want to know how to define such functions or use their outputs? |
| 11:33 | AeroNotix | ingsoc: yes, much better than the way Erlang does it, too. |
| 11:33 | AeroNotix | ingsoc: because you don't have supervision trees to tear down as a whole, you can just redefine whatever you need in-place and the running code picks it up. |
| 11:34 | Glenjamin | AeroNotix: as long as there's no state :D |
| 11:34 | justin_smith | ingsoc: as I mentioned before, vars are mutable, so to the extent that your code is all vars, yes - the tricky thing is of course any closed over state, sometimes to get a good reload you need to define a restart of some sort |
| 11:34 | Glenjamin | see also, the "component" library |
| 11:34 | AeroNotix | Yeah component is really good |
| 11:34 | justin_smith | Glenjamin: yes, component was what I was getting at :) |
| 11:34 | ingsoc | hmmm, to get this straight in my mind, does the Java VM when running clojure listen on the nrepl port all the time |
| 11:35 | ingsoc | so you can connect at any time or do you have to enable something in the project ? |
| 11:35 | Glenjamin | ingsoc: when you run "lein repl", it starts a client+server |
| 11:35 | justin_smith | ingsoc: only if you open an nrepl listener |
| 11:35 | justin_smith | lein opens one for you |
| 11:35 | justin_smith | or you can do so yourself in production code if you wish |
| 11:35 | justin_smith | but you should not use lein in production |
| 11:35 | AeroNotix | In production code I have nrepl spawning a listener as part of main |
| 11:36 | ingsoc | ok i see. I was doing this in counterclockwise. I spose when you run your project in counterclockwise it does plumbing for you |
| 11:36 | annelies | I wish I wrote production code. |
| 11:36 | AeroNotix | annelies: Why don't you? |
| 11:36 | ingsoc | (it runs lein) |
| 11:37 | justin_smith | ingsoc: the code to start your own nrepl server is clojure.tools.nrepl package |
| 11:37 | justin_smith | it's pretty easy |
| 11:38 | cristian | ambrosebs: I want to know how you define such functions. For instance, you can define a function that returns Either in Scala (or haskell), and the client of the function knows that it has to pattern match the result to know if the computation succeeded or not (and if not, you get useful data about what went wrong). How do you guys handle such cases in clojure? I don't want to just emulate what I do in |
| 11:38 | cristian | imperative languages... I want something more Clojure-idiomatic |
| 11:38 | annelies | AeroNotix: I mean in Clojure. |
| 11:39 | annelies | I write it in Python though. |
| 11:39 | ambrosebs | cristian: in Clojure you just return null in the function and document it in the docstring or contract. |
| 11:39 | cristian | Ok |
| 11:39 | cristian | Thanks |
| 11:40 | Glenjamin | ambrosebs: does core.typed let you annotate as "will not return null" ? |
| 11:40 | ambrosebs | Glenjamin: yes, references are non-nullable |
| 11:40 | annelies | cristian: it's better to use \/ than Either for that in Scala. Either isn't designed for failure vs. success, but just as a utility union type. |
| 11:40 | Glenjamin | and presumably with anything that can return null i have to handle it to type check? |
| 11:40 | ambrosebs | cristian: check out some->, when for some macros to help *use* nullable values |
| 11:41 | cristian | annelies: pardon my ignorance... what do you mean by \/ |
| 11:41 | ingsoc | i need to learn how this works then. I thought this wasn't possible on JVM and afaict all clojure code is compiled into java classes / byte code ? so what's the deal there ? Or could you also do this with java code ? |
| 11:41 | ambrosebs | Glenjamin: yes, just in the same way you'd do it in clojure. (fn [a :- (U nil Int)] (when a (inc a))) |
| 11:42 | Glenjamin | i think mostly i forget to check for nil :) i should really find an excuse to play with core.typed |
| 11:42 | justin_smith | ingsoc: it's the opposite - every object in the jvm is nullable, and we just adapt to that |
| 11:42 | annelies | cristian: http://docs.typelevel.org/api/scalaz/nightly/#scalaz.$bslash$div has a right-bias (right indicates success) for map, filter etc... which is far more useful than Either's left and right projections when dealing with failure vs. success |
| 11:44 | ingsoc | just looking at jetty, looksamazingly easy to providew a simple http api |
| 11:44 | justin_smith | ingsoc: in clojure, use ring |
| 11:44 | ingsoc | fun stuff :) |
| 11:44 | ingsoc | ring ? |
| 11:44 | ingsoc | oh ok |
| 11:44 | justin_smith | there are very few reasons not to use the ring abstraction |
| 11:45 | cristian | annelies: thanks. That's interesting. Why doesn't clojure have something like that? Is it not need ti? |
| 11:45 | ambrosebs | Glenjamin: a good excuse, but my advice is to become comfortable with some-> and the like. |
| 11:45 | justin_smith | it turns mutating code on streams into pure functions of request-map / response-map |
| 11:45 | annelies | cristian: No idea. I always throw exceptions when something goes wrong. |
| 11:46 | ambrosebs | Glenjamin: or least use contracts to be explicit about what values you think are allowed at certain points. |
| 11:46 | justin_smith | correct me if I am wrong, but my gist is that as opposed to the scala approach where they try to define a more sane semantics (and all the work that goes into that...) clojure takes the lazier approach of taking the java semantics as a given and dealing with it in a way that tries to minimize complexity |
| 11:46 | Glenjamin | ambrosebs: i suspect the greater benefit to me would be the tool reminding me i forgot to use some/when/if/or etc |
| 11:46 | ambrosebs | Glenjamin: sure, core.typed is the perfect tool for that. |
| 11:46 | ambrosebs | it will find *all* the cases you forget in typed code. |
| 11:48 | ambrosebs | the only time I've described core.typed as the perfect tool for anything. |
| 11:49 | Glenjamin | haha |
| 11:49 | ambrosebs | but you exactly described the reasons for core.typed's existence |
| 11:49 | justin_smith | ambrosebs: your humility is appreciated |
| 11:49 | ambrosebs | :) |
| 11:54 | ingsoc | AeroNotix: last question for the day (hopefully :P). Overall what are your impressions of clojure as a compliment to erlang and how it compares on productivity to alternatives ? |
| 11:57 | annelies | Heh, clojure as a compliment to erlang. "Hey erlang, you've got a nice clojure there!" |
| 11:57 | ingsoc | :) |
| 11:57 | ingsoc | :P |
| 11:57 | justin_smith | "hey erlang, love those actors, mind if I borrow a few ideas?" |
| 11:58 | annelies | such as lightweight processes ;_; |
| 11:58 | justin_smith | annelies: isn't this what core.async was going for? |
| 11:59 | annelies | Never looked into core.async. |
| 11:59 | ingsoc | well erlang = (robustness, concurrency, stability) clojure = (speed, libraries, deployability, lisps - so worth learning to expand programming knowledge) |
| 11:59 | ingsoc | this is how i am viewing it |
| 12:00 | annelies | Elixir runs on the Erlang VM and borrows many ideas from Clojure. |
| 12:00 | pdk | it's got... |
| 12:00 | pdk | a promising future |
| 12:00 | annelies | Such as macros and protocols. |
| 12:00 | justin_smith | ingsoc: clojure is no slouch on concurrency eitehr, if you compare it to anything *but* erlang :) |
| 12:00 | annelies | If you are into that stuff. |
| 12:03 | andyf | ambrosebs: core.typed is also the perfect tool to break Eastwood, and/or stretch it to its limits :) |
| 12:03 | ambrosebs | andyf: glad to be of service |
| 12:03 | andyf | I think I?ll declare it done when it gives correct warnings for core.typed :) |
| 12:04 | ambrosebs | hehe |
| 12:04 | andyf | That reminds me, there is a pretty darn big function generated via macro in one namespace I wanted to note to you. Let me find its name. |
| 12:05 | justin_smith | andyf: I've wondered, is eastwood named after the actor? |
| 12:05 | andyf | justin_smith: Clojure LINT :) |
| 12:05 | justin_smith | omg it's worse than I imagined |
| 12:05 | justin_smith | thanks |
| 12:06 | andyf | Jonas Enlund came up with the name, so I can't take credit. I wish I would have thought of it. |
| 12:07 | Glenjamin | thats genius |
| 12:09 | andyf | ambrosebs: Also, I have to ask, what do you use to navigate your 150+ namespaces? :) |
| 12:09 | ambrosebs | andyf: is it that many?! vim's Command-T |
| 12:10 | andyf | Counting test namespaces, definitely. I don't recall if non-test namespaces exceed that on their own. |
| 12:12 | ambrosebs | well that's a great success. I had a few 8000 liners a few years ago. |
| 12:14 | andyf | ambrosebs: Namespace clojure.core.typed.base-env-clj-rclass, the delay-and-cache-env call. It is only too large for Eastwood, not Clojure, I think because of extra tools.reader metadata and the way syntaxquote works. That means it is probably within a factor of 2 of being too large for Clojure, though. |
| 12:15 | ambrosebs | andyf: oh that's a stupid hack. I can fix that for you. |
| 12:15 | ambrosebs | andyf: it should really be reading those forms from a separate file, the code should be minimal. |
| 12:16 | andyf | No need to fix it for me, but I certainly won't stop you if you wish ;) |
| 12:16 | ambrosebs | sure |
| 12:17 | andyf | You aren't the first to auto-generate huge Clojure functions, and you won't be the last. 64KB max method size seems strangely small for the JVM bytecode, but I understand there has to be a limit somewhere. |
| 12:17 | annelies | After being here for a few hours I can say I like this chatroom. |
| 12:18 | ambrosebs | the other delay-and-cache-env calls hit the method limit all the time. |
| 12:22 | andyf | core.typed: 161 non-test namespaces, 143 test namespaces. 304 total. Not counting cljs |
| 12:22 | ambrosebs | wow! |
| 12:23 | justin_smith | I have libraries with fewer lines than that |
| 12:24 | Glenjamin | does that include all the clojure.core annotations? |
| 12:24 | ambrosebs | Glenjamin: that's just one file |
| 12:26 | andyf | Glenjamin: If you were asking me regarding core.typed namespaces, I don't know which ones contain those annotations. |
| 12:26 | ambrosebs | https://github.com/clojure/core.typed/blob/master/module-check/src/main/clojure/clojure/core/typed/base_env.clj |
| 12:26 | ambrosebs | it's a big un |
| 12:27 | Glenjamin | i love how a "big" clojure file is < 2k lines |
| 12:27 | Glenjamin | i've had similar "this is getting a bit big" feelings, then looked to note the file is ~250 lines |
| 12:27 | justin_smith | Glenjamin: yeah, seriously |
| 12:28 | justin_smith | Glenjamin: I propose that the platonic ideal of a clojure namespace is a perfect square: longest line is 80 chars, 80 lines long. |
| 12:29 | Glenjamin | otoh, a huge flat namespace of non-interacting pure functions is probably still quite tidy |
| 12:29 | justin_smith | of course |
| 12:29 | Glenjamin | did you see the joe armstrong post about namespaces recently? |
| 12:30 | ambrosebs | if anyone needs a big ns form for some reason: https://github.com/clojure/core.typed/blob/master/module-check/src/main/clojure/clojure/core/typed/check.clj |
| 12:30 | Glenjamin | http://erlang.org/pipermail/erlang-questions/2011-May/058768.html |
| 12:30 | Glenjamin | read that this week - only just noticed it's > 3 years old |
| 12:30 | justin_smith | Glenjamin: the one where he digressed to talk about letrec, yeah |
| 12:31 | justin_smith | I think technomancy brought it up recently |
| 12:31 | Glenjamin | aha |
| 12:32 | Glenjamin | i have occasionally thought to build to "lein util" plugin, that lets you build your util.clj namespace by pulling functions from a remote repo w/ metadata into one file |
| 12:33 | andyf | Glenjamin: To avoid the extra dependency for utils only? |
| 12:34 | Glenjamin | andyf: yeah, and flatten it a bit |
| 12:34 | Glenjamin | core.experimental, useful, medley etc could all just be functions in a util-function repository |
| 12:35 | andyf | I've got a pre-alpha 'dolly' lib that helps me copy code into Eastwood source and rename its namespaces, to avoid namespace version conflicts with projects being linted. |
| 12:35 | Glenjamin | similar sort of idea i guess, but for fns |
| 12:35 | andyf | I wouldn't recommend it for general use: https://github.com/jafingerhut/dolly |
| 12:35 | Glenjamin | that sounds like it'd be very useful for lein itself too |
| 12:36 | andyf | Glenjamin: Are there often conflicts between Leiningen namespaces and namespaces of projects managed by Leiningen? |
| 12:36 | Glenjamin | i've had issues between lein and speclj before |
| 12:37 | Glenjamin | only affects plugins, not app code |
| 12:37 | Glenjamin | unless the app pulls in lein for some reason |
| 12:41 | andyf | Yes, my guess was that something like dolly would be useful for some plugins, but not a lot else. |
| 12:49 | m1dnight | Hmm, I get "can not embed object in code" when I try to build a macro |
| 12:49 | m1dnight | I want to grab a variable defined in the scope of macro expansion, is that not possible? (a macro to be specific) |
| 12:50 | m1dnight | I.e., create a variable in your macro function, and make the expanded code use it |
| 12:50 | m1dnight | I'll build a minimal testcase, to make things clear perhaps |
| 12:50 | AeroNotix | show the code |
| 12:51 | m1dnight | okay, but it might be confusing :p |
| 12:51 | m1dnight | hold on |
| 12:52 | AeroNotix | because it sounds like you just want a gensym |
| 12:52 | AeroNotix | unless you're making an anaphoric macro, of which I am not going to help anyone make one of those. |
| 12:52 | justin_smith | AeroNotix: how principled of you |
| 12:53 | AeroNotix | justin_smith: I find anaphoric macros incredibly annoying |
| 12:53 | justin_smith | AeroNotix: does #(= x %) count? |
| 12:54 | AeroNotix | justin_smith: no |
| 12:54 | AeroNotix | justin_smith: you provide the symbol, technically |
| 12:55 | m1dnight | https://www.refheap.com/92918 |
| 12:55 | justin_smith | oh, so as-> would be anaphoric |
| 12:55 | m1dnight | what is an anaphoric macro? :p |
| 12:55 | justin_smith | http://en.wikipedia.org/wiki/Anaphoric_macro |
| 12:56 | m1dnight | I have a list of expressions, but I want to modify them, such that they instead of execute, put their parameters in an atom |
| 12:56 | m1dnight | afterwards, I'll execute another function that will do something with those parameters |
| 12:56 | ingsoc | Macros scare me. Well, I mean maintaining code that someone had gone macro crazy with would be scary |
| 12:56 | m1dnight | in a different lexical scope |
| 12:56 | hyPiRion | m1dnight: imagine if-let worked like this: (if-let (get my-map :foo) (+ 2 it) 1) – where it is the result of the if-let expression |
| 12:57 | AeroNotix | ingsoc: it's all about using them judiciously |
| 12:57 | justin_smith | ingsoc: to be fair, things like ->, ->>, or, and, when, def, defn are indespensible - but making new macros definitely demands a compelling reason |
| 12:57 | m1dnight | I'm just trying to make a proof of concept here, not production code :p |
| 12:58 | AeroNotix | m1dnight: what are you actually trying to accomplish |
| 12:58 | m1dnight | well, I have a list of expressions that I execute in a dosync block. One of those expressions can be "(! actor message [values])" |
| 12:58 | m1dnight | but, in a dosync block we can retry, so I have to make sure to send those messages only once. |
| 12:59 | arrdem | for those of you who hanve't tried it, I highly reccomend core.logic+pldb if you want to play with a smallish dataset |
| 12:59 | justin_smith | m1dnight: what about using a delay for that? a delay will only be realized once |
| 12:59 | m1dnight | euhm |
| 12:59 | m1dnight | holy *beep beep beep* |
| 12:59 | justin_smith | ,(def d (delay (do (println "realized") 1))) |
| 12:59 | clojurebot | #'sandbox/d |
| 12:59 | justin_smith | ,@d |
| 12:59 | clojurebot | realized\n1 |
| 13:00 | justin_smith | ,@d |
| 13:00 | clojurebot | 1 |
| 13:00 | m1dnight | that could work as well |
| 13:00 | m1dnight | but what I was trying to accomplish was |
| 13:01 | m1dnight | transform any expression in the dosync of form (send actor message [vars]) to (swap! storage (fn [msgs] (cons {:msg message :actor actor :vars vars} msgs)) |
| 13:01 | m1dnight | this way, I can send the messages during commit phase |
| 13:02 | m1dnight | but since that commit phase happens in a different lexical scope I have to figure out something such that I can write to an atom or something outside the scope of my actual dosync body |
| 13:02 | m1dnight | which I can then access in the scope present during committing |
| 13:02 | m1dnight | hence, I tried putting my code in a let as yo ucan see |
| 13:03 | AeroNotix | m1dnight: your juxt function doesn't seem right |
| 13:03 | m1dnight | oh, it is |
| 13:03 | m1dnight | output is right, is what i mean by that :p |
| 13:03 | justin_smith | AeroNotix: what's wrong with that juxt? |
| 13:04 | AeroNotix | justin_smith: looks like they wanted to split the expressions into things which begin with #'! and those which don't |
| 13:04 | justin_smith | ,((juxt filter remove) even? (range 10)) |
| 13:04 | clojurebot | [(0 2 4 6 8) (1 3 5 7 9)] |
| 13:04 | justin_smith | and that's what it does |
| 13:04 | m1dnight | AeroNotix: yes so I can then transform those to the form I showed above |
| 13:04 | AeroNotix | Right yeah I expected that to remove them altogheter |
| 13:05 | justin_smith | m1dnight: I can't prove it, but this almost smells like a hand rolled monad |
| 13:05 | m1dnight | hahaha |
| 13:06 | m1dnight | spare me monads, please |
| 13:06 | m1dnight | :'( |
| 13:06 | arrdem | hahaha |
| 13:06 | arrdem | don't fear the state monad :P |
| 13:06 | m1dnight | I don't fear it, if I can keep it at a safe distance in a cage |
| 13:06 | m1dnight | \o/ |
| 13:07 | justin_smith | your problem is that you are using ~ on delayed-msgs |
| 13:07 | justin_smith | that doesn't really make sense |
| 13:07 | m1dnight | yeah, when i remove it I get what I want, but then it says it cant find the variable |
| 13:07 | justin_smith | remember that your macro should build the form to compile, not run the code you want run directly |
| 13:07 | m1dnight | no such var: meta-clojure.stm.actor-friendly/delayed-msgs |
| 13:08 | justin_smith | m1dnight: right, because it is not bound in that scope - I think you want to return a binding form that captures the atom |
| 13:08 | m1dnight | oh |
| 13:08 | justin_smith | `(let [delayed-msgs# (atom {})] ...) |
| 13:09 | AeroNotix | >>> because it sounds like you just want a gensym |
| 13:09 | justin_smith | AeroNotix: right, some of us were a bit slower connecting the dots |
| 13:09 | AeroNotix | No, I just called it. I didn't look too hard at the code! :) |
| 13:09 | AeroNotix | justin_smith: good job on figuring it out :) |
| 13:10 | justin_smith | but the gensym isn't the crux of it, the need to capture the binding is - the gensym is just one tool in doing that |
| 13:11 | madscientist` | 0 |
| 13:11 | madscientist` | doh |
| 13:11 | m1dnight | yeah, I was too focused on capturing the atom and forgot about just putting it in the macro as well |
| 13:11 | m1dnight | thanks a bunch :) really |
| 13:12 | justin_smith | m1dnight: yeah a macro body can capture a literal form to be embedded, but cannot capture a value |
| 13:12 | m1dnight | my head is de-hurting at the moment :D |
| 13:12 | m1dnight | I get it \o/ |
| 13:12 | justin_smith | awesome |
| 13:19 | m1dnight | what does wrong number of args (-1) mean, actually? |
| 13:19 | m1dnight | 0+ would be more logical, no? :p |
| 13:25 | justin_smith | yes, that is weird |
| 13:25 | andyf | m1dnight: There is a bug in Clojure for wrong arity errors for macros that subtracts 2 because macros have &form &env hidden args. |
| 13:25 | justin_smith | m1dnight: but macros get two invisible arguments |
| 13:25 | andyf | I've seen a CLJ ticket for it. |
| 13:25 | andyf | I think |
| 13:25 | m1dnight | oh that might explain :D |
| 13:25 | justin_smith | yeah, that is about it |
| 13:26 | justin_smith | clojure, the land of leaky abstractions |
| 13:30 | andyf | http://dev.clojure.org/jira/browse/CLJ-1279 Vote early, vote often. |
| 13:34 | arrdem | justin_smith: eh could leak worse |
| 13:34 | justin_smith | arrdem: sure, but we do have a lot of them if you go looking |
| 13:35 | arrdem | I guess |
| 13:38 | justin_smith | arrdem: I never really got the impression that seamlessness in abstractions was even a goal with clojure. I mean we don't really make much effort to hide implementation details in general. |
| 13:38 | justin_smith | not a dig or a complaint, just an observation of the design style |
| 13:39 | bbloom_ | i think that if an abstraction is well designed, you don't have to bother hiding the implementation details: people simply won't go looking for them |
| 13:40 | justin_smith | bbloom_: right, so we let them leak, they are useful regardless |
| 13:40 | bbloom_ | ,(.tail []) ; whoops! |
| 13:40 | clojurebot | #<Object[] [Ljava.lang.Object;@189f393> |
| 13:41 | AeroNotix | Yeah the JVM leaks through everywhere |
| 13:41 | bbloom_ | ,clojure.lang.PersistentVector/EMPTY_NODE |
| 13:41 | clojurebot | #<Node clojure.lang.PersistentVector$Node@537a5a> |
| 13:41 | bbloom_ | ,(.tail clojure.lang.PersistentVector/EMPTY_NODE) |
| 13:41 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: tail for class clojure.lang.PersistentVector$Node> |
| 13:42 | bbloom_ | ,(.tail (clojure.lang.PersistentVector/EMPTY_NODE)) |
| 13:42 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: tail for class clojure.lang.PersistentVector$Node> |
| 13:42 | bbloom_ | ,(.array (clojure.lang.PersistentVector/EMPTY_NODE)) ; ah of course |
| 13:42 | clojurebot | #<Object[] [Ljava.lang.Object;@8ded54> |
| 13:43 | bbloom_ | ,(.shift []) |
| 13:43 | clojurebot | 5 |
| 13:43 | bbloom_ | ,(set! (.shift []) 0) |
| 13:43 | clojurebot | #<IllegalAccessException java.lang.IllegalAccessException: Can not set final int field clojure.lang.PersistentVector.shift to java.lang.Integer> |
| 13:43 | bbloom_ | aw, final |
| 13:44 | bbloom_ | oh well, still |
| 13:44 | AeroNotix | bbloom_: yes Clojure is on the JVM :) |
| 13:44 | bbloom_ | AeroNotix: i was trying to break all vectors w/o reflection :-P |
| 13:45 | bbloom_ | well, w/o nefarious reflection |
| 13:46 | andyf | bbloom_: You can break their immutability without much effort by aset'ing .tail |
| 13:46 | bbloom_ | andyf: that i know / have done in this very channel before :-) i was trying to break ALL vectors |
| 13:47 | andyf | You mean, one Java interop call that would cause every instance of a vector to behave incorrectly from that point forward? |
| 13:47 | bbloom_ | yes |
| 13:47 | justin_smith | bbloom_: we played with a similar trick for breaking the number 5 |
| 13:47 | justin_smith | it was amusing |
| 13:47 | bbloom_ | justin_smith: do share |
| 13:48 | justin_smith | finding it in my notes |
| 13:48 | gfredericks | (.tail [1 2 3]) |
| 13:48 | gfredericks | ,(.tail [1 2 3]) |
| 13:48 | clojurebot | #<Object[] [Ljava.lang.Object;@1ba146b> |
| 13:48 | justin_smith | ,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field 5 2)) |
| 13:48 | clojurebot | nil |
| 13:48 | justin_smith | ,(inc 5) |
| 13:48 | clojurebot | 3 |
| 13:48 | andyf | You can break the JVM's 5, but Plato's 5 is safe in the world of forms |
| 13:49 | justin_smith | haha |
| 13:49 | gfredericks | ~5 is the set of all sets with 5 elements |
| 13:49 | clojurebot | Ik begrijp |
| 13:49 | bbloom_ | , (.getDeclaredFields Long) 3) |
| 13:49 | clojurebot | #<Field[] [Ljava.lang.reflect.Field;@5753b0> |
| 13:49 | bbloom_ | ,(.getName (.getDeclaredFields Long) 3)) |
| 13:49 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: getName for class [Ljava.lang.reflect.Field;> |
| 13:49 | bbloom_ | ,(.name (.getDeclaredFields Long) 3)) |
| 13:49 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: name for class [Ljava.lang.reflect.Field;> |
| 13:49 | bbloom_ | ,(clojure.reflect/reflect (.getDeclaredFields Long) 3)) |
| 13:49 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.reflect> |
| 13:49 | bbloom_ | ,(require 'clojure.reflect) |
| 13:49 | clojurebot | nil |
| 13:49 | bbloom_ | eh wahtever... how do i get the name of a field? |
| 13:50 | gfredericks | .getName? |
| 13:50 | bbloom_ | i tried that |
| 13:50 | bbloom_ | oh dur it's an array |
| 13:50 | gfredericks | with 3? |
| 13:50 | bbloom_ | ,(.name (nth (.getDeclaredFields Long) 3)) |
| 13:50 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: name for class java.lang.reflect.Field> |
| 13:50 | bbloom_ | i suck |
| 13:50 | bbloom_ | ,(.getName (nth (.getDeclaredFields Long) 3)) |
| 13:50 | clojurebot | "value" |
| 13:51 | andyf | The world of forms: Bringing you real immutability since 348 BC |
| 13:51 | bbloom_ | ah ok i gotcha. boxed small numbers are interned |
| 13:51 | justin_smith | , (nth (.getDeclaredFields Long) 3) |
| 13:51 | clojurebot | #<Field private final long java.lang.Long.value> |
| 13:51 | justin_smith | ,(.getName (nth (.getDeclaredFields Long) 3)) |
| 13:51 | clojurebot | "value" |
| 13:51 | bbloom_ | andyf: https://en.wikipedia.org/wiki/348_BC <- i was hoping you knew the actual year |
| 13:51 | justin_smith | bbloom_: ^ |
| 13:52 | bbloom_ | justin_smith: i got there eventually :-P |
| 13:52 | justin_smith | bbloom_: aha, I missed it while I was finding it in my own repl |
| 13:52 | andyf | Sorry, I don't know when he wrote about it first, so I approximated by the year Plato died. |
| 13:53 | justin_smith | ,(= 5 3) |
| 13:53 | clojurebot | false |
| 13:53 | justin_smith | ,(= 5 2) |
| 13:53 | clojurebot | true |
| 13:54 | justin_smith | ,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field 5 (inc 4))) |
| 13:54 | clojurebot | nil |
| 13:54 | justin_smith | ,(= 5 2) |
| 13:54 | clojurebot | true |
| 13:54 | justin_smith | I thought I fixed that... |
| 13:54 | justin_smith | ,(let [field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field (inc 4) (inc 4))) |
| 13:54 | clojurebot | nil |
| 13:54 | justin_smith | ,(= 5 2) |
| 13:54 | clojurebot | true |
| 13:54 | justin_smith | ,(inc 2) |
| 13:54 | clojurebot | 3 |
| 13:54 | justin_smith | ,(inc 5) |
| 13:54 | clojurebot | 3 |
| 13:54 | mearnsh | this is why we can't have nice things |
| 13:55 | AeroNotix | ,(inc (+ 3 2)) |
| 13:55 | clojurebot | 6 |
| 13:55 | justin_smith | :( I forgot how to fix it |
| 13:55 | AeroNotix | ,(inc 5) |
| 13:55 | clojurebot | 3 |
| 13:55 | AeroNotix | 5 |
| 13:55 | AeroNotix | ,5 |
| 13:55 | clojurebot | 2 |
| 13:55 | justin_smith | ,(let [five (long (int (+ (int 1) (int 4)))), field (nth (.getDeclaredFields Long) 3)] (.setAccessible field true) (.set field five (int (+ (int 1) (int 4))))) |
| 13:55 | clojurebot | nil |
| 13:55 | andyf | Once you make 5 equal to something else, the JVM extrapolates and is able to prove that all numbers are simultaneously equal to, and not equal to, all others. |
| 13:55 | justin_smith | ,5 |
| 13:55 | clojurebot | 5 |
| 13:55 | justin_smith | ok, found the fix |
| 13:55 | justin_smith | andyf: if only |
| 13:55 | andyf | It's downhill from there |
| 13:56 | bbloom_ | this statement is false. |
| 13:56 | andyf | and simultaneously not downhill from there |
| 13:56 | justin_smith | I can't take credit for the trick, I just made a note of it to study, amalloy_ was who I saw do it |
| 14:00 | AeroNotix | ,(inc []) |
| 14:00 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 14:08 | m1dnight | What function do I have to map over a list of functions to execute all of them? |
| 14:09 | justin_smith | #(%) |
| 14:09 | justin_smith | equivalently (fn [f] (f)) |
| 14:09 | m1dnight | riiight! |
| 14:09 | m1dnight | thanks justin_smith |
| 14:09 | justin_smith | np |
| 14:10 | justin_smith | if you want to get way into semantic overload, (fn [fn] (fn)) actually works |
| 14:10 | m1dnight | hahaha |
| 14:10 | arrdem | hehe |
| 14:10 | justin_smith | but that shadows fn which is weird so don't do that |
| 14:11 | m1dnight | :D |
| 14:11 | andyf | justin_smith: Please, no. Zach Tellman's Manifold library defines a function called 'catch' that uses try/catch in its definition. |
| 14:11 | justin_smith | ,(take 42 (map (fn [fn] (fn)) (repeat (constantly 42)))) |
| 14:11 | clojurebot | (42 42 42 42 42 ...) |
| 14:11 | justin_smith | andyf: ouch |
| 14:12 | andyf | It all works, where the catch occurrences inside try are try/catch, and the ones not inside try are the function, but yeah, weird. |
| 14:13 | justin_smith | yeah, that seems gratuitously clever |
| 14:13 | gfredericks | ,((fn [fn] (fn fn fn fn fn fn fn)) list) |
| 14:13 | clojurebot | (#<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> #<clojure.lang.PersistentList$1@f90a8b> ...) |
| 14:13 | justin_smith | haha |
| 14:13 | justin_smith | gfredericks: it's now reminding me of "Being John Malkovich" |
| 14:14 | justin_smith | but instead of crawling in to be Malkovich, you crawl into the weird little door and suddenly you are an anonymous function... |
| 14:14 | justin_smith | https://www.youtube.com/watch?v=Q6Fuxkinhug |
| 14:14 | andyf | self reference isn't what i used to be |
| 14:15 | justin_smith | classic scene |
| 14:15 | justin_smith | nor is semantic satiation |
| 14:52 | ghadishayban | about to release this tiny library of clojure 1.7 "helpers" https://github.com/ghadishayban/reducers |
| 14:52 | ghadishayban | more reducible sources, reduce-based ops and a couple other novel things |
| 14:53 | ghadishayban | would love to get some eyes on it |
| 14:54 | ghadishayban | inspired by some an musing from hiredman |
| 14:55 | ghadishayban | the implementation of select-keys with transducers becomes super nice (and fast): |
| 14:56 | ghadishayban | (defn select-keys |
| 14:56 | ghadishayban | [map keyseq] |
| 14:56 | ghadishayban | (into {} (keep #(find map %)) keyseq)) |
| 14:57 | justin_smith | ,(doc find) |
| 14:57 | clojurebot | "([map key]); Returns the map entry for key, or nil if key not present." |
| 14:57 | justin_smith | is that an optimization for get? |
| 14:58 | ghadishayban | it returns the whole MapEntry. sister function to get |
| 14:58 | justin_smith | oh, interesting |
| 14:59 | justin_smith | ,(find [:a] 0) |
| 14:59 | clojurebot | [0 :a] |
| 14:59 | ghadishayban | ,(conj {} [:a :b]) |
| 14:59 | justin_smith | assuming that's odd |
| 14:59 | clojurebot | {:a :b} |
| 14:59 | gfredericks | useful for implementing plumbing.core/safe-get |
| 14:59 | gfredericks | or more generally, for doing both contains? and get in one lookup |
| 15:01 | ghadishayban | ,(class (find {:a :b} :a)) |
| 15:01 | clojurebot | clojure.lang.MapEntry |
| 15:01 | justin_smith | ,(type (find [:a] 0)) |
| 15:01 | clojurebot | clojure.lang.MapEntry |
| 15:02 | gfredericks | lifehack: to protect yourself against accidentally evaling a scratch file, put (don't load this) on the first line |
| 15:02 | gfredericks | I guess it works just as well without the parens |
| 15:02 | gfredericks | could even be englishified as "Don't load this." |
| 15:02 | justin_smith | alternatively (why did you load this file? you shouldn't have tried) |
| 15:03 | justin_smith | gfredericks: the bonus with the parens I think is that you would get the whole thing, not just the first invalid symbol |
| 15:03 | ghadishayban | ,filter-key |
| 15:03 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filter-key in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:03 | ghadishayban | ,*clojure-version* |
| 15:03 | clojurebot | {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"} |
| 15:03 | justin_smith | gfredericks: err... I guess not |
| 15:05 | ghadishayban | (defn filter-key [keyfn pred coll] (into (empty coll) (filter (comp pred keyfn)) coll)) |
| 15:05 | ghadishayban | ,(defn filter-key [keyfn pred coll] (into (empty coll) (filter (comp pred keyfn)) coll)) |
| 15:05 | clojurebot | #'sandbox/filter-key |
| 15:06 | ghadishayban | (filter-key val even? {:a 2 :b 1 :c 4 :d 5}) |
| 15:06 | ghadishayban | ,(filter-key val even? {:a 2 :b 1 :c 4 :d 5}) |
| 15:06 | clojurebot | {:c 4, :a 2} |
| 15:06 | ghadishayban | ,(filter-key key string? {:a 2 :b 1 "HI" 4 :d 5}) |
| 15:06 | clojurebot | {"HI" 4} |
| 15:06 | justin_smith | oh, that's very nice |
| 15:07 | ghadishayban | transducers are the shit |
| 15:07 | ghadishayban | that's all using transients |
| 15:07 | justin_smith | so I am seeing |
| 15:08 | ghadishayban | similarly, |
| 15:09 | ghadishayban | ,(filter-key :a string? [{:a 3} {:a "foo"}]) |
| 15:09 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: filter-key in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:09 | ghadishayban | guess that var expired? |
| 15:09 | justin_smith | clojurebot protects us from ourselves with periodic automatic resets |
| 15:09 | gfredericks | ~transducers |are| the shit |
| 15:09 | clojurebot | Ack. Ack. |
| 15:20 | ghadishayban | what do people normally call the find-first function: |
| 15:20 | ghadishayban | (first (filter pred coll)) |
| 15:21 | bbloom_ | ghadishayban: i usually just do (let [[x] (filter pred coll)] ... |
| 15:21 | ghadishayban | slick |
| 15:22 | ghadishayban | i called it any...and i hate it |
| 15:22 | ghadishayban | https://github.com/ghadishayban/reducers/blob/master/src/ghadi/reducers.clj#L66-L80 |
| 15:22 | bbloom_ | ghadishayban: i've seen it called "one" in ORMs ಠ_ಠ |
| 15:23 | ghadishayban | let's call it some! |
| 15:23 | ghadishayban | jk |
| 15:25 | SagiCZ1 | if i have a custom loop in which i am building a list (adding an element to it in each iteration) is there any way to make this lazy? |
| 15:25 | justin_smith | cinderella (like how the prince lines up all the women and takes the first one that can wear the shoe) |
| 15:25 | ghadishayban | nice |
| 15:26 | justin_smith | SagiCZ1: use a function that self calls within lazy-seq |
| 15:26 | bbloom_ | SagiCZ1: just use a recursive call and lazy-seq |
| 15:26 | bbloom_ | justin_smith: heh |
| 15:26 | SagiCZ1 | (doc lazy-seq) |
| 15:26 | clojurebot | "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls. See also - realized?" |
| 15:26 | SagiCZ1 | this one right? |
| 15:26 | justin_smith | right |
| 15:26 | justin_smith | @grim lazy-seq |
| 15:26 | SagiCZ1 | k thanks |
| 15:26 | justin_smith | $grim lazy-seq |
| 15:26 | justin_smith | not in yet, OK |
| 15:27 | SagiCZ1 | what is grim? |
| 15:27 | justin_smith | it would have found this http://grimoire.arrdem.com/1.6.0/clojure.core/lazy-seq/ |
| 15:27 | ghadishayban | SagiCZ1: depending on what you're doing, look at iterate |
| 15:27 | justin_smith | has some examples |
| 15:27 | justin_smith | oh yeah, iterate sometimes works - depends |
| 15:28 | ghadishayban | i added a reducible iterate that little reducers lib: https://github.com/ghadishayban/reducers/blob/master/src/ghadi/reducers.clj#L43-L50 |
| 15:28 | SagiCZ1 | and is it generally a good idea to make your functions return lazy seqs? i mean i just end up rewriting it to use lazy seq.. |
| 15:28 | justin_smith | SagiCZ1: in some cases lazy-seqs are very handy |
| 15:30 | ghadishayban | SagiCZ1: though i will say, almost in 100% of cases there a way using clojure seq functions (like iterate, map, mapcat, filter) without having to call lazy-seq manually |
| 15:30 | ghadishayban | i mean, to express a loop |
| 15:30 | ghadishayban | if you can paste your loop to refheap... |
| 15:31 | SagiCZ1 | ghadishayban: but loop is specifically for cases where you cant express it another way |
| 15:32 | ghadishayban | unless you can't see that there is another way to express it :) |
| 15:32 | SagiCZ1 | ghadishayban: which might be very possible.. i have no problem pasting it on refheap, maybe you can take a look if you want |
| 15:32 | ghadishayban | usually if you're iterating simultaneously through two collections, then loop is your only option |
| 15:33 | amalloy | ghadishayban: in many of those cases, map is fine |
| 15:33 | amalloy | i definitely wouldn't say "usually" |
| 15:33 | SagiCZ1 | i guess i am doing all kinds of weird stuff https://www.refheap.com/92926 |
| 15:35 | justin_smith | as-is, that could be a reduce on ticks |
| 15:35 | justin_smith | where events is the accumulator |
| 15:36 | SagiCZ1 | justin_smith: is reduce lazy? |
| 15:36 | justin_smith | and uncompleted bars is also an accumulator |
| 15:36 | justin_smith | no |
| 15:37 | SagiCZ1 | you are just saying i dont necessarily need loop |
| 15:37 | justin_smith | it could also be a (:events (last (take-while pred (iterate f [ticks bars])))) |
| 15:37 | justin_smith | or something like that |
| 15:37 | justin_smith | definitely don't need loop |
| 15:38 | ghadishayban | justin_smith: that's kinda hard to grok |
| 15:38 | justin_smith | there may be a more straightforward way to use iterate there actually |
| 15:38 | justin_smith | ghadishayban: yeah, it's a mess, sorry |
| 15:39 | SagiCZ1 | i just need to make it lazy.. |
| 15:40 | justin_smith | SagiCZ1: it would be fairly straightforward to make it lazy with reductions, where you would have completed-bars and uncomplete-bars for each step |
| 15:41 | SagiCZ1 | i thought reduce is not lazy? |
| 15:41 | SagiCZ1 | reductions not= reduce |
| 15:42 | SagiCZ1 | (doc reductions) |
| 15:42 | clojurebot | "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init." |
| 15:43 | SagiCZ1 | i need to learn this stuff.. i will probably head to 4clojure, before i tackle this big loop |
| 15:45 | justin_smith | SagiCZ1: something like this I think https://www.refheap.com/92929 |
| 15:46 | justin_smith | no wait... |
| 15:46 | SagiCZ1 | wow, thanks for taking the time to write that.. i will look into it |
| 15:46 | justin_smith | I just saw a mistake in that actually |
| 15:48 | justin_smith | SagiCZ1: updated, I am sure it is still imperfect https://www.refheap.com/92929 |
| 15:48 | justin_smith | but may be a good starting point |
| 15:49 | justin_smith | SagiCZ1: the big picture is that at each step it generates a two element vector of the events (completed bars) and the bars (the ones still being used) and you get a lazy-seq with one pair of these generated from each tick |
| 15:49 | justin_smith | (or that is what it does if it isn't still buggy) |
| 15:50 | amalloy | SagiCZ1's loop looked a lot like a filter and/or a mapcat to me; i don't have time to write it up atm, but i don't see any steps depending on the results of previous steps |
| 15:50 | justin_smith | amalloy: it moves things between completed / uncompleted |
| 15:50 | justin_smith | well, one way |
| 15:50 | amalloy | okay |
| 15:51 | justin_smith | it does an update of the previous "completed" bars at each step |
| 15:51 | justin_smith | that's why I think it need accumulators |
| 15:52 | justin_smith | but I have been known to use reduce / reductions when a filter or mapcat would do, so it's worth a second check on that |
| 15:53 | justin_smith | SagiCZ1: one trivial change I did is replace #(:complete %) with :complete in a couple places - in that context it was identical |
| 15:54 | justin_smith | but I tried to keep each of the steps of the core logic the same as your version, so the adaptation is clear |
| 15:55 | justin_smith | *should be clear, barring more mistakes on my part |
| 15:58 | SagiCZ1 | amalloy: in one iteration some bars get completed (and they get replaced by new bars) but others have to be past to the next step |
| 15:58 | SagiCZ1 | justin_smith: thanks again, i will try it out once i get back to it |
| 15:59 | justin_smith | np, I was just spinning my wheels before trying a big db migration on my scratch db, that I am procrastinating on because it will probably fail and I will need to reset the db again... |
| 15:59 | justin_smith | :) |
| 16:11 | SagiCZ1 | :) |
| 16:19 | justin_smith | well, I sure did call that one, time to wipe the test db again! |
| 16:58 | donbonifacio | I have a hash, with a lazy-seq somewhere, how can I find it |
| 17:00 | justin_smith | so it's a hash map with a lazy-seq inside it? |
| 17:00 | justin_smith | do you have a handle to that hash-map? |
| 17:01 | justin_smith | or maybe the better question is - where did this hash map and lazy seq come from, and what do you expect to find in them? |
| 17:03 | donbonifacio | I have a hash that I'm passing to monger, and it's complaining clojure.lang.LazySeq cannot be cast to java.lang.String |
| 17:04 | donbonifacio | I do have a key that's an array, I'm gessing that it can't convert that to a string and maybe it's calling it a LazySeq |
| 17:04 | justin_smith | I doubt it |
| 17:05 | justin_smith | you could use clojure.walk/postwalk |
| 17:09 | justin_smith | ,(clojure.walk/postwalk (fn [el] (when (isa? (type el) clojure.lang.LazySeq) (println el)) el) {:a 0 :b 1 :c {:d (range 10)}}) |
| 17:09 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk> |
| 17:10 | justin_smith | maybe something like that? but there is probably a more elegant way to do it |
| 17:10 | justin_smith | ,(require 'clojure.walk) |
| 17:10 | clojurebot | nil |
| 17:10 | justin_smith | ,(clojure.walk/postwalk (fn [el] (when (isa? (type el) clojure.lang.LazySeq) (println el)) el) {:a 0 :b 1 :c {:d (range 10)}}) |
| 17:10 | clojurebot | (0 1 2 3 4 ...)\n{:a 0, :b 1, :c {:d (0 1 2 3 4 ...)}} |
| 17:18 | justin_smith | ,(do (clojure.walk/postwalk (fn [el] (when (isa? (type el) clojure.lang.LazySeq) (println el)) el) {:a 0 :b 1 :c {:d (range 10)}}) nil) ; a little more clear maybe? |
| 17:18 | clojurebot | (0 1 2 3 4 ...)\n |
| 17:27 | irctc | Would anyone have any idea why my tiny Clojure server will not read from a Socket before the Python Client closes its own socket. -> gist https://gist.github.com/KristoKoert/3d1aa3ccd90a8bfcc341 |
| 17:30 | justin_smith | irctc: how do you know the clojure code is not reading? |
| 17:32 | justin_smith | are you developing inside an editor by any chance? because your defns are in the wrong order |
| 17:33 | irctc | I had a load of printlns in between every step, The server executed till the comment i left. At the same time the python server continued sending its message until I exit the python script and once I exit it all the messages are recieved and the Clojure program continues as expected (will read every time), but will not hear the client if I try reconnecting. |
| 17:34 | irctc | It might be that my python script is wrong as well.. |
| 17:34 | irctc | Inside emacs, I am just trying it out, so evaling :) |
| 17:35 | justin_smith | irctc: using cider? |
| 17:35 | justin_smith | look for an *nrepl-connection* buffer - that should get your .println output |
| 17:36 | irctc | Yes, cider. |
| 17:36 | justin_smith | yeah, the way emacs/cider/clojure handle stdout is way weird, some things from threads go in the wrong buffer due to dynamic binding and how that works when spawning threads |
| 17:37 | irctc | Actually I DO get all the messages and I have the cider repl open and see them in there. But the problem is that the messages only come through AFTER I stop the Python script. For whatever reason.. |
| 17:37 | irctc | And all of them at the same time. |
| 17:39 | justin_smith | oh, sorry, yeah |
| 17:39 | justin_smith | is that python code sending full lines? |
| 17:40 | justin_smith | because .readLine might be waiting for a newline |
| 17:40 | justin_smith | maybe socket.send does not insert newlines? |
| 17:40 | irctc | Oh? I will try that right now! |
| 17:40 | justin_smith | actually I would be surprised if it did |
| 17:45 | irctc | Nice, it worked! Great, a really simple mistake... Thanks guys :) |
| 17:49 | justin_smith | np |
| 18:22 | justin_smith | is there a paredit command that is like C-t but for list elements and not characters? |
| 18:22 | justin_smith | so if I have [a b |c d] and I run that command, it should become [a c b |d] |
| 18:23 | Bronsa | justin_smith: isn't that transpose-sexps? |
| 18:24 | justin_smith | Bronsa: probably, I didn't find it on my paredit cheat-sheet |
| 18:24 | Bronsa | justin_smith: don't think it's a paredit function |
| 18:25 | justin_smith | Bronsa: yeah, it kind-of works, but totally doesn't respect hash-map structure |
| 18:25 | justin_smith | but better than nothing |
| 18:25 | Bronsa | justin_smith: yeah looks like it's in emacs and bound to C-M-t |
| 18:25 | justin_smith | yeah |
| 18:27 | annelies | oh the joy of writing code in Java |
| 18:49 | amalloy | justin_smith: doesn't respect hash-map structure how? |
| 18:49 | justin_smith | it transposes keys and values separately, not as a pair |
| 18:49 | justin_smith | not that it would be reasonable to expect that I guess |
| 18:50 | justin_smith | maybe I will write a nice dwim that moves key value pairs forward and back in hashmap literals |
| 18:50 | justin_smith | and otherwise acts just like transpose-sexps |
| 19:38 | annelies | I am going to sleep ladies and gentlemen. |
| 19:38 | Bronsa | bye |
| 19:38 | annelies | goodbye |
| 19:41 | annelies | There is get and get-in, assoc and assoc-in, and update-in, but why not update? |
| 19:41 | andyf | annelies: There will be in Clojure 1.7 |
| 19:41 | Bronsa | annelies: update has been added in 1.7 |
| 19:41 | annelies | Nice. :) |
| 19:42 | andyf | you ask interesting questions while you sleep :) |
| 19:43 | annelies | I also really wish numerator and denominator worked on integers. :c There's a bug report of it already though. |
| 19:43 | andyf | have you voted for it? |
| 19:43 | annelies | Yeah |
| 19:44 | andyf | Then except for encouraging others to vote on it and writing a patch that works, you've done all you can :) |
| 19:45 | Bronsa | in my experience, a ticket with no patch will hardly get considered unless it's a serious bug |
| 19:49 | andyf | Bronsa: I think it matters more whether Rich or a screener like Alex think the description is something they agree is a problem, not whether there is currently a patch. |
| 19:50 | andyf | A screener triaging a ticket, or Rich vetting one, seem to me to have little to do with the presence/absence of a patch, but I'm guessing based on watching, not knowing. |
| 19:50 | Bronsa | andyf: I would like to agree with you but I'm pretty sure there is a *large* number of valid tickets that have never been seen by Rich or by any screener |
| 19:51 | andyf | Alex Miller has seen every one multiple times, I'm sure. |
| 19:52 | andyf | Summer 2013 he checked and/or updated the state of every single open ticket, and he's vetted about 1/5 of the open ones. |
| 19:52 | andyf | sorry, triaged, not vetted |
| 19:52 | justin_smith | andyf: is 0.1.5 the latest eastwood available from maven? |
| 19:52 | andyf | justin_smith: yes |
| 19:52 | justin_smith | cool, thanks |
| 19:52 | justin_smith | so this does not have the from-repl stuff you talked about recently, right? |
| 19:52 | andyf | You can check on clojars.org for any project hosted there what all version are that have been released, fyi, but I don't mind answering. |
| 19:53 | justin_smith | OK |
| 19:53 | andyf | It can be run from the REPL, and you don't need Leiningen. |
| 19:53 | justin_smith | oh, cool |
| 19:53 | andyf | Instructions here: https://github.com/jonase/eastwood#running-eastwood-in-a-repl |
| 19:53 | andyf | With I hope appropriate and not-too-scary warnings |
| 19:54 | justin_smith | andyf: I had assumed, given the big version difference between github and clojars, that the newer feature was not available or maybe I just wasn't finding it |
| 19:54 | andyf | Don't do it in a live production JVM is the most important warning. |
| 19:54 | justin_smith | right, I wouldn't need that anyway, thanks |
| 19:54 | andyf | Oh, you mean the 0.2.0-SNAPSHOT on github? |
| 19:54 | justin_smith | right |
| 19:55 | justin_smith | that's what confused me |
| 19:55 | andyf | That is not binding, but I am hoping it encourages me to add the feature for source code annotations to disable linters on a per-file and/or per-expression basis, which I consider worth bumping the version to 0.2.0 when released. |
| 19:56 | annelies | well, time to really sleep |
| 19:56 | annelies | goodbye! <3 |
| 19:56 | andyf | I'm doing development on master. You have to checkout a version-specific tag if you want to see source code for a specific release (or unzip the jar) |
| 19:57 | Bronsa | andyf: eh well, updating the status of a ticket doesn't mean it has been considered, it's just maintainance from my POV. there are a lots of "dead" tickets (i.e. that see no activity whatsoever) in jira |
| 19:58 | andyf | I'm gradually becoming accustomed to taking the long view, e.g. 5 years out :) |
| 19:58 | justin_smith | andyf: thanks. This message is confusing (caused by a misnamed file that I forgot to delete) - is it worth filing a ticket for? https://www.refheap.com/92941 |
| 19:58 | Bronsa | andyf: I'm not criticizing Alex's work btw, the process is just really frustrating sometimes |
| 19:59 | andyf | Understood. Paraphrasing Sir Lawrence of Arabie from the movie, the trick is not minding that it takes the time it does :) |
| 19:59 | andyf | Arabia, even. |
| 20:00 | Bronsa | andyf: it's counterproductive though. Say I open a ticket and attach a patch and that ticket doesn't get considered until 2 years later when the patch doesn't apply anymore |
| 20:00 | Bronsa | in the meantime I've lost interest in clojure and/or don't use it anymore for my work and I'm not going to update the patch, and the ticket becomes stale |
| 20:00 | andyf | Bronsa: That is the same situation we would be in even if all of the other 400 open tickets were considered before that ticket's patch -- most likely it wouldn't apply cleanly any more |
| 20:01 | justin_smith | andyf: update with suggested replacement message https://www.refheap.com/92941 |
| 20:02 | andyf | justin_smith: Sure, open a ticket for that. The message you see now is correct, but I agree a bit verbose for the common special case you have. |
| 20:02 | Bronsa | andyf: I'm not sure it would be this bad. consider patch 1 that affects file a and patch 2 that affects the same file is written 3 months later |
| 20:03 | Bronsa | andyf: if patch 1 has been merged within the 3 months period, patch 2 will be writte on top of patch 1 and will apply cleanly |
| 20:03 | justin_smith | andyf: the "has namespace" / "should have namespace" are identical, which I thought may have been a bug. I'll file it as a suggestion. |
| 20:03 | Bronsa | andyf: if patch 1 has not been merged, patch 1&2 will conflict and once one gets merged the other will not apply anymore |
| 20:04 | andyf | justin_smith: I'd call it a confusing message, to be sure, and worth a special case in the code that prints the messages. |
| 20:04 | andyf | justin_smith: that sentence fragment combined with the "or should be in file" are technically correct, where it is really the second part after the or that is true in this instance. I'm all for clearer warning messages. |
| 20:05 | justin_smith | cool, thanks |
| 20:06 | andyf | Bronsa: We are not alone in wishing the process went faster sometimes. To me, the heart of the issue is: our wishes do not trump someone else's free will in choosing what they do with their time. |
| 20:08 | andyf | Another way of looking at it is this: ~8 years after first working on the project, the creator still spends a chunk of his free time every month enhancing it. i.e. it is not abandoned. |
| 20:10 | andyf | And, he adds things to it like transducers, rather than restricting himself to considering problem reports that have been created by others. |
| 20:11 | Bronsa | andyf: I envy your ability to feel this way knowing the amount of time you spend around JIRA and noticing the (mostly) lack of activity around it by any core member other than Alex |
| 20:12 | andyf | Bronsa: I would not have spoken like this 2 years ago. It is an acquired attitude :) |
| 20:13 | Bronsa | andyf: I don't see your last point as a positive thing. To me that shows exactly how little issues reported by community members are valued |
| 20:13 | andyf | In the mean time, I think you are having a big impact on projects like core.typed, core.async, Eastwood, and whatever else tools.analyzer.* are getting use in. |
| 20:15 | andyf | Bronsa: I don't know exactly how much time is spent by who on what, but I get the distinct impression that if all they did was focus on tickets from community members, they wouldn't have time/energy left for adding cool new stuff. |
| 20:16 | andyf | Bronsa: Out of curiosity, do you know of any other projects besides the ones I mentioned using tools.analyzer? |
| 20:17 | Bronsa | andyf: crossclj uses t.a AFAIK |
| 20:17 | andyf | Oh, yeah. That site is amazing. |
| 20:19 | andyf | Francesco even found and fixed an issue I reported recently, where many of the "this var is used in places x, y, z, ..." had a bug in it. |
| 20:19 | Bronsa | it is indeed. my only complaint is that the UI feels a bit too "heavy" sometimes |
| 20:22 | Bronsa | andyf: ah, nrepl-refactor or however it's called uses t.a too. not sure if in a released version or a still in dev |
| 20:25 | andyf | I bet the list will grow as more people think of uses for it. Hats off to you, my friend. |
| 20:26 | justin_smith | (inc andyf) |
| 20:26 | lazybot | ⇒ 5 |
| 20:26 | justin_smith | eastwood is awesome, thanks |
| 20:26 | justin_smith | I just regret I didn't start using it sooner |
| 20:27 | Bronsa | (inc andyf) |
| 20:27 | lazybot | ⇒ 6 |
| 20:28 | andyf | Got to go for a while. Talk to you folks later. |
| 20:28 | Bronsa | have some internet points. I'll need yo buy you a beer if we ever get the chance to meet, for having my back when I break things |
| 20:30 | andrewhr | Bronsa: maybe a stupid question, but there is any work around a t.e.js? found only the t.e.jvm |
| 20:31 | Bronsa | andrewhr: no and I honestly have no interested in forking the cljs compiler to adapt its emitter to compiler t.e.js's AST rather than cljs.analyzer's one |
| 20:32 | andrewhr | *you* don’t have any interest or the *community* don’t see any value with that? |
| 20:33 | nonuby | destructing question, i dont what the difference is between defn x [handlers] and defn x [[& handlers]] |
| 20:33 | andrewhr | btw, I’m just asking to you bc your work with t.e.jvm |
| 20:34 | andrewhr | not want to mean anything bad, please |
| 20:35 | Bronsa | andrewhr: *I* don't have interest nor time, and I guess neither does the community. There's not much value in another cljs compiler, t.a.js otoh is valuable because it is (in my biased opinion) a lot more powerful than cljs.analyzer |
| 20:35 | amalloy | nonuby: the second version is just silly |
| 20:36 | amalloy | you are correct in implying that there is no difference |
| 20:36 | Bronsa | amalloy: there is though, the first will accept "1", the second won't |
| 20:36 | amalloy | well, yes |
| 20:36 | Bronsa | it's a silly way to assert (coll? arg) |
| 20:36 | amalloy | and the second will convert [] to nil |
| 20:36 | Bronsa | wut? |
| 20:36 | nonuby | so its like some form of weak typing checking... ah you said first |
| 20:36 | amalloy | won't it? |
| 20:37 | Bronsa | no idea |
| 20:37 | amalloy | ,((fn [[& xs]] xs) []) |
| 20:37 | clojurebot | nil |
| 20:37 | amalloy | Bronsa: because & destructuring never returns an empty seq, only nil or non-empty |
| 20:37 | Bronsa | TIL |
| 20:37 | nonuby | amalloy, cool. thanks just something i noticed on compojure.core/routes |
| 20:38 | andrewhr | Bronsa: thanks. just want to know how the clj(s) community feels about that |
| 20:38 | Bronsa | amalloy: do you happen to know if that was a conscious decision or an accident of the impl? |
| 20:38 | amalloy | Bronsa: i believe it's a legacy of the time when there was no such thing as a non-empty seq |
| 20:39 | Bronsa | and/or if there's an obvious reason why it doesn't return () that I'm missing |
| 20:39 | amalloy | it's a decision that i really wish we could undo |
| 20:39 | amalloy | er, no such thing as an empty seq |
| 20:40 | Bronsa | andrewhr: well I'm not the right person to ask such a thing then :) I'm not really part of the cljs sub-community |
| 20:41 | amalloy | the problem is that it means you should never use & xs destructuring in a lazy function. consider this reasonable implementation of map: (fn map [f xs] (lazy-seq (when-let [[x & xs] (seq xs)] (cons (f x) (map f xs))))) |
| 20:41 | amalloy | it looks correct, but because xs will never be nil, you end up forcing one more element of the input collection than the user asks for |
| 20:41 | andrewhr | Bronsa: still think it’s a valulable opinion :) |
| 20:43 | andrewhr | another shot for you: t.a is capable of doing some kind of incremental analysis? let’s say - to use it for making some kind of code highlight for example |
| 20:43 | Bronsa | amalloy: makes sense, thanks |
| 20:47 | Bronsa | andrewhr: t.a assumes fully evaluated env but there are ways to analyzing code w/o evaluating it, even though that requires a bit of configuration & the analysis might be inaccurate |
| 20:47 | Bronsa | andrewhr: not sure if that's what you were asking me though |
| 20:49 | andrewhr | Bronsa: so you will only be able to really analyze code in a “live runtime”, if I get it right |
| 20:49 | andrewhr | (in a precise way) |
| 20:49 | Bronsa | andrewhr: in t.a.jvm yes. for cljs it's a bit different because it has no resident compiler & reified namespaces |
| 20:50 | andrewhr | got it |
| 20:50 | andrewhr | thanks again! |
| 20:51 | Bronsa | andrewhr: silly example, "(defmacro foo [] (list 'def 'bar 1)) (foo) bar", the analyzer has no way to know that "bar" refers to a var if you don't evaluate the defmacro expr and it's invocation before analyzing the symbol "bar" |
| 20:53 | Bronsa | andrewhr: I mean, there are certainly techniques it could use to figure it out in this case, but that's out-of-scope for t.a |
| 21:01 | andrewhr | Bronsa: I see. requiring a live environment will not be a true problem for what I have in mind |
| 21:08 | puredanger | Bronsa (and andyf ) : just browsing the back chat. just fyi, the ticket situation is frustrating for me too. |
| 21:08 | dc_ | whats the best way to combine two lists in clojure like this: [1 2 3] [4 5 6] => [[1 4][2 5][3 6]] |
| 21:08 | dc_ | like is there a function that does that? |
| 21:08 | godd2 | interleave? |
| 21:08 | hyPiRion | ,(apply map list [[1 2 3] [4 5 6]]) |
| 21:09 | clojurebot | ((1 4) (2 5) (3 6)) |
| 21:09 | dc_ | ahh ok yep, that's what i'm looking for |
| 21:09 | hyPiRion | If you want vectors |
| 21:09 | hyPiRion | ,(apply mapv vector [[1 2 3] [4 5 6]]) |
| 21:09 | clojurebot | [[1 4] [2 5] [3 6]] |
| 21:09 | dc_ | godd2 hipirion: thanks |
| 21:09 | hyPiRion | np |
| 21:10 | Bronsa | puredanger: yeah I don't find it hard to believe that. I'm sorry if you've been named in my small rant but I assure you I that I (and I hope to talk for most of the community) really apprecciate your work |
| 21:10 | puredanger | I do what I can |
| 21:11 | godd2 | ,(map vector [1 2 3] [4 5 6]) |
| 21:11 | clojurebot | ([1 4] [2 5] [3 6]) |
| 21:11 | godd2 | oh I see that doesn't return a vector |
| 21:12 | godd2 | ,(mapv vector [1 2 3] [4 5 6]) |
| 21:12 | clojurebot | [[1 4] [2 5] [3 6]] |
| 21:25 | smnirven | okay folks, let's say I have a sequence of maps, and I want to call a certain function once for every map in the sequence, but for use in the -> macro |
| 21:27 | smnirven | any ideas on how i might accomplish that? |
| 21:28 | Bronsa | smnirven: you want to map inside a -> expression? |
| 21:28 | smnirven | yeah something like that |
| 21:29 | Bronsa | you can do (-> coll ... (as-> coll (map f coll)) ..) |
| 21:29 | TEttinger | (doc as->) |
| 21:29 | Bronsa | smnirven: assuming you can't use ->> |
| 21:29 | clojurebot | "([expr name & forms]); Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form." |
| 21:30 | justin_smith | ,(-> [{:a 0 :b 1} {:a 1 :b 2}] (#(map :a %))) ; another option |
| 21:30 | clojurebot | (0 1) |
| 21:31 | TEttinger | ,(-> [{:a 0 :b 1} {:a 1 :b 2}] ((partial map :a))) ; yet another option |
| 21:31 | clojurebot | (0 1) |
| 21:32 | smnirven | ahh, partial might be the ticket here |
| 21:32 | Bronsa | justin_smith: I find that really ugly |
| 21:33 | justin_smith | ,(-> [{:a 0 :b 1} {:a 1 :b 2}] (->> (map :a))) ; yet another |
| 21:33 | clojurebot | (0 1) |
| 21:33 | Bronsa | whenever I find myself wanting to (-> .. (#(..))) I just lift the lambda in a let over the -> expr |
| 21:33 | TEttinger | that last one looks like a winner, justin_smith |
| 21:34 | justin_smith | TEttinger: and of course it can bump up a level again if you need -> again |
| 21:34 | Bronsa | and I also tend to avoid nesting ->/->>/doto as that gets unreadable pretty fast :P |
| 21:34 | smnirven | let's say the collection coll [{:a 1} {:a 2}] |
| 21:35 | smnirven | I want to insert the same function in an existing thread macro once for each map in that collection |
| 21:35 | smnirven | (-> orig (f1) (f2 {:a 1}) (f2 {:a 2}) |
| 21:36 | smnirven | trying to figure out how to do that with any number of maps in that collection |
| 21:36 | justin_smith | smnirven: that does not work in general unless you know the maps (or at least how many there are) when the macro is expanded |
| 21:36 | TEttinger | that sounds like a different use case |
| 21:37 | Bronsa | smnirven: are you sure you want (f2 (f2 (f1 orig) {:a 1}) {:a 2})? |
| 21:38 | smnirven | Bronsa: yep |
| 21:40 | Bronsa | that's (reduce f2 (f1 orig) [{:a 1} {:a 2}]), I wouldn't really insert it in a -> expr |
| 21:40 | smnirven | there's a pretty good chance im attacking this in the wrong way entirely -- basically im trying to compose a sqlkorma select with the possibility of multiple joins |
| 21:55 | arrrms | What are people's opinions on the Web Development with Clojure book? There are only two Amazon reviews (http://www.amazon.com/Web-Development-Clojure-Build-Bulletproof/dp/1937785645/ref=sr_1_1?ie=UTF8&qid=1415500923&sr=8-1&keywords=clojure+web+development) |
| 22:19 | godd2 | Is there a way to have lein repl print out transients in a prettier way? |
| 22:20 | gfredericks | godd2: check out print-method |
| 22:20 | gfredericks | ,(transient [1 2 3]) |
| 22:20 | clojurebot | #<TransientVector clojure.lang.PersistentVector$TransientVector@13c422e> |
| 22:21 | gfredericks | ,(defmethod print-method clojure.lang.TransientVector [tv pw] (print-method (into [] (map #(get tv %) (range (count tv)))) pw)) |
| 22:21 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: clojure.lang.TransientVector, compiling:(NO_SOURCE_PATH:0:0)> |
| 22:21 | gfredericks | ,(defmethod print-method clojure.lang.PersistentVector$TransientVector [tv pw] (print-method (into [] (map #(get tv %) (range (count tv)))) pw)) |
| 22:21 | clojurebot | #<MultiFn clojure.lang.MultiFn@18eaab5> |
| 22:21 | gfredericks | ,(transient [1 2 3]) |
| 22:21 | clojurebot | [1 2 3] |
| 22:21 | godd2 | oh wow |
| 22:21 | gfredericks | or if you want it to be less ambiguous |
| 22:21 | godd2 | did you just change clojurebot for good? (or at least for a while) |
| 22:22 | gfredericks | ,(defmethod print-method clojure.lang.PersistentVector$TransientVector [tv pw] (.write pw "#transient ") (print-method (into [] (map #(get tv %) (range (count tv)))) pw)) |
| 22:22 | clojurebot | #<MultiFn clojure.lang.MultiFn@18eaab5> |
| 22:22 | gfredericks | ,(transient [1 2 3]) |
| 22:22 | clojurebot | #transient [1 2 3] |
| 22:22 | godd2 | I like that even more |
| 22:22 | gfredericks | godd2: I think it'll reboot after 10 minutes or something |
| 22:23 | godd2 | Where should I put code for lein repl to run as it's booting up? |
| 22:23 | godd2 | in a dependency? |
| 22:24 | justin_smith | godd2: clojure will load user.clj |
| 22:24 | justin_smith | src/user.clj for example |
| 22:24 | justin_smith | more detail here http://dev.solita.fi/2014/03/18/pimp-my-repl.html |
| 22:25 | godd2 | yay! |
| 22:25 | minaminamina | Hey there! I was trying to write a cljs library that I could deploy to clojars, and require in another project. The library is written, it's simple, and it works, but when I try to require it somewhere else, the only visible namespace is my-namespace.core |
| 22:25 | minaminamina | Would anyone mind looking at the project.clj file to see what I'm doing wrong? |
| 22:25 | smnirven_ | link plz |
| 22:26 | minaminamina | https://github.com/minasmart/squelch/blob/master/project.clj |
| 22:27 | minaminamina | including it in the dependencies section of another project doesn't produce errors, but trying to require anything other than squelch.core makes it complain: WARNING: No such namespace: squelch.audio-context at line 1... |
| 22:27 | justin_smith | minaminamina: you have - in your file names |
| 22:28 | smnirven_ | yep thats it |
| 22:28 | justin_smith | clojure cannot find files named that way |
| 22:28 | smnirven_ | underscores to the rescue |
| 22:28 | minaminamina | OK, I was wondering about that. Should they be underscored? |
| 22:28 | justin_smith | rename audio-context.clj to audio_context.clj |
| 22:28 | minaminamina | Then should namespaces be named with hyphens or underscores? |
| 22:28 | justin_smith | yeah, the namespace can keep the same name, just rename all the files |
| 22:28 | smnirven_ | filenames should be underscored, but the namespace names can still be hypens |
| 22:28 | justin_smith | so ns is audio-context, file is audio_context |
| 22:29 | minaminamina | For namespace naming, what is more typical? Hyphen or underscore? |
| 22:29 | justin_smith | minaminamina: there is a nice tool called eastwood (a lein plugin) that detects these kinds of issues |
| 22:29 | justin_smith | hyphen is preferred for namespaces |
| 22:29 | justin_smith | but it has to be underscore in the file |
| 22:29 | minaminamina | OK, cool! And thanks Justin! I'll check out that plugin! |
| 22:29 | minaminamina | Thanks alot! |
| 22:30 | justin_smith | np |
| 22:49 | grandy | i'm new to clojure and a bit confused about how to use sessions in compojure, anyone know of a public repo that does this? |
| 22:50 | godd2 | how do you get the keys from a transient hashmap? |
| 22:50 | godd2 | ,(keys (transient {:a 1 :b 7})) |
| 22:50 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.PersistentArrayMap$TransientArrayMap> |
| 22:52 | justin_smith | grandy: https://www.refheap.com/92948 you can use this definition as a middleware foar a cookie session |
| 22:53 | grandy | justin_smith: thanks! |
| 22:53 | justin_smith | that uses ring.middlware.session/wrap-session |
| 22:53 | justin_smith | there are other options for in-memory rather than server sessions |
| 22:53 | grandy | justin_smith: dumb question but how do I set the session to {:hello "world"} |
| 22:53 | justin_smith | of course you probably want to fix the key, cookie-name, max-age |
| 22:54 | verma | how do I run the jar chestnut gives me? just doing a java -jar app.jar doesn;t seem to work, |
| 22:54 | justin_smith | grandy: in your handler create a response map, with {:body "text of page" :status 200 :session {:hello "world}} |
| 22:54 | verma | it just drops me into a clojure repl |
| 22:54 | grandy | justin -- I tried that but then I removed it and refreshed the page and it was gone from the session data, |
| 22:55 | justin_smith | verma: you can specify a class / method to run, if you have a -main defined and aot compile that namespace |
| 22:56 | justin_smith | grandy: with the middleware set up properly, you should see the same data come in under :request |
| 22:56 | grandy | hmm |
| 22:56 | justin_smith | grandy: you need to watch out for accidentally attaching a null :session in between of course |
| 22:56 | verma | justin_smith, :uberjar profile says :aot :all, so I guess it'd be aot compiled, I am also not sure what the command line would look like |
| 22:57 | justin_smith | verma: if your main ns is set up properly (such that lein run works) the compiled jar will work too |
| 22:57 | grandy | justin_smith: this is my handler, do you see anything obviously wrong with it? quite possible there is something very dumb going on: https://gist.github.com/mmmurf/0cfe722ad60c47c34b1f |
| 22:57 | verma | justin_smith, oh let me try lein run |
| 22:57 | justin_smith | you aren't returning the right thing |
| 22:58 | justin_smith | grandy: you are passing the session as the response map |
| 22:58 | justin_smith | you want to pass the session INSIDE the response map |
| 22:58 | verma | justin_smith, does the class with -main needs to have :gen-class, I was just wondering since chestnut didn't do that |
| 22:58 | grandy | justin_smith: hmm I think I have to review the signatures that are going on there... I'll try w/ a simple text response |
| 22:58 | justin_smith | grandy {:body [:body ...] :session (assoc (:session params) :count 1)} |
| 22:59 | justin_smith | grandy: you need to put what you were previously returning into the :body key |
| 22:59 | justin_smith | right now, [:body ...] inside common is doing nothing, it's just a data literal that is not used or returned by the function |
| 22:59 | grandy | justin_smith: ahh so {:body is not a hiccup function it's a map for ring? |
| 23:00 | amalloy | grandy: yes |
| 23:00 | justin_smith | grandy: yes, ring accepts multiple return values |
| 23:00 | amalloy | justin_smith: how do you mean? |
| 23:00 | justin_smith | if you specify a string, that becomes the page body, if you return a map, the :body key is used for that |
| 23:00 | justin_smith | amalloy: just that it is polymorphic on what you return to it |
| 23:00 | grandy | justin_smith: ahh ok, so does this mean that in my compojure code all handlers that update hte session need to return a map? |
| 23:01 | justin_smith | right |
| 23:01 | justin_smith | amalloy: I should have said "accepts multiple return types" |
| 23:01 | grandy | justin_smith: ahh ok i see, now it is starting to make sense |
| 23:02 | justin_smith | grandy: and I was wrong above, you want {:body (common [:body ...]) :session ...} in the response map |
| 23:02 | justin_smith | or bind the rendered result of common in a let, of course |
| 23:02 | grandy | justin_smith: ok cool I think I've done that... |
| 23:03 | grandy | justin_smith: https://gist.github.com/anonymous/586bf33aea6347999969 |
| 23:03 | justin_smith | verma: you can specify an arg that says run clojure.core and then another arg that tells clojure.core to run a specific function in a specific ns - one moment, I need to find it |
| 23:04 | justin_smith | grandy: yeah, that looks about right |
| 23:04 | verma | justin_smith, nice! I actually tried to run lein run and it had problems, so I fixed those and running a lein uberjar right now |
| 23:04 | verma | 51seconds to compile clojurescript :( |
| 23:05 | grandy | justin_smith: oddly it's not persisting |
| 23:06 | justin_smith | grandy: so :count 1 is not coming in on the next load? |
| 23:06 | grandy | justin_smith: correct, not if I comment out line 8 above |
| 23:07 | justin_smith | grandy: and you have the ring-session middleware in place? |
| 23:07 | grandy | justin_smith: in other words, the line that prints the session (line 5 above) prints {} |
| 23:07 | grandy | justin_smith: [ring.middleware.session :refer :all] |
| 23:07 | justin_smith | that requires the session, are you putting it in your middleware? |
| 23:07 | grandy | https://www.irccloud.com/pastebin/INl3FSu0 |
| 23:08 | grandy | I think so, see the paste |
| 23:08 | justin_smith | OK, you might want add some arguments to wrap-session |
| 23:08 | justin_smith | also check in your browser if the cookie is being created |
| 23:08 | grandy | justin_smith: ahh good idea |
| 23:09 | justin_smith | maybe create an unencrypted cookie while debugging |
| 23:09 | justin_smith | verma: java -cp foo.jar clojure.main -m foo |
| 23:09 | justin_smith | where foo/-main is the main function |
| 23:10 | justin_smith | verma: you may not need that, but the advantage there is you don't need any aot for that to work |
| 23:10 | justin_smith | clojure finds and loads your code |
| 23:11 | zerkms | guys, could you please give me some hints about how idiomatically implement a file reader that would read all the lines that are added in runtime (which is more or less obvious) with ability to gracefully stop it |
| 23:14 | justin_smith | zerkms: basic idea is to create a file reader using clojure.java.io (io/reader (io/file "name")) and then you have a few options, probably easiest is to put it in a future, (def reader-thread (future (while (not (.isInterrupted (Thread/currentThread))) (.readLine reader)))) |
| 23:14 | justin_smith | then you can call (future-cancel reader-thread) if you want it to stop |
| 23:14 | justin_smith | and probably you want to do something with the return value of .readLine of course :) |
| 23:15 | zerkms | I've head similar thoughts |
| 23:15 | zerkms | but |
| 23:15 | zerkms | .readLine is blocking |
| 23:15 | justin_smith | yeah, put it in a future |
| 23:15 | zerkms | what? (.readlLine reader)? |
| 23:15 | justin_smith | zerkms: the whole loop, like I did above |
| 23:15 | grandy | justin_smith: hmm do you see anything wrong w/ this? |
| 23:15 | grandy | https://www.irccloud.com/pastebin/rqHj35ln |
| 23:16 | justin_smith | or, use polling and non-blocking read |
| 23:16 | justin_smith | polling is guaranteed more complex though, of course |
| 23:17 | justin_smith | grandy: that isn't a valid key I don't think - the number of X in my example was exactly the number of characters that need to be in the key |
| 23:17 | zerkms | I see, so in your solution you don't immediately terminate .readLine() but just don't care if it's still there in memory awaiting for next line |
| 23:17 | grandy | justin_smith: ahh ok |
| 23:18 | justin_smith | zerkms: well, it checks if the thread is interrupted (future-cancel will do the thread-interruption for you) |
| 23:18 | zerkms | justin_smith: for the check to occurr a next line should arrive |
| 23:19 | justin_smith | right, polling is more complicated, but also possible |
| 23:19 | zerkms | ok |
| 23:19 | justin_smith | zerkms: like adding an if based on whether data is available, and a sleep if it isn't |
| 23:19 | justin_smith | then you are guaranteed to check the condition more often |
| 23:20 | zerkms | I'm not caviling (not sure if it's a correct word here, cannot find better in my dictionary) - just pretty newbie with clojure so want to make sure I'm not missing something basic |
| 23:20 | verma | justin_smith, nice! that seems to work great! thanks for your help |
| 23:20 | verma | (inc justin_smith) |
| 23:20 | lazybot | ⇒ 120 |
| 23:20 | justin_smith | zerkms: and you just need to look out for the pathological condition where there is data, but it freezes in the middle of giving you a line |
| 23:20 | justin_smith | verma: which one, the fixing lein run, or specifying the main class? |
| 23:21 | zerkms | honestly I tried implementing polling then realized the code looks like java |
| 23:21 | justin_smith | heh |
| 23:21 | justin_smith | there isn't much purely functional about a polling loop |
| 23:22 | zerkms | tried to reimplement simplified http://commons.apache.org/proper/commons-io/apidocs/src-html/org/apache/commons/io/input/Tailer.html which is I find nice implementation for this task (in java though) |
| 23:22 | verma | justin_smith, oh actually chestnut comes with a Procfile which had the exact same command :P |
| 23:22 | justin_smith | zerkms: there is java.nio.* too, I don't have a whole lot of experience with it though |
| 23:23 | justin_smith | verma: haha, nice |
| 23:23 | justin_smith | verma: so I could have just said rtfpf |
| 23:23 | verma | justin_smith, totally :P |
| 23:24 | zerkms | " java.nio.* too" --- yep, I deliberately want to do that as much manually as possible, as a person who only read A LOT and watched A LOT of different things about clojure but have written < 100 lines in total in clojure |
| 23:24 | justin_smith | grandy: small thing about your last paste, the comment about (:session session) isn't quite accurate, for what it's worth - you probably meant (:session params), but that's just a nitpick |
| 23:25 | justin_smith | zerkms: interop isn't super hard, and this is the sort of thing clojure just doesn't have a simple clojure-wrapped solution for |
| 23:25 | justin_smith | sorry |
| 23:25 | grandy | justin_smith: please do nitpick, this is my first clojure project so I need to be informed of any/all stupidity :) |
| 23:25 | zerkms | (inc justin_smith) |
| 23:25 | lazybot | ⇒ 121 |
| 23:25 | grandy | justin_smith: ok so now it works nearly as expected, with the following three handlers: |
| 23:26 | zerkms | would it ban me if I inc myself? :-D |
| 23:26 | grandy | https://www.irccloud.com/pastebin/X5Wu3LCN |
| 23:26 | justin_smith | it'll just be sassy about it |
| 23:26 | grandy | justin_smith: those map to /session /session1 and /session2 |
| 23:26 | justin_smith | grandy: cool |
| 23:27 | justin_smith | grandy: what's handy for this kind of thing is update-in / assoc-in |
| 23:27 | grandy | justin_smith: hmm how woudl I modify those? |
| 23:27 | justin_smith | ,(update-in {:session {:count 0}} [:session :count] inc) |
| 23:27 | clojurebot | {:session {:count 1}} |
| 23:27 | justin_smith | ,(update-in {:session {:count 0}} [:session :count-2] (fnil inc 0)) |
| 23:27 | clojurebot | {:session {:count-2 1, :count 0}} |
| 23:28 | justin_smith | grandy: update-in is pretty much perfectly designed for this kind of case (I intentionally burried :session deeper than needed to show how it digs in) |
| 23:29 | justin_smith | &*clojure-version* |
| 23:29 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 23:30 | verma | TIL fnil |
| 23:30 | justin_smith | fnil is my friend |
| 23:30 | justin_smith | (inc fnil) |
| 23:30 | lazybot | ⇒ 3 |
| 23:31 | grandy | justin_smith: thanks! |
| 23:31 | justin_smith | grandy: np, glad you figured it out |
| 23:36 | zerkms | justin_smith: cannot get it working :-( (while ...) blocks while not finished which is never |
| 23:37 | justin_smith | zerkms: did you put it in a future? |
| 23:37 | zerkms | yep, and whern I'm dereferencing it - it blocks |
| 23:37 | zerkms | since `while` works forever |
| 23:37 | justin_smith | yeah, deref is not what you want |
| 23:38 | justin_smith | unless you want it to be done, and get the return value |
| 23:38 | justin_smith | futures run whether you deref them or not |
| 23:38 | zerkms | yep, but how to get the value from it then |
| 23:38 | zerkms | a global atom would be ugly |
| 23:38 | justin_smith | zerkms: you could send the values to an agent or queue |
| 23:39 | justin_smith | or act on the data within the loop itself |
| 23:39 | zerkms | or that... doesn't look idiomatic hmm |
| 23:39 | zerkms | I thought it will be trivial to implement an infinite list |
| 23:39 | zerkms | s/list/sequence/ |
| 23:39 | Raynes | Well that's not great. |
| 23:41 | justin_smith | zerkms: hmm (defn f [handle] (when more-data (cons (read-available handle) (lazy-seq (f handle))))) |
| 23:41 | justin_smith | that's kind of like line-seq |
| 23:41 | justin_smith | maybe that's all you need? but line-seq will block too won't it? |
| 23:41 | zerkms | handle is the last resort for me, but yes |
| 23:53 | grandy | justin_smith: oddly it appears that it's not using the cookie params I am setting, it is also not using the name, therefore I think it is ignoring the configuration info for cookie sessions -- thoughts? |
| 23:53 | grandy | https://www.irccloud.com/pastebin/thNcygv4 |
| 23:56 | justin_smith | that looks right |