2013-05-03
| 00:00 | axle_512 | Raynes: Cool, I like it. I'll dig a little more into it and see if it's something I can use with my little scheduler |
| 00:00 | holo | (inc Raynes) |
| 00:00 | lazybot | ⇒ 28 |
| 00:05 | djwonk | (dec djwonk) |
| 00:05 | lazybot | You can't adjust your own karma. |
| 00:05 | djwonk | (inc danielglauser) |
| 00:05 | lazybot | ⇒ 1 |
| 00:05 | holo | thanks to Raynes, and numerous contributors for tryclj.com, my girlfriend could try programming without setting her hair on fire. she actually enjoyed it |
| 00:06 | djwonk | (inc clojurebot) |
| 00:06 | lazybot | ⇒ 21 |
| 00:06 | djwonk | (inc technomancy) |
| 00:06 | lazybot | ⇒ 53 |
| 00:06 | djwonk | (inc lazybot) |
| 00:06 | lazybot | ⇒ 18 |
| 00:07 | Raynes | holo: It's all a cunning plot to steal your girlfriend. |
| 00:09 | holo | she was sad there weren't more levels to solve though.. just imagine how many more girls are out there.. trying clojure |
| 00:09 | Raynes | Oh dear. I'll get right on it. |
| 00:10 | holo | :> |
| 00:11 | amalloy | holo: 4clojure.com? |
| 00:12 | holo | amalloy, she gave up on that one. not because of difficulty i think (some problems are indeed really easy), but because it was enough for the day |
| 00:14 | axle_512 | Raynes and amalloy: Read the code for chronicle. That is slick — I love the lazy seq of times that match the spec. |
| 00:15 | amalloy | it's good that you love it, because that is literally the only thing in chronicle |
| 00:15 | axle_512 | haha |
| 00:15 | axle_512 | simplicity is good |
| 00:15 | amalloy | yeah, i wrote it in an hour. now Raynes will market it for me |
| 00:24 | callen | Clojure: programming without the burning hair. |
| 00:26 | holo | Clojure: the fresh maker |
| 00:29 | arrdem | Clojure: macros for the JVM |
| 01:00 | technomancy | holo: let's film a series of advertisements |
| 02:38 | tomoj | should ring provide names for comp and #(comp %2 %1)? |
| 02:42 | tomoj | hmm, not #(comp %2 %1) |
| 02:45 | tomoj | oh, yeah. https://www.refheap.com/paste/163cd2a1090c780ac4b2b8ba2 |
| 02:46 | tomoj | I guess I can just keep writing those functions in many namespaces since it's just two lines.. |
| 02:52 | augustl | pjstadig: ah, the good old source :) |
| 02:52 | augustl | I guess clojure.core/addMethod could be considered a public and supported API |
| 02:54 | tomoj | hmm https://www.refheap.com/paste/765fc76fe098a715d6edd1239 |
| 02:56 | tomoj | oh that's just (def in-response ((in-args reverse) (partial partial comp))) |
| 03:55 | Glenjamin | tomoj: i don't quote follow the example at the bottom, where abouts in a ring app would you need this? |
| 03:57 | mindbender1 | what is cljs version of js/Array? |
| 03:57 | mindbender1 | this issue has been bugging me |
| 04:00 | tomoj | mindbender1: (array) ? |
| 04:00 | tomoj | what do you mean |
| 04:00 | tomoj | Glenjamin: anytime you want a middleware which just applies a function to the request or the response |
| 04:01 | Glenjamin | doesn't ring have separate request/response maps? or am i just blinkered by compojure here? |
| 04:01 | tomoj | yes |
| 04:01 | Glenjamin | ah, i see |
| 04:01 | tomoj | the example is not ring-conformant |
| 04:01 | mindbender1 | I mean something that allows me to insert anywhere and have the index re-ordered |
| 04:02 | tomoj | and also I was actually thinking of clj-http middleware.. is it the same for ring? |
| 04:02 | Glenjamin | ring has request map in, and response map out |
| 04:03 | tomoj | oh yeah, it's the same-ish |
| 04:03 | Glenjamin | (def app (fn [req] {:status 200, :body "Hello World", :headers {}})) |
| 04:04 | tomoj | mindbender1: hmm.. port clojure.core.rrb-vector ? |
| 04:04 | mindbender1 | let me see.. |
| 04:04 | Glenjamin | so middleware can either operate on req and pass it along, or call the wrapped function, operate on the returned response and pass it back |
| 04:04 | tomoj | then you'd have slice conj slice splice for an insert-at |
| 04:05 | tomoj | or maybe finger trees? |
| 04:05 | tomoj | no cljs version of that yet afaik either |
| 04:07 | tomoj | Glenjamin: yeah -- (fn [app] (fn [req] (app (f req)))) is comp, and (fn [app] (fn [req] (f (app req)))) is #(comp %2 %1) |
| 04:07 | tomoj | ..well, with the f param somewhere in there |
| 04:16 | ddellacosta | what's the best way to short-circuit an iteration? I mean, what kind of looping construct to use? filter is close, but I want something more like Ruby's detect: http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-detect |
| 04:16 | ddellacosta | I feel like I must be missing something obvious. |
| 04:16 | Glenjamin | ddellacosta: you probably want some |
| 04:17 | ddellacosta | Glenjamin: THAT'S what I've been looking for…thanks! |
| 04:17 | Glenjamin | ,(doc some) |
| 04:17 | clojurebot | "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)" |
| 04:17 | ddellacosta | yes, perfect. |
| 04:17 | ddellacosta | I always forget about "some." |
| 06:37 | augustl | I end up writing this function quite often: (defn assoc-if [m key value] (if value (assoc m key value) m)) |
| 06:38 | augustl | only assoc if the value is truthy. I use this for threading macro goodness, such as (-> base-data (assoc-if :some-key some-value)) |
| 06:38 | augustl | since assoc-if is not in core, and I find it insanely useful, I guess I'm "doing it wrong" :) Anyone got some favorite ways of doing hashmap building based on conditions? |
| 06:39 | tomoj | well there is (cond-> m value (assoc key value)) :/ |
| 06:41 | jballanc | ,(let [value true] (and value (assoc {} :test value))) |
| 06:41 | clojurebot | {:test true} |
| 06:41 | jballanc | I find 'and' and 'or' are underutilized...but that may just be me |
| 06:43 | tomoj | here they are not very helpful |
| 06:44 | jballanc | ah, I see...the hash should still be returned if value is false |
| 06:44 | jballanc | hmm... |
| 06:45 | jballanc | ,(let [value false m {:first "thing"}] (and (or value m) (assoc m :test value))) |
| 06:45 | clojurebot | {:test false, :first "thing"} |
| 06:45 | jballanc | oh, whoops |
| 06:45 | jballanc | hmmm... |
| 06:46 | jballanc | ,(let [value false m {:first "thing"}] (or (and value (assoc m :test value) m)) |
| 06:46 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 06:46 | jballanc | d'oh |
| 06:46 | jballanc | ,(let [value false m {:first "thing"}] (or (and value (assoc m :test value)) m)) |
| 06:46 | clojurebot | {:first "thing"} |
| 06:46 | tomoj | seems like a strange way to write (if value (assoc m :test value) m) :) |
| 06:46 | jballanc | there we go |
| 06:46 | jballanc | heh |
| 06:47 | tomoj | &(clojure.walk/macroexpand-all '(or (and value (assoc m :test value)))) |
| 06:47 | lazybot | ⇒ (let* [and__3822__auto__ value] (if and__3822__auto__ (assoc m :test value) and__3822__auto__)) |
| 06:47 | clgv | augustl: go for `cond->` as proposed |
| 06:48 | tomoj | oops |
| 06:48 | tomoj | &(clojure.walk/macroexpand-all '(or (and value (assoc m :test value)) m)) |
| 06:48 | lazybot | ⇒ (let* [or__3824__auto__ (let* [and__3822__auto__ value] (if and__3822__auto__ (assoc m :test value) and__3822__auto__))] (if or__3824__auto__ or__3824__auto__ m)) |
| 06:49 | jballanc | haha |
| 06:49 | jballanc | yeah, I keep forgetting that and/or are macros and if is the special form |
| 06:49 | tomoj | semantically equivalent in this case? |
| 06:50 | jballanc | I swear that's backward from one of the schemes I've used... |
| 06:50 | tomoj | I always think it's the other way too |
| 06:53 | augustl | thanks folks :) |
| 06:54 | augustl | why u not 1.5, http://clojure.org/cheatsheet ! |
| 06:55 | tomoj | (filter (comp #{"1.5"} :added meta) (vals (ns-publics (find-ns 'clojure.core)))) :) |
| 06:56 | tomoj | I just realized that that's fucking sweet |
| 06:58 | augustl | tomoj: ah, nice one :) |
| 07:12 | augustl | is zipmap "the best" way to map the values of a hashmap? |
| 07:12 | augustl | seems wasteful to create so many temporary collections |
| 07:13 | Velrok | Hi, quick question: |
| 07:14 | Velrok | I have some problems resolving a java class |
| 07:14 | Velrok | cern.colt.matrix.io.MatrixInfo.MatrixField |
| 07:14 | Velrok | CompilerException java.lang.ClassNotFoundException: cern.colt.matrix.io.MatrixInfo.MatrixField, compiling:(NO_SOURCE_PATH:1) |
| 07:14 | Velrok | (import (cern.colt.matrix.tint.impl SparseIntMatrix2D) |
| 07:14 | Velrok | (cern.colt.matrix.tdouble.impl SparseDoubleMatrix2D) |
| 07:14 | Velrok | (cern.colt.list.tint IntArrayList) |
| 07:14 | Velrok | (cern.colt.matrix.io MatrixVectorWriter |
| 07:14 | Velrok | MatrixVectorReader |
| 07:14 | Velrok | MatrixInfo |
| 07:14 | Velrok | MatrixSize) |
| 07:15 | Velrok | user=> cern.colt.matrix.io.MatrixInfo |
| 07:15 | Velrok | cern.colt.matrix.io.MatrixInfo |
| 07:15 | Velrok | works |
| 07:15 | brainproxy | Velrok: please use gist or refheap |
| 07:15 | noidi | augustl, (into {} (for [[k v] m] [k (f v)])) |
| 07:16 | noidi | where m is your map and f is the function to map over the values |
| 07:16 | augustl | noidi: ah, cool |
| 07:17 | noidi | that iterates over the entires in the map, destructuring them into a key and a value, and creating a vector that is close enough to a MapEntry that it can be stuffed into a new map |
| 07:17 | Velrok | as suggested here the code as gist: https://gist.github.com/Velrok/5508551 |
| 07:19 | Velrok | Do I have to change my import call? I can't access inner classes of MatrixInfo |
| 07:21 | noidi | Velrok, try MatrixInfo$MatrixField |
| 07:21 | noidi | AFAIK that's the real name of the inner class |
| 07:21 | noidi | MatrixInfo.MatrixField is syntactic sugar provided by Java (again AFAIK) |
| 07:21 | Velrok | Indeed |
| 07:22 | Velrok | Thanks @noidi |
| 07:24 | Velrok | cern.colt.matrix.io.MatrixInfo$MatrixField works but |
| 07:24 | Velrok | MatrixInfo$MatrixField fails |
| 07:25 | Velrok | do I have to giv it the complete name space ? |
| 07:27 | Velrok | Ah ok |
| 07:28 | Velrok | I also need to import MatrixInfo$MatrixField |
| 07:28 | Velrok | (cern.colt.matrix.io MatrixVectorWriter |
| 07:28 | Velrok | MatrixVectorReader |
| 07:28 | Velrok | MatrixInfo |
| 07:28 | Velrok | MatrixInfo$MatrixField |
| 07:28 | Velrok | MatrixSize) |
| 08:04 | luxbock | has anyone here tried writing a Firefox extension using ClojureScript? |
| 08:34 | TimMc | Velrok: Please don't paste more than 1 or 2 lines to the channel -- use a pastebin such as http://refheap.com or http://gist.github.com instead. |
| 08:35 | Velrok | @TimMc ok Thanks |
| 08:41 | dnolen | luxbock: someone mentioned doing a Chrome Ext at one point I think |
| 10:01 | jcromartie | so here's something I wish Clojure had: lazy maps |
| 10:02 | jcromartie | i.e. in OOP languages I can make a class with a variety of lazy property getters |
| 10:02 | jcromartie | but in Clojure if I want some sort of associative structure it usually has to be all-or-nothing |
| 10:02 | jcromartie | like, for parsing content from a URL |
| 10:03 | jcromartie | If the map values are functions that use futures or delays, then that is one option |
| 10:04 | jcromartie | I guess @(:title foo) is not too bad |
| 10:04 | nDuff | jcromartie: you can certainly implement clojure.lang.Associative yourself. |
| 10:04 | tomoj | or just ILookup |
| 10:06 | tomoj | but what happens when you print the "lazy map"? |
| 10:06 | tomoj | I was thinking about something somewhat related earlier, I'm putting lazy IO seqs in ring responses, so if you print the response that causes IO... |
| 10:07 | tomoj | well that's probably just nuts |
| 10:08 | jcromartie | yeah I suppose there's nothing stopping a lib from implementing this |
| 10:09 | tomoj | say, datomic |
| 10:09 | tomoj | with lazy EntityMaps |
| 10:13 | juhu_chapa | kjkl |
| 10:22 | beaky | hello |
| 10:33 | beaky | where can I read more about design patterns related to functional programming? |
| 10:39 | stuartsierra | clojurescript 0.0-1798 is out the door and on its way. |
| 10:39 | poi519 | beaky: if you find anything, let me know please. I do not think there are many design patterns already, though. |
| 10:41 | beaky | ah |
| 10:43 | stuartsierra | beaky - I did a talk at Strange Loop last year called "Functional Design Patterns." The video is on InfoQ. Pretty basic stuff, but maybe useful. |
| 10:46 | beaky | ah thanks |
| 10:46 | poi519 | stuartsierra: thanks, watching |
| 10:47 | ambrosebs | It would be nice if *out* had a Writer type hint. |
| 11:58 | gdev | ,(= *) |
| 11:58 | clojurebot | true |
| 11:59 | gfredericks | ,(= * + -) |
| 11:59 | clojurebot | false |
| 12:00 | kmicu | , (= comp comp comp complement true) |
| 12:00 | clojurebot | false |
| 12:01 | poi519 | ,(if nil true false) |
| 12:01 | clojurebot | false |
| 12:03 | justin_smith | ,(= (/ 0.0 0.0)) |
| 12:03 | clojurebot | true |
| 12:03 | justin_smith | NaN should not equal NaN, I would call that a bug |
| 12:05 | justin_smith | ,(== (/ 0.0 0.0) (/ 0.0 0.0)) |
| 12:05 | clojurebot | false |
| 12:05 | justin_smith | ,(== (/ 0.0 0.0)) |
| 12:05 | clojurebot | true |
| 12:05 | justin_smith | bugs |
| 12:06 | IamDrowsy | ,(= (/ 0.0 0.0) (/ 0.0 0.0)) |
| 12:06 | clojurebot | false |
| 12:06 | IamDrowsy | NaN isn't equal to NaN... |
| 12:06 | justin_smith | right |
| 12:07 | justin_smith | but (== (/ 0.0 0.0)) implies it is |
| 12:07 | IamDrowsy | the equality of a single element is true because it makes not alot of sense to check the equality of a single thing |
| 12:07 | justin_smith | until things are not supposed to be equal to themselves |
| 12:08 | edoloughlin | ,(doc ==) |
| 12:08 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false" |
| 12:08 | edoloughlin | Not 'equal', but 'equivalent'??? |
| 12:08 | lazybot | edoloughlin: How could that be wrong? |
| 12:17 | IamDrowsy | well i dont think you can get it right... because you can always argue in different directions.. so its more a decision then a bug |
| 12:18 | TimMc | NaN is a bug. :-/ |
| 12:18 | justin_smith | yeah, but it is a bug in a standard |
| 12:19 | TimMc | I actually don't see what's wrong with (= Double/NaN) => true |
| 12:19 | TimMc | You're not aksing whether NaN = NaN, you're saying that there are no argument pairs where = yields false. |
| 12:19 | TimMc | And there are no argument pairs, period. |
| 12:20 | IamDrowsy | so the bug is that (= Double/NaN Double/NaN) is false? |
| 12:20 | justin_smith | no |
| 12:20 | justin_smith | that is correct behaviour |
| 12:20 | TimMc | That's "broken as designed". |
| 12:25 | manutter | "NaN is not equal to anything, including itself." |
| 12:26 | clgv | manutter: what's the philosophical or technical idea behind that? |
| 12:26 | bbloom | clgv: i believe there are multiple ways to represent NaN |
| 12:27 | axle_512 | manutter: I think that is correct. Instead of comparing NANs, use isNaN() |
| 12:27 | bbloom | so it would be weird to have SOME nans be equal |
| 12:27 | bbloom | yeah, see http://stackoverflow.com/questions/640109/what-is-the-internal-representation-of-inf-and-nan |
| 12:27 | manutter | If I understand correctly, NaN represents what something *isn't*, so it's not really a thing in-and-of itself |
| 12:27 | clgv | ,-0 |
| 12:27 | clojurebot | 0 |
| 12:27 | clgv | ,-0.0 |
| 12:27 | clojurebot | -0.0 |
| 12:28 | clgv | ,(= -0,0 0,0) |
| 12:28 | clojurebot | true |
| 12:28 | bbloom | weeee floating point |
| 12:28 | clgv | ^^ |
| 12:28 | axle_512 | bbloom is right, for doubles and floats, there is more than one way a NAN can be represented bitwise |
| 12:29 | bbloom | floats are a PITA ##(= (/ 1.0 3.0) 0.33333333333333334) |
| 12:29 | lazybot | ⇒ true |
| 12:29 | clgv | bbloom: you should learn that in programming courses ;) |
| 12:30 | avishai | hi |
| 12:30 | avishai | i'm a total clojure noob |
| 12:30 | avishai | doing a ring toturial |
| 12:30 | axle_512 | avishai: hi |
| 12:30 | avishai | hi |
| 12:30 | bbloom | clgv: don't they teach twos complement and IEEE representation in early CS courses? i'm pretty sure we covered that... |
| 12:30 | avishai | i got not locate ring/middleware/reload__init.class or ring/middleware/reload.clj on classpath |
| 12:31 | avishai | not sure why |
| 12:31 | clgv | yeah they do. that was what I meant ^^ |
| 12:31 | weavejester | avishai: Have you included the ring/ring-devel dependency? |
| 12:31 | avishai | as dev-dependency |
| 12:32 | bbloom | the real bitch of floating point math is that it actively thwarts analysis |
| 12:32 | clgv | bbloom: I have some thousands of floating point numbers that probably need to be added in a divide-and-conquer manner... :/ |
| 12:32 | bbloom | you want to do common expression elimination? constant folding? NOPE |
| 12:33 | justin_smith | hell, they aren't even transative, yay |
| 12:33 | weavejester | avishai: Using :dev-dependencies, or :profiles {:dev {:dependencies …}} ? |
| 12:33 | technomancy | at least they're fast =\ |
| 12:33 | bbloom | clgv: communicative? associative? transitive? NOPE |
| 12:33 | avishai | :dev-dependencies |
| 12:33 | avishai | haven't yet mastered the secrets of lein profiles |
| 12:34 | weavejester | avishai: That's been deprecated in Leiningen for a while. I don't think the latest Leiningens support it… do they, technomancy? |
| 12:34 | technomancy | yeah, :dev-dependencies is for lein1 |
| 12:34 | bbloom | technomancy: agreed, but totally the wrong default (holy hell i freak out when i see people tracking money in floats) and absolutely the wrong ONLY POSSIBLE SOLUTION (argh javascript) |
| 12:34 | weavejester | avishai: Profiles are pretty easy. They're just maps that are merged into your main project map. |
| 12:34 | technomancy | bbloom: are there any languages where decimal literals read as non-floats? |
| 12:35 | justin_smith | technomancy: sql? |
| 12:35 | justin_smith | not that sql decimals are a good thing mind you |
| 12:35 | bbloom | technomancy: common lisp? |
| 12:35 | avishai | which means? |
| 12:35 | technomancy | justin_smith: heh; I was just wondering whether it would be a cautionary tale of woe =) |
| 12:35 | avishai | how do i choose which profile to work with? |
| 12:36 | technomancy | bbloom: huh; I had no idea |
| 12:36 | bbloom | gnu clisp doesn't even support IEEE floats |
| 12:36 | technomancy | haha |
| 12:36 | bbloom | IEEE is an extension that most impls have |
| 12:37 | technomancy | I am surprised CLers don't lord that over other languages more. |
| 12:37 | weavejester | avishai: Well, lets say you have {:dependencies [foo "1.0"]} in your project |
| 12:37 | avishai | yes |
| 12:37 | bbloom | technomancy: they are too busy arguing about things that don't matter |
| 12:37 | weavejester | avishai: And you also have: {:profiles {:dev {:dependencies [bar "1.0"]}}} |
| 12:37 | avishai | so far |
| 12:37 | bbloom | technomancy: the most important thing that Clojure did for lisp was to change the subject |
| 12:38 | weavejester | avishai: Then when the dev profile is active, the content of the dev profile is merged into your main project. |
| 12:38 | avishai | that i got |
| 12:38 | weavejester | avishai: So with the dev profile, you have deps foo and bar |
| 12:38 | avishai | but how do i choose which profile is active? |
| 12:38 | technomancy | bbloom: heh |
| 12:38 | weavejester | avishai: By default the following profiles are active: user, dev and … um, some other one whose name escapes me |
| 12:39 | weavejester | avishai: You can choose profiles explicitly with "lein with-profile <profile> <command>" |
| 12:39 | avishai | ah |
| 12:39 | weavejester | avishai: So I usually have a profile for testing different clojure versions |
| 12:39 | avishai | and the default is dev? |
| 12:39 | weavejester | avishai: So I can run: lein with-profile 1.3 test |
| 12:39 | weavejester | avishai: To test against Clojure 1.3 |
| 12:39 | avishai | ah |
| 12:40 | avishai | now i have a ton of other questions.... |
| 12:40 | weavejester | avishai: And in my project file: {:profiles {:1.3 {:dependencies [org.clojure/clojure "1.3.0"]}}} |
| 12:40 | weavejester | avishai: You can have multiple profiles active at once, so the default is user + dev + something-else |
| 12:40 | avishai | found the profiles docs |
| 12:41 | avishai | i'll look there and not waste your time |
| 12:41 | weavejester | Oh, :provided |
| 12:41 | weavejester | :user, :dev and :provided are active by default |
| 12:41 | bbloom | technomancy: like on the latest HN post RE: Light Table…. some dude was clojure bashing b/c clearly all good ideas were had by mccarthy |
| 12:41 | avishai | 10x |
| 12:41 | avishai | and dev-dependencies == {:profiles {:dev {:dependencies ? |
| 12:42 | technomancy | bbloom: or the one about how we shouldn't have reader syntax for hash tables because the reader doesn't know what performance characteristics we're going to want |
| 12:42 | bbloom | technomancy: the most common argument is "reader macros can do that" |
| 12:42 | bbloom | which is the stupidest thing i've ever heard |
| 12:42 | bbloom | turing machines can do it too! |
| 12:43 | bbloom | defaults fucking matter people. |
| 12:43 | gdev | tail calls can do it from behind |
| 12:51 | avishai | ok, it works with :dependencies |
| 12:51 | avishai | so i guess :dev-dependencies was just wrong |
| 12:51 | avishai | 10x |
| 12:51 | nDuff | ... |
| 12:51 | technomancy | avishai: if you can report a bug or whatever with the docs you found that would be decent |
| 12:52 | jcromartie | I really appreciate the fact that deploying the average Clojure system requires only Java as a dependency... |
| 13:07 | ppppaul | i find it a bit strange that dissoc and select-keys have different protocols |
| 13:08 | justin_smith | someone probably has a function that returns two maps, the first a select-keys and the second a dissoc - I could imagine that being very useful |
| 13:08 | avishai | question |
| 13:08 | avishai | regarding ring performance |
| 13:08 | ppppaul | i just made one |
| 13:08 | weavejester | avishai: Go ahead |
| 13:08 | avishai | i take it the dev setup isn't optimized |
| 13:09 | avishai | by after testing a "hello world" handler, it's .... slow |
| 13:09 | avishai | compared to go or ever cherrypy |
| 13:09 | avishai | compared to go or even cherrypy |
| 13:09 | avishai | on my laptop i get around 6k rps |
| 13:10 | weavejester | avishai: To be honest I haven't checked the development setup |
| 13:10 | avishai | ah |
| 13:10 | ppppaul | (def split (juxt select-keys (partial apply dissoc))) |
| 13:10 | avishai | so i'll rephrase |
| 13:10 | justin_smith | ppppaul: nice |
| 13:10 | avishai | is clojure ring performance much worse the say java + jetty? |
| 13:10 | avishai | ^the^then |
| 13:10 | ppppaul | i just find it a bit weird that these functions have such different protocols |
| 13:11 | nDuff | avishai: There was a recent benchmark with a huge number of languages/tools that got published around a bit. |
| 13:11 | weavejester | avishai: http://www.techempower.com/benchmarks/ indicate it's around twice as slow, at least when deployed as a servlet. |
| 13:11 | nDuff | Ahh, that's the one. |
| 13:12 | avishai | i can live with twice as slow |
| 13:12 | weavejester | I suspect that using dedicated adapter would push up the speed considerably. |
| 13:12 | avishai | instead of the jetty adapter? |
| 13:13 | weavejester | Yes, because the Jetty adapter sits on top of the servlet interface. |
| 13:13 | weavejester | I've been meaning to run that benchmark suite against something like https://github.com/RallySoftware/netty-ring-adapter |
| 13:14 | weavejester | It should be a fair bit quicker. Enough to push Compojure into the top 10 at least. |
| 13:14 | nDuff | avishai: Notably, those benchmarks put compojure and (especially) http-kit well ahead of _any_ Python-based framework. |
| 13:14 | avishai | well, since in real life performance degrades mostly due to logic and implementation |
| 13:15 | nDuff | *nod*. |
| 13:15 | avishai | i prefer a language which is clear but a little slower |
| 13:15 | avishai | then tons of horsepower with many quirks |
| 13:15 | mefisto | or more to the point, tons of horespower but you have to supply your own wheels :D |
| 13:16 | avishai | if only my wheels weren't so edgy |
| 13:19 | gdev | i think of it more as mpg |
| 13:19 | gdev | you get more milage per gallon of effort |
| 13:21 | justin_smith | which reminds me, I need to top off my effort tank |
| 13:28 | avishai | another question |
| 13:28 | avishai | is there an encoding middleware? |
| 13:29 | avishai | e.g. to serialize be accept header? |
| 13:47 | justin_smith | avishai: yes, there are middlewares for headers and encoding, for example I am looking at ring.middleware.content-type in my code at the moment |
| 14:03 | mabes | whenever I use nrepl-macroexapnd it simply puts the name of the macro I'm trying to expand in the buffer.. so, I must be doing something wrong. I've tried highlighting the form in question but that didn't work.. any tips? |
| 14:04 | justin_smith | ,(macro-expand '(#(+ % %) 1)) |
| 14:04 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: macro-expand in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:05 | justin_smith | ,(macroexpand '(#(+ % %) 1)) |
| 14:05 | clojurebot | ((fn* [p1__69#] (+ p1__69# p1__69#)) 1) |
| 14:05 | mabes | yeah, I've resorted to doing the expansion in the repl... I was just curious if I was making a common mistake in using nrepl.el |
| 14:07 | silasdavis | with sqlkorma, where are you meant to place your defentity declarations? |
| 14:07 | gdev | silasdavis:) since it uses the last defdb as its default, if you place it after that you won't have to specify the db |
| 14:09 | silasdavis | gdev, so do I just have to ensure that file get's loaded before I run queries in another file? |
| 14:09 | silasdavis | gets* |
| 14:10 | gdev | silasdavis:) yeah definitely |
| 14:11 | gdev | otherwise you'll get a symbol not found exception |
| 14:11 | amalloy | mabes: if it's anything like slime, point has to be on the open-paren at the start of the macro invocation |
| 14:11 | mabes | amalloy: ah, that was it. thanks! |
| 14:13 | gdev | silasdavis:) is your project on github? |
| 14:13 | mabes | I need a macro to reference a var that lives in the same namespace as the macro.. right now I'm manually referencing the fully qualified var in the macro... Is there a better way to do this so that the fully qualified var gets expanded for me? |
| 14:15 | mabes | i.e. I have something like: (ns foo-bar) (def foo 23) (defmacro my-macro [& body] `(something foo-bar/foo ~@body)) ... can I replace the foo-bar/foo with something that gets expanded to that? |
| 14:17 | silasdavis | gdev, not publically I'm afraid |
| 14:17 | clojurebot | Gabh mo leithscéal? |
| 14:18 | gdev | silasdavis:) that's fine, I just realized mine wasn't either, so I'm putting it up there now |
| 14:20 | gdev | now i'm trying to figure out how I can set the db connection information from a settings file that gets gitignored instead of putting user names and passwords hardcoded on the internet |
| 14:21 | klrr | is there any clojure implementation that compiles to machine code? |
| 14:25 | amalloy | mabes: yes, just foo will do that, when inside a syntax-quote |
| 14:26 | amalloy | &`(inc 10), for example |
| 14:26 | lazybot | ⇒ (clojure.core/inc 10) |
| 14:26 | mabes | amalloy: nice.. I thought I had tried that.. thanks! |
| 14:28 | mikerod | Is there a "term" to describe a macro that incorrectly generates code if the arguments given are "complex" forms instead of forms that evaluate to themselves. |
| 14:28 | mikerod | Since this doesn't make sense much as I explain, an example is: (defmacro mc [x] `(let [y ~(resolve x)])) |
| 14:28 | nightfly__ | broken |
| 14:28 | mikerod | Where (mc MySymbol) is ok, but (mc (symbol (str "MySymbol"))) is not. |
| 14:29 | mikerod | nightfly__: Hah, yes broken indeed. |
| 14:29 | amalloy | aw, nightfly__ got to my joke before i'd even finished reading the question |
| 14:30 | amalloy | although, mikerod, that particular example is so poorly written that it generates incorrect code no matter what arguments are passed to it |
| 14:30 | mikerod | I was just wondering if there is a good way to describe that situation. Where the macro doesn't work depending on how the structure of the argument passed to it. |
| 14:31 | mikerod | amalloy: I know that was a poor example. I'm just looking for a way to describe the macro mistake of assuming the argument takes a certain form before evaluation |
| 14:31 | amalloy | mikerod: i mean, a reasonable point of view is that *every* macro and function must assume its arguments take a certain form. the problem you're describing is making the wrong assumption |
| 14:31 | amalloy | so it's really just "bad code" |
| 14:37 | gdev | so in leiningen I was trying to create a new project inside an existing directory with the same name that lein new would've generated, --to-dir for the win |
| 14:39 | gdev | (inc technomancy) |
| 14:39 | lazybot | ⇒ 54 |
| 14:39 | nightfly__ | (incf lazybot) |
| 14:40 | technomancy | I didn't do that |
| 14:41 | gdev | karma for good documentation? |
| 14:42 | gdev | i didn't have to submit a feature request to see it already existed, just command line help files |
| 14:47 | gdev | _{^_^}_:) Y U NO pick one name and stick with it? |
| 14:49 | _{^_^}_ | gdev: cause im indecisive, im seeking help |
| 14:52 | nDuff | _{^_^}_: I'd suggest something you'd be willing to live with indefinitely. On which point, cute has a limited shelf life. |
| 14:53 | hfaafb | _{^_^}_ clearly has issues picking names |
| 14:55 | [tab][tab][tab] | *cough* |
| 15:05 | gdev | whats the opposite of currying? |
| 15:05 | beaky | uncurrying |
| 15:06 | beaky | :t uncurry |
| 15:06 | beaky | (a -> b -> c) -> (a, b) -> c |
| 15:07 | bbloom | beaky: eehhh not really |
| 15:08 | beaky | :( |
| 15:08 | gdev | I thought it was yogurting |
| 15:08 | bbloom | beaky: yes, you are correct that that is the type of uncurry in haskell |
| 15:08 | bbloom | however, it's not really the inverse of "curry" |
| 15:08 | beaky | ah right |
| 15:09 | bbloom | well sorta |
| 15:09 | technomancy | a reversible partial application would have to store the original fn somewhere |
| 15:09 | bbloom | it IS the inverse of haskell's curry function |
| 15:09 | bbloom | lol |
| 15:09 | bbloom | but haskell functions DO CURRYING |
| 15:09 | gdev | i asked for the opposite, not the inverse |
| 15:09 | bbloom | and the uncurry function makes them NOT do currying |
| 15:09 | rasmusto | is it lunchtime? |
| 15:09 | beaky | haskell automagically currys for you |
| 15:09 | bbloom | mmm curry. |
| 15:10 | beaky | imo curry would be a cool name for a functional programming language |
| 15:10 | bbloom | beaky: it was one of the candidate names for haskell, if i recall correctly heh |
| 15:10 | bbloom | curry :: ((a, b) -> c) -> a -> b -> c |
| 15:10 | bbloom | curry converts an uncurried function to a curried function. |
| 15:10 | bbloom | uncurry :: (a -> b -> c) -> (a, b) -> c |
| 15:10 | bbloom | uncurry converts a curried function to a function on pairs. |
| 15:11 | bbloom | that's with the doc strings ^^ |
| 15:11 | gdev | stuartsierra:) wtf is yogurting? |
| 15:13 | raek | beaky: there is a logic programming language called curry.. |
| 15:14 | beaky | ah |
| 15:14 | beaky | where did the name 'clojure' come from? |
| 15:14 | gdev | closure + java |
| 15:15 | pppaul | cloja |
| 15:15 | beaky | ah |
| 15:15 | gdev | coca-cloja |
| 15:15 | beaky | what's a closure? |
| 15:15 | gdev | a resolution to a conflict |
| 15:15 | pppaul | sounds like an anxiety attack |
| 15:16 | raek | beaky: a function with its lexical environment |
| 15:16 | gdev | lisp and the jvm had a huge fight, went out for beers and realized they needed clojure |
| 15:17 | beaky | a closure is a poor man's objects |
| 15:17 | beaky | or was it the other way around? |
| 15:17 | raek | hehe :) |
| 15:18 | gdev | Joel Moses credits Landin with introducing the term closure to refer to a lambda expression whose open bindings (free variables) have been closed by (or bound in) the lexical environment, resulting in a closed expression, or closure |
| 15:19 | beaky | ah |
| 15:19 | gdev | adopted by Sussman and Steele in Scheme in 75 which is where it became widespread |
| 15:19 | beaky | so it's like a function escaping and forming its own universe? |
| 15:20 | gdev | it's often mistakenly used to mean an anonymous function |
| 15:20 | beaky | ah |
| 15:21 | beaky | yeah closures are a bit more than lambadas |
| 15:21 | gdev | lambadas? |
| 15:21 | mikerod_ | amalloy: I had a meeting and couldn't follow up earlier (I asked about a a term for a macro that depends on the structure of the unevaluated form). |
| 15:21 | beaky | lambads* |
| 15:21 | gdev | lambads? |
| 15:21 | beaky | lambdas* |
| 15:23 | gdev | also to make things even more confusing, http://shop.oreilly.com/product/0636920001416.do |
| 15:23 | mikerod_ | The concept I was getting at is would you consider a macro to be poorly written, if the caller of the macro had to know to treat it differently than calling a function? |
| 15:23 | bbloom | beaky: i think that objects are one way to implement closures :-) |
| 15:24 | mikerod_ | If a macro specifies that it is to take a symbol as an argument, but then it doesn't accept forms that evaluate to a symbol. |
| 15:24 | bbloom | beaky: and, given an alternative implementation of closures, then closures are one way to implement objects ;-) |
| 15:24 | beaky | ah thats a nice way to think about that; that's what I use c++ classefor |
| 15:24 | beaky | clases* |
| 15:28 | gdev | Closures were left out of Java initially more because of time pressures than anything else. In the early days of Java the lack of closures was pretty painful, and so inner classes were born: an uncomfortable compromise that attempted to avoid a number of hard issues. But as is normal in so many design issues, the simplifications didn't really solve any problems, they just moved them. |
| 15:28 | gdev | quote from James Gosling |
| 15:29 | bbloom | well yeah, "final" variables plus inner classes ARE closures |
| 15:29 | bbloom | they just aren't also lambdas |
| 15:29 | bbloom | :-P |
| 15:29 | beaky | ah |
| 15:29 | beaky | what's an inner class? |
| 15:30 | bbloom | an inner class (in java anyway) is when you define a class within a class |
| 15:30 | bbloom | or even within a method |
| 15:30 | beaky | ah |
| 15:30 | bbloom | the compiler will rewrite that class to have a name like TheParentClass$TheChildClass |
| 15:30 | gdev | java can only have one public class for every class file, but it can have as many non-public ones it wants |
| 15:30 | bbloom | and then rewrite the constructor and calls to 'new TheChildClass(foo)' to be 'new TheChildClass(TheParentClass.this)' |
| 15:31 | bbloom | rather 'new TheChildClass(TheParentClass.this, foo)' |
| 15:31 | bbloom | effectively closing over "this" |
| 15:31 | beaky | so in java every file may only export a single class? :( |
| 15:31 | bbloom | a single top level class, yes |
| 15:31 | beaky | ah |
| 15:31 | bbloom | however, if you make a final variable and then use it inside an inner class, the constructor will be rewritten there too to take a copy of that variable |
| 15:31 | bbloom | that's why it needs to be final |
| 15:31 | bbloom | it's not a true closure |
| 15:32 | bbloom | ti's a manually hacky closure via rewriting constructors to patch up the closure |
| 15:32 | gdev | on the file system you'll have Foo$InnerFoo.class and Foo$1.class for inner classes and anonymous inner classes |
| 15:32 | llasram | Except for may be "static inner classes", which AFAICT are the same damn thing as regular classes modulo the funky `$` in their name |
| 15:32 | llasram | Plus the convenience of being able to have more than one per file |
| 15:33 | gdev | anonymous innerclasses are also a way to add listeners |
| 15:33 | bbloom | well, the static modifier on a class just says "dont add TheParentClass.this" to the constructor :-) |
| 15:35 | gdev | if you've had to deal with listeners, factory patterns, IOC, decorators, or iterators in java you appreciate Clojure a lot more |
| 15:36 | beaky | ah I never programming in java |
| 15:36 | beaky | I've never coded in java* |
| 15:37 | gdev | give it a try =D |
| 15:37 | llasram | Just other parts of Indonesia? |
| 15:37 | beaky | :D |
| 15:37 | beaky | I heard that java was a nice programming language |
| 15:38 | gdev | depends on your definition of "nice" |
| 15:38 | axle_5121 | a lot of people pick on java today, but it was one of the first to really reach that holy grail of platform independent executables |
| 15:38 | bbloom | axle_5121: people pick on the language more than the virtual machine |
| 15:39 | beaky | the virtual machine is genius |
| 15:39 | bbloom | axle_5121: the JVM and core libraries was/is/are a fine piece of work |
| 15:39 | axle_5121 | bbloom: agreed |
| 15:39 | bbloom | the language was (obviously) very successful in this respect: |
| 15:40 | bbloom | "We were not out to win over the Lisp programmers; we were after the C++ programmers. We managed to drag a lot of them about halfway to Lisp." |
| 15:40 | bbloom | - Guy Steele, Java spec co-author |
| 15:40 | axle_5121 | Yes, it definitely was a more palattable version of C++ |
| 15:40 | TimMc | cemerick: Did you end up creating a ticket for automatic namespace loading for defrecords? https://groups.google.com/forum/#!msg/clojure-dev/4CtSVWcD15A/shpMuyjMpxsJ I can't find one. |
| 15:40 | axle_5121 | palatable even. |
| 15:42 | mikerod_ | I'm a bit of an IRC n00b. What causes/caused my "nick" (user name?) to get an underscore after it suddenly? |
| 15:42 | devn | what's the pattern for developing a new lein plugin? I have a new clojure project and created src/leiningen/foo.clj which contains a single function: (defn foo "Foo" [] (println "hi")) |
| 15:42 | devn | Based on a couple of the other lein plugins I've looked at this should let me run the task inside my lein-foo plugin, is that wrong? |
| 15:43 | TimMc | mikerod_: You probably disconnected and then reconnected, and your old nick stuck around just long enough to be unavailable to your new session. |
| 15:43 | TimMc | (aka a ghost) |
| 15:43 | devn | I keep getting "Task: 'foo' not found" |
| 15:44 | devn | lol nevermind... |
| 15:47 | mikerod_ | TimMc: That makes sense. Thanks! |
| 15:47 | mikerod_ | I'm a ghost now. Yikes. |
| 15:51 | gdev | mikerod:) welcome back to the land of the living |
| 15:51 | jcromartie | this Clojure quiz on Smarterer is driving me insane |
| 15:51 | jcromartie | Q: "What are the 3 phases clojure code is processed in?" A: "Read-time, compile-time, run-time" |
| 15:51 | gdev | ,(= *) |
| 15:51 | clojurebot | true |
| 15:52 | gdev | you got it right, why is it driving you insane? |
| 15:52 | jcromartie | because every question is weird |
| 15:52 | gdev | what about that question is weird? |
| 15:53 | mikerod | gdev: Thank you. It feels good to be back. |
| 15:53 | jcromartie | because as a user of the language you don't care about a compile phase |
| 15:53 | jcromartie | there's a reader, but you don't necessarily need to use it to create Clojure code |
| 15:53 | jcromartie | and the code is evaluated, period, from a user standpoint |
| 15:54 | jcromartie | the bytecode compilation has no bearing on someone programming clojure |
| 15:54 | jcromartie | unless they are doing something tricky with AOT |
| 15:54 | TimMc | mikerod: It's actually the old nick that is the ghost. If you register your nick with NickServ, you can kill the ghost and recover your nick. |
| 15:54 | gdev | jcromartie:) and if you're using macros |
| 15:54 | TimMc | Not all servers have that service, though. |
| 15:55 | TimMc | s/servers/networks/ |
| 15:55 | gdev | jcromartie:) macros are a way to get the code to program in clojure for you |
| 15:55 | jcromartie | yeah |
| 15:55 | devn | jcromartie: from a "user" standpoint you don't care at all about the code, you just care that it works. |
| 15:55 | jcromartie | I'm not talking about a user of an application, I'm talking about a user of the Clojure language. |
| 15:56 | jcromartie | A programmer writing Clojure. |
| 15:56 | gdev | jcromartie:) those are called developers |
| 15:56 | jcromartie | sure |
| 15:56 | ToxicFrog | ...and as a programmer writing Clojure, you are in fact interested in the distinction between the read, compile, and run phases, because macros are tasty |
| 15:56 | devn | ^ |
| 15:56 | devn | That was what I driving at |
| 15:57 | devn | Mainly trying to demonstrate that "user" is ambiguous. Some programmers might not need to care about read, compile, and run, but some care. |
| 15:58 | gdev | There's a Rich Hickey video where he talks about why homoiconicity is so important and goes into comparing languages that compile from text into byte code with lisp |
| 16:00 | gfredericks | clojure supports annotations? |
| 16:00 | jcromartie | I feel like this test was created to troll Clojure developers |
| 16:00 | jcromartie | "True or False? A symbol in Clojure can contain symbols that most imperative language variables can't handle. (Example. You can't define a variable with the name of +1-.)" |
| 16:01 | gdev | jcromartie:) I took the Sun Certified Java Programmer exam, that one is a huge troll to a clojure programmer |
| 16:01 | jcromartie | Q: "True or False? The Clojure language is a data manipulation language written in data." A: True |
| 16:01 | gfredericks | any language that wants infix notation tends to disallow - |
| 16:01 | Pupnik | gdev, got a link to that talk? |
| 16:02 | Chousuke | :P |
| 16:02 | gdev | Pupnik:) I'm googling for it as we speak =D |
| 16:02 | jcromartie | technomancy: you may also be surprised to learn that Clojure is NOT an imperative language :) |
| 16:02 | Pupnik | rich hickeys talks are always very interesting and i havent heard this one |
| 16:02 | jcromartie | technomancy: if you just ignore `do' and atoms and all that |
| 16:05 | muhoo | does this really not exist anywhere in the clojure standard libraries? https://www.refheap.com/paste/14188 |
| 16:06 | jcromartie | muhoo: it really does not… that's specialized enough and not hard to write |
| 16:07 | mikerod | TimMc: Thanks, I will look at this. I use the freenode webchat client right now. I think my network blocks me from connecting through the IRC client I usually use. |
| 16:09 | muhoo | jcromartie: it wasn't hard to write, but it sure ain't specialized. many languages have a "capitalize words" function |
| 16:09 | devn | Is there an easy way to build a leiningen plugin to add a key/val to the user's project.clj? |
| 16:10 | Pupnik | muhoo, does java have one? |
| 16:10 | jcromartie | muhoo: right… just not Ruby or Java or JavaScript or ... |
| 16:10 | jcromartie | Python does |
| 16:11 | gdev | Pupnik:) I think this is the one, or at least he's talking about the same thing at about 24 minutes into it http://channel9.msdn.com/Shows/Going+Deep/Expert-to-Expert-Rich-Hickey-and-Brian-Beckman-Inside-Clojure |
| 16:12 | Pupnik | gdev, im always interested to here bits about homoiconicity and macros, I still don't particularly know under what circumstances they are useful |
| 16:13 | jcromartie | C# has the ever-so-intuitive System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase("exAmpLe sTrinG") |
| 16:13 | gdev | Pupnik:) at about 48 minutes in he gives a better explanation with better visuals http://www.youtube.com/watch?v=P76Vbsk_3J0 |
| 16:14 | brainproxy | dnolen: in your opinion, is mori still a viable approach to provide persistent data structures to JavaScript? I tried building after cloning and updating to latest cljsbuild, but the more.node.js it outputs is throwing errors realated to goog.string |
| 16:14 | brainproxy | rather than spend a bunch of time hunting that down, i figured i would ask if you still think mori is worthwhile, or if things have happened with cljs that make it unviable |
| 16:14 | gdev | actually, the "Clojure for Java Programmers" videos were the most entertaining because of the old guy that kept interupting |
| 16:14 | muhoo | jcromartie: python, perl, php, from memory. hmm, if java string library has one, i should just use that. |
| 16:16 | brainproxy | jimduey: you might like https://github.com/michaelsbradleyjr/jonas/blob/master/index.js |
| 16:17 | brainproxy | i took what I learned from protocol-monads and used technique to build a State monad abstraction for JavaScript that layers on top of JS promises |
| 16:17 | Pupnik | cheers gdev |
| 16:17 | muhoo | jcromartie: CurrentCulture???!! what are they doing, growing yogurt? |
| 16:17 | gdev | Pupnik & jcromartie actually at 58 minutes in to "Clojure for Java Programmers" video he has all three phases that clojure is processed in |
| 16:19 | Chousuke | brainproxy: that's funny, promises form a sort of monad by themselves :P |
| 16:19 | muhoo | ah, commons has one http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/text/WordUtils.html |
| 16:20 | brainproxy | Chousuke: they do, yes |
| 16:20 | jimduey | brainproxy: nice |
| 16:20 | jimduey | Chousuke: I've got to look at it more, but I think promises are more like comonads. |
| 16:20 | brainproxy | Chousuke: but my thought is that the State monad idiom of [state, value] and the standard "helpers" is pretty useful |
| 16:21 | brainproxy | especially if you have a "do" like thing |
| 16:21 | jimduey | but they're also easy to think about as monads. |
| 16:21 | brainproxy | that gives you a lexical environment for chaining operations wherein you can refer back to results of previous steps |
| 16:21 | brainproxy | which I'll be working on soon |
| 16:21 | Chousuke | there's a yo dawg joke here somewhere. but I bet you could get a monad out of DAWGs too and then it would get ridiculous |
| 16:21 | jimduey | Chousuke: lol |
| 16:21 | brainproxy | :) |
| 16:23 | gdev | Pupnik:) macros are useful when you want something to be in the language that isn't. most people take it for granted. Macros are way better than JSRs |
| 16:23 | brainproxy | the downside in JavaScript is that mutable state can bite you in the butt if you're not careful regarding how you work with the the state and values you're passing through a program |
| 16:23 | Pupnik | gdev, JSRs? |
| 16:23 | gdev | Pupnik:) Java Specifications Requests |
| 16:23 | brainproxy | promises and I think my State abstraction help, but don't completely eliminate the problem |
| 16:23 | Pupnik | ah, I don't know java |
| 16:23 | muhoo | Pupnik: consider yourself lucky. |
| 16:23 | Pupnik | I only know actionscript 3, lua and a little bit of C/C++ and Clojure |
| 16:23 | Chousuke | promises are a great tool in JS though |
| 16:24 | brainproxy | Chousuke: they are, but I now suddenly have a renewed interest in dnolen's mori |
| 16:24 | Chousuke | handling all that async code control flow explicitly is a huge pain in the butt |
| 16:24 | gdev | Pupnik:) okay, well in java if you want something in the language you have to go through a huge ceremony |
| 16:24 | brainproxy | as mori's persistent data structures are the perfect kind of things to use for state/values |
| 16:25 | gdev | I can't tell you how many goats were sacrificed just to get the foreach keyword |
| 16:25 | jcromartie | gdev, Pupnik: JSRs are one thing… not to mention the huge ceremony of actually implementing it! |
| 16:25 | brainproxy | Chousuke: yep, except you can still end up with a bunch of boilerplate depending on how you are chaining promises |
| 16:26 | brainproxy | the other night I was doing some complex chains that drove me toward a helpful pattern, which when I stood back and looked at it, I said "hey, that's more or less the state monad" |
| 16:26 | Chousuke | brainproxy: sure, but it's probably way less than all the nested anonymous functions. :) |
| 16:26 | gdev | being a java developer around clojure developers who've never used java, I feel like one of those old vietnam vets who always says "i've seen some things, and some stuff...i wouldn't recommend it" |
| 16:26 | brainproxy | Chousuke: exatcly, but I think w/ an abstraction layered on top of promises, we can make it even better |
| 16:27 | brainproxy | iow, callbacks < promises < State |
| 16:27 | brainproxy | in terms of efficiency of abstraction |
| 16:28 | Chousuke | as far as I understand state should be orthogonal to promises. Combining them can of course be useful (composition is great, after all) |
| 16:29 | technomancy | "I've seen things you people wouldn't believe. Build servers on fire off the shoulder of Orion. I watched maven artifacts glitter in the dark near the Tannhäuser Gate. All those... moments... will be lost in time, like tears in the rain." |
| 16:30 | jcromartie | (inc technomancy) |
| 16:30 | lazybot | ⇒ 55 |
| 16:30 | clojurebot | that will show you what jars (including the clojure jar) leiningen is using |
| 16:30 | jimduey | brainproxy: perhaps of interest http://www.cs.umd.edu/~jfoster/papers/cs-tr-4923.pdf |
| 16:31 | brainproxy | Chousuke: you may be right |
| 16:31 | technomancy | "We couldn't find any repositories matching 'tannhauser'" <- github, I'm disappointed. |
| 16:31 | gdev | technomancy:) everytime you quote something I assume its from bladerunner |
| 16:32 | jimduey | brainproxy: or this might be a better link http://www.cs.umd.edu/projects/PL/arrowlets/ |
| 16:32 | brainproxy | jimduey: very cool |
| 16:32 | brainproxy | I spent a loooong time working with Flapjax a couple of years ago |
| 16:33 | brainproxy | which is related |
| 16:33 | devn | (inc technomancy) |
| 16:33 | lazybot | ⇒ 56 |
| 16:33 | technomancy | huh; Tannhauser is a Wagner reference. nicely played, Rutger Hauer. |
| 16:34 | brainproxy | jimduey: i mean related conceptually |
| 16:34 | Chousuke | brainproxy: It's always interesting to me to see how people are implementing more and more Haskell idioms in other languages |
| 16:34 | devn | parsec all the languages! |
| 16:34 | tieTYT2 | why doesn't clojure have (all)? |
| 16:35 | devn | tieTYT2: like, (all even? [2 4 6]) or? |
| 16:35 | tieTYT2 | the first |
| 16:35 | tieTYT2 | it has an every? |
| 16:35 | tieTYT2 | ok i'll use that |
| 16:35 | devn | yes |
| 16:36 | tieTYT2 | ugh but it doesn't takes multiple args |
| 16:36 | jimduey | Chousuke: I see them more as category theory abstractions than Haskell idioms |
| 16:36 | jimduey | and it's my mission in life to implement all of them in Clojure. :) |
| 16:36 | Chousuke | jimduey: same thing. it's funny how category theory translates into practical programming |
| 16:36 | tieTYT2 | i'll just wrap my args in a vector |
| 16:36 | brainproxy | jimduey: have you seen bilby.js |
| 16:37 | Chousuke | though I still have no idea what the hell profunctors are supposed to be about |
| 16:37 | tieTYT2 | i feel (every? nil? [e1 e2]) is more readable than (nil? (or e1 e2)) Is there an even clearer way? |
| 16:38 | brainproxy | jimduey: https://github.com/pufuwozu/bilby.js <-- the author is doing some pretty serious work with functional programming for javascript |
| 16:38 | Chousuke | functors I can see, they're really useful all the time, but I don't even understand the definition of a profunctor, much less why it would ever be useful. |
| 16:39 | Chousuke | jimduey: it's just one of those things I've encountered reading random things about haskell that I haven't yet been able to make sense of |
| 16:40 | Pupnik | man i could listen to rich hickey all day |
| 16:40 | jimduey | brainproxy: bilby looks ambitious. I think most of the libraries I've done so far that are based on protocols will be portable to clojurescript |
| 16:40 | pjstadig | tieTYT2: if you're using it as a conditional, then just use (and e1 e2) |
| 16:40 | pjstadig | or whatever |
| 16:40 | jimduey | brainproxy: protocol-monads already has been |
| 16:40 | brainproxy | jimduey: yeah, saw that |
| 16:40 | Chousuke | jimduey: but apparently the lens library uses profunctors so it must have some practical use |
| 16:40 | tieTYT2 | pjstadig: ha, I feel dumb |
| 16:41 | tieTYT2 | pjstadig: well actually I'm doing the opposite of and |
| 16:41 | jimduey | Chousuke: lenses are also on my list. BTW, it's a really long list. |
| 16:41 | tieTYT2 | i'm checking that they're both null |
| 16:41 | tieTYT2 | not that they both exist |
| 16:41 | amalloy | mikerod: https://www.refheap.com/paste/776ba83c0bcd45f07eb024dae |
| 16:41 | Chousuke | jimduey: as far as I can tell lenses are the ultimate code golfing tool |
| 16:42 | pjstadig | tieTYT2: yeah so you could do (not (or e1 e2)) or (and (nil? e1) (nil? e2)) |
| 16:43 | tieTYT2 | pjstadig: you think that's easier to read than (every? nil? [e1 e2]) ? |
| 16:44 | tomoj | bilby lenses aren't van laarhoven, right? |
| 16:44 | tieTYT2 | IMO the latter expresses its intent better |
| 16:44 | pjstadig | tieTYT2: it may depend on the context, but i think i'd favor something with ands or ors to using every? and making a vector out of the expressions |
| 16:46 | gdev | "Quite an experience to live in fear, isn't it? That's what it is to be a java dev doing concurrency" |
| 16:47 | tomoj | I just got this passing https://www.refheap.com/paste/242b5b8583854d7411312acf1 but what's the point, I want van laarhoven :( |
| 16:47 | technomancy | heh nice |
| 16:48 | justin_smith | tieTYT2: (empty? (remove nil? [e1 e2])) |
| 16:48 | rodnaph_ | using enlive, is it possible to do a selector using element attributes? like jquery would be: input[name=foo] ? |
| 16:48 | brainproxy | gdev: http://image.slidesharecdn.com/concurrencygotchas-100408105435-phpapp01/95/slide-7-728.jpg?1270742095 |
| 16:49 | nkoza | how you can see the tcp port used by nrepl to listen for connections from inside the nrepl session? |
| 16:51 | rodnaph_ | to answer my own question, yes, using (attr= :href "foo") |
| 16:52 | tieTYT2 | rodnaph_: you want to check that the name = foo? |
| 16:52 | tieTYT2 | yes |
| 16:52 | tieTYT2 | i hate enlive btw |
| 16:52 | rodnaph_ | whaaa? i am currently loving enlive. what don't you get on with? |
| 16:52 | gdev | brainproxy:) i thought that was going to be a link to some slideshow, i almost fell out of my chair laughing |
| 16:52 | tieTYT2 | I don't like the double nested vectors |
| 16:52 | gfredericks | TimMc: I like your inclusion of hiredman as a debugging requirement |
| 16:53 | tieTYT2 | and their significance, it's confusing to me |
| 16:53 | tieTYT2 | and i wish the selectors were better documented |
| 16:53 | gdev | (inc brainproxy) |
| 16:53 | lazybot | ⇒ 1 |
| 16:53 | rodnaph_ | i haven't gone too deep into the selector syntax tbh (as u can tell from my q) |
| 16:53 | brainproxy | gdev: :) that came from one of Alex Miller's slideshows |
| 16:53 | tieTYT2 | i've only used the selector part |
| 16:54 | rodnaph_ | i use it for html templating, works really nicely. |
| 16:56 | tieTYT2 | can someone explain to me why I should have to use a dorun when I use map in a precondition? |
| 16:57 | Chousuke | tieTYT2: map is lazy |
| 16:57 | tieTYT2 | yeah but why isn't pre trying to get the results? |
| 16:59 | mikerod | amalloy: Thanks. I think I can see your point on that with functions and macros having some assumptions on argument forms. |
| 16:59 | Raynes | gfredericks: Wtf, I wasn't following you on twitter? No wonder my life is so empty. |
| 17:00 | gfredericks | I have finally made it! |
| 17:00 | gfredericks | no more striving for me |
| 17:01 | Raynes | I have a haircut. |
| 17:01 | gfredericks | so no more striving for you either |
| 17:01 | gfredericks | "v1.9" == birthday? |
| 17:02 | Raynes | gfredericks: Nope. |
| 17:02 | technomancy | just minor bugfixes |
| 17:02 | technomancy | or a complete VM rewrite, if you're ruby |
| 17:03 | Raynes | $google list of burn centers |
| 17:03 | lazybot | [List of burn centers in the United States - Wikipedia, the free ...] http://en.wikipedia.org/wiki/List_of_burn_centers_in_the_United_States |
| 17:05 | gdev | gfredericks:) after i starting following you it suggested i also follow the parody account for charles manson |
| 17:07 | gfredericks | gdev: good? |
| 17:08 | gdev | gfredericks:) depends, I'm just assuming its a parody account, but I'm too scared to google search if charles manson is still alive while at work |
| 17:09 | AimHere | I believe he's still alive, yes |
| 17:12 | gdev | is there a safer way to do this? (read-string (slurp "some.properties")) |
| 17:12 | justin_smith | clojure.data.edn/read-string |
| 17:12 | justin_smith | for 1.5+ |
| 17:13 | justin_smith | there is also a thing before 1.5 where you can turn some magic evaluation reader macros off |
| 17:16 | justin_smith | oh, yes - it is good to bind *read-eval* to false - but there are still gotchas |
| 17:17 | gdev | justin_smith:) thanks |
| 17:18 | gdev | justin_smith:) am I being too paranoid if the file I'm reading from is a properties file i wrote? |
| 17:18 | justin_smith | heh, maybe, but we have had the exact same conversation at my workplace :) |
| 17:19 | justin_smith | but clojure.data.edn/read-string, in 1.5+, is the thing that is designed to be safe to read without weird unintended security issues |
| 17:20 | tieTYT2 | I have a bunch of date Intervals and I need to do certain things with them. EG: If one contains the other, keep the container. If one is after the other, keep both. At first I thought a (reduce) would be a good fit. But I'm having second thoughts because if I return both, the reduce function now has to check if the input is a Interval or a vector of two Intervals. |
| 17:20 | gdev | justin_smith:) if I just use an edn file instead of a properties file couldn't I just validate the data its reading |
| 17:20 | tieTYT2 | oh i left out a detail: I've got a list of the details, and I'm trying to decide which ones to keep and which to throw away |
| 17:21 | gfredericks | what do you folk use instead of capistrano? |
| 17:21 | justin_smith | gdev: the issue is that just in being parsed, it can make other things happen, even before you use the data |
| 17:21 | justin_smith | unless you are using c.d.edn |
| 17:21 | justin_smith | http://clojuredocs.org/clojure_core/clojure.core/read toward the end of that page it is explained in more detail |
| 17:22 | gdev | justin_smith:) yeah that's what i meant, I'll use an edn file with the edn reader and I'll sleep safe at night |
| 17:22 | gdev | mkay I'll check out that link |
| 17:34 | TimMc | gfredericks: That was ha-ha-only-serious -- I'm really not sure I would have gotten to the bottom of that without the help of someone well-versed in JVM. |
| 17:36 | gdev | so now I've painted myself into an awkward corner; (def configs (read-string (slurp "super-secret.config"))) (def oracle-db {:user (:user configs) ...}) |
| 17:37 | gdev | i elipsed out the rest of the def, but you get the idea, i have to deref with the same key as the key i'm trying to set a value for |
| 17:37 | gdev | could i simply say (def oracle-db configs) ? |
| 17:37 | justin_smith | why not make the oracle db a submap of the config? {:db {:user ...}} then (def orcle-db (:db config)) |
| 17:38 | gdev | the file has the exact map that the def needs |
| 17:38 | TimMc | gdev: select-keys |
| 17:38 | justin_smith | if that will always be the case and any other configs will be in another file, why not (def orcale-db configs) |
| 17:39 | gdev | justin_smith:) yeah, that's what i'm going for, just trying to keep company server, username, passwords etc off the interwebs |
| 17:39 | justin_smith | makes sense, yeah |
| 17:40 | gdev | it's tricky posting database examples since to connect you have to have username and passwords stored |
| 17:40 | TimMc | &(select-keys {:user {:blah "blah"} :un "related"} [:user]) |
| 17:40 | lazybot | ⇒ {:user {:blah "blah"}} |
| 17:41 | justin_smith | TimMc: my problem with doing configs that way is you end up with unrelated configs interleaved, when nesting would clearly indicate the separation. And then some configs should use the same key with different values... |
| 17:41 | avishai | q |
| 17:41 | avishai | require vs use |
| 17:41 | avishai | u probably get that a lot |
| 17:42 | gdev | avishai:) I have to look it up every time |
| 17:42 | TimMc | avishai: Are you asking whether to use :require or :use? Definitely :require, almost always. |
| 17:42 | avishai | really? |
| 17:42 | TimMc | And only use :use with :only. |
| 17:42 | avishai | why? |
| 17:42 | clojurebot | http://clojure.org/rationale |
| 17:42 | TimMc | Namespace pollution. |
| 17:43 | avishai | why require and not use |
| 17:43 | justin_smith | yeah, use makes reorganizing code a pain in the ass, or even reading it |
| 17:43 | gdev | avishai:) you can use :as with require |
| 17:43 | akhudek | use :require and :refer rather than :use |
| 17:43 | TimMc | avishai: It's really hard to read code that heavily refers vars. |
| 17:43 | akhudek | if you really want to use everything, you can do (:require [library :refer :all]) |
| 17:44 | avishai | so (ns blah (:require [some-ns :as n])) ? |
| 17:44 | TimMc | Yep. |
| 17:44 | avishai | so other then style use and require do the same thing? |
| 17:45 | akhudek | avishai: require with refer is the same as use with only, but is now the preferred style as I understand |
| 17:45 | TimMc | avishai: (:use foo) == (:require foo :refer :all) -- but you really don't want that anyway. |
| 17:45 | akhudek | and as TimMc, it is better to require :as if most cases |
| 17:46 | justin_smith | avishai: they both make libraries accessible - but if your json lib and your xml lib both have a parse function, then require is your only option, use just won't work |
| 17:46 | TimMc | People will hate reading your code. |
| 17:46 | avishai | can i import with the full name/ |
| 17:46 | avishai | ? |
| 17:46 | justin_smith | require lets you use the full name |
| 17:46 | avishai | ah |
| 17:46 | justin_smith | but also lets you use :as |
| 17:46 | avishai | so i want just (:require some-ns) |
| 17:47 | justin_smith | if you want to spell it all the way out, yeah |
| 17:47 | avishai | great |
| 17:47 | avishai | 10x |
| 17:47 | gdev | although the only pain point for me in using ":as" is when i have (kd/this (kc/that (ps/i-like-turtles (ps/wat 42) all the slashes, slashes everywhere =( |
| 17:47 | justin_smith | but (:require [foo.bar :as bar]) ... (foo.bar/x ...) still works |
| 17:48 | justin_smith | (let [foo bar/foo] ...) is helpful sometimes |
| 17:48 | justin_smith | still more readable than a :use |
| 17:49 | avishai | i find long names more readable |
| 17:49 | avishai | and if you work with autocompletion writing is easy |
| 17:50 | nkoza | how you can get the tcp port used by nrepl to listen for connections from inside the nrepl session? |
| 17:51 | gdev | so i would say (let [this kd/this that kc/that i-l-t ps/i-like-turtles wat ps/wat] (this (that (i-l-t (wat 42)))) ? |
| 17:52 | gdev | who is working on the strunk and white for clojure? |
| 17:53 | justin_smith | well, it doesn't help much for that example, but if you were using string/join over and over in one block but not in the rest of your ns, (let [join clojure.string/join] ...) totally makes sense |
| 17:53 | akhudek | bbatsov |
| 17:53 | akhudek | https://github.com/bbatsov/clojure-style-guide |
| 17:53 | justin_smith | but yeah, pretty much |
| 17:58 | tomoj | you lose typehints in that case right, or is clojure smart enough? |
| 17:59 | gdev | i'm totally forking that repo, not in a pycon way either, like literally |
| 17:59 | pppaul | clojure brains |
| 17:59 | tomoj | nope, not smart enough |
| 17:59 | hiredman | clojure-style-guide is silly |
| 18:00 | gdev | hiredman:) yes, once you've used the language for a while, but when first starting out it seems helpful |
| 18:01 | hiredman | I submitted a pr to make it less so, but it was rejected https://github.com/hiredman/clojure-style-guide/commit/0e904f2b41866fcccddc924a3e5faf5660b2cb4a |
| 18:01 | gdev | hiredman:) oh i thought you were talking about the idea of a style guide, i didn't know you meant that specific one |
| 18:02 | justin_smith | gdev: read his rq, you were right |
| 18:03 | gdev | justin_smith:) his rq? |
| 18:03 | justin_smith | the pull request he linked |
| 18:03 | justin_smith | you were right the first time |
| 18:03 | hiredman | the style guide is basically "let's write down how emacs formats lisp", which even as an emacs user I think is silly |
| 18:04 | justin_smith | the reason emacs formats it that way is because reasonable people wanted that as a default |
| 18:04 | gfredericks | if macros could include metadata to suggest formatting, would that be cool or stupid? |
| 18:04 | technomancy | gfredericks: CL indents differently depending on whether slime is connected or not |
| 18:04 | technomancy | do not want |
| 18:04 | clojurebot | No entiendo |
| 18:04 | gdev | lol i just read the pull request very clever hiredman, very clever |
| 18:04 | hiredman | that is almost how the emacs indenting system works |
| 18:04 | hiredman | you add indenting info to the plist of symbols |
| 18:04 | technomancy | but emacs is always "live" |
| 18:04 | technomancy | elisp |
| 18:05 | gfredericks | hiredman: that's symbol based instead of var based though, right? |
| 18:05 | technomancy | gfredericks: symobls in elisp are kind of like vars |
| 18:05 | technomancy | they are storage locations |
| 18:05 | hiredman | technomancy: works for non-elisp lisps too |
| 18:05 | justin_smith | yeah, every symbol has a plist, like in cl |
| 18:06 | hiredman | technomancy: I have a little mode for the lisp I am writing that does it |
| 18:06 | gfredericks | technomancy: are you still bullish on racket? |
| 18:06 | technomancy | hiredman: right, but the whole "language describing its own indentation" thing only works for slime and elisp |
| 18:06 | technomancy | gfredericks: there are a couple things about it I hate. but there's a lot to like. |
| 18:06 | hiredman | technomancy: sure, or a pretty printer |
| 18:07 | technomancy | gfredericks: it seems like a good fit for this project I'm doing on the raspberry pi. |
| 18:08 | hiredman | I'm telling you, the jvm will run great on that |
| 18:08 | technomancy | my fallback plan is elisp =P |
| 18:12 | technomancy | wait is bullish good or bad? |
| 18:13 | hiredman | https://en.wikipedia.org/wiki/Market_trend |
| 18:13 | TimMc | Good, I think. |
| 18:13 | technomancy | huh. I assumed with such a low edit distance from "bullshit"... |
| 18:14 | hiredman | yo, it's the animal spirits |
| 18:15 | hiredman | http://en.wikipedia.org/wiki/Animal_spirits_%28Keynes%29 |
| 18:18 | mthvedt | well a lot of bullish opinions are reflective of that edit distance |
| 18:18 | learner | Hello Clojure Gurus, I have been learning clojure. Trying to understand apply function more clearly. I executed "(apply vector [:a :b] [:c :d])" expecting result [:a :b :c :d] -- one single vector --> instead I got [[:a :b] :c :d]. If any of you explain me how exactly apply works, it's great. Thanks for your time. |
| 18:18 | TimMc | hiredman: Not to be confused with spirit animals. |
| 18:19 | trptcolin | learner: apply unrolls only the last arg given; the rest of the args are passed directly (in front of the last arg) |
| 18:19 | trptcolin | ,(apply vector :a :b [:c :d]) |
| 18:19 | clojurebot | [:a :b :c :d] |
| 18:19 | gfredericks | which is useful a lot of the time |
| 18:21 | learner | trptcolin: Thanks. Excuse me for my lack of knowledge and little brain, would it be possible to explain me in simple words. what do you mean by "apply unrolls only the last arg given" |
| 18:23 | trptcolin | learner: here's an easier-to-understand example: you can think of (apply + 1 2 [3 4]) as more or less the same as (+ 1 2 3 4) |
| 18:23 | trptcolin | the last argument [3 4] needs to be a sequence-like thing, and it gets "unrolled" when it's passed to the function (the first argument to `apply`) |
| 18:25 | TimMc | http://dev.clojure.org/jira/browse/CLJ-1208 "Namespace is not loaded on defrecord class init" |
| 18:25 | learner | trptcolin: Exactly that example confused me. I was expecting (apply vector [:a :b] [:c :d]) to behave (apply vector [:a :b :c :d]).. but it's not |
| 18:26 | trptcolin | (apply vector [:a :b] [:c :d]) is like (vector [:a :b] :c :d) |
| 18:26 | TimMc | (apply vector [:a :b] [:c :d]) => (vector [:a :b] :c :d) |
| 18:26 | TimMc | sniped |
| 18:26 | trptcolin | hehe |
| 18:27 | tomoj | do you really want to be using records directly from java anyway? |
| 18:27 | TimMc | Yep. |
| 18:30 | learner | trptcolin: Based on your explanation, I tried couple of examples on REPL. I am clear now. Cheers mate. BTW, quoting-without-confusion -> is my one of my favourite bookmark. |
| 18:31 | learner | TimMc: Thanks for clarifying apply vector question |
| 18:34 | mikerod | What is "quoting-without-confusion"? |
| 18:35 | learner | mikerod: it's Colin's article. trptcolin: http://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html |
| 18:37 | mikerod | learner: Ah, I didn't realize that. I have read this before and agree that it is useful. |
| 18:42 | learner | Another question Gurus. To practice & improve my clojure skills, I am planning to write a simple password cracker (brute force). I would like to control number of threads I initiate, and if password found I update an atom(found) value to TRUE. Loop terminates if TRUE found. I am using https://github.com/clojure/math.combinatorics to get various combinations. But I am not sure on how to control threads and stuff. Any pointers are rea |
| 18:47 | SegFaultAX | learner: That's a really inefficient way to crack passwords. Dictionary attack is much better. |
| 18:48 | AimHere | Phishing scam is better still! |
| 18:48 | SegFaultAX | learner: http://www.openwall.com/john/ |
| 18:48 | SegFaultAX | Not that I'm endorsing that sort of thing for malicious purposes, you see. |
| 18:48 | SegFaultAX | I'm just sayin... |
| 18:49 | learner | SegFaultAX: Thanks for your reply. I don't mean to crack passwords really. But to learn concurrent programming and experiment on threads. If I were to crack password, Yes I target to get Hash! |
| 18:52 | SegFaultAX | learner: This sounds like an awesome opportunity to learn about reducers and Fork/Join! |
| 18:53 | learner | SegFaultAX: True. I am not sure where to start though. I am wondering if the community can point me to couple of examples. |
| 18:54 | SegFaultAX | learner: Probably do it in phases. Start with a single threaded synchronous version, then a second version built on futures, etc. |
| 18:55 | SegFaultAX | But get a working conceptual model first before you try and add paralellism. |
| 19:01 | learner | I think understanding clojure way of solving sleeping barber's problem gives me a good start on concurrency. Just in case if any of you also looking for examples. Thanks for all your support. |
| 19:06 | amalloy | SegFaultAX: this sounds like a terrible opportunity to use fork/join, right? |
| 19:07 | amalloy | or, at any rate, a bad time to use reducers |
| 19:07 | amalloy | since r/fold has no provisions for stopping early |
| 19:07 | amalloy | or in fact coordinating at all with the other threads working on the task |
| 19:08 | amalloy | really he wants like...a queue of "passwords to try", and a threadpool of workers taking jobs from there; he just stops putting stuff on the queue, or shuts down the threadpool, when an answer is found |
| 19:10 | tieTYT2 | is a reducer different from the reduce function? |
| 19:14 | amalloy | $google clojure reducers |
| 19:14 | lazybot | [Clojure - reducers] http://clojure.org/reducers |
| 19:14 | tomoj | "reducers are composable", huh |
| 19:15 | apoc | whats (fn*)? I get it from something like '#(+ % 1) but I've trouble finding out what the * does |
| 19:15 | tomoj | reducer combinators are composable, but they're just functions, so what does that even mean? |
| 19:16 | SegFaultAX | amalloy: I didn't know that about reducers, I just lumped that into Fork/Join. Probably misspoke. But FJ is still reasonable here. |
| 19:16 | tomoj | I guess maybe it means that there are functions in the reducers library :) |
| 19:16 | tomoj | which is better than lots of collection libraries at least |
| 19:18 | amalloy | tomoj: composable is just a word rhickey likes. saying it soothes him |
| 19:18 | SegFaultAX | tomoj: Not all functions are composable. |
| 19:19 | tieTYT2 | thanks |
| 19:20 | tomoj | I mean reasonable functions :) |
| 19:20 | SegFaultAX | tomoj: "Reasonable" isn't a word I understand in this context. |
| 19:20 | tomoj | "composable" |
| 19:20 | justin_smith | apoc: fn* is a function, that the fn macro calls |
| 19:20 | justin_smith | similar let* / let |
| 19:20 | tomoj | or, say, "pure" |
| 19:20 | justin_smith | maybe special form? anyway it doesn't do data decomposition and stuff |
| 19:21 | SegFaultAX | tomoj: Pureness is not what makes functions composable. |
| 19:21 | apoc | the * makes it really difficult to search for, looks like most search engines ignore it ;) |
| 19:21 | apoc | maybe have a doc link for me? |
| 19:21 | SegFaultAX | tomoj: For two functions f and g to be properly composable with each other (f . g) the co-domain of g must be a subset of the domain of f |
| 19:22 | tomoj | ok, so "composable" then. my point is just that reducers themselves seem very uncomposable. if I've got two reducers, well, shit |
| 19:22 | SegFaultAX | It may or may not be a proper subset (eg the co-domain of g may match the domain of f exactly, but that's not a requirement) |
| 19:23 | tomoj | but I guess maybe that enables the kind of composition that is there |
| 19:25 | justin_smith | apoc: you can expand the source tab on this page to see how fn calls fn* http://clojuredocs.org/clojure_core/clojure.core/fn |
| 19:26 | justin_smith | fn* isn't meant to be called by normal code, it is just a less useful primitive that fn is made of |
| 19:41 | tieTYT2 | I'm reading this fogus article: http://www.drdobbs.com/architecture-and-design/the-clojure-philosophy/240150710 |
| 19:41 | tieTYT2 | he uses this code as an example: x = [5]; process(x); x[0] = x[0] + 1 |
| 19:42 | tieTYT2 | you can't tell what x will become because you don't know if process mutates |
| 19:42 | tieTYT2 | and clojure is better because locals are immutable |
| 19:42 | tieTYT2 | BUT, if x is a java object, aren't you just as unsure as any other language? |
| 19:43 | technomancy | tieTYT2: yes |
| 19:43 | technomancy | it's just that it's easy to avoid that in clojure and nearly impossible in most languages |
| 19:43 | tieTYT2 | i must be writing clojure wrong if it's easy to avoid that |
| 19:44 | tieTYT2 | also some of my clojure is embedded in a java app |
| 19:44 | SegFaultAX | tieTYT2: Are you using lots of POJOs in your Clojure code? |
| 19:44 | tieTYT2 | SegFaultAX: not lots, but usually a main one |
| 19:44 | tieTYT2 | i've used seesaw, clj-http and things like that |
| 19:44 | tieTYT2 | they're all using java objects under the hood |
| 19:45 | SegFaultAX | tieTYT2: Yea, there really isn't anything you can do about that. |
| 19:45 | SegFaultAX | Clojure isn't a pure language and Java sure as hell isn't a pure runtime. |
| 19:45 | tieTYT2 | right, so in that case I don't understand the clarity argument |
| 19:46 | tieTYT2 | if I don't use any java libraries directly or indirectly things are easy to understand, but otherwise you never know, right? |
| 19:46 | technomancy | you can get a seq over a mutable java object |
| 19:46 | technomancy | and it's guaranteed to be stable |
| 19:47 | tieTYT2 | what do you mean? Like (let [x [java-object] ...) ? |
| 19:47 | technomancy | (seq java-list-thingy) ; <- not gonna change |
| 19:47 | tieTYT2 | but the objects inside could |
| 19:48 | tieTYT2 | when I pass that seq into any function, right? |
| 19:48 | technomancy | well, you have to apply the seq at the right level |
| 19:48 | technomancy | if it's a list of strings or numbers, you're fine |
| 19:48 | tieTYT2 | right |
| 19:48 | technomancy | otherwise maybe you (map bean list-of-pojos) instead |
| 19:49 | tieTYT2 | yeah I suppose that's better |
| 19:50 | technomancy | clojure encourages you to keep the yucky mutable bits as small as possible |
| 19:50 | tieTYT2 | pure clojure does, yes |
| 19:51 | technomancy | so you do your interop in one namespace, and as long as you don't let the objects escape, your namespaces implementing the rest of the logic are clean |
| 19:51 | tieTYT2 | maybe the unusual thing with my experience is I've always been using java somewhere |
| 19:51 | SegFaultAX | tieTYT2: Well, all Clojure encourages you to keep the lucky bits isolated. |
| 19:51 | SegFaultAX | tieTYT2: Even when you're working in Java interop, it's still encouraged. |
| 19:52 | SegFaultAX | s/lucky/yucky/ |
| 19:52 | tieTYT2 | SegFaultAX: maybe as a philosophy. But I can take a seesaw label and call (.setText l "foo") on it any time I want. |
| 19:53 | SegFaultAX | Why is the null check in RT.seqFrom second? |
| 19:53 | technomancy | more importantly, someone else could do that |
| 19:53 | tieTYT2 | technomancy: you mean a library that requires label's? |
| 19:53 | SegFaultAX | tieTYT2: Clojure is not a pure language. It doesn't claim to be. |
| 19:53 | technomancy | I guess? I don't know swing |
| 19:53 | technomancy | or java |
| 19:54 | SegFaultAX | There is absolutely nothing to stop you from doing that. |
| 19:54 | technomancy | it's just more insidious when mutation comes from places you don't control |
| 19:54 | SegFaultAX | But if that's the way you choose to do it, why use Clojure at all? |
| 19:54 | SegFaultAX | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L489 |
| 19:57 | hiredman | SegFaultAX: because you might call seq on nil? |
| 19:59 | SegFaultAX | hiredman: But why is the null check second? |
| 20:01 | hiredman | SegFaultAX: *shrug*, as as it is before the method calls |
| 20:15 | tomoj | "values of type X are composable" =?= "the X library provides at least one non-identity function of type X -> X (in spirit)" |
| 20:37 | axle_512 | anyone recommend a good continuous build setup for lein? Is jenkins an option or is there something better? |
| 20:38 | justin_smith | we use jenkins with hooks on git |
| 20:38 | justin_smith | I am not the one that set it up, but it works fine |
| 20:38 | axle_512 | justin_smith: thanks. Does it require a jenkins plugin? |
| 20:38 | justin_smith | and we all get to ritually humiliate the one who checked in the bad commit |
| 20:39 | justin_smith | the guy who set it up is out of office (late on a friday), I only know it oworks, sorry |
| 20:39 | axle_512 | cool. thanks, will look into it |
| 20:39 | justin_smith | jenkins even has an irc bot - think of the possibilities |
| 20:40 | axle_512 | I've used jenkins with jabber to get IM notifications, that was pretty cool |
| 20:40 | amalloy | travis seems popular for clojure folks |
| 20:41 | axle_512 | will take a look at travis as well. thanks |
| 20:52 | lpetit | axle_512: Travis also has handful of options for post build notifications (email, irc, etc.): http://about.travis-ci.org/docs/user/notifications/ |
| 20:52 | axle_512 | lpetit: thanks, I just signed up on travis-ci.org.. digging deeper |
| 20:54 | lpetit | axle_512: it's very straightforward, read about it a little bit, then tried to push my maven + tycho (for Eclipse plugins) tonight. First successful build in less than an hour |
| 21:13 | Apage43 | when I kill an nrepl evaluation (ctrl-c) is there a way to see the stack trace as of when I killed it? |
| 21:14 | Apage43 | Trying to debug a deadlock |
| 21:15 | gdev | Apage43: trace log? |
| 21:19 | nkoza | I want to test if something can be converted to a seq with (seq x) ... there is some predicate to know if that is possible? (seq? x) doesn't work, for example (seq? [1 2]) evaluates to false |
| 21:22 | nkoza | I see in clojure 1.2 there was a clojure.contrib.core/seqable? function, where is now? |
| 21:22 | axle_512 | lpetit: saw you over on #travis as well. travis ci is quite nice, I'm already up and running with a little help from henrikhodne. |
| 21:23 | Apage43 | nkoza: you can grab it from the old repo. https://github.com/clojure/clojure-contrib/blob/b8d2743d3a89e13fc9deb2844ca2167b34aaa9b6/src/main/clojure/clojure/contrib/core.clj#L78 |
| 21:23 | nkoza | there is no modern way? |
| 21:24 | Apage43 | don't know what you mean. |
| 21:24 | gdev | ,(instance? clojure.lang.Seqable [1 2 3]) |
| 21:24 | clojurebot | true |
| 21:25 | Apage43 | ,(instance? clojure.lang.Seqable "i'm a string") |
| 21:25 | clojurebot | false |
| 21:25 | Apage43 | ,(seq "I'm a string") |
| 21:25 | clojurebot | (\I \' \m \space \a ...) |
| 21:26 | Apage43 | so no. If you want to check if seq will succeed you have to check all the things it works on |
| 21:26 | nkoza | I mean, seems to be some very basic, I'm surprised there is no official predicate to check for that |
| 21:26 | nkoza | but thanks for the link, I will use it |
| 21:27 | gdev | thats not that many checks in an or statement |
| 21:27 | tomoj | presumably it was removed for a reason :) |
| 21:28 | gdev | don't be presumptuous |
| 21:28 | amalloy | Apage43: "all the things it works on" is an open-ended set |
| 21:28 | Apage43 | mm, it could increase in the future |
| 21:29 | amalloy | Apage43: it can increase right now. [B, [[B, [[[B... |
| 21:29 | amalloy | there are already an infinite number of seqable classes |
| 21:29 | Apage43 | amalloy: right, but that's checkable |
| 21:29 | amalloy | sure, using reflection |
| 21:30 | amalloy | if you can find it, dnolen has a blog post about memoizing that reflection check for seqable? by dynamically extending protocols at runtime |
| 21:30 | gdev | ,(seq \x) |
| 21:30 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character> |
| 21:30 | gdev | ,(seq 42) |
| 21:30 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long> |
| 21:31 | gdev | ,(seq 'seq) |
| 21:31 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol> |
| 21:32 | tomoj | http://web.archive.org/web/20120726061808/http://dosync.posterous.com/51626638 |
| 21:33 | tomoj | I figured extending protocols at runtime was evil |
| 21:34 | amalloy | well, basically yes. but the goal is evil too, so it evens out |
| 21:34 | tomoj | I guess it's only evil if I use it to implement implementation inheritance? |
| 21:34 | tomoj | ah :) |
| 21:34 | dnolen | tomoj: extend-type is inately a runtime thing |
| 21:35 | tomoj | dunno how to say what I mean but I figure you know? |
| 21:35 | tomoj | I guess I mean extending in a default impl |
| 21:35 | dnolen | tomoj: it's your protocol, what's the problem? |
| 21:35 | Apage43 | okay, I broke emacs enough times today, time to head home |
| 21:36 | tomoj | I think the problem is that my goal is evil |
| 21:36 | dnolen | tomoj: oh I probably missed that |
| 21:37 | tomoj | I want protocol<->protocol extension |
| 21:37 | dnolen | tomoj: terrible idea |
| 21:37 | dnolen | well IMO, I know other people have done it and like it. |
| 21:37 | tomoj | so I'm left thinking that there is something wrong with reducers, because it has an ugly workaround for that |
| 21:38 | dnolen | tomoj: that said, extending protocols to interfaces is less of a hassle in CLJ |
| 21:38 | tomoj | oh, yeah, but that's cheating :) |
| 21:38 | dnolen | in CLJS you gotta do that work in default implementations |
| 21:38 | amalloy | tomoj: what workaround? |
| 21:39 | tomoj | https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/protocols.clj#L39 |
| 21:40 | dnolen | tomoj: that's just the default implementation |
| 21:41 | tomoj | the 'ugly workaround' is to use the default impl to extend a protocol to a closed set of other protocols |
| 21:42 | nkoza | maybe is simpler to do (defn seqable? [x] (try (seq x) true (catch Exception e false))) |
| 21:42 | Apage43 | nkoza: well, that'll also eat any exception realizing the first element of a lazy seq |
| 21:43 | amalloy | it also doesn't work for empty collections, but that's an easy fix |
| 21:44 | nkoza | true, maybe there is a way to check if the exception was made before or after realizing that element... maybe inspecting the stack or something |
| 21:44 | amalloy | the original implementation wasn't evil enough for you, nkoza? |
| 21:44 | tomoj | I hadn't noticed that cljs has the IReduce impls directly on all the concrete seq types |
| 21:44 | tomoj | that is nice |
| 21:44 | nkoza | learning is to explore all the evil corners :) |
| 21:45 | nkoza | can you call (seq col) without realizing the seq first element? |
| 21:46 | tomoj | if that's what clj wants to do, then I retract my complaint - I'll just have to implement IReduce directly on all my concrete types |
| 21:46 | tomoj | otoh if clj really wants to abuse the default impl, it seems unfair :) |
| 21:46 | dnolen | tomoj: it's the right way if more tedious. |
| 21:47 | tomoj | hmm |
| 21:48 | dnolen | tomoj: it does make a compelling argument for some language level type union. |
| 21:49 | dnolen | solves the tedium - tho not the closed problem |
| 21:49 | tomoj | so should (into [] (reify clojure.lang.ISeq (seq [this] this) (first [_] :foo) (next [_]))) fail? |
| 21:50 | tomoj | er, (r/reduce conj [] (reify ...)) say |
| 21:50 | tomoj | (oh, same thing-ish) |
| 21:51 | tomoj | not sure what you mean about the union, but I'm guessing it would allow that to succeed, and then like you say the problem is just that it won't work for (reify com.example.MyISeq ...) ? |
| 21:53 | dnolen | tomoj: sorry I'm talking about a problem for CLJS which does get to ride on interface inheritance to avoid tedium. |
| 21:53 | dnolen | doesn't |
| 21:54 | tomoj | yeah, like clojure.data.diff? and the reify thing fails there iirc |
| 21:55 | tomoj | ah well, moot if I'm right that IReduce is wrong |
| 21:56 | dnolen | tomoj: I'm missing some context here, why is IReduce wrong? |
| 21:57 | nkoza | btw, I found two posts by Rich about the "seqable?" issue: https://groups.google.com/d/msg/clojure/sqok3RqGEC8/m63Kv_qYUDgJ https://groups.google.com/d/msg/clojure/CPFPkyTYXGc/jfuaHOjWPPwJ |
| 22:00 | dnolen | nkoza: those are old posts, CLJS has ISeqable and seqable? |
| 22:00 | dnolen | in fact strings and arrays were extended to ISeqable until recently |
| 22:00 | tomoj | dnolen: reducers need to be broken up more, I think. CollReduce specifies synchronous single-threaded execution and CollFold (sort of) specifies ForkJoin |
| 22:01 | dnolen | they no longer are, but I pretty much agree on the minor utlity of seqable? |
| 22:01 | tomoj | I'd rather those concerns be separate |
| 22:02 | nkoza | dnolen: "grep -r ISeqable *" gives nothing on clojure 1.5.1 source |
| 22:02 | dnolen | tomoj: reading the code I don't really agree. |
| 22:02 | dnolen | nkoza: ClojureScript |
| 22:03 | dnolen | sorry I abbreviated it as CLJS |
| 22:03 | nkoza | why ISeqable exists on CLJS and not in CLJ? CLJS is more based on protocols, like a CLJ cleanup? (I'm new to CLJS) |
| 22:04 | tomoj | say I have some other way to execute a binary tree of tasks besides FJ -- I have to copy+paste foldvec, replace the FJ bits, and then wrap my vectors in a special CollFold wrapper that uses my execution mechanism? |
| 22:06 | tomoj | "wrong" was probably too strong - I quite like reducers, I just want more (really, less?) |
| 22:06 | dnolen | tomoj: it might be usefult to break out the strategy, but then why not make a more flexible protocol for your own use? |
| 22:07 | clojurebot | forget chouser: it's tougher with guards (arbitrary tests), where grouping is less clear. I need to work that out still. |
| 22:07 | dnolen | nkoza: CLJS is newer is all |
| 22:07 | tomoj | dnolen: yeah, that's what I hope to be able to do |
| 22:08 | nkoza | dnolen: ok, thanks |
| 22:09 | amalloy | dnolen: that seems like a weird answer to nkoza's question. you couldn't define ISeqable usefully in clj-jvm. you have to either make it an interface, in which case it can't be extended to existing jvm types; or a protocol, in which case it's very hard to bootstrap the compiler up to the level where protocols exist |
| 22:11 | dnolen | amalloy: I didn't mean to imply that CLJ JVM could solve this issue easily - I just meant that CLJS is newer and designed w/ protocols in mind from the beginning. |
| 22:12 | nightfly__ | is cljs self hosting yet? |
| 22:12 | dnolen | nightfly__: nope |
| 22:13 | nightfly__ | That's too bad. I really like the idea of it but am really attached to macro expansion happening in the same dialect/implementation as the runtime. |
| 22:15 | dnolen | nightfly__: I've written some fancy macros and never needed access to the runtime so it doesn't bother me. But it's useful for the very fanciest of fancy macros. |
| 22:16 | dnolen | nightfly__: CLJS will likely bootstrap at some point but there's a quite a bit of work to do. There is a fork of CLJS that bootstraps - http://github.com/kanaka/clojurescript |
| 22:17 | nightfly__ | I'll definitely check that out, thanks. |