2014-08-13
| 00:23 | shriphani | hi I was wondering if anyone has any experience with aleph. I am trying to talk to an aleph tcp server from a java client and calling readLine on the socket's inputstream causes it to block (while a clojure client is able to speak to the server). |
| 00:27 | codygman | xeqi: Thanks. |
| 02:34 | supreme__ | I am new to clojure. would you say Clojure is good (perfect) for building scalable REST based API's? Since clojure have macros and is scale well making it the perfect DSL creator? |
| 03:47 | r4vi | supreme__: I think any/most languages would be fine for building a REST API; just a matter of preference |
| 04:14 | bajabongo | hi, I'm learning ClojureScript and I'm curious about "special" form (js* string), but I cannot find where and how it's implemented |
| 04:15 | bajabongo | could anybody provide info where can I find it's definiotion? |
| 04:19 | bryanmaass | What's cooler than how clojure maps are implemented? |
| 04:22 | clgv | bajabongo: probably in the clojurescript compiler |
| 04:23 | wink | supreme__: ever seen http://www.techempower.com/benchmarks/#section=data-r9 ? |
| 04:24 | bajabongo | clgv: well, probably :), but I was looking for "js*" string and, actually, did not find any definiotion |
| 04:24 | bajabongo | *definition |
| 04:24 | bajabongo | clgv: it's used frequently, but nowhere I can find a definition |
| 04:25 | clgv | bajabongo: https://github.com/clojure/clojurescript/blob/4ba56712274d67b592cff5160bb2a6aea397c72d/src/clj/cljs/analyzer.clj#L1284 |
| 04:26 | bajabongo | clgv: hm, looks like I didn't notice that since as for now, I don't know what "defmethod" is, |
| 04:26 | bajabongo | clgv: thanks, I'll look around |
| 04:27 | clgv | bajabongo: oh well so you are just a beginner? then do not try to find that source ;) |
| 04:27 | supreme__ | wink: nope, thanks! |
| 04:27 | clgv | bajabongo: js* just emits literal javascript as far as I read |
| 04:27 | bajabongo | clgv: yeah, started learning Clojure(Script) a few days ago :) |
| 04:28 | bajabongo | clgv: yes, and that's what I exactly needed to understand, how ClojureScript handles "this" in JS |
| 04:28 | clgv | bajabongo: is there some docstring for (doc js*)? |
| 04:28 | wink | supreme__: but take it with a grain of salt. I think you can build a reasonably scalable api in most languages. Only the top top end, server costs or speed of development matter as hard facts |
| 04:28 | supreme__ | I saw there was a video series of rick hickey about learning clojure for a java programmer. they are from 2012, still relevant? waiting for my book to drop in the mail anyday so thought I could look at thoose while waiting. cool that the creator has done the videos himself |
| 04:29 | clgv | bajabongo: yeah well the javascript passed to js* will just show up in the non-optimized javascript output |
| 04:29 | bajabongo | it turned out there's macro (this-as), but it just makes a binding and uses (js*) internally, and that's the reason I wanted to know more about (js*) |
| 04:29 | clgv | bajabongo: there is probably some information in one of the tutorial series |
| 04:30 | supreme__ | wink: what webframeworks are clojure that are on that list? |
| 04:30 | bajabongo | clgv: I've got no idea, but looking for "this in clojurescript" yields this http://stackoverflow.com/questions/15531261/accessing-this-in-clojurescript |
| 04:30 | ener2 | is there something like cons in cl that will create pair instead of treating second value as a sequence? |
| 04:31 | bajabongo | clgv: which is nice, but I actually don't see why I cannot just use (let [this (js* "this") ...]) by myself |
| 04:31 | supreme__ | wink: found the abbrevation now |
| 04:31 | wink | supreme__: there's a column where you see 'clj' - but most people use libraries and ring middleware to combine stuff, not use a full stack framework, altough there's pedestal and a few more |
| 04:35 | bajabongo | clgv: anyway, thanks for providing an exact line :) |
| 04:38 | clgv | bajabongo: wont help you much though, since you need to understand clojure pretty well and maybe need some cljs compiler knowledge |
| 04:41 | bajabongo | clgv: it's OK, after a few days I have a vague idea how it may work; mostly I just wanted to know how to handle "any" JS |
| 04:41 | clgv | bajabongo: I guess, you should use js* seldomly anyway |
| 04:41 | supreme__ | wink: are you familiar with the rick hickey videos learning clojure for a java programmer? are they still relvent |
| 04:42 | supreme__ | ? |
| 04:43 | clgv | supreme__: the general ideas yes. some syntax has change meanwhile |
| 04:45 | bajabongo | clgv: sure, it's just I now know, that I have yet another way to refer to JS |
| 05:02 | xfel | Hi. Has there been non-trivial changes to the syntax/etc in Clojure since version 1.4 and/or 1.3? |
| 05:02 | llasram | ener2: just using a 2-element vector is generally the idiomatic way to represent a pair. |
| 05:03 | llasram | xfel: Not really. 1.4 added reader tagged literals, but everything else and since has pretty much been bug fixes and standard library features |
| 05:03 | llasram | xfel: See https://github.com/clojure/clojure/blob/master/changes.md for the details |
| 05:05 | xfel | llasram: Ok, thanks. (Asked because I picked up a book from 2012 which seemed nice, Clojure Programming by Chas Emerick, and would be a bit silly spending time on "old material") |
| 05:06 | llasram | Good choice. And yeah, anything covering 1.3 or later should be pretty much still relevant. |
| 05:39 | thesaskwatch | Hi, anyone knows how to encode url when using clj-http? |
| 05:42 | karls | thesaskwatch: i've used java.net.URLEncoder with success before |
| 05:42 | thesaskwatch | karls: thanks |
| 06:21 | martinklepsch | anyone experience using nth-child selectors with garden? I can't require garden.selectors that contains some nth-child related things |
| 06:34 | ener2 | what am I doing wrong here? |
| 06:34 | ener2 | (let [trgs (.split com.badlogic.gdx.graphics.g2d.TextureRegion texture tw th)] |
| 06:34 | ener2 | I get No matching method found: split for class java.lang.Class |
| 06:35 | ener2 | why is it getting java.lang.Class instead of com.badlogic.gdx.graphics.g2d.TextureRegion ? |
| 06:36 | broquaint | ener2: If it's a static method then com.badlogic.gdx.graphics.g2d.TextureRegion/splot should work IIRC. |
| 06:36 | rolfb | broquaint: s/splot/split ? |
| 06:36 | broquaint | That too :) |
| 06:36 | ener2 | I get |
| 06:36 | ener2 | CompilerException java.lang.RuntimeException: No such namespace: .com.badlogic.gdx.graphics.g2d.TextureRegion, compiling:(simvivor/loader.clj:37:22) |
| 06:37 | ener2 | with |
| 06:37 | ener2 | (let [trgs (.com.badlogic.gdx.graphics.g2d.TextureRegion/split texture tw th)] |
| 06:37 | broquaint | Drop the leading dot. |
| 06:37 | ener2 | ah okay thanks |
| 06:37 | ener2 | hmm |
| 06:38 | ener2 | No matching field found: length for class [[Lcom.badlogic.gdx.graphics.g2d.TextureRegion; |
| 06:38 | ener2 | you can't query java arrays same way? |
| 06:39 | broquaint | The same way as? |
| 06:39 | ener2 | well |
| 06:39 | ener2 | array.length |
| 06:39 | ener2 | (.length array) |
| 06:39 | broquaint | ,(let [a (int-array '(1 2 3))] (.length a)) |
| 06:40 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: length for class [I> |
| 06:40 | broquaint | ,(let [a (int-array '(1 2 3))] (alength a)) |
| 06:40 | clojurebot | 3 |
| 06:41 | broquaint | http://clojure.org/java_interop |
| 06:42 | broquaint | ^^ Should have all the answers :) |
| 06:49 | llasram | ener2: Yeah, the property-like query for array length is a Java syntax feature vs a JVM feature. Clojure distinguishes between them, I assume due to dynamism -- otherwise w/o full type information, you'd have this weird special case in the Clojure compiler for any attempt to access a property named `length` |
| 06:50 | ener2 | ah alright |
| 06:50 | ener2 | hmm is (for [foo (range x)] (...)) |
| 06:50 | ener2 | 0 based or 1 based? |
| 06:51 | llasram | ~tias |
| 06:51 | clojurebot | Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance. |
| 06:51 | llasram | :-) |
| 06:51 | ener2 | because it ignores the whole thing if I have (range 1) ... |
| 06:51 | llasram | ,(range 1) |
| 06:51 | clojurebot | (0) |
| 06:53 | ener2 | http://pastebin.com/4VRzr1QW |
| 06:54 | ener2 | it nevers gets into that (let [array (nth trgs i)] block |
| 06:54 | ener2 | even if range returns ä0) |
| 06:54 | ener2 | *(0) |
| 06:56 | Bronsa | ener2: for is lazy |
| 06:56 | clgv | ener2: you misunderstood `for`. `for` is lazy and its body is only executed if elements are requested or the whole lazy sequence is forced |
| 06:56 | ener2 | I found this is how you do for loops in clojure.... |
| 06:56 | Bronsa | ener2: use (dotimes [i times] ..) rather than (for [i (range times)] ..) |
| 06:56 | clgv | ener2: that's wrong. `for` constructs a lazy sequence, so for each "loop" you get an element in a lazy sequence |
| 06:57 | clgv | ener2: in your example you want to replace it with `reduce` |
| 06:57 | Bronsa | ener2: also struct maps have been deprecated in favour of records for years |
| 06:57 | llasram | Aaaand the `conj` onto `output` is treating it like something mutable, when instead it will yield a new persistent value each time, never accumulating anything |
| 06:58 | ener2 | llasram: yeah forgot setting |
| 06:58 | clgv | ener2: llasram comment is the reason why you want a `reduce` there ;) |
| 06:59 | llasram | And destructuring -- your highest-level `let` could be written as `(let [[symbol path tw th ft] pair] ...)` |
| 06:59 | llasram | In fact, you could ditch the `let` entirly and stick the whole binding form in the `doseq` |
| 06:59 | ener2 | hmm you can't set! into let variable? |
| 06:59 | llasram | Oh dear no |
| 06:59 | ener2 | I come from CL background so... |
| 06:59 | llasram | We are polite and functional around here |
| 06:59 | ener2 | well that is all and dandy but not all the time :) |
| 06:59 | clgv | ener2: yeah you should forget how you' program in the "mutable world" for now ;) |
| 07:00 | llasram | As clgv suggested, a `reduce` is probably what you want, "mutating" via iterative application to successive return values |
| 07:01 | ener2 | hmm, unless closure has yield... |
| 07:01 | llasram | Also, you can directly iterate over arrays -- no need to access by index |
| 07:01 | llasram | ener2: OOC what resource/s are you learning from? |
| 07:02 | ener2 | llasram: google and right now finished watching https://www.youtube.com/watch?v=7mbcYxHO0nM |
| 07:03 | ener2 | how will reduce help in this case? |
| 07:03 | ener2 | I need to basically flatten array of arrays into list |
| 07:04 | llasram | I'd suggest checking out one of the introductory books (like the O'Reilly one -- there are others, but I can vouch for that one). Even if you have a Lisp background, introducing the functional stuff can be helpful |
| 07:04 | llasram | Well, we were saying `reduce` because of the accumulation you have in the most-nested form form of your loops, but |
| 07:05 | ener2 | in lisp I would accumunalte into list, either with setf into it or loop append/loop collect ... |
| 07:05 | llasram | You may just want to directly accumulate a lazy seq... |
| 07:05 | llasram | What is trgs? A 2-dimensional array? |
| 07:05 | ener2 | yes |
| 07:05 | ener2 | 2-dimensional java array |
| 07:06 | llasram | Try replacing the whole thing with (mapcat seq trgs) :-) |
| 07:08 | ener2 | hmm interesting |
| 07:08 | ener2 | it seems to work |
| 07:09 | ener2 | I guess (seq java-array) returns list containing that array content? |
| 07:12 | clgv | ener2: almost it returns a specialized sequence but it only matters that it is a sequence |
| 07:14 | clgv | ener2: you can checkout http://www.braveclojure.com/ |
| 07:15 | ener2 | clgv: thanks |
| 07:15 | ener2 | I am really fond of common lisp (even made thesis about it) but I have to work in java in company, so I am trying some crazy things (like this :P) |
| 07:19 | clgv | ener2: well clojure fits perfectly in this scenario ;) |
| 07:22 | CookedGryphon | can anyone think of a neat way to express "first of the following statements to fulfil this predicate", ideally short circuiting like and/or |
| 07:23 | CookedGryphon | and i want the value of the thing, not the value of the predicate |
| 07:23 | opqdonut | I often have (defn find-first [p s] (first (filter p s))) |
| 07:24 | CookedGryphon | yeah, I have that option or a load of nested ifs, neither of which I'm 100% happy with |
| 07:24 | CookedGryphon | as if the first one matches, I shouldn't have to calculate the second |
| 07:27 | ener2 | CookedGryphon: well I don't know about closure but it is possible in lisp so it might be |
| 07:27 | ener2 | if you find how, you can wrap it in macro for something easier to use |
| 07:28 | ener2 | you nca use throw/catch |
| 07:28 | ener2 | *can |
| 07:28 | ener2 | and build macro around it |
| 07:30 | john2x_ | CookedGryphon: I think opqdonut's suggestion does what you need? filter is lazy, so it it will just calculate up to the first match |
| 07:30 | CookedGryphon | john2x_: yes, but I have fewer than 32 items in the list and each is expensive to compute individually |
| 07:30 | CookedGryphon | and so laziness gives me no benefit |
| 07:31 | CookedGryphon | it doesn't matter, I'll just take the hit and if it's a problem rewrite it with if-lets |
| 07:31 | ener2 | kinda shame clojure does not have function exist as in return-from <block> value ... |
| 07:31 | ener2 | *exits |
| 07:31 | opqdonut | CookedGryphon: can't you call seq to unchunk the sequence? |
| 07:32 | clgv | CookedGryphon: expensive item calculation where you possibly dont need each item is exactly one of the shining use cases for lazy sequences ;) |
| 07:32 | opqdonut | err, no, I'm raving |
| 07:33 | opqdonut | but anyway, use a non-chunked sequence |
| 07:33 | opqdonut | see e.g. seq1 in http://stackoverflow.com/questions/12412038/in-clojure-are-lazy-seqs-always-chunked |
| 07:33 | clgv | CookedGryphon: you should avoid chunked sequences though, e.g. no (range n) but you can use (take n (iterate inc 0)) |
| 07:34 | CookedGryphon | I think I have a better solution, |
| 07:34 | CookedGryphon | I'm just going to rewrite my predicate to return the value or nil |
| 07:34 | CookedGryphon | and then use or |
| 07:35 | CookedGryphon | which looks neat, conveys the intention properly, and has no lazy sequence overheads or chunking uncertainties |
| 07:35 | clgv | but wasnt part of the problem that you have more than 4 items? |
| 07:38 | IceD^ | question - I have clojure app (http api) handling ~150K rps, each request in the end will consume some amount of some resource - {:r1 100 :r2 200 :r3 100500} - there are ~10K resources. request processing code will build list of resources that could be consumed and will try to consume each of them sequentually till success (e.g. request can [[:r1 200], [:r2 10]]) |
| 07:40 | IceD^ | so question is - what to use to handle this mutable state - e.g. refs, external kv, ...? |
| 07:42 | IceD^ | on typical load most "popular" resources can be accessed ~10K tps |
| 08:05 | danielszmulewicz | ,(clojure.walk/macroexpand-all '(-> (read) (eval) (println) (loop-forever))) |
| 08:05 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk> |
| 08:06 | danielszmulewicz | ,(require 'clojure.walk) |
| 08:06 | clojurebot | nil |
| 08:06 | danielszmulewicz | |
| 08:06 | danielszmulewicz | ,(clojure.walk/macroexpand-all '(-> (read) (eval) (println) (loop-forever))) |
| 08:06 | clojurebot | (loop-forever (println (eval (read)))) |
| 08:06 | danielszmulewicz | ,(macroexpand '(-> c (+ 3) (* 2))) |
| 08:06 | clojurebot | (* (+ c 3) 2) |
| 08:07 | danielszmulewicz | ,(clojure.core/macroexpand '(-> c (+ 3) (* 2))) |
| 08:07 | clojurebot | (* (+ c 3) 2) |
| 08:09 | danielszmulewicz | ,(clojure.walk/macroexpand-all '(-> routes |
| 08:09 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 08:09 | danielszmulewicz | (wrap-transit-params) |
| 08:09 | danielszmulewicz | (wrap-datomic (env :db-url)) |
| 08:09 | danielszmulewicz | (wrap-defaults api-defaults))) |
| 08:10 | danielszmulewicz | oops |
| 08:16 | noncom|2 | i need to pass a form to a macro, and then return it as read but not evaled. however, whatever i try, the form gets evaled inside the macro. how could i acheive the desired result ? |
| 08:17 | noncom|2 | like (defmacro m [form] `(.doSomethingJava java-object ~form)) |
| 08:17 | noncom|2 | the java method should receive the actual form, which is read, but not evaled |
| 08:17 | noncom|2 | ? |
| 08:17 | ohpauleez | You don't want to escape the form, potentially |
| 08:18 | noncom|2 | what do you mean? i should not use ` ? |
| 08:18 | ohpauleez | not use ~ |
| 08:19 | ohpauleez | wait, nvm. That would take the actually symbol form |
| 08:19 | noncom|2 | nope.. it simply treats "form" as a symbol |
| 08:19 | noncom|2 | yeah |
| 08:19 | noncom|2 | so i am still wandering.. :) |
| 08:19 | noncom|2 | so it gets inside the macro read, but not evaled.. |
| 08:19 | noncom|2 | theeeeen... |
| 08:19 | noncom|2 | ? |
| 08:20 | noncom|2 | i think that ~ implies evaluation.. |
| 08:20 | noncom|2 | am i right ? |
| 08:20 | noncom|2 | i can make all work if i pass a manually quoted form |
| 08:21 | noncom|2 | but these additional manual quotes will be annoying if i get to many calls like that.. |
| 08:21 | ohpauleez | quote it |
| 08:21 | ohpauleez | like this: (defmacro a [f] `(prn '~f)) |
| 08:21 | noncom|2 | wow, gotta try now.. |
| 08:22 | noncom|2 | umm, it still evals the form |
| 08:23 | noncom|2 | but quotes the result |
| 08:23 | ohpauleez | On your repl (or in a comment block), use the code I pasted above |
| 08:23 | ohpauleez | and call: (a (inc 1)), you'll see "(inc 1)" |
| 08:24 | ohpauleez | that's not what you want? |
| 08:24 | noncom|2 | oh wait, maybe i made a mistake, just a sec |
| 08:25 | noncom|2 | ohpauleez: right, i made a mistake, i had "defn" instead of "defmacro" :) your last proposed solution works just fine! |
| 08:25 | noncom|2 | thank you |
| 08:25 | ohpauleez | Excellt! |
| 08:25 | clojurebot | no, thank *you*: http://nedroid.com/2010/11/thanks-for-reading-my-comics/ |
| 08:25 | ohpauleez | np, more than happy to help! |
| 08:26 | ohpauleez | wow, I think I need to charge my keyboard, it's dropping letter |
| 08:26 | noncom|2 | also i think you're on mac |
| 08:26 | noncom|2 | am i right ? |
| 08:26 | ohpauleez | Correct |
| 08:26 | ohpauleez | (currently) |
| 08:27 | noncom|2 | heh.. sometimes the symbol gets inserted by mac |
| 08:27 | noncom|2 | instead of spaces |
| 08:27 | noncom|2 | idk why |
| 08:27 | noncom|2 | sometimes when my boss, who's on mac, writes me in skype, his messages are full of this symbol |
| 08:27 | noncom|2 | so weird :) |
| 08:28 | noncom|2 | the symbol is a dot in the middle of the line (not in the bottom, like the normal dot, more like the dot-the-multiplication-sign) |
| 08:53 | llasram | CookedGryphon: scrolling back, you could also use an eager version of `first-filter`: https://gist.github.com/llasram/995be648aa22e0630ce8 |
| 08:59 | the-kenny | ClojureScript/Closure Question: I have (def ^:export enable-validation false) in a project. I'd like to be able to set this at runtime from the js-console (or some <script> tag) to enable/disable validation for production builds or on-demand. The problem: Closure inlines the `false' in the functions which are responsible validation. I need some kind of ^:volatile meta-data for this use-case, but couldn't |
| 08:59 | the-kenny | find anything yet. Any ideas? |
| 09:00 | the-kenny | (If there isn't anything like this, I'd just check for some property on the window object, but I find that quite ugly) |
| 09:04 | dnolen_ | the-kenny: yeah ^:export doesn't work for configurable properties - that why we generally export functions to do this like set-print-fn! |
| 09:05 | the-kenny | dnolen_: That sounds reasonable, thanks |
| 09:09 | clgv | llasram: linter alert! please use `when` ;) |
| 09:15 | the-kenny | dnolen_: Btw. we're running our application built entirely in Om in production for some time now. We're super happy with it. As I already said in Krakow: Thanks for Om :) |
| 09:15 | TimMc | clgv: or add a nil alternative clause |
| 09:16 | TimMc | I've been coming around to technomancy's view on if/when. |
| 09:16 | dnolen_ | the-kenny: awesome! :) |
| 09:17 | daniel___ | can anyone explain to me when and why transducers could be better than reducers? |
| 09:17 | daniel___ | they seem to accomplish more or less the same, but with arguments in a different order |
| 09:18 | daniel___ | and are built into code as a one-less arity |
| 09:18 | daniel___ | core* |
| 09:18 | dnolen_ | daniel___: reducers aren't reusable in the same way |
| 09:18 | dnolen_ | daniel___: transducers can be composed via function composition and then applies to lazy sequences, core.async buffers etc. |
| 09:19 | dnolen_ | not possible w/ reducers - and transducers subsume reducer behavior |
| 09:19 | daniel___ | reducers can't also be composed? |
| 09:19 | clgv | TimMc: that view consists of adding unnecessary nils? |
| 09:20 | dnolen_ | daniel___: not in the same way no. |
| 09:20 | daniel___ | reducers you have to nest like (r/filter even? (r/map inc [...])) rather than comp |
| 09:20 | bhauman | Morning all. Are people generally using Webjars and serving them through ring for static client side js libs? |
| 09:20 | daniel___ | reducers can be composed with comp too |
| 09:21 | bhauman | Or are there downsides like libs not getting downloaded when deploying to prod? |
| 09:21 | dnolen_ | daniel___: but you must supply something concrete, the interface just doesn't work for something like core.async buffers for example |
| 09:22 | dnolen_ | daniel___: in the transducer case the channel can take the transducer stack since there are no assumptions about how it will actually be used. |
| 09:22 | dnolen_ | s/the channel/the core.async channel |
| 09:24 | dnolen_ | daniel___: fundamentally reducers must take a reducible thing (in the Clojure sense), not true for transducers. |
| 09:27 | TimMc | clgv: Depends on your definition of "unnecessary". Swearjure, for instance, eschews unnecessary alphanumerics... |
| 09:28 | daniel___ | dnolen_: it's a little clearer, thanks |
| 09:29 | thesaskwatch | I have a question - I have an app which is supposed to read an external config file (which willl be clojure code). So I want to read it dynamically but also pass some values to it. How to do it the best way? |
| 09:29 | clgv | TimMc: the context was clojure :P |
| 09:30 | alandipert | bhauman, we have the https://github.com/tailrecursion/hoplon/tree/master/vendor system for boot-based cljs projects, with conventions that amene to gclosure etc |
| 09:30 | the-kenny | thesaskwatch: so you want to *eval* the code in the config file? |
| 09:30 | clgv | TimMc: I'd hesitate to add additional (unnecessary) noise |
| 09:30 | thesaskwatch | the-kenny: yes .. it's supposed to be a config which returns data (kind of dsl) |
| 09:32 | thesaskwatch | the-kenny: to be more specific - it's a program which provisions some heroku componens - I want to separate configuration from execution engine |
| 09:33 | TimMc | clgv: The idea is to have "when" signal "side-effects ahead!" |
| 09:34 | TimMc | I'm the wrong person to defend this idea, though. |
| 09:35 | clgv | TimMc: well it also signals you did not forget the else-clause ;) |
| 09:36 | enn | Is HoneySQL is the best current option for generating SQL? In particular, is there anything out there that already supports window functions? |
| 09:39 | TimMc | clgv: I think that's the part that attracts me more. |
| 09:39 | thesaskwatch | the-kenny: however if I *eval* it - how can I pass some external values to it? |
| 09:43 | thesaskwatch | Ok, I guess this is the way: http://stackoverflow.com/a/8630122/343699 |
| 09:48 | llasram | clgv: `when` is for side-effects :-p |
| 09:49 | clgv | ,(doc when) |
| 09:49 | clojurebot | "([test & body]); Evaluates test. If logical true, evaluates body in an implicit do." |
| 09:49 | clgv | llasram: not by contract :P |
| 09:50 | TimMc | meh |
| 09:50 | clgv | llasram: I have a lot of when-usage in absence of side-effects ;) |
| 09:50 | llasram | Sure, but by increasingly-common convention; which convention I happen to follow |
| 09:51 | hyPiRion | I tend to mutate vectors, as there's no contract saying I cannot do so |
| 09:52 | clgv | if you think about it there probably should have been (when pred expr) and a (dowhen pred expr1 ... exprN) |
| 09:53 | hyPiRion | ,(let [a [0 1 2]] (aset (.tail a) 0 10) (conj a 1)) |
| 09:53 | clojurebot | [10 1 2 1] |
| 09:56 | llasram | (inc hyPiRion) |
| 09:56 | lazybot | ⇒ 42 |
| 09:59 | TimMc | ,(let [a [0]] (aset (.tail a) 0 a) a) |
| 09:59 | clojurebot | [[[[[[[[[[#]]]]]]]]]] |
| 09:59 | TimMc | Suck it, haskell! |
| 09:59 | TimMc | I can tie a knot too. |
| 10:00 | hyPiRion | hehe |
| 10:01 | clgv | ,(binding [*print-level* 100] (let [a [0]] (println (aset (.tail a) 0 a) a))) |
| 10:01 | clojurebot | [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[#]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[#]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]... |
| 10:25 | mikerod | hyPiRion: I still don't really get why these fields are public |
| 10:26 | hyPiRion | mikerod: rrb-tree compat afaik |
| 10:26 | hyPiRion | want to share structure with it |
| 10:26 | mikerod | hyPiRion: share with what? |
| 10:26 | mikerod | another core datastructure? |
| 10:27 | Bronsa | mikerod: a contrib datastructure |
| 10:27 | mikerod | Bronsa: oh.. |
| 10:27 | Bronsa | mikerod: I mean, rrb-tree is a contrib ds, it needs to share structure with clojure vectors |
| 10:29 | mikerod | Bronsa: this sounds like a strange reason to make a public field on a core data structure of the main language :P |
| 10:30 | Bronsa | mikerod: that public field is an implementation detail and not part of the public API anyway |
| 10:30 | Bronsa | you're not supposed to use it |
| 10:30 | mikerod | I think that is fairly clear. |
| 10:30 | mikerod | I just pretend it is not there |
| 10:30 | mikerod | However, I'd hope others do to. |
| 10:31 | Bronsa | mikerod: nobody but TimMc and hyPiRion know about that field. |
| 10:31 | hyPiRion | mikerod: Well, I use it for the exact same reason as the rrb-tree impl. |
| 10:31 | hyPiRion | haha |
| 10:32 | mikerod | Which is for - efficiency? |
| 10:33 | hyPiRion | mikerod: right. I'm implementing a data structure which can be efficiently converted from a persistent vector, and uses same structural sharing |
| 10:34 | mikerod | hyPiRion: hmm, I see |
| 10:36 | sdegutis | Hi. |
| 10:36 | sdegutis | "Caused by: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@4fc5fa85 rejected from java.util.concurrent.ThreadPoolExecutor@51cf0670[Shutting down, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 94]" |
| 10:37 | oskarkv | I have a function that returns code, that I usually use inside a macro. But if I want to skip the macro, can I just eval the result of the function (the code)? I think I remember that someone said that using eval like that is not exactly the same thing, because the environment might be different, or something. |
| 10:37 | sdegutis | Please help. Thanks? |
| 10:39 | Bronsa | sdegutis: nobody can help you with just that exception line and no context |
| 10:39 | sdegutis | Thanks. |
| 10:39 | hyPiRion | sdegutis: we need some context |
| 10:39 | sdegutis | Yes. |
| 10:39 | llasram | sdegutis: BTW, have you considered providing some context? |
| 10:40 | sdegutis | Hi. |
| 10:40 | llasram | :-) |
| 10:40 | sdegutis | This is caused by a failed Datomic query on a background thread. |
| 10:40 | sdegutis | I'll give you the relevant line of code if you promise to give it back when you're done. |
| 10:40 | sdegutis | Because we need it for our website to run. |
| 10:41 | llasram | oskarkv: Well, compiling a macro-expansion vs explicit eval uses nearly the same mechanisms but with very different semantic implications. What exactly are you trying to achieve? |
| 10:43 | sdegutis | Here is a secret gist. |
| 10:43 | sdegutis | https://gist.github.com/sdegutis/00a9cdecc632abd12f3b |
| 10:43 | sdegutis | I will now change to the nick starlord. |
| 10:43 | starlord | Now I am using it. |
| 10:44 | llasram | starlord: But now you've changed color :-( |
| 10:44 | starlord | Yes. That is part of my special powers. |
| 10:44 | starlord | But don't worry it's just an optimal allusion. |
| 10:44 | starlord | I also own star-lord and star_lord. |
| 10:47 | oskarkv | llasram How about something like this https://www.refheap.com/a5c6a638ef7b0733f0ebefdf5 |
| 10:47 | oskarkv | my internet connection is very bad, took forever to paste that :P |
| 10:48 | peeja | Hey, folks. I just went through the two Om tutorials on its wiki, and I'm looking for some good Om code to read, particularly code that persists data back to the server-side. Any suggestions? |
| 10:48 | starlord | Thanks in advance. |
| 10:50 | oskarkv | llasram it just seems unnecessary to do use the version with a macro. Wasn't sure if the version with eval is the same thing. |
| 10:50 | oskarkv | -do |
| 10:54 | maravillas | peeja: about halfway through the om readme is a list of applications written using om |
| 10:55 | llasram | Oh, top-level `eval`. Yeah, AFAIK that should be pretty much equivalent to defining a macro then immediately using it at top-level. |
| 10:56 | starlord | Hello. |
| 10:56 | llasram | ^ oskarkv on the last, obv |
| 10:56 | AlwaysBCoding | peeja: https://github.com/sgrove/omchaya ? |
| 10:56 | starlord | Is there some reason that might cause me to get an exception when in the background thread but not in the frontground thread? |
| 10:57 | llasram | starlord: Did someone call `shutdown-agents`? |
| 10:57 | starlord | Not beforehand, no. |
| 10:57 | starlord | Oh wait, yes. |
| 10:57 | llasram | Well there you go |
| 10:57 | starlord | Thanks in advance llasram. |
| 10:57 | starlord | You've solved it for me :) |
| 10:58 | oskarkv | llasram ok, thanks. Just out of curiosity, when is `eval` not equivalent to normal evaluation? |
| 10:59 | starlord | Well, this solves the latest mystery. But it doesn't solve the original one. |
| 10:59 | starlord | I think maybe it's just because Datomic is a giant hoarder. |
| 11:00 | llasram | oskarkv: Oh, when you call it at runtime (for whatever "runtime" means in your application) |
| 11:00 | alandipert | oskarkv, eval'd forms don't capture locals is one big difference |
| 11:00 | alandipert | ,(let [x 1] (eval 'x)) |
| 11:00 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 11:01 | oskarkv | I see |
| 11:01 | oskarkv | Thanks |
| 11:04 | zot | heeeeello, within my .lein/profiles.clj, if i have multiple :jvm-opts, should it be of the form [["-Dfoo"] ["-Dbar"]], or something else? |
| 11:08 | oskarkv | zot I think ["op1" "op2"] |
| 11:10 | peeja | AlwaysBCoding: That looks perfect, thanks! |
| 11:12 | zot | oskarkv: tnx! |
| 11:18 | clgv | zot, oskarv: did that change? previously it was just a string with all options |
| 11:19 | clgv | ah no, you are right, a vector of strings per parameter |
| 11:19 | oskarkv | I dunno. I tried it yesterday and it worked. |
| 11:30 | eric_normand | anyone know of any Clojure consulting opportunities? |
| 11:32 | clgv | eric_normand: you want to consult companies how to use clojure? or you want someone to consult you? |
| 11:33 | eric_normand | clgv: I will consult them. Not necessarily training. Also contract work. |
| 11:34 | clgv | eric_normand: hmm the cognitect people will know some, but they are your competition ;) |
| 11:34 | clgv | *competitors |
| 11:34 | justin_smith | I have a retainer doing clojure work for my ex employer (after a couple of years of being a full time clojure dev, so it's a downgrade) |
| 11:44 | starlord | clgv: they aren't /quite/ competitors, as they can't take on /every/ client, and must turn some away; i.e. there is room for taking up their scraps :) |
| 11:45 | eric_normand | I've heard mixed things about Clojure consulting |
| 11:45 | eric_normand | some say there isn't much work |
| 11:45 | eric_normand | some say there's a ton |
| 11:45 | starlord | I personally would not use Clojure for web apps anymore, now that I've worked on a Clojure web app for the last 2 years. |
| 11:45 | clgv | starlord: maybe, maybe not... |
| 11:45 | starlord | I would just work on Rails. |
| 11:46 | clgv | starlord: why? |
| 11:46 | starlord | Because in Rails all the web-related functionality is done for you, all you have to do is bring the application logic; in Clojure you have to reinvent every wheel, hoping some are already invented for you. |
| 11:47 | starlord | And to be honest, I have not found Clojure's unique features (homoiconicity, macros, immutability, threads) to be significantly more helpful than using Ruby for solving most problems. |
| 11:47 | clgv | starlord: ah ok, so you need the ORM stuff and associated features? |
| 11:48 | mgaare | starlord: what libs were you using in your clojure web stack? |
| 11:48 | rboyd | starlord: did you do rails before your clojure web project? on a large scale? |
| 11:49 | starlord | clgv: no, but for example Rails has many security features built-in which in Clojure we do not have equivalent libraries for yet. |
| 11:49 | starlord | mgaare: ring, compojure, hiccup, garden, datomic, probably some others |
| 11:50 | starlord | rboyd: I've consulted on very large, ugly Rails projects. |
| 11:50 | starlord | rboyd: But the ugliness was not caused by the largeness; the apps would have been large either way. The ugliness was simply because they were implemented in a hurry. |
| 11:51 | rboyd | still waiting to see a large elegant rails codebase |
| 11:51 | starlord | Right now we have a mycompany.web namespace and a mycompany.features namespace; if I were to port it to Rails, the .web namespace would just be Rails controllers and models and such, and the .features namespace would be somewhere under lib/ or whatever it's called. |
| 11:52 | mgaare | starlord: I've found that compojure/ring tend to get ungainly above a certain size, but liberator makes things quite a bit nicer |
| 11:58 | justin_smith | so, one of the lead csound devs is writing a synthesis engine, inspired by supercollider with similar planned features to overtone, in clojure |
| 11:59 | justin_smith | the difference from overtone is that clojure will be used not just to define "instruments" staticaly and send events, but clojure will run inside the synthesis units themselves |
| 11:59 | TimMc | What's wrong with SC and overtone, one might ask. |
| 11:59 | justin_smith | see my last |
| 11:59 | TimMc | hmm |
| 12:00 | justin_smith | an actual programming language inside the synth |
| 12:00 | TimMc | Why not Lua? :-P |
| 12:00 | justin_smith | right now you have two languages - a weak one to run synths, and a powerful one on the client (controlling) side |
| 12:00 | justin_smith | csound has lua embedded, so that is an existing option |
| 12:00 | TimMc | (I don't actually know Lua, but it seems popular for fast and lean scripting.) |
| 12:01 | justin_smith | but this way we can use clojure, if we like it, and it's the full stack |
| 12:01 | starlord | mgaare: thanks, looking into it |
| 12:02 | justin_smith | TimMc: anyway, I find it interesting because Steven Yi knows his shit with audio synthesis (being one of the lead devs on csound for a while now). He has also been adding clojure inspired features to csound, maybe this is part of a master plan of some sort |
| 12:04 | justin_smith | TimMc: my experience, which I think is part of Yi's motivation, is that you have to juggle three layers of implementation to do serious work in most audio synthesis languages: the engine/plugins, written in C/C++, the synthesis language, made by chaining said plugins (not a full language by any means), and the control language, some kind of scripting language for building calls to and creation of said chains of plugins |
| 12:05 | justin_smith | TimMc: there is something very attractive about just using a reasonable language and flattening the three levels (if the language can handle all these roles) |
| 12:06 | justin_smith | TimMc: for example, in overtone you have macros that look like clojure code, but aren't, they are actually a DSL that emulates clojure but builds chains of plugins to run in the supercollider engine process |
| 12:07 | justin_smith | there's an overhead to remembering what's clojure and what's a DSL over scsynth |
| 12:13 | martinklepsch | anyone experience using nth-child selectors with garden? I can't require garden.selectors that contains some nth-child related things |
| 12:13 | TimMc | justin_smith: Interesting. I haven't played enough with Overtone to run into that. |
| 12:25 | starlord | Is there a channel-specific way to hide joins/quits/parts on the server-side? |
| 12:27 | amalloy | hide them on the server side? that doesn't make sense. the server has to tell you who's in the room; it's your client who decides what to print on your screen |
| 12:27 | starlord | Thanks. |
| 12:28 | starlord | I should edit my client then, becuase it only allows this toggle universally, not per-channel. |
| 12:28 | starlord | That resolves my question. Thanks. |
| 12:30 | TimMc | starlord: If you're using irssi it looks like /ignore -network freenode #clojure JOINS PARTS QUITS NICKS |
| 12:30 | eric_normand | does anyone know how to print out the profile names that are being pulled in with lein? |
| 12:30 | starlord | TimMc: Thank you in advance. I am not using irssi but thank you anyway. |
| 12:30 | starlord | I should use irssi, but I don't own a slicehost account anymore. |
| 12:31 | TimMc | The syntax may be similar for your client. |
| 12:31 | TimMc | (particularly the level names) |
| 12:31 | starlord | I have tried it and saw no effect. I will perhaps ask in #limechat. |
| 12:31 | starlord | Thank you for your time in advance. Thanks. |
| 12:33 | starlord | What is a good alternative to slicehost for hosting your own persistent irssi between two computers these days? Thanks in advance, Regards. |
| 12:33 | starlord | Oh wait this is off topic now. |
| 12:33 | starlord | My apologies. |
| 12:36 | amalloy | starlord: you may be looking for what's called a bouncer. znc is a good one |
| 12:37 | starlord | Thank you amalloy in retrospect. |
| 13:30 | andonilsson | is it only possible to have one binding in an if-let? |
| 13:31 | andonilsson | ...and if I want more local bindings I should put them in a separate let, within the if-let |
| 13:31 | tanzoniteblack | andonilsson: correct |
| 13:35 | andonilsson | guess that makes sense |
| 13:35 | andonilsson | thx tanzoniteblack |
| 13:35 | justin_smith | ,(if-let [[a & bs] (range 5)] bs) |
| 13:35 | clojurebot | (1 2 3 4) |
| 13:35 | justin_smith | yes, destructuring works in if-let |
| 13:36 | justin_smith | wait, nobody mentioned destructuring |
| 13:36 | justin_smith | clearly I am out to lunch |
| 13:36 | starlord | Destructuring is probably the one feature I'd miss the most if I were to go back to Rails. |
| 13:36 | andonilsson | justin_smith: that might actually work in my case...I think |
| 13:37 | tanzoniteblack | destructuring inside an if-let and cause things to not quite work like you might expect: |
| 13:37 | tanzoniteblack | ,(if-let [[a b c d e f] (concat (range 5) [nil])] f) |
| 13:37 | clojurebot | nil |
| 13:38 | tanzoniteblack | which makes sense, since if-let is only testing a, but if you're expecting it to be checking for all of the args to be truthy you're going to have some bugs |
| 13:38 | technomancy | ruby has destructuring, kinda |
| 13:38 | andonilsson | in my case I have a re-find in my if-let, so it'll work for me |
| 13:38 | amalloy | tanzoniteblack: it's not testnig a; it's testing the entire sequence |
| 13:38 | amalloy | ie, testing that the sequence is neither nil nor false |
| 13:39 | tanzoniteblack | makes sense, thanks for the clarification amalloy |
| 13:40 | tanzoniteblack | ,(if-let [[a b c d e f] (repeat 6 nil)] (boolean f)) |
| 13:40 | clojurebot | false |
| 13:45 | splunk | anyone know how to get the name of anonymous fn? `(name (fn foo [] 42))` |
| 13:46 | starlord | Oh good question. |
| 13:46 | clgv | can I disable shrinking in test.check? |
| 13:46 | starlord | Another good one. |
| 13:46 | starlord | So far so good everyone, nice job. |
| 13:47 | Bronsa | splunk: you can, but that needs |
| 13:47 | Bronsa | splunk: but that needs to deal with how the compiler munges the generated classname |
| 13:47 | splunk | Bronsa: ah, so it won't be the symbol 'foo |
| 13:47 | Bronsa | splunk: why do you need it? the name of the anon fn is only usable from within the function |
| 13:48 | Bronsa | splunk: no, but ##(class (fn foo [])) you can get it back from this |
| 13:48 | lazybot | ⇒ sandbox5671$eval14042$foo__14043 |
| 13:48 | splunk | Bronsa: trying to construct the following. given (fn foo ..) => {:f <fn> :name 'foo} |
| 13:48 | justin_smith | ,(if-let [[a & bs] (cons nil (range 5))] bs) ; tanzoniteblack it does not work like that |
| 13:48 | clojurebot | (0 1 2 3 4) |
| 13:49 | splunk | Bronsa: could do it with a custom macro, trying to avoid it |
| 13:49 | tanzoniteblack | justin_smith: yeah, amalloy pointed out that it's testing the entire sequence, not a |
| 13:50 | justin_smith | yeah, I'm still out to lunch, I see that now |
| 13:50 | splunk | Bronsa: or even just {'foo <fn>, 'bar <fn>} |
| 13:50 | amalloy | maybe you should have some actual lunch, justin_smith |
| 13:51 | Bronsa | splunk: (defn fn-name [f] (symbol (clojure.repl/demunge (first (clojure.string/split (last (clojure.string/split (.getName ^Class (class f)) #"\$")) #"__"))))) should work |
| 13:51 | amalloy | Bronsa: (class f) is already hinted to return Class; no need to hint it there |
| 13:51 | Bronsa | amalloy: oh, yeah |
| 13:52 | amalloy | but more importantly i'd lean towards "dude are you sure you really want to do this, it is a super-weird thing" and not "here is some gibberish you can paste into your program that will work most of the time" |
| 13:52 | llasram | (inc amalloy) |
| 13:52 | lazybot | ⇒ 156 |
| 13:52 | splunk | Bronsa: you just blew my mind. Thanks! Will consider this carefully vs. the macro vs. none of the above. |
| 13:53 | arohner | if you're going to go the macro route, another option is to stick the 'real' name in metadata |
| 13:53 | llasram | splunk: OOC, why do you want these names? |
| 13:54 | technomancy | it's super annoying that the name isn't already in the metadata |
| 13:54 | splunk | arohner: thanks, I've been looking at metadata more and more, I don't have strong understanding of how it works (e.g. if it's associated with the symbol rather than the value, what if the values is bound to a different symbol??) |
| 13:54 | technomancy | though the arglists would be more useful than the name |
| 13:54 | llasram | Well, otherwise each instance would need to have a separate copy of the metadata map in case some one mut... Oh, wait |
| 13:55 | amalloy | Bronsa: clojure.repl/demunge is nice, though. i didn't know about that. but there are multiple munging schemes the compiler uses, right, for different scenarios? like the munging for a function name is different from the munging for the field of a deftype, i think |
| 13:55 | technomancy | <3 vary-meta |
| 13:55 | amalloy | i guess technically it should be spelled mungeing |
| 13:56 | arohner | splunk: I'm confused about your use of 'symbol' there. fns are just objects. There's no binding unless you use def or let |
| 13:56 | llasram | splunk: metadata is implemented via the `clojure.lang.{IMeta,IObj}` JVM interfaces. Any JVM type can carry metadata by implementing those interfaces |
| 13:57 | splunk | llasram: long story short: (defn make-ring-handler [db other-dep] (fn my-handler [request] <response-goes-here>)) ;; would like 'my-handler to be somehow associcated with the returned fn |
| 13:58 | splunk | the point of the gymnastics is so that `db` and `other-dep` are closed over in the handler |
| 13:58 | Bronsa | amalloy: TBH I don't think deftype fields get munged at all |
| 13:58 | arohner | splunk: I'd use metadata |
| 13:58 | technomancy | (inc metadata) |
| 13:58 | lazybot | ⇒ 1 |
| 13:58 | technomancy | huh, just one? |
| 13:59 | llasram | splunk: Ok, but again why? Where are you intending to use the name? |
| 13:59 | amalloy | Bronsa: they do |
| 13:59 | amalloy | ,(deftype Foo [-_$*x]) |
| 13:59 | clojurebot | sandbox.Foo |
| 13:59 | amalloy | ,(seq (.getFields Foo)) |
| 13:59 | clojurebot | (#<Field public final java.lang.Object sandbox.Foo.__$_STAR_x>) |
| 13:59 | amalloy | it's not even a reversible mungeing: you can't tell the _ apart from the - |
| 14:00 | Bronsa | amalloy: uh, ok |
| 14:00 | llasram | amalloy: Sure you can. '_' is culturally verboten in all identifiers |
| 14:00 | jonasen | Bronsa: That was a great read on the mailing list. You've done an amazing amount of work on these libraries! |
| 14:00 | amalloy | oh, llasram. treasure your youthful innocence |
| 14:00 | TimMc | snake_case_forever |
| 14:01 | llasram | wow, typing |
| 14:01 | ToxicFrog | snake-cases? |
| 14:01 | Bronsa | jonasen: thanks! |
| 14:01 | llasram | ToxicFrog: cf, typing |
| 14:01 | amalloy | ,(do (require 'clojure.repl) (clojure.repl/demunge "__$_STAR_x")) |
| 14:01 | clojurebot | "--/*x" |
| 14:02 | arohner | ToxicFrog: foo_bar, rather than foo-bar or FooBar |
| 14:02 | hiredman | metadata on functions is terrible, don't do it |
| 14:02 | TEttinger | gah, amalloy! |
| 14:02 | amalloy | demunge is *super* wrong for deftype fields. which is fine, since the docstring says it's for lambda names. just noting that there is another way to munge and it's not easy to reverse |
| 14:03 | Bronsa | amalloy: I was confused because (deftype x [-x]) (.--x (x. 1)) works, but it obviously works because field names in field access gets munged too |
| 14:04 | amalloy | ,(defrecord Bar []) |
| 14:04 | clojurebot | sandbox.Bar |
| 14:04 | splunk | arohner: thanks will check it out. disregard my comment about metadata on symbols, I was keying off http://clojure.org/metadata, which says it applies to symbols, or collections, but `(meta ^{:k "v"} (fn [] 42))` appears to totally work |
| 14:04 | Bronsa | also there are some places in the compiler where munging is just s/-/_/ but I can't remember where. probably just for namespaces |
| 14:04 | amalloy | ,(.---meta (Bar.)) |
| 14:04 | clojurebot | nil |
| 14:04 | amalloy | ,(.-meta (Bar.)) |
| 14:04 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: meta for class sandbox.Bar> |
| 14:04 | arohner | splunk: probably old docs. meta got added to fns in 1.2? 1.3? |
| 14:04 | hiredman | splunk: don't do it |
| 14:05 | hiredman | metadata on functions is terrible |
| 14:05 | arohner | hiredman: could you provide reasons rather than just asserting? |
| 14:05 | arohner | splunk: oh, one more question, is this just for debugging informative purposes, or are you running production code based on (meta f)? |
| 14:07 | splunk | llasram: arohner: long story short, I have a tree of functions, I am doing a tree traversal where I want to say "find fn in tree with id 'foo" |
| 14:07 | hiredman | arohner: metadata is implemented for functions as values, but functions as values for things like equality is very complex, the with-meta contract returns "new" value with the extra metadata, doing that for functions (bits of compiled byte code that close over state) is problematic |
| 14:07 | hiredman | arohner: the way it is implemented in clojure also leaves a lot to be desired |
| 14:07 | dopamean | ive got sort of noob question if anyone is up for it. |
| 14:08 | amalloy | ~ask |
| 14:08 | clojurebot | The Ask To Ask protocol wastes more bandwidth than any version of the Ask protocol, so just ask your question. |
| 14:08 | hiredman | ,(let [f (fn [] 1) y (with-meta f {:a 1})] [(class f) (class y)]) |
| 14:08 | clojurebot | [sandbox$eval187$f__188 clojure.lang.AFunction$1] |
| 14:08 | llasram | splunk: I'd recommend just associating a keyword name with the fn object when you build the tree. |
| 14:08 | arohner | splunk: that sounds.... strange |
| 14:08 | dopamean | thanks amalloy |
| 14:08 | arohner | hiredman: thanks |
| 14:08 | hiredman | metadata is almost always the wrong answer |
| 14:08 | dopamean | so ive got a vector of maps |
| 14:08 | llasram | splunk: No need to have the function object itself know its name, especially since that ties the name of the object implementation to the name w/in the context of your tree |
| 14:08 | ToxicFrog | hiredman: I like metadata :( it's been quite good to me in spellcast |
| 14:09 | Bronsa | also functions with metadata print horribly ##(with-meta (fn x []) {}) |
| 14:09 | lazybot | ⇒ #< clojure.lang.AFunction$1@500d3200> |
| 14:09 | ToxicFrog | dopamean: a good start. |
| 14:09 | hiredman | given the contract of with-meta those instances should be equal, but given the equality semantics of functions, they are not |
| 14:09 | arohner | it's nice to have, but I don't use meta "in production" |
| 14:09 | hiredman | ,(let [f (fn [] 1) y (with-meta f {:a 1})] (= (class f) (class y))) |
| 14:09 | clojurebot | false |
| 14:09 | dopamean | all of them have the same keys in them and i want to return one of the maps where a given key returns a particular value |
| 14:09 | amalloy | i'm kinda bummed about that, bronsa, since i thought a ticked of mine improving the printing of that had been applied |
| 14:09 | technomancy | hiredman: that's an argument against calling vary-meta on functions and keeping the original function around |
| 14:09 | splunk | llasram: yeah that seems like the safe option, was hoping to not have to re-specify the name, but totally fine |
| 14:09 | technomancy | hiredman: adding metadata to a function and discarding the original doesn't run into those problems |
| 14:10 | amalloy | ,(with-meta (fn x []) {}) |
| 14:10 | Bronsa | amalloy: it has, lazybot runs 1.4 though |
| 14:10 | clojurebot | #<clojure.lang.AFunction$1@597692> |
| 14:10 | hiredman | technomancy: it still does |
| 14:10 | amalloy | ah, yes. it prints slightly better in real life |
| 14:10 | Bronsa | amalloy: but I was talking about the lack of "x" in the class name, not about the extra space |
| 14:10 | dopamean | something like... [{"name" "nick"} {"name" "max"} {"name" "alan"}]. so if the name is alan i want to get back that entire map |
| 14:10 | hiredman | technomancy: you get an AFunction wrapper around the original function with all the problems of wrappers |
| 14:10 | technomancy | like say you have a macro that returns a function and you want to know the arities. doing that without metadata is terrible. |
| 14:11 | amalloy | dopamean: (first (filter #(= "alan" (get % "name")) maps)) |
| 14:11 | TEttinger | damn that was fast amalloy |
| 14:11 | amalloy | although of course if you're doing lookups like this often, you should use a better data structure than a list of maps |
| 14:11 | TEttinger | (inc amalloy) |
| 14:11 | lazybot | ⇒ 157 |
| 14:11 | splunk | arohner: yeah it's weird, but I'm playing with the concept that web routes are just a tree, which sort of makes a lot of sense to me. Similar to this: https://github.com/elliot42/siesta |
| 14:11 | dopamean | thank amalloy |
| 14:11 | dopamean | ill play around with that |
| 14:11 | amalloy | TEttinger: i was bummed i couldn't use (comp #{"alan"} :name) because his maps have string keys |
| 14:11 | hiredman | technomancy: given that by definition metadata isn't considered when checking equality, should function arity information be part of the metadata? |
| 14:12 | technomancy | hiredman: that kind of question only makes sense if you have sensible equality semantics for functions to begin with |
| 14:13 | hiredman | technomancy: metadata on values only makes sense if you have sensible equality semantics for the values |
| 14:13 | hiredman | which clojure doesn't for functions, so metadata on functions is a terrible idea |
| 14:13 | technomancy | that's an interesting assertion, but it appears groundless |
| 14:13 | ToxicFrog | amalloy: along similar lines, I keep getting tripped up by (some p xs) returning (p x) rather than x when it finds something. |
| 14:13 | hiredman | which one? |
| 14:14 | amalloy | ToxicFrog: yes, i hate the contract for 'some, but it's been water under the bridge for a long time |
| 14:14 | technomancy | the notion that metadata doesn't work with identity-based equality |
| 14:14 | technomancy | you can put metadata on atoms, and they have identity-based equality |
| 14:14 | hiredman | technomancy: you skipped part of the assertion |
| 14:14 | hiredman | technomancy: "metadata on values ..." |
| 14:14 | Bronsa | hiredman: we often use metadata as a way to work-around the lack of mutiple values returns, in that context metadata on functions makes sense |
| 14:15 | justin_smith | dopamean: amalloy: if doing frequent "name" lookups, there is always ##(group-by #(get % "name") [{"name" "bob"} {"name" "joe"} {"name" "al"}]) |
| 14:15 | lazybot | ⇒ {"bob" [{"name" "bob"}], "joe" [{"name" "joe"}], "al" [{"name" "al"}]} |
| 14:15 | hiredman | technomancy: clojure effectively has two parallel metadata systems for values and identities |
| 14:15 | hiredman | functions are plugged in to the value system |
| 14:15 | hiredman | in a way that makes things terrible |
| 14:15 | technomancy | hiredman: this seems like a distinction you're inventing to defend your position |
| 14:15 | hiredman | technomancy: it isn't alter-meta vs. vary-meta |
| 14:16 | hiredman | Bronsa: nah, that sounds pretty terrible too |
| 14:17 | Bronsa | hiredman: I partially agree, but I find it more useful than I find it "terrible" |
| 14:17 | technomancy | hiredman: oh, ok... interesting. there isn't any overlap. |
| 14:17 | technomancy | I assumed vary-meta worked on identities, but it blows up |
| 14:18 | technomancy | but I still agree with Bronsa |
| 14:18 | hiredman | Bronsa: using binding to setup a return stack seems better |
| 14:18 | technomancy | it's a much better way of expressing introspectable arity than the alternatives |
| 14:19 | Bronsa | hiredman: and use a map of fn -> value? I never thought about it |
| 14:19 | amalloy | Bronsa: not everything you want to return can support metadata anyway. what if i want to "multiple return" the values 1 and 2? |
| 14:19 | Bronsa | hiredman: I guess that could be an ok alternative, but that assumes you always have the thread-local binding set |
| 14:19 | hiredman | the problem is, functions are sort of values, have value metadata, but identity eqaulity due to Entscheidungsproblem |
| 14:20 | amalloy | Bronsa: well, you need something like multiple-value-bind to establish the thread-local binding that's set!-able by the function you're calling |
| 14:20 | mthvedt | hiredman: i don’t think it’s neccesary to solve the decision problem to have a meaningful definition of function equality |
| 14:20 | Bronsa | amalloy: yeah obviously, I was just making a case for fns |
| 14:20 | hiredman | Bronsa: no, I mean, logcally returns happen on a stack, a returning function pushes a value to return on to the stack, the caller pops it off the return stack to consume it |
| 14:20 | Bronsa | amalloy: hiredman with metadata the caller doesn't need to worry or even know about the fn having metadata attached if it doesn't care about it |
| 14:21 | hiredman | so you use binding to steup a thread local stack, and called functions push extra return values to it, and calling functions pop them off |
| 14:21 | amalloy | Bronsa: indeed, using metadata for multiple returns is a scheme that's easy to invent. i've done it myself. i just don't like it very much |
| 14:22 | technomancy | if only destructuring worked with metadata |
| 14:23 | hiredman | the problem with metadata is it is so easy to (mis)use that people grab it and use it for whatever terrible purpose |
| 14:29 | technomancy | anyway, I think it's pretty clear that just because functions have identity-based equality doesn't mean that they're intended to act as reference types |
| 14:30 | starlord | technomancy: you are correct. |
| 14:30 | starlord | technomancy: equality for functions is a very controversial topic and not widely agreed upon; in short, do not rely on testing functions for equality. |
| 14:30 | starlord | technomancy: I hope that helps. Thanks in advance. Regards. |
| 14:31 | bbloom | starlord: wait, what's controversial? |
| 14:32 | starlord | bbloom: Correct. |
| 14:32 | bbloom | function equality is proven undecidable |
| 14:32 | starlord | bbloom: You are correct. |
| 14:32 | bbloom | and clojure functions are compiled, so structural equality doesn't make sense... |
| 14:32 | bbloom | and the default equality procedure is reference equality |
| 14:33 | bbloom | soooo seems like a total no-brainer to me... |
| 14:33 | clojurebot | Excuse me? |
| 14:33 | technomancy | proven undecidable doesn't mean there's no way to know whether two functions are ever the same |
| 14:33 | technomancy | I mean, for all pairs of functions |
| 14:33 | bbloom | technomancy: what good is an equality function that *sometimes* works? |
| 14:34 | llasram | true, false, FileNotFound |
| 14:34 | bbloom | yeah, seriously... equal, not-equal, and not-sure |
| 14:34 | starlord | bbloom: Now you see, it is controversial. |
| 14:34 | TimMc | true, false, and (System/exit 17) |
| 14:34 | bbloom | starlord: nope, still no controversy |
| 14:34 | technomancy | bbloom: I dunno, bloom filters are a thing? =) |
| 14:34 | sritchie | dnolen_: hey david, if you’re around, got a Q for you about component design |
| 14:35 | starlord | bbloom: Correct, there is disagreement. |
| 14:35 | bbloom | starlord: nope, there's a misunderstanding.... |
| 14:35 | sritchie | dnolen_: working on the documentation site for this om-bootstrap project: https://github.com/racehub/om-bootstrap |
| 14:35 | starlord | Thanks in advance. |
| 14:35 | bbloom | technomancy: bloom filters implement a different contract |
| 14:35 | starlord | Regards. |
| 14:35 | bbloom | technomancy: the contract of equals (or clojure equiv) is that it provides a decision procedure |
| 14:36 | dnolen_ | sritchie: actually gotta run, catching a plane |
| 14:36 | bbloom | technomancy: a heuristic procedure is, by definition, not Object.equals |
| 14:36 | dnolen_ | sritchie: ping me later |
| 14:36 | technomancy | bbloom: I think could be room conceptually for another predicate, that's all |
| 14:36 | technomancy | certainly not c.c/= |
| 14:36 | starlord | There are cases where two functions may be equal due to the same definition even though they are compiled as anonymous functions twice. |
| 14:36 | sritchie | dnolen_: has to do with prop mutation, I’ll write a mailing list note |
| 14:36 | Bronsa | starlord: can you please stop with thist "Thanks in advance. Regards" thing? it's honestly pretty annoying |
| 14:36 | starlord | I am not aware of whether Clojure optimizes this use-case. |
| 14:36 | sritchie | for sure, thanks! |
| 14:36 | starlord | Bronsa: Noted. |
| 14:36 | Bronsa | starlord: thanks |
| 14:36 | starlord | Bronsa: Pleasure. |
| 14:37 | bbloom | technomancy: now *that* is a controversy :-) |
| 14:37 | bbloom | technomancy: whether or not having multiple defined equality predicates in your core language is a good idea, and if so which :-P |
| 14:37 | technomancy | bbloom: well, we have identical? and = |
| 14:37 | starlord | Imagine this line of code: (fn[] (fn[a b] (+ a b))) |
| 14:37 | starlord | It will return twice the same identical function, with no lexical captures. But are they equal? That is dependent on the compiler, even though we may infer that it clearly is. |
| 14:38 | starlord | It may not be, although that is up to the JVM compiler as well as the Clojure compiler. |
| 14:38 | technomancy | bbloom: and == |
| 14:38 | starlord | Now this is clearly problematic: how can we rely on equality testing for functions if we don't know whether they will always return intuitive results? |
| 14:38 | hiredman | technomancy: I find this pretty funny given the arguments we've had were you insist egal solves everything and I say equality is difficult and the only reasonable thing is to have lots of predicates ala common lisp |
| 14:38 | starlord | Herein lies the initial problem. |
| 14:38 | bbloom | there are actually schema implementations that compare closures by comparing each closed over value |
| 14:38 | bbloom | *cringe* |
| 14:39 | technomancy | hiredman: huh? I've never said egal should be the only predicate. |
| 14:39 | technomancy | hiredman: just that egal is necessary but not sufficient |
| 14:39 | bbloom | one things certainly clear: egal is by far the best default |
| 14:39 | starlord | I hope this is now clear so that the confusion is resolved. |
| 14:39 | kirill | hi all, I'm new to clojure. someone recommended that I use this (https://github.com/abarbu/sanity). any thoughts on this from someone who knows more than I do (which should be anybody at this point)? |
| 14:40 | technomancy | hiredman: obviously you can't be self-hosting without having identical? so that seems like a bit of a straw man to begin with. |
| 14:40 | bbloom | i'd also argue that you can (in theory, but not as well in practice) encode any equality scheme in to egal by inventing new equality-class wrappers |
| 14:41 | amalloy | kirill: i would not touch this sanity thing |
| 14:41 | kirill | amalloy: how come? |
| 14:42 | amalloy | the readme indicates that it was written by a grumpy person with experience in some other lisp |
| 14:42 | technomancy | wow |
| 14:42 | technomancy | kirill: yeah, this guy has no idea what he's doing |
| 14:42 | kirill | can you elaborate why he has no idea? |
| 14:43 | kirill | I mean, I'm happy to throw around accusations as much as the next guy, but you know what I mean :) |
| 14:43 | amalloy | the "improvements" he made don't fit with the rest of clojure, and if you use them you'll be writing this weird language that nobody but you or he can deal with |
| 14:43 | amalloy | like, (seq ()) throwing an exception? that is the worst thing you could possibly do. it will break every function that exists |
| 14:43 | technomancy | kirill: he doesn't understand how syntax-quote's auto-qualification affects Clojure's macro system |
| 14:44 | amalloy | technomancy: well, i can sympathize with wanting something like #`. i've wanted it myself on occasion |
| 14:44 | amalloy | sometimes i just want to build a list, not write a macro |
| 14:44 | bbloom | amalloy: there's backtick! :-) |
| 14:44 | TimMc | ,`(~@()) ;; wait, really? |
| 14:44 | clojurebot | nil |
| 14:44 | amalloy | ,`() |
| 14:44 | clojurebot | () |
| 14:44 | bbloom | https://github.com/brandonbloom/backtick ; w00t |
| 14:44 | Bronsa | TimMc: I've already made a patch for that! |
| 14:45 | TimMc | This doesn't match the complaint-- oh, OK. |
| 14:45 | amalloy | Bronsa: just replacing the call to 'seq with a call to 'sequence? |
| 14:45 | technomancy | "The scoping of def and defn is broken yet for some reason they're still allowed outside the toplevel." doesn't really seem to understand what vars are either? |
| 14:45 | Bronsa | amalloy: correct |
| 14:45 | Bronsa | I can't find the ticket now because jira sucks |
| 14:46 | Bronsa | but trust me on that. |
| 14:46 | kirill | technomancy: eh... again I'm new here, but I don't find it productive to say "oh he doesn't understand what he's doing" without some more elaboration? I mean, I guess you seem like you know what you're doing, so can you elaborate what you mean? |
| 14:46 | bbloom | kirill: in short, he has invented a new language |
| 14:46 | bbloom | kirill: his individual complaints/changes may or may not be a good idea |
| 14:46 | Bronsa | here http://dev.clojure.org/jira/browse/CLJ-1444 |
| 14:46 | bbloom | but the result is "Not Clojure (tm)" |
| 14:47 | technomancy | kirill: he appears to be complaining about def's scoping, which indicates he doesn't understand that the point of it is to create a var, not to act like CL's setq |
| 14:47 | tanzoniteblack | kirill: at least for learning Clojure, it'd be a bad idea to use a library that attempts to completely re-write subsections of the language. The most obvious reason being it will be very difficult to get help on here or stackoverflow (or just google) with any issues you run into, because they very well might be caused solely due to those changes |
| 14:47 | llasram | Hmm, and he redefines some things in clojure.core. Like `let` |
| 14:47 | mthvedt | kirill: also, the docs suggest he doesn’t understand clojure’s decisions |
| 14:47 | mthvedt | always be suspicious of people who disagree with things they don’t understand |
| 14:47 | kirill | mthvedt: perhaps understands vs. agrees? :) |
| 14:48 | bbloom | some of the comments are kinda funny |
| 14:48 | alandipert | looks fun to me |
| 14:48 | alandipert | all the best stuff seems to come from grumpy lisp people! |
| 14:48 | amalloy | i like bbloom's explanation |
| 14:48 | mthvedt | kirill: well, if a guy is creating a new way because he doesn’t trust a widely trusted existing way… the bayesian infrerence is his new way probably won’t make sense due to a lack of understanding |
| 14:48 | kirill | I dunno, I don't mean to antagonize anyone, but only about two people so far managed to provide some kind of productive explanations as to why they don't like it as opposed to "comments are kinda funny" |
| 14:48 | technomancy | my suspicion is he's a CL fan who was forced to write clojure and treats every divergence from CL as a mistake |
| 14:48 | mthvedt | like his comment about |
| 14:48 | lavokad | hi, how can fix "Fireplace: :Connect to a REPL or install classpoath.vim" message? I have classpath.vim install. Each time i want to use fireplace, i need to manually :Connect to running repl |
| 14:48 | mthvedt | This default behaviour (of quasiquote) leads to a lot of strange and broken code |
| 14:49 | kirill | mthvedt: I think he means that quasiquote has context-sensitive behaviour, which can produce surprises when you just need to construct a list? |
| 14:49 | llasram | kirill: He layers a different language on top of Clojure, by re-defining core constructs to support what he considers to be "more sane" interfaces/behaviors (usually CL/Scheme-derived). |
| 14:49 | bbloom | https://github.com/abarbu/sanity/blob/master/src/sanity/core.clj#L238-L244 |
| 14:49 | bbloom | weeee |
| 14:49 | bbloom | what if i want tenth? |
| 14:49 | bbloom | WHERE DOES IT END!?! |
| 14:49 | mthvedt | kirill: right, but the design goal of quasiquote is a way to write hygenic macros |
| 14:50 | llasram | kirill: The result will probably yield all sort of unexpected interactions, and will be a this little isolated tower of not-really-Clojure |
| 14:50 | kirill | mthvedt: do people write macros more often than lists in clojure? |
| 14:50 | kirill | |
| 14:50 | bbloom | kirill: the tradeoff is different |
| 14:50 | hiredman | bbloom: ony can only hope he will fork the compiler and gnerate as needed |
| 14:50 | bbloom | kirill: most of the time when you create a list, you have the data you want in locals, or can get it via fn calls |
| 14:51 | amalloy | oh man. i was reading the description of https://github.com/abarbu/sanity/blob/master/src/sanity/improvements.clj#L115, and i misread it in a way that made me really interested |
| 14:51 | mthvedt | kirill: personally, i almost never use lists, unless you count calls to `cons` |
| 14:51 | bbloom | kirill: but when creating a list for a template, you want to stop evaluation |
| 14:51 | bbloom | kirill: it's pretty rare you want to create a list that isn't code but also want to prevent evaluation |
| 14:51 | amalloy | i misread "bracketing" as "backtracking", because i'd also read the macro name as "conde" |
| 14:51 | technomancy | kirill: yes. since clojure has vectors, they're used more often than lists for literals. |
| 14:51 | mthvedt | the only time i can think of where i manipulate lists programatically is when i’m doing complicated macros |
| 14:51 | bbloom | kirill: yeah, and what technomancy said about vectors |
| 14:51 | technomancy | also symbols are used very rarely outside macros because of keywords |
| 14:52 | lemonodor | i am sympathetic to the cond (and let) bracketing complaint. |
| 14:52 | bbloom | i often want an `each` function, but he apparently hasn't seen doseq: https://github.com/abarbu/sanity/blob/12081bd2b61db5f58a8158827066a3e02a23eb20/src/sanity/core.clj#L249-L250 |
| 14:52 | llasram | And evidence that he doesn't understand the language he's replacing: https://github.com/abarbu/sanity/blob/master/src/sanity/improvements.clj#L18 |
| 14:52 | kirill | technomancy: what is the difference (practically) between using keywords and symbols? |
| 14:52 | jonasen | https://github.com/abarbu/sanity/blob/master/src/sanity/core.clj#L164 should obviously be renamed to tau |
| 14:52 | llasram | Which is a lot of work over (defn core-count @#'clojure.core/count) (if he really needed that) |
| 14:52 | technomancy | kirill: keywords evaluate to themself |
| 14:53 | kirill | llasram: sorry, but I can't take what you say seriously, because so far it seems like it's just direct accussations without backup :( |
| 14:53 | TimMc | kirill: I think it handles sequences better (nil != ()) but other than that it's not enough to justify a language replacement. |
| 14:54 | llasram | kirill: THat's why I explained. He says "it'd be nice if I could get a handle to these functions; oh well, now I'll copy-paste in a whole bunch of code instead". When really there's a simple way to get a handle to them |
| 14:54 | kirill | hmm so far this experience is somewhat strange. there are about 2-3 people here who are discussing things productively, and an array of people just posting insults and various troll-level messages that don't contribute anything. is this common for channels like this? |
| 14:54 | bbloom | kirill: the problem is the tone of the prose in the sanity project |
| 14:54 | bbloom | ...even the name "sanity" |
| 14:55 | bbloom | it reads like an attack, so people counter-attack |
| 14:55 | kristof | kirill: Yes. |
| 14:55 | technomancy | yeah, it's pretty clearly a troll to begin with |
| 14:55 | kristof | What's the context here? |
| 14:55 | hiredman | technomancy: and he didn't even bother to call it lava |
| 14:55 | amalloy | kristof: not really. #clojure is pretty friendly most of the time |
| 14:55 | kirill | but if we remember for a moment that we are not obligated to impress anyone, can we please discuss "sanity" in an objective manner such that we can hopefully do something productive here? |
| 14:55 | technomancy | "I'm forced to use clojure at work, but no one can force me to like it" afaict |
| 14:55 | TimMc | kirill: People also get tired of seeing these kinds of things over and over again, so people jump to ridicule pretty quickly. |
| 14:55 | technomancy | hiredman: missed opportunity! |
| 14:55 | kristof | technomancy: But, briefly, what's his/her problem? |
| 14:56 | amalloy | lemonodor: interestingly, you can define a let+ that supports both styles of bracketing |
| 14:56 | bbloom | kristof: decreased brain plasticity? |
| 14:56 | technomancy | kristof: CL superiority complex would be my guess |
| 14:56 | TimMc | bbloom: Not helpful. |
| 14:56 | kristof | Oh, well I've got one of those, so now I'm interested. |
| 14:56 | amalloy | (let+ [foo 1 (bar 2)] (+ foo bar)) ; the open paren doesn't make any sense in clojure's let, so this must be a lispy bracketing |
| 14:57 | kirill | bbloom: see? this is exactly what I'm talking about. you're probably a nice person, so why did you write that? we're not here to shit on anyone. the editorial choices of the dude on github don't have to turn all of us into insult machines =) |
| 14:57 | bbloom | sheesh, it was a joke... |
| 14:57 | kristof | I still don't know what this person even said. |
| 14:57 | kirill | a joke usually contains some element of cleverness or surprise at the end, which causes people to laugh. I didn't see that in that statement, which was just an insult |
| 14:57 | rweir | yowzer |
| 14:57 | kirill | so again, please... |
| 14:58 | TimMc | kristof: They linked to https://github.com/abarbu/sanity and people weren't impressed. |
| 14:58 | kirill | on the technical side, and if we ignore the editorial choices there, are there any *good* ideas in that repository? |
| 14:58 | amalloy | and you can do similarly with cond+, sorta: (cond+ (even? x) :even [(odd? x) :odd]); here it's a [ that doesn't make sense in clojure's cond, so you can use that to disambiguate |
| 14:59 | llasram | kirill: the `sanity.reader` namespace provides something which could be helpful, but bbloom's "backtick" does it better |
| 14:59 | technomancy | TimMc: oh, in some sense it's impressive; the level of dedication to his tribe. it's just not something that should be inflicted upon a Clojure beginner. =) |
| 14:59 | lavokad | hi, how can fix "Fireplace: :Connect to a REPL or install classpoath.vim" message? I have classpath.vim install. Each time i want to use fireplace, i need to manually :Connect to running repl |
| 14:59 | bbloom | kirill: defining infinity in core would be useful for clj/cljs compat |
| 14:59 | llasram | kirill: The `sanity.core` namespace has some reasonable-looking helpers, but there are many well-establish (flatland/useful, primsatic/plumbing) |
| 14:59 | tanzoniteblack | kirill: there seem to be some good ideas, like https://github.com/abarbu/sanity/blob/12081bd2b61db5f58a8158827066a3e02a23eb20/src/sanity/core.clj#L255 , but the problem is that that's already implemented in clojure core with mapv |
| 14:59 | amalloy | lemonodor: now, i wouldn't advocate actually using either of those macros, but it's neat that you can get the two styles of cond/let to coexist peacefully |
| 14:59 | bbloom | similarly, for the static functions on the java Math class |
| 15:00 | TimMc | kirill: The empty-seq-is-never-nil thing is good, but many of the other good things could just be used with Clojure as-is and do not demand a new language. |
| 15:00 | bbloom | tanzoniteblack: and mapv does it better too, with transients |
| 15:01 | amalloy | TimMc: i don't understand what you mean about the empty seq |
| 15:01 | mthvedt | timmc: i don’t agree with his complaints about seq equality, including that one. in clojure you are not supposed to generally compare seqs without putting them into the same data structure |
| 15:01 | mthvedt | because in both clojure and java, different data structures have different equality impls |
| 15:02 | kirill | mthvedt: is it appropriate to have a generic+deep+polymorphic equality tester for cases where the particular speed of the operation is of no consequence to the app in question? |
| 15:02 | bbloom | i genuinely don't understand how anybody can think it's a good idea to (def car first) (def cdr rest) .... |
| 15:02 | kirill | bbloom: why? |
| 15:02 | bbloom | i get it, you like car and cdr.... but really, clojure lists are always proper, so caddadadddr is never useful |
| 15:03 | kirill | bbloom: are some list selection procs (car, cdr, etc.) more frequently used than others? |
| 15:03 | hiredman | what I don't understand is why he doesn't just use a scheme or common lisp for the jvm, it seems like he would be so much happier |
| 15:03 | Bronsa | also frffrrffrest is so much better. |
| 15:03 | amalloy | bbloom: i don't think proper vs improper lists is terribly relevant to whether caddaaadadadr is useful |
| 15:03 | kristof | bbloom: There's a lot of anti-interface mentality in here. |
| 15:03 | lemonodor | bbloom: the issue of taking things typically used via java interop and moving them into clojure itself for consistency with clojurescript and other implementations seems like a thread that could be pulled on for quite a distance. do you have any general thoughts on that strategy? |
| 15:03 | bbloom | amalloy: it's somewhat relevant, but even more relevant is the fact that we have maps and destructuring :-P |
| 15:04 | TimMc | amalloy: I don't like punning nil with empty seqs. I agree with that author that it leads to too many problems. |
| 15:04 | kristof | bbloom: (def string-ref "Alias for clojure.core/nth" nth). What is the point of this? |
| 15:04 | bbloom | lemonodor: i think that if there is a function that is obviously available and consistent cross-platform, it should be surfaced in a non-interop way. however, i don't think we should try to patch up platform differences |
| 15:04 | TimMc | amalloy: That said, we're basically stuck with that. |
| 15:05 | amalloy | bbloom: did you ever see the with-cxrs macro i wrote, to bring the glory of caddaddddaaaadr to clojure? |
| 15:05 | bbloom | kristof: porting CL code? |
| 15:05 | bbloom | amalloy: haha, yes, hilarious |
| 15:05 | kristof | bbloom: I don't know anyone who likes the fact that there are a million different "nth" implementations for every datatype in CL. |
| 15:06 | bbloom | kristof: no idea |
| 15:06 | mthvedt | kirill: i think if you’re comparing equality in a ‘generic’ way that ignores structure and behavior, that’s probably a code smell |
| 15:06 | bbloom | like i said, it's quite clear that this guy (knowningly or not) wants a different language |
| 15:06 | kristof | bbloom: Or the fact that there's a "copy-list" and a "copy-seq" which essentially do the same thing. |
| 15:06 | bbloom | and the beauty of lisp is that you can make any language you want |
| 15:06 | bbloom | ... as long as it's another lisp |
| 15:06 | kirill | bbloom: I think anyone who introduces proposals for improving clojure wants a "different language". it's just that some of them make it and some don't.. |
| 15:06 | bbloom | i take issue with his tone, however |
| 15:07 | kirill | there is no reason for you to feel personally offended by his tone. he probably doesn't know you and not writing it specifically to upset you :P |
| 15:07 | bbloom | kirill: there's a point when two cultures are separated for so long that their common language diverges in to two distinct languages, rather than two distinct dialects |
| 15:08 | amalloy | kirill: you seem offended by the things bbloom is saying, even though he's not saying them to offend you |
| 15:08 | bbloom | kirill: growing a language by adding definitions or idioms does not a new language make |
| 15:08 | amalloy | arguably this is because some of them are offensive, whether he intends it or not; the stuff in sanity is pretty offensive too |
| 15:08 | bbloom | kirill: replacing fundamental sentence structure? that's a new language... |
| 15:08 | kirill | amalloy: I'd like to avoid the one-uppery gymnastics just by pointing out that we're trying to discuss the technical aspects of that repository, nothing else.. |
| 15:09 | bbloom | amalloy: other than the brain plasticity joke, have i said something offensive? |
| 15:09 | amalloy | bbloom: nothing that offends *me* |
| 15:10 | amalloy | although for example "i genuinely don't understand how anybody can think it's a good idea to (def car first) (def cdr rest)" is a lot like "anyone who thinks this is bad at thinking" |
| 15:10 | bbloom | amalloy: well ok then :-P |
| 15:10 | Raynes | I want to know what happened but don't feel like all the ridiculousness in backlog. |
| 15:10 | AeroNotix | Same. |
| 15:10 | kristof | Raynes: Some guy posted a library that fixes things he doesn't like in clojure, and people find it silly. |
| 15:10 | bbloom | amalloy: no, i really think that it's a bad idea to define car and cdr on clojure list.... car and cdr are operations on pairs, not lists |
| 15:11 | Raynes | Oh, I see. |
| 15:11 | kristof | bbloom: Why does that change anything? |
| 15:11 | kirill | but lists are made of pairs, so the distinction appears academic at best |
| 15:11 | Raynes | So it immediately turned into a discussion not about his actual code, but about how offensive the response was. |
| 15:11 | kristof | A list is a pair whose cdr is another list or nil. *shrug* |
| 15:12 | Raynes | So, as per usual in these sorts of things, drama vs usefulness. |
| 15:12 | kirill | the fact that car "could" operate on an improper list doesn't change the fact that it can be used "safely" with proper lists? |
| 15:12 | bbloom | i think it's a perfectly reasonable idea to (def first car) and (def rest cdr) if you take the implicit restriction that first and rest are only defined for proper lists |
| 15:12 | bbloom | ... made of pairs |
| 15:12 | kristof | Rest won't work on an improper list, right? |
| 15:12 | kristof | Then I agree with that sentiment. |
| 15:12 | xeqi | but I was going to use them on a vector |
| 15:12 | kirill | it will, but it will return a value such that (null? x) => #t |
| 15:12 | bbloom | xeqi: then you need polymorphism |
| 15:13 | bbloom | :-) |
| 15:13 | kirill | I mean, that's in scheme, not clojure :) |
| 15:13 | amalloy | kristof: but lists actually *aren't* made of pairs in clojuer |
| 15:13 | kristof | amalloy: What? What the hell are they made of, then? |
| 15:13 | amalloy | or at any rate seqs aren't, and rest works on seqs, not on lists |
| 15:14 | kristof | No, I was talking about lists, not seqs. |
| 15:14 | AeroNotix | kristof: you can't do dotted pairs, either |
| 15:14 | bbloom | kristof: https://github.com/clojure/clojure/blob/43cc1854508d655e58e377f84836ba128971f90c/src/jvm/clojure/lang/PersistentList.java#L18-L20 |
| 15:14 | bbloom | they are counted and the "rest" must also be an IPersistentList |
| 15:14 | bbloom | you can't put a non-list in the "cdr" cell |
| 15:14 | hiredman | what I don't understand is the persistent attachement to this library |
| 15:15 | AeroNotix | a link again to the library? |
| 15:15 | kristof | AeroNotix: yes, I'm aware. |
| 15:15 | TimMc | AeroNotix: *sigh* If I must... https://github.com/abarbu/sanity |
| 15:15 | kristof | Someone should just put it in the topic and declare Clojure dead. |
| 15:16 | hiredman | like "hey, I am new to clojure, is this any good" <a channel full of people, many of whom write clojure for a living> "no" <continued arguing> |
| 15:16 | kirill | hiredman: not sure what your point is :) |
| 15:16 | bbloom | hiredman: i've moved on to discussion pairs :-P |
| 15:16 | Raynes | In general, if you are one single person and you write a library called 'sanity' to fix an 'insane' language, you're probably kinda into yourself. |
| 15:17 | viperscape | lol |
| 15:17 | kirill | I suppose I ought to get information from a place where the level of discussion is more aimed towards the productive.. |
| 15:17 | Raynes | "Hey guys, I've decided Clojure is insane and wrote this to fix it. Y'all best use it now." |
| 15:17 | kirill | I don't understand what's so hard in not making things personal |
| 15:17 | kristof | I wish I could inline assembly into clojure, and use go-tags, but *no* |
| 15:17 | bbloom | kirill: i take that personally. |
| 15:17 | kristof | This language is insane. |
| 15:17 | kirill | wow... okay, thanks to everyone who tried to help. |
| 15:17 | kirill | |
| 15:18 | Raynes | kirill: People have addressed every single thing. |
| 15:18 | hiredman | kirill: my point is, you approached the channel as clojure novice asking if this is any good, and you got your answer from clojure experts, but you just seem to want to argue about it, which makes me wonder if you wrote this or something |
| 15:18 | Raynes | I don't know what more you're asking for. |
| 15:18 | Raynes | Nobody is trying to be hateful, this guy was hateful first. |
| 15:18 | kristof | (def list->vector vec) (def vector->list seq) |
| 15:18 | kirill | hiredman: hah no, I didn't write sanity... this isn't my "shtick" where I write controversial (apparently) libraries and then pretend I didn't, hah |
| 15:18 | Raynes | From what I can tell reading backlog, people have picked this apart and proved that he lacks some fundamental understanding of the things he is trying to fix. |
| 15:18 | kristof | What exactly is the point of any of this library |
| 15:19 | Raynes | I'm not gonna give him a hug for that. |
| 15:19 | kirill | Raynes: they haven't "proved" it though |
| 15:19 | kristof | kirill: I've been posting examples this whole time |
| 15:19 | kristof | Like what I just wrote. |
| 15:19 | Raynes | kirill: You're the only person who turned this into a dramafest over whos being a big meanie. |
| 15:19 | kristof | (inc Raynes) |
| 15:19 | lazybot | ⇒ 48 |
| 15:19 | AeroNotix | Instead of separating people into groups of "clojure experts" and "not clojure experts". It may behoove some of you to try to understand where some of these people are coming frm. |
| 15:19 | hiredman | kirill: sure, but you seem to have some emotional attachment to this library which makes you want to argue with #clojure when it is found wanting |
| 15:19 | starlord | "provides some functions which are more compatible with their better thought out Scheme counterparts." |
| 15:19 | AeroNotix | Some of the problems addressed here definitely are not without merit |
| 15:19 | starlord | zing! |
| 15:20 | kirill | Raynes: I called attention to the fact that people jumped on the bandwagon of insulting a person who's not even here, and making blanket statements like "this guy doesn't know what he's talking about" etc. |
| 15:20 | kristof | AeroNotix: since when did you start idling this channel? |
| 15:20 | AeroNotix | kristof: dunno, ~year ago? |
| 15:20 | Raynes | Because he bloody doesn't, and people have provided you with examples why. |
| 15:20 | kristof | AeroNotix: ...then when did you start idling #lisp? |
| 15:20 | AeroNotix | kristof: about ~2 years ago |
| 15:20 | kirill | hiredman: again, let's cut the ad hominem and stick to the facts. I'm just a person who's trying to find out information, and instead it sounds like people are just trying to bully anyone who smells like they might be "against the family" |
| 15:20 | kristof | Weird |
| 15:20 | AeroNotix | kristof: why? |
| 15:20 | ToxicFrog | kirill: you asked what people asked of the library, and their analysis is "this library was written by someone who doesn't know what they're doing". |
| 15:21 | hiredman | ad hominem? |
| 15:21 | ToxicFrog | And they have explained why. |
| 15:21 | kristof | Woah! Everyone stop! Do-over. Fresh plate. Someone ask a question, someone answer. |
| 15:21 | ToxicFrog | *what people thought. |
| 15:21 | arrdem | hiredman: argumentation technique based on personal insults |
| 15:21 | Raynes | This is ridiculous. |
| 15:21 | ToxicFrog | Raynes: I concur. |
| 15:21 | lemonodor | kirill: there’s always an aspect of that, because people are not abstract logic machines. but if you filter out the nonsense, it does seem like people have posted some concrete criticisms. |
| 15:21 | AeroNotix | ANYWAY |
| 15:21 | AeroNotix | WHO ELSE THINKS RICH HICKEY IS A DREAM BOAT? |
| 15:21 | kristof | Don't you mean |
| 15:21 | arrdem | not I... |
| 15:21 | lemonodor | (and there’s always nonsense, so filtering it is a useful skill) |
| 15:21 | kristof | A hunk |
| 15:21 | kristof | nudge nudge |
| 15:23 | llasram | A chunk? |
| 15:23 | llasram | No, wait. There's totally a better one with hunked-seqs in there somewhere |
| 15:24 | starlord | Please help me understand what `(~@(map (fn [x] (+ x 1)) '(1 2 3))) is supposed to do. |
| 15:24 | xeqi | does this fall under sexist behavior? |
| 15:24 | Raynes | I'm always entertained when this sort of thing happens and it's like one guy says this one thing that effectively everyone disagrees with, and the few supporters of the guy stop talking about the actual problem and turn it into some sort of minority hate crime crap. "against the family". This dude isn't rebel forces, he's just a guy with some opinions that most folks don't agree with. That's all. |
| 15:25 | Bronsa | starlord: return '(2 3 4) |
| 15:25 | llasram | xeqi: I think it might be inappropriate sexual comments, but which in this context are not sexist |
| 15:25 | kirill | Raynes: the fact that everyone disagrees with one person certainly has no impact on the validity of that person's statements or questions? just trying to figure out how this works |
| 15:25 | oskarkv | I wrote (defprotocol Something (some-fn [this] [this arg])) How should I write the code in defrecord to define the two versions? Also, what does "java.lang.AbstractMethodError: Method something.auto_size(Ljava/lang/Object;)Ljava/lang/Object; is abstract" mean? |
| 15:26 | Raynes | The fact that everyone disagrees with this person should be making you think "Wow, maybe this library is really bad.", but instead you've jumped straight into "THE MAN IS KEEPING US DOWN!" |
| 15:26 | Bronsa | oskarkv: (defrecord x [] Proto (f [_]) (f [_ _]) ..) |
| 15:26 | mthvedt | oskarkv: you probably forgot to implement a method in your deftype/defrecord |
| 15:26 | Raynes | Anyways, we've appeared to have moved on. I'd be happy to keep having a meta discussion in private if you like. |
| 15:26 | TimMc | (inc Raynes) |
| 15:26 | Raynes | we appear* |
| 15:26 | lazybot | ⇒ 49 |
| 15:27 | kirill | Raynes: really? is this how it works? 7 people on the internet said a library is bad, so I'm supposed to just go "yeah I guess it's bad because these guys say they write clojure for a living..." ? are you serious? |
| 15:27 | Raynes | Are you serious? |
| 15:27 | Raynes | Why did you even ask about this library/ |
| 15:27 | llasram | Let's take a vote -- who here (a) writes Clojure for a living, and (b) is in favor of using `sanity`, especially for a newbie? |
| 15:27 | TimMc | Please take this to #sanity-shitfest-and-misunderstanding-gala |
| 15:27 | Raynes | You clearly didn't want truthful responses. |
| 15:28 | TimMc | llasram: Can we *not* feed this? |
| 15:28 | llasram | In the interest of reducing channel clutter, I'll assume any non-yays are nays |
| 15:28 | hiredman | clojurebot: the answer? |
| 15:28 | clojurebot | the answer is 42 |
| 15:28 | llasram | TimMc: Ok, that's fair |
| 15:29 | Raynes | kirill: https://www.youtube.com/watch?v=lDlofPAOZy0 relevant to both of us |
| 15:29 | starlord | Did someone in here write sanity? |
| 15:29 | oskarkv | Bronsa mthvedt thanks |
| 15:29 | arrdem | (inc Raynes) |
| 15:29 | lazybot | ⇒ 50 |
| 15:29 | starlord | Also why is `(~@(...)) around it? |
| 15:30 | AeroNotix | I think a lot of the butthurt in here might be caused by the wording of the README. Calling a lot of core.clj "broken" is not a way to entice Clojurians. |
| 15:30 | kirill | I think the issue might be that people take it personally when a tool they use is being insulted(?) by someone else |
| 15:31 | AeroNotix | Sure, ego and time invested into learning something are hard to separate. That's not unique to clojure |
| 15:31 | kirill | and then they just defer to the person who memorized the most docs to jump on the bandwagon of like "yeah this guy clearly has absolutely nothing to say... let's get back to the echo chamber now" |
| 15:31 | Raynes | http://www.thestate.ae/wp-content/uploads/2012/04/running-in-place-2.gif this is us right now. |
| 15:31 | starlord | kirill: who recommended you use sanity? |
| 15:32 | AeroNotix | kirill: if this has really affected you, I suggest a quick walk to clear your head or something. Programming shouldn't make you mad. |
| 15:32 | kirill | starlord: I was just cruising some clojure repositories on github and this one seemed curious because I have a Scheme background. I don't profess that Scheme is "superior" to any other language, but it looked interesting |
| 15:32 | llasram | kirill: But *no one* in this channel thinks this library is something you should use. It's not just the loudest people being heard |
| 15:32 | Raynes | kirill: Dude, can you please go to http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-08-13.txt and re-read this whole conversation. |
| 15:32 | ToxicFrog | kirill: so, do you actually care about people's opinions on this library? If not, why did you ask in the first place? If so, why are you dismissing those opinions as "echo chamber" and similar? |
| 15:32 | Raynes | If you read what you've said and what everyone else said one more time and still feel the same way, I give up. |
| 15:33 | kirill | ToxicFrog: I care about their opinions, but not when they're not backed up by anything and/or consist entirely of blanket claims |
| 15:33 | Raynes | Dear God. |
| 15:34 | Raynes | technomancy: Let's talk about Rust. How do you feel about Rust? |
| 15:34 | Raynes | I enjoy algebraic data types with my morning coffee. |
| 15:34 | arrdem | Raynes: best thing since sliced bread if you absolutely have to write something C like... |
| 15:35 | ToxicFrog | kirill: except that people have repeatedly explained, in detail, why they hold those opinions, and you have casually dismissed and ignored those explanations out of hand. |
| 15:35 | Raynes | arrdem: And want to change your code every 45 minutes as releases are pushed. |
| 15:35 | Raynes | ToxicFrog: no. stop. bad |
| 15:35 | Raynes | No more talking to kirill. I'm banning it. |
| 15:35 | Raynes | (about this topic) |
| 15:35 | kirill | hah :) |
| 15:35 | arrdem | Raynes: I look forwards to the day that Rust 1.0.0s at which point I will drop literally everything and hack rust for several months. Until then I just like the idea of rust. |
| 15:35 | Raynes | (please do keep talking to him about other topics) |
| 15:36 | ToxicFrog | I really should try Rust one of these days, but for now I'm having fun with Clojure and honestly not sure what I'd use Rust for. |
| 15:36 | Raynes | arrdem: Yeah, I really just want some stability before I start using it. Most of what I write is http stuff and I need a stable http client as well. There isn't a very good one, but there is a very good one in active development. |
| 15:36 | ToxicFrog | If it's ABI-compatible with C, maybe it would be a good choice for writing lua libraries in. |
| 15:37 | arrdem | ToxicFrog: My last non-GSoC job was writing sub-OS level software. Rust woulda been really nice for that. |
| 15:37 | rweir | ToxicFrog, it is! |
| 15:38 | lemonodor | aspiring bloggers might see the sanity library as fuel for an educational post, critiquing the good and bad from a position of experience… |
| 15:38 | ToxicFrog | arrdem: yeah, my industry work prior to this job was all kernel/driver stuff, and my thesis work was embedded systems -- but the former was in an established C++ codebase and the latter used a custom compiler that only understood a bastardized dialect of C. |
| 15:38 | ToxicFrog | It would have been useful back when I was doing a lot of Lua extension work, but that hasn't been for a few years except for vstruct, which has no C code at all. |
| 15:39 | starlord | I am liking Lua. |
| 15:39 | ToxicFrog | It's one of my favourite languages, although I've been increasingly moving to clojure for things more than a page or two long. |
| 15:40 | starlord | ToxicFrog: Why? |
| 15:41 | ToxicFrog | I've still got three major lua projects, emufun (HTPC frontend using the love2d engine), ss1edit (editing tools for System Shock), and vstruct (a binary data wrangling library used by ss1edit) |
| 15:41 | arrdem | how's it stood up? I've only ever used LUA for scripting my WM, and for that it didn't prove as modular as I would like. |
| 15:41 | ToxicFrog | starlord: library management in clojure with lein is way more convenient than it is for lua, deployment is generally easier with lein uberjar (it's a nightmare on windows, but so is lua) |
| 15:42 | starlord | ToxicFrog: Oh I see, so mostly just the tooling is nicer? Do you have any preference over the language itself? |
| 15:42 | ToxicFrog | I would still wholeheartedly recommend lua for scripting/configuration uses, but I've moved away from it for standalone programs. |
| 15:42 | ToxicFrog | (because in the former case, you can safely assume that the host program has solved all library/deployment issues for you) |
| 15:42 | ToxicFrog | (usually) |
| 15:44 | AWizzArd | I don’t know what version of Cider I’m using in Emacs, but it’s a few months old. Quick test: type this into your repl: (defn foo [& {:keys [a] :or {a 1/2}}] a). Now just type “(foo” and hit <space>. This crashes my emacs, and I see this error message: |
| 15:44 | ToxicFrog | Also, Lua's embedding API is excellent. |
| 15:44 | AWizzArd | ERROR: Unhandled REPL handler exception processing message {:id 28, :op info, :session 27d6fa9b-98a1-41ed-b818-1102fe9942eb, :ns user, :symbol foo} |
| 15:44 | arrdem | yeah LUA has done really well in all the embedded contexts I've seen it, I just can't imagine architecting a large (1k+LoC) program in it. |
| 15:44 | AWizzArd | java.lang.IllegalArgumentException: Cannot write value of type class clojure.lang.Ratio |
| 15:45 | AWizzArd | Emacs wants to display the function signature and there are problems displaying ratios, for some reason. |
| 15:45 | ToxicFrog | As for the language itself -- it's minimal but in a good way. Readable, very easy to learn. Simple but powerful. I do miss macros, though; metalua is no replacement and it's awkward using pcall/error rather than (try+). |
| 15:46 | ToxicFrog | And yeah, there's not much for making large programs in it tractable the way you can get, say, bolt-on static type checking for clojure. |
| 15:46 | ToxicFrog | Its compiler is a lot better than clojure's, though :P |
| 15:46 | arrdem | they also have LuaJIT which is literally magic :D |
| 15:47 | ToxicFrog | Yeah, luajit is kind of awesome and I hope love2d moves to it at some point. |
| 15:47 | ToxicFrog | I actually have a medium-sized game idea kicking around that, if I ever write, I'll probably write in lua using love2d. |
| 15:47 | starlord | ToxicFrog: Wait, Lua's compiler is better than Clojure's? |
| 15:48 | ToxicFrog | starlord: mostly that was a jab at the clojure compiler's shit-awful error handling |
| 15:48 | starlord | ToxicFrog: I thought the advantage of Clojure's was that it just compiles to straightforward JVM bytecode, and thus has all the power of the JVM behind it. |
| 15:48 | ToxicFrog | I don't actually know enough about e.g. compiler internals to compare their code generation or the like |
| 15:48 | starlord | Oh. |
| 15:48 | starlord | ToxicFrog: So mostly you prefer Lua, but like Clojure macros for the sake of (try)? |
| 15:48 | ToxicFrog | As far as VM shootout goes, the Lua VM is actually very well designed and tiny, and the LuaJIT VM is larger but blazing fast. |
| 15:49 | Jaood | starlord: that's an advantage or disadvantage, depends on how you see it ;) |
| 15:49 | starlord | Jaood: what is? |
| 15:50 | ToxicFrog | starlord: no, I wouldn't say that. I like both for different reasons. Clojure, being a lisp, honestly doesn't have that much "language" in the sense of built-in syntax and stuff, it's mostly libraries (core and third-party) -- and clojure's libraries make it way more convenient to develop stand-alone stuff in than lua. |
| 15:50 | Jaood | starlord: compiling to JVM bytecode |
| 15:50 | ToxicFrog | It also, IME, tends to be more concise and easier to debug when it goes wrong, albeit harder to read at first glance. |
| 15:52 | ToxicFrog | starlord: Basically I would say, in a vacuum, I think clojure is a better language with better libraries. But lua is faster, smaller, easier to embed, has a lower barrier to entry, and is generally more newbie-friendly, which gives it an advantage in specific areas. |
| 15:52 | starlord | ToxicFrog: So far it sounds like most of what you like about Clojure is that it is batteries-included (i.e. like Python, Ruby), and that it has very easy and consistent dependency tooling. |
| 15:53 | arrdem | $google computercraft |
| 15:53 | lazybot | [ComputerCraft | Programmable Computers for Minecraft] http://www.computercraft.info/ |
| 15:53 | arrdem | ^ lua embedded awesome |
| 15:53 | ToxicFrog | ...which is kind of just a long-winded way of saying that I think clojure is a better general-purpose language and I think lua is much better at the specific purpose it was designed for |
| 15:54 | ToxicFrog | For a while I used lua as my primary programming language, now I'm moving to clojure for general purpose stuff and lua for embedding stuff. |
| 15:54 | starlord | ToxicFrog: Have you used Lua with a batteries-included library? |
| 15:54 | starlord | I've seen a few on github but can't remember their names. |
| 15:54 | ToxicFrog | starlord: a few, yeah. The problem is that there's still nothing nearly as good as lein uberjar for actually distributing the result. |
| 15:54 | starlord | Right. |
| 15:54 | starlord | Okay I think I understand fully now. |
| 15:55 | ToxicFrog | Like, luaforwindows is batteries included. But I also want to distribute my program on linux. Do I build linux versions of all these libraries and ship with? Tell them to use the package manager? What if I depend on something that's in luaforwindows but not, say, the Fedora repositories? |
| 15:55 | xeqi | hmmm, I wonder how much lein contributes to clojure being useable |
| 15:55 | arrdem | xeqi: massively |
| 15:55 | arrdem | xeqi: if I had to deal with bare jars I'd probably still be writing python |
| 15:56 | ToxicFrog | So, for personal work, those things are great. For distribution, you can manage it, but it takes a lot of effort, whereas with clojure I can just go 'lein uberjar' and get one file that works everywhere* and contains all the dependencies. |
| 15:56 | ToxicFrog | * offer not valid on windows machines on days ending in y |
| 15:56 | TimMc | AeroNotix: "Programming shouldn't make you mad." <-- I think that means you're not programming hard enough. :-P |
| 15:56 | xeqi | arrdem: theres maven |
| 15:57 | llasram | I will take this occasion to |
| 15:57 | llasram | (inc technomancy) |
| 15:57 | lazybot | ⇒ 130 |
| 15:57 | arrdem | xeqi: true but it's not completely retard proof like lein, thus requires effort |
| 15:57 | AeroNotix | TimMc: I forgot to add "... at people" |
| 15:58 | starlord | ToxicFrog: This is the same conclusion I've come to, mostly. |
| 15:58 | xeqi | $google why you heff to be mad |
| 15:58 | lazybot | [Why you heff to be mad? (Original) - YouTube] http://www.youtube.com/watch?v=xzpndHtdl9A |
| 15:58 | starlord | ToxicFrog: I've used Ruby and Python for about 4 years, Clojure for 2, and Lua for 6 months. So far I'd agree that Lua is not great for distributing whole programs unless they're embedded in a host which takes care of all dependencies. |
| 15:59 | TimMc | AeroNotix: I dunno, ever worked with legacy code? |
| 15:59 | starlord | ToxicFrog: However, I would use Ruby for one-off programs since it feels considerably lighter-weight to me than Clojure (i.e. any JVM language). |
| 15:59 | TimMc | It also sometimes makes me mad at myself. |
| 16:00 | starlord | ToxicFrog: I admit that I don't like Ruby as a language, but relatively speaking, Clojure isn't better enough to make it worth waiting for the JVM. |
| 16:00 | ToxicFrog | starlord: for me -- python 2 years, clojure the same, lua 10 or so. Ruby not at all, I dabbled in it but didn't like the taste of either the language or community. |
| 16:00 | Jaood | we need a Clojure in C ! |
| 16:00 | starlord | I like that I can write Ruby in most editors without needing special plugins. |
| 16:00 | ToxicFrog | For one-off programs I generally use lua or python, depending on what kind of library capabilities I need. Or bash for really small things. |
| 16:01 | starlord | ToxicFrog: fwiw, Ruby and Python are mostly equivalent |
| 16:01 | ToxicFrog | starlord: Ruby's syntax and feature set makes me think it was designed by someone who thought perl was a good idea but didn't go far enough~ |
| 16:02 | ToxicFrog | Also, I looked at like three Ruby tutorials and all of them were incredibly condescending and pretentious |
| 16:02 | ToxicFrog | To date I have not ever had to work on someone else's Ruby code and thus have not regretted not pursuing it further |
| 16:03 | llasram | starlord: There are some pretty significant differences in the communities and available libraries, but yeah -- what the language semantics let you do easily are super-close |
| 16:04 | Jaood | there's also mruby now which can replace lua use cases |
| 16:04 | justin_smith | for a light weight, concise, high level language, with low startup time and runtim performance, ocaml is pretty hard to beat |
| 16:05 | justin_smith | that and was too ambiguous: low startup time, and great runtime performance |
| 16:06 | AeroNotix | justin_smith: terrible concurrency story though |
| 16:06 | AeroNotix | in the same league as python |
| 16:06 | justin_smith | no worse than python or ruby really |
| 16:06 | justin_smith | but yeah, true that |
| 16:06 | lemonodor | i’d kinda love to use clojure on raspberry pi/beaglebone, but it’s sooo slooow on those platforms. |
| 16:07 | AeroNotix | lemonodor: which aspects of clojure interest you? |
| 16:07 | technomancy | racket is great on arm |
| 16:07 | AeroNotix | because there are many dialects of Lisp |
| 16:07 | ToxicFrog | Oh right, that's the other thing. If I were doing cluster computing I'd use Lua, at least for all the glue. |
| 16:07 | justin_smith | lemonodor: I wonder if the lower in-memory size with clojure-clr would help |
| 16:07 | ToxicFrog | Mostly because I have Lua bindings for a message-passing library (Pilot) on top of MPI and I like that a lot more than C. |
| 16:07 | lemonodor | i wonder if dalvik could run on beaglebone/raspberry |
| 16:11 | ToxicFrog | Back to Clojure for a moment -- my main objections are the slow startup time (which prevents me from using it for small scripts), the unpleasantness of developing in it without lein (ditto -- I can't just start something with #!/usr/bin/clojure and toss it in in ~/bin), and the compiler (which is the main reason I'm hesitant to recommend it) |
| 16:11 | Raynes | I can't think of a non-Go language that is easy to develop without some sort of tooling like lein. |
| 16:12 | justin_smith | lemonodor: I see references here and there to a thing called "alien dalvik", I dunno if it is available for raspberry pi though, seems people are using it on ios? |
| 16:12 | ToxicFrog | Raynes: lua and python come to mind :P |
| 16:12 | ToxicFrog | No compilation needed, I can just whip out a script, give a #! line and away it goes. |
| 16:13 | ToxicFrog | For python I can even split it into multiple files, then zip them and make the zip +x and it just works. |
| 16:13 | ToxicFrog | Although at that point there is an Actual Build Step. |
| 16:14 | Raynes | ToxicFrog: uh |
| 16:14 | ephemeron | ToxicFrog: For scripting, you might want to check out https://github.com/tailrecursion/boot. (I have not tried it yet.) |
| 16:14 | technomancy | Raynes: racket is like that |
| 16:14 | Raynes | ToxicFrog: Go try to write me a couple Python projects without virtualenv, pip, and setuptools. |
| 16:14 | ToxicFrog | If I look in ~/bin/ basically everything there is bash, lua or python. One is a symlink to a python-zip. Five or so are binaries compiled from C. |
| 16:14 | Raynes | Distribute some libraries, programs, write a website. |
| 16:14 | Raynes | Do it all without any tooling. |
| 16:14 | ToxicFrog | Raynes: I've never used any of those soooooo |
| 16:14 | AeroNotix | ToxicFrog: *never* ? |
| 16:14 | ToxicFrog | Wait, no, I lie, I used pip once to install the dependencies for a FUSE module |
| 16:14 | Raynes | Can you show me some of your Python projects? |
| 16:15 | fading | I tried helloworld in ClojureCLR and was suprised how long it took to print |
| 16:15 | AeroNotix | Do you write Python professionally? |
| 16:15 | Raynes | I do. |
| 16:15 | AeroNotix | Raynes: who doesnt |
| 16:15 | fading | Whereas F# helloworld was instantaneous |
| 16:15 | Raynes | You literally cannot use Python without virtualenv. As soon as you need one single thing installed with pip, you're totally screwed. |
| 16:15 | ToxicFrog | AeroNotix: yes, but at my job we have our own custom tooling for everything; I'm just talking about one-off scripts here. |
| 16:15 | Raynes | Sure, you can write random scripts and execute them without dependencies and dependency management. |
| 16:16 | ToxicFrog | Raynes: bear in mind that the context is writing 1-2 page scripts for personal use, not production-quality release software |
| 16:16 | Raynes | Yeah, I still wouldn't do that without a virtual environment. |
| 16:16 | ToxicFrog | I can do that in python without tooling or any sort of build phase, I can't do the same in clojure. |
| 16:16 | Raynes | I'd rather not completely destroy my system package index. |
| 16:16 | Raynes | Sure you can |
| 16:16 | AeroNotix | Raynes: what does "completely destroy"? |
| 16:16 | ToxicFrog | As for released software in python, I believe I only have one, https://github.com/toxicfrog/misc/tree/mo |
| 16:16 | Raynes | It's gonna startup slow, but you can do it with just clojure.jar. |
| 16:17 | AeroNotix | if all your serious projects use a venv, one-off scripts should be fine to fubar everything |
| 16:17 | llasram | AeroNotix: Python packages are not guaranteed to be uninstallable |
| 16:17 | AeroNotix | llasram: and? |
| 16:17 | ToxicFrog | Raynes: so, how much setup do I need to get to the point where I can write a script in clojure, chmod it a+x, and run it from the shell? |
| 16:17 | Raynes | AeroNotix: Develop two projects. Have dependency with transitive dependency on two different versions of the same library. |
| 16:17 | ToxicFrog | Because that's the bar to clear here. |
| 16:17 | Raynes | AeroNotix: boom without virtualenv. |
| 16:17 | AeroNotix | Raynes: one-off scripts vs projects |
| 16:17 | AeroNotix | a script I'm writing to parse some turds out of a file does not need a venv |
| 16:17 | Raynes | If your one-off scripts never require dependencies, then you're good to go. |
| 16:18 | seangrove | Virtualenv burrito is pretty nice for python, from what I hear |
| 16:18 | Jaood | ToxicFrog: with java -cp clojure.jar clojure.main script.clj |
| 16:18 | Raynes | But I think it's silly to make that assumption and even more silly to champion one language over another for making this arguably not that useful use-case easy. |
| 16:18 | ToxicFrog | The only one that requires deps outside the python stdlib is the one I just linked, which requires mutagen |
| 16:19 | Raynes | But yeah, you can do exactly the same thing with a shebang like Jaood demonstrated. It'll just be slow, of course, so Python is clearly a better choice. |
| 16:19 | Raynes | But I don't think tooling is the reason. |
| 16:20 | Jaood | Raynes: do you prefer Python over Ruby? |
| 16:20 | ToxicFrog | Jaood: and where do I find clojure.jar? Because locate sure doesn't know of it. |
| 16:20 | Raynes | Jaood: Yes. |
| 16:20 | Raynes | I have Rails 2 PTSD. |
| 16:20 | Jaood | ;) |
| 16:21 | Raynes | ToxicFrog: clojure.org probably still offers clojure jar downloads. Otherwise, find it in your ~/.m2 folder where maven has stored it already. |
| 16:21 | xeqi | ToxicFrog: if you've already used lein, then ~/.m2/repository/org/clojure/clojure/1.6.0/clojure-1.6.0.jar for the right version |
| 16:21 | Jaood | ToxicFrog: well it should have a version in it clojure-1.6.0.jar |
| 16:21 | ToxicFrog | Raynes: well, I had three objections, of which tooling was only one of them; and I still maintain that '#!/usr/bin/python' is easier to remember than '#!/usr/bin/java -cp /path/to/wherever/the/hell/clojure.jar clojure.main'. |
| 16:22 | ToxicFrog | Aah, I was just looking for 'clojure.jar', without version number. |
| 16:22 | technomancy | #!/usr/bin/env lein run -m clojure.main |
| 16:22 | technomancy | ^ is a thing that might work? |
| 16:22 | Raynes | Yes, clearly, but my point was more that "Oh look, I can just write this one off script. *writes 70% of one-off script*; oh shit, I need that library..." |
| 16:22 | ToxicFrog | technomancy: you can use lein run outside a lein project directory? I'll try that. |
| 16:22 | Raynes | I prefer to just start with an actual project from the beginning. |
| 16:22 | AeroNotix | Raynes: I just install that library globally. #yolo |
| 16:23 | mocker | heh |
| 16:23 | justin_smith | fading: I was mainly thinking the lower memory usage, but looking at a 1:1 comparison it's not a huge margin |
| 16:23 | technomancy | ToxicFrog: yeah, it starts in like half the time too |
| 16:23 | ToxicFrog | Raynes: yes, and then I go "zypper in that-library" and keep on trucking, at least in python/lua |
| 16:23 | Jaood | lein run will startup slower than just java -cp clojure.jar ... |
| 16:23 | Raynes | ToxicFrog: https://github.com/Raynes/basement makes it really easy to go from zero to executable properly structured Python program here. |
| 16:23 | Jaood | ToxicFrog: ^^ |
| 16:23 | Jaood | technomancy: err ^^ |
| 16:23 | ToxicFrog | Well, 20% of the time I do that, the other 80% of the time it was already pulled in as a dependency by something else |
| 16:23 | technomancy | Jaood: only inside a project dir |
| 16:23 | justin_smith | fading: that is, comparing java -jar <path to>clojure-1.4.jar and mono clojure-1.4.exe |
| 16:23 | starlord | ToxicFrog: Sorry to delay, just had a meeting. |
| 16:24 | ToxicFrog | Raynes: you are completely missing my point, which is that my goal is to be able to dash off quick scripts with zero setup or deployment overhead. |
| 16:24 | lemonodor | yes, python needs a lein! |
| 16:24 | ToxicFrog | Python satisfies that handily. |
| 16:24 | Raynes | You're missing my point, which is that I think that's bad. |
| 16:24 | AeroNotix | Raynes: why do I need my shitty turd parser to have a setup.py? |
| 16:24 | starlord | ToxicFrog: I have seen good and bad code in both Ruby and Python, and good and bad documents and community activity in both also. I don't hold it against either of them. |
| 16:24 | Raynes | If you knew how much of that shit I've had to clean up over my very brief Python career, perhaps you'd be more sympathetic I suppose. |
| 16:24 | AeroNotix | Raynes: dude we all work with shit |
| 16:24 | AeroNotix | Raynes: don't play that card |
| 16:24 | ToxicFrog | Raynes: yes, and at work, or for things that I'm actually releasing, I take more care |
| 16:24 | AeroNotix | that's not even an argument |
| 16:25 | Raynes | AeroNotix: ...? |
| 16:25 | Jaood | ToxicFrog: oh ok |
| 16:25 | technomancy | I just write elisp for quick one-off scripts |
| 16:25 | starlord | ToxicFrog, llasram: I personally have found that both communities tend to rely a little too much on inheritance, but the only time I found this to be excessively painful was when using Python's 'twisted' library. |
| 16:25 | AeroNotix | technomancy: but you obviously hate yourself |
| 16:25 | technomancy | ... why is everyone looking at me funny |
| 16:25 | Jaood | err technomancy I mean |
| 16:25 | Raynes | AeroNotix: I'm asking him to not *create* the shit we all work with. Not claiming I'm the only person who has ever worked with 'shit'. |
| 16:25 | ToxicFrog | Raynes: but not when I want to use /usr/share/dict/words to cheat at scrabble, or quickly scrape a website for some data, or download the complete Pterodactyl Squad discography |
| 16:25 | AeroNotix | Raynes: why would you be using his one-off scripts? |
| 16:25 | technomancy | AeroNotix: I've actually been switching to racket for that stuff |
| 16:25 | starlord | justin_smith: I have not gotten into OCaml nor seen a good reason to use it over Ruby for the tasks I wan to accomplish. |
| 16:25 | Raynes | Okay kids. |
| 16:26 | Raynes | I'm gonna go back to work now. |
| 16:26 | AeroNotix | Raynes: Just seems a funny thing to care about how untidy someone else leaves their site-packages when it doesn't affect you |
| 16:26 | Raynes | lol |
| 16:26 | AeroNotix | He said many times that in real projects he takes more care |
| 16:26 | Raynes | Okay. |
| 16:27 | technomancy | throw-away code is great if it actually gets thrown away |
| 16:27 | AeroNotix | I'm definitely not rolling out a requirements.txt or setup.py to run some quick numbers or make a few scripted HTTP call |
| 16:27 | AeroNotix | s |
| 16:27 | Raynes | I sure am |
| 16:27 | starlord | I like Lua from a language standpoint - very lightweight, small, minimalist. But in practice, it's hard to write stand-alone programs in it. |
| 16:27 | AeroNotix | Raynes: learn to not waste time |
| 16:27 | Raynes | Because it's literally just 'ment athing' |
| 16:27 | technomancy | and that's why we need to develop a mechanism for programs that literally self-destruct after a given time |
| 16:27 | ToxicFrog | technomancy: mine actually lives in ~/bin/ forever and ever because sometimes I do actually need it again years later, to be honest. |
| 16:27 | starlord | I wrote this documentation scraper pretty quickly in Ruby: https://github.com/mjolnir-io/core.window/blob/master/gendocs.rb |
| 16:27 | fading | and virtualenv is pretty recent right? I mean I remember seeing how proud various IDEs where that they supported it now |
| 16:27 | Raynes | AeroNotix: You're getting a tad out of line. |
| 16:28 | starlord | I considered rewriting it in Lua, but it was too impractical. Ruby's standard libraries wouldn't have been available, so I would have had to write `map` myself, for example. |
| 16:28 | Raynes | Lets take this to PM. |
| 16:28 | AeroNotix | It's IRC, not a playgroup. |
| 16:28 | aperiodic | lemonodor: the most performant way to get clojure onto a raspberry pi or similar is to use clojurescript & node.js. the JVM can be run on it but it's a bit heavyweight for the platform |
| 16:29 | lemonodor | aperiodic: yeah, i was just thinking that. |
| 16:29 | ToxicFrog | starlord: yeah, the lua stdlib is extremely minimal. There's a few libraries that try to flesh it out. IME, most lua programmers gradually build up a personal utility library of such things. |
| 16:29 | AeroNotix | aperiodic: as much as I hate node.js, that's not a bad idea! |
| 16:29 | technomancy | aperiodic: https://github.com/greghendershott/rackjure! |
| 16:29 | technomancy | at least it has runtime-eval =) |
| 16:29 | starlord | ToxicFrog: Now in my Objective-C application that embeds Lua, it's a lot easier: I can shell out to Foundation.framework for most things, i.e. HTTP, JSON, etc. |
| 16:30 | ToxicFrog | starlord: and yeah, I spent years using it for stand-alone stuff, but these days I've come to terms with the fact that it's not a good choice for that and is more comfortable in conjunction with a host language. |
| 16:30 | technomancy | it's "not clojure" but hey, neither is cljs |
| 16:30 | starlord | ToxicFrog: So I imagine in the future I'll be writing many more one-off programs as Lua extensions to this program that I'm writing. But that's a slightly different use-case than a documentation-scraper like I linked here. |
| 16:30 | aperiodic | you're probably better off with something like that and not having to weave your code in with node.js's crazy conventions |
| 16:30 | starlord | By the way, I wrote one of my first legit Makefiles: https://github.com/mjolnir-io/core.window/blob/master/Makefile |
| 16:30 | AeroNotix | SBCL should run fine on a raspberry pi |
| 16:31 | starlord | Very proud :) |
| 16:32 | starlord | ToxicFrog: That Makefile would have been less pleasant to write if I had used Clojure instead of Ruby for this task, fwiw. |
| 16:32 | AeroNotix | less pleasant to use as well |
| 16:32 | starlord | Yep. |
| 16:32 | ToxicFrog | So, out of curiosity I checked my ~/bin. bash: 33; binary: 7; python: 3; lua: 2. |
| 16:32 | arrdem | eh just build a "Clojure on SBCL" library and leave it for the rest of us :P |
| 16:32 | ToxicFrog | So apparently I do most of my one-offs in bash. |
| 16:33 | ToxicFrog | Although some of those bash scripts contain embedded blocks of lua code that it pipes stuff through~ |
| 16:33 | starlord | ToxicFrog: mine only has `lein` in it. |
| 16:33 | lemonodor | yeah, actually clozure might be better for constrained platforms |
| 16:33 | starlord | I guess I don't have any one-off scripts. |
| 16:33 | technomancy | starlord: remind me to tell you about my referral marketing program |
| 16:33 | starlord | technomancy: Remember to tell me about your referral marketing program. |
| 16:33 | technomancy | "Leiningen: it's all you need. Thanks in advance. Regards." --starlord |
| 16:34 | ToxicFrog | starlord: yeah, I tend to write things at the drop of a hat, I'd rather spend an hour writing a program to automate a tedious task for me than spend half an hour on that task |
| 16:34 | starlord | technomancy: nailed it |
| 16:34 | Bronsa | (inc technomancy) |
| 16:34 | lazybot | ⇒ 131 |
| 16:34 | ToxicFrog | Some of these I can probably actually remove, they're interfaces to sites or services that no longer exist or helpers for completed projects. |
| 16:34 | iris_ | Is it possible to use extend-protocol with a generic abstract Java class? For instance AbstractNode<T>? |
| 16:34 | starlord | ToxicFrog: I guess I don't have many tedious tasks; the few I do, I've been putting into my Objective-C program's custom configuration file for hotkeys. |
| 16:35 | ToxicFrog | But in general I write a lot of these, they live in ~/bin for a while, and then either graduate to ~/devel for cleanup and eventual release (that's what mo did -- it started as two python scripts, mtag and msort) or get removed some years later. |
| 16:35 | starlord | ToxicFrog: For example, I bound Mash-D to launch Dictionary.app for me or bring it to the front if it's not open. |
| 16:35 | starlord | *if it is |
| 16:36 | ToxicFrog | Bigger things -- where I expect up front that it'll need more than one file, or will be released someday more formally than "yo here's a bash script you might find interesting <pastebin>" on IRC, or that it needs actual testing -- start in ~/devel to begin with. |
| 16:36 | amalloy | my goodness #clojure has been vociferous today |
| 16:37 | ToxicFrog | starlord: right, for me, I'd probably write a small script to query a dictionary and display the results on stdout. |
| 16:37 | starlord | ToxicFrog: well Dictionary.app has find-as-you-type which I find helpful |
| 16:37 | Jaood | amalloy: chim in with your favorite scripting language! |
| 16:37 | starlord | ToxicFrog: I'd love it if there was an OS X command-line program that tapped into Dictionary.app's sources to do the same thing using ncurses or something. |
| 16:38 | arrdem | awk all day erry day |
| 16:38 | starlord | amalloy: I don't know what that word means. Thanks in advance, regards? |
| 16:38 | aperiodic | starlord: don't you have dictionary.app bound to mash-d? |
| 16:38 | TimMc | arrdem: Was it Tetris? |
| 16:38 | ToxicFrog | I use awk and sed a lot but generally only in small snippets in support of bash. |
| 16:38 | starlord | aperiodic: Yes. |
| 16:39 | aperiodic | starlord: well then, why don't you know what vociferous means? |
| 16:39 | arrdem | TimMc: neg it's a genealogy graph generator |
| 16:39 | TimMc | mash? |
| 16:39 | starlord | aperiodic: I have not used it just now. |
| 16:39 | starlord | amalloy: I don't know what vehement or clamorous mean, thanks in advance regards. |
| 16:39 | ToxicFrog | seangrove: I still do :D |
| 16:39 | ToxicFrog | Not for anything I want to be robust, though. |
| 16:40 | amalloy | wait wait wait, has starlord been sdegutis all along, or was there a nick changeover? |
| 16:40 | seangrove | ToxicFrog: Fair enough, heh |
| 16:40 | sdegutis | What? |
| 16:40 | clojurebot | What is sampling a random integers betwen 2, 12 s..t. P(X = i) = (7-|i-7|)/36 |
| 16:40 | sdegutis | No I'm here. |
| 16:40 | ToxicFrog | Then again, "robust" and "web scraping" don't generally go well together no matter what tech you're using. |
| 16:40 | sdegutis | amalloy: Why did you ping me? |
| 16:40 | amalloy | *eyeroll* |
| 16:41 | ToxicFrog | And now, home! |
| 16:41 | TimMc | amalloy: Just today, yeah. |
| 16:41 | TimMc | And suddenly using "regard" a lot. |
| 16:41 | star-lord | Yeah. |
| 16:41 | AeroNotix | I'm sure it didn't have the hyphen before |
| 16:41 | star_lord | I own all three. |
| 16:41 | star_lord | Just in case. |
| 16:41 | llasram | So many color changes |
| 16:42 | AeroNotix | yeah, it's confusing me |
| 16:42 | star_lord | Thanks in advance. |
| 16:42 | amalloy | i have to say i rather enjoyed the starlord personality he crafted. a solid troll |
| 16:42 | AeroNotix | I associate people's personalities with colours |
| 16:42 | starlord | amalloy: <3 |
| 16:42 | AeroNotix | sigh |
| 16:42 | AeroNotix | +b |
| 16:43 | sdegutis | Anyone got some advice on tuning a JVM for massive Datomic queries? |
| 16:43 | amalloy | AeroNotix: +b for nick changes? i wouldn't want to let you be king |
| 16:44 | AeroNotix | amalloy: I run a tight ship |
| 16:44 | lemonodor | my boss doesn’t know it yet, but the “Decrease [redacted] latency by 80%” item i put in my quarterly goals is going to be accomplished by writing and open sourcing clojure library. |
| 16:44 | AeroNotix | cool story |
| 16:45 | llasram | geez |
| 16:45 | TEttinger | lemonodor, decrease [java usage] by 80% |
| 16:45 | sdegutis | Ideally I don't think Datomic is the right overall choice, but the background thread that calculates statistics is really hurting performance. |
| 16:46 | sdegutis | We can't necessarily switch to Postgres just yet, so I have to performance-tune this beast in the meantime. |
| 16:46 | sdegutis | Fortunately I can reliably reproduce the 60+ second hang on staging. So now I just need to fine-tune it. |
| 16:46 | sdegutis | And no, I'm not going to rewrite the site in Lua. It's not batteries-included enough. |
| 16:46 | sdegutis | (Ruby, maybe.) |
| 16:48 | dsrx | how can I get clojars to know about the github repo for my project + list it on the project page? |
| 16:48 | technomancy | dsrx: put a :url in project.clj |
| 16:48 | dsrx | already done so |
| 16:49 | dsrx | https://github.com/tomjakubowski/weasel/blob/master/project.clj |
| 16:49 | dsrx | to be clear, I mean the section on this page with the github icon, just below the project description in the main area of the page: https://clojars.org/weasel |
| 16:50 | sdegutis | I bet it's happening because Datomic is producing tons of intermediate small immutable garbage objects that the GC can't keep up with. |
| 16:50 | technomancy | dsrx: hm... I think it reads the .git directory during pom generation? |
| 16:50 | technomancy | not sure |
| 16:50 | amalloy | sdegutis: probably not. tons of small immutable garbage objects is what the GC is pretty good at doing |
| 16:51 | TimMc | Heap too big? |
| 16:51 | amalloy | probably |
| 16:51 | dsrx | oh, does leiningen insert SCM information into the generated pom.xml? |
| 16:51 | technomancy | dsrx: yeah, but you can override it; see lein help sample |
| 16:51 | TimMc | I don't know why this is a problem we have. |
| 16:52 | TimMc | Does the JVM come with a collector that can do smaller pauses, or is it always stop-the-world? |
| 16:52 | arohner | sdegutis: are you holding onto the resultset somehow? |
| 16:52 | amalloy | TimMc: there are better collectors bundled with the popular jvms |
| 16:52 | arohner | TimMc: depends. there are multiple, configurable, GC engines |
| 16:52 | puredanger | sdegutis: you should probably ask your datomic question on the datomic mailing list https://groups.google.com/forum/#!forum/datomic |
| 16:52 | sdegutis | Possible. Or maybe Datomic is internally. They're pretty big Datomic queries that touch almost the whole database. |
| 16:52 | arohner | sdegutis: gathering data is a good place to start. VisualVM is good for this kind of thing |
| 16:52 | sdegutis | puredanger: It's not quite a fully formed question yet. I'm mostly just trying to figure out what /could/ be the cause. |
| 16:53 | sdegutis | arohner: Yeah I checked that but my results seemed meaningless (mostly longs and char[]s) |
| 16:53 | TimMc | amalloy: Any that allow you to use giant heaps without big pauses? |
| 16:53 | arohner | TimMc: that's kind of the holy grail of GC |
| 16:53 | rweir | TimMc, azul is 'pauseless' |
| 16:54 | BorisKourt | What is an efficient way for me to get a val for :name in the same map as an :id of n. Here is a sample of data: https://gist.github.com/BorisKourt/f52826c40ee766d72954 I have been searching and can't come up with a clean solution myself. |
| 16:54 | rweir | in exchange for $$$$ and hassle |
| 16:54 | puredanger | sdegutis: if you suspect gc, then turn on gc logging -verbose:gc and other such options |
| 16:54 | sdegutis | puredanger: Ahh, thanks. Will check it out. |
| 16:54 | islon | so guys, i have this function that needs to generate a cartesian product of tuples like [[1 2] [3 4]...] The best I could came up with was that: https://gist.github.com/stackoverflow/89104188d940616dbb62 which is even worse than the Java equivalent |
| 16:55 | amalloy | TimMc: -XX:+UseConcMarkSweepGC can't *guarantee* no pauses, but if you give it good tuning options it does enough work proactively that on the rare occasions you do get STW pauses they're reasonable |
| 16:55 | islon | there's probably a much easier way to do that |
| 16:55 | amalloy | &(partition 2 (range 10)) |
| 16:55 | lazybot | ⇒ ((0 1) (2 3) (4 5) (6 7) (8 9)) |
| 16:55 | sdegutis | islon: not knowing much about the pattern you mentioned, it looks like you can just use partition with range to get this. |
| 16:55 | puredanger | TimMc: agreed with rweir - Azul (and Zing) are really the best at huge heaps, but G1 is a good option in newer vms |
| 16:55 | sdegutis | amalloy beat me to it. |
| 16:55 | sdegutis | (inc amalloy) |
| 16:55 | lazybot | ⇒ 158 |
| 16:55 | sdegutis | Whoa. |
| 16:55 | sdegutis | amalloy: you've been busy |
| 16:56 | islon | i have 2 ranges not only one |
| 16:56 | amalloy | puredanger: i actually had some trouble with big pauses in G1 and found ConcMarkSweep solved them |
| 16:56 | dsrx | technomancy: bingo, adding the scm to the project.clj did the trick, thanks |
| 16:56 | amalloy | obviously that's not conclusive: i surely missed some useful settings |
| 16:56 | islon | it's like a cartesian product of (range x) and (range y) |
| 16:56 | amalloy | &(for [x (range 5) y (range 6 10)] (list x y)) |
| 16:56 | lazybot | ⇒ ((0 6) (0 7) (0 8) (0 9) (1 6) (1 7) (1 8) (1 9) (2 6) (2 7) (2 8) (2 9) (3 6) (3 7) (3 8) (3 9) (4 6) (4 7) (4 8) (4 9)) |
| 16:56 | TimMc | The context here is on-heap caching; we'll probably just end up using off-heap caching anyhow. |
| 16:57 | TimMc | but it sounds like there are some options! |
| 16:57 | puredanger | amalloy: CMS is great when it can keep up but has generally failed disastrously for me when it can't |
| 16:57 | islon | amalloy: perfect! I knew there was a better way =D |
| 17:13 | sdegutis | Why is everyone quitting IRC suddenly? |
| 17:13 | sdegutis | Perhaps it is a strike? |
| 17:13 | sdegutis | I had not heard of one though. |
| 17:14 | aperiodic | sdegutis: mission accomplished? |
| 17:14 | sdegutis | Seems like it was a short lived strike. |
| 17:14 | sdegutis | aperiodic: I do not understand you. |
| 17:15 | aperiodic | don't be coy |
| 17:16 | sdegutis | aperiodic: I don't know what coy means. |
| 17:16 | sdegutis | aperiodic: Now I know what coy means, but I don't see how I'm being coy. |
| 17:17 | aperiodic | whatever you say, starlord |
| 17:18 | sdegutis | aperiodic: I don't know what you're implying by referring to me as my other nick. |
| 17:19 | sdegutis | aperiodic: Are you implying that I secretly do not like Clojure and thus plotted the downfall of #clojure via some kind of secret spy-bot attack? Because if so, the fragments of what story you think you may have are not very believable and will not be accepted widely. |
| 17:19 | sdegutis | aperiodic: Besides, rest assured that nobody you discuss it with will take it very seriously, for various suspicious reasons. |
| 17:21 | aperiodic | I'm implying that your masterful troll of this channel as starlord made everyone delayed rage-quit IRC |
| 17:21 | aperiodic | but more likely it's just a netsplit |
| 17:21 | aperiodic | perhaps the BGP tables are filling up again |
| 17:21 | sdegutis | Oh. |
| 17:22 | sdegutis | aperiodic: Yes, let's go with that. |
| 17:22 | sdegutis | aperiodic: That's a very benign cause and doesn't put much blame on me. |
| 17:22 | technomancy | the #emacs channel has a bot feature that will emit technobabble when you ask it for an ,excuse |
| 17:22 | sdegutis | I see someone else has a similar mindset to me but is more prepared. |
| 17:22 | rweir | Let's use #emacs as a role model |
| 17:23 | technomancy | hehe |
| 17:23 | arrdem | lets not get hasty now... we're way more on topic than #emacs ever is.. |
| 17:23 | TimMc | technomancy: Hell, I do that and I'm not even a bot. |
| 17:24 | technomancy | I don't know if that was intentional, but one of the other #emacs traditions is to make outlandish suggestions starting with "Let's ..." |
| 17:24 | Jaood | #emacs is 99% off-topic |
| 17:24 | rweir | (it was, i've been in there on and off for like 13 years) |
| 17:24 | arrdem | technomancy: is this where the "lets rebuild emacs atop guile" thing came from? it's just a huge misinterpreted joke? |
| 17:25 | technomancy | arrdem: we can only speculate =) |
| 17:25 | iris_ | Is it possible to use extend-protocol with a generic abstract Java class? For instance AbstractNode<T>? |
| 17:25 | technomancy | iris_: the JVM doesn't have generics |
| 17:25 | hyPiRion | arrdem: let's rebuild emacs atop clojure |
| 17:26 | sdegutis | In the theme of #lua vs #lua-support (see lua-l) someone ought to fork #clojure with #clojure-support due to "constant off-topic noise" in here. |
| 17:26 | arrdem | hyPiRion: I thought someone tried that already.. |
| 17:26 | iris_ | parameterized types? |
| 17:26 | technomancy | iris_: they're part of the java language only. |
| 17:26 | rweir | hyPiRion, don't joke about things you don't want to risk happening |
| 17:26 | hyPiRion | arrdem: I thought that was vi |
| 17:26 | iris_ | makes sense |
| 17:26 | sdegutis | On a related note, lower-case L in anything is almost always a bad decision, especially by itself. |
| 17:26 | arrdem | hyPiRion: I'd totally help with this but I'm busy forking clojure |
| 17:26 | sdegutis | arrdem: how is your Clojure compiler going? |
| 17:27 | hyPiRion | rweir: Well, I don't think it would case significant harm |
| 17:27 | iris_ | Unlike the CLR... ah I remember now... thanks |
| 17:28 | rweir | hyPiRion, famous last words |
| 17:28 | TimMc | technomancy: I think you can ask for type params via reflection (on a class, not an instance, natch) |
| 17:28 | hyPiRion | sdegutis: I wasted 30 minutes because of that today actually |
| 17:30 | sdegutis | hyPiRion: l ? |
| 17:31 | hyPiRion | sdegutis: not alone, but somehow managed to replace a capital I with l. |
| 17:31 | sdegutis | Yeah, it's very confusing to see it in the Programming in Lua book and in their documentation, and on their mailing list. None of these managed to have a decent font that renders it differently enough from 1. I've wasted many minutes in the past few weeks confused over simple things due to it. |
| 17:32 | sdegutis | Fortunately in clj it's not too hard to spot due to the pattern. |
| 17:32 | AeroNotix | cIj |
| 17:32 | sdegutis | sdegutis -> starlord |
| 17:32 | starlord | done. |
| 17:33 | starlord | 1 I l |
| 17:33 | metellus | |1Il |
| 17:33 | starlord | the 1 and l are harder for me to differentiate than I and l. |
| 17:34 | dav | Can anyone give me good pointers on how to use authenticate on Google in order to use GAPI on Picasa in Clojure? (i.e. generate an URL that can be open in a browser to get a token, etc.) |
| 17:35 | starlord | ToxicFrog: Also have you tried Penlight? It doesn't solve the platform problem but it solves the stdlib problem. |
| 17:54 | dav | nobody? |
| 17:54 | clojurebot | nobody wants to refer clojure.edn/read fully-qualified over and over |
| 18:13 | SagiCZ1 | . |
| 18:22 | SagiCZ1 | whats the equvivalent function definition using the hash mark notation to this? |
| 18:22 | SagiCZ1 | (fn [x] [x i]) |
| 18:22 | SagiCZ1 | #([% i]) does not work |
| 18:23 | Slackwise | The anonymous function literal only uses implicit parameters. They're positionally numbered. |
| 18:23 | Slackwise | Oh wait, I read that wrong. |
| 18:23 | tanzoniteblack | SagiCZ1: #(vector % i) |
| 18:24 | technomancy | ,`#([% i]) |
| 18:24 | clojurebot | (fn* [p1__25__26__auto__] ([p1__25__26__auto__ sandbox/i])) |
| 18:24 | technomancy | ^ for a hint as to why it doesn't work |
| 18:24 | SagiCZ1 | technomancy: thank you, that explains it |
| 18:24 | SagiCZ1 | tanzoniteblack: thanks, that works |
| 18:29 | SegFaultAX | Is there an easy way to split a string from the right? |
| 18:32 | SagiCZ1 | SegFaultAX: reverse it first? |
| 18:39 | ToxicFrog | technomancy: so, regarding the #! discussion earlier -- |
| 18:39 | ToxicFrog | 'lein run -m clojure.main foo.clj' works just fine. |
| 18:41 | ToxicFrog | '#!/usr/bin/lein run -m clojure.main' does not; it tries to pass 'run -m clojure.main' as a single argument. |
| 18:41 | technomancy | ah sure; that's too bad. needs an alias. |
| 18:41 | ToxicFrog | Yeah, easy enough to set up. |
| 18:42 | technomancy | maybe we can add one built-in |
| 18:42 | ToxicFrog | Also, wow, that does start up way faster. |
| 18:43 | ToxicFrog | Still needs 100MB of memory though~ |
| 18:47 | SegFaultAX | SagiCZ1: :( |
| 19:05 | justin_smith | ToxicFrog: what about #!/usr/bin/env ... |
| 19:07 | justin_smith | never mind, I just tried that, to no avail |
| 19:10 | danielcompton | Does anyone use evil with Cider in emacs? |
| 19:13 | verma | ToxicFrog, tried with env? |
| 19:13 | verma | oh |
| 19:13 | verma | sorry justin_smith already suggested that |
| 19:14 | verma | danielcompton, try #clojure-emacs too |
| 19:15 | ToxicFrog | Yeah, it looks like #! passes everything after the command proper as a single arg |
| 19:15 | technomancy | that's ... pretty dumb |
| 19:15 | technomancy | actually wait |
| 19:15 | technomancy | that's really dumb |
| 19:17 | danielglauser | technomancy: How do you really feel? |
| 19:23 | bbloom | heh, the lesson of unix is "parsing is hard" |
| 19:27 | Guest19631 | exit |
| 19:27 | Guest19631 | exit |
| 19:27 | Guest19631 | exit |
| 19:33 | bbloom | maybe i'm crazy, but has anybody ever seen such a thing as an "immutable weak map" ? or i guess a "persistent weak map" ...? |
| 19:34 | technomancy | only as a proposed april fool's post? |
| 19:35 | bbloom | weak map in the sense that entries disappear if the key is no longer reachable, but persistent in the sense that i can make many small variants of a particular weak map that all share structure |
| 19:35 | bbloom | it would be observably immutable, but not seqable |
| 19:35 | bbloom | and uncounted |
| 19:36 | bbloom | technomancy: c'mon, this can't be that crazy |
| 19:36 | arrdem | bbloom: it looks... possible with some hackery. |
| 19:36 | arrdem | I consider this a rather strange datastructure... but the tools exist to forge it. |
| 19:37 | technomancy | you have to admit it sounds humorous |
| 19:37 | danielglauser | What would you use it for? |
| 19:37 | bbloom | so as some of you know, i've experimented with first class environments |
| 19:37 | bbloom | in interpreters |
| 19:38 | bbloom | the issue is related to locals clearing, where you have things you can, but don't reference going forward |
| 19:38 | bbloom | each new let binding or fn or whatever introduces a small variation on previous environments and the environments don't change |
| 19:38 | bbloom | but some portions of the environments may be "semantic garbage" in that they are never accessed again |
| 19:39 | bbloom | assuming your keys are uniquely generated ids instead of symbols |
| 19:39 | bbloom | i guess now that i say it, that could just be one global mutable weak map, if the ids are truly unique |
| 19:39 | danielglauser | bbloom: you mention the entries disappear if they are no longer reachable, but then you say you can reach them |
| 19:40 | bbloom | danielglauser: i mean the internal structure can reach them |
| 19:40 | danielglauser | Ah...got it |
| 19:40 | bbloom | like subvec |
| 19:40 | bbloom | (doc subvec) |
| 19:40 | clojurebot | "([v start] [v start end]); Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done." |
| 19:40 | Jaood | technomancy: I tested 'time lein run -m clojure.main foo.clj' vs 'time java -cp clojure-1.6.0.jar clojure.main foo.clj' and got 4 vs 1 secs |
| 19:40 | bbloom | ,(def v (subvec (vec (range 1000)) 0 10)) |
| 19:40 | clojurebot | #'sandbox/v |
| 19:40 | bbloom | ,v |
| 19:40 | clojurebot | [0 1 2 3 4 ...] |
| 19:40 | Jaood | outside of a lein project |
| 19:40 | technomancy | Jaood: do you have a lot of user plugins? |
| 19:41 | bbloom | ^^ 9990 wasted values |
| 19:41 | bbloom | or i guess 990 |
| 19:41 | technomancy | Jaood: I've gotten lein to launch in ~800 ms outside a project |
| 19:41 | technomancy | and I have a computer from 2009 |
| 19:42 | Jaood | technomancy: only {:user {:plugins [[cider/cider-nrepl "0.8.0-SNAPSHOT"]]}} - could that be it? |
| 19:42 | technomancy | I don't think so, but try without? |
| 19:44 | Jaood | technomancy: yeah, without that plugin the results are most equal |
| 19:45 | technomancy | wow |
| 19:45 | technomancy | probably worth filing a bug report |
| 19:46 | Jaood | technomancy: to cider-nrepl or lein? |
| 19:46 | technomancy | Jaood: cider-nrepl |
| 19:46 | bobwilliams | is there a way to run lein such that you do not have to restart it on code changes? |
| 19:47 | technomancy | bobwilliams: lein repl? |
| 19:48 | Jaood | bobwilliams: yeah, that's what the repl is for |
| 19:48 | bobwilliams | technomancy: thx! I'm writing a HipChat bot in clojure |
| 19:48 | bobwilliams | technomancy: and so need to run the code and test the plugins and what not |
| 19:49 | bobwilliams | technomancy, Jaood: was looking for away to have it restart or whatnot as I'm making changes...guess I could do repl |
| 19:49 | technomancy | doesn't really matter what you're writing; reloading the code as you go is just how you write clojure |
| 19:49 | bobwilliams | technomancy, Jaood: thx! |
| 19:49 | technomancy | (or any non-painful language, now that you mention it) |
| 19:49 | bobwilliams | haha! |
| 19:50 | bobwilliams | yea, was wondering if anything existed that would detect a file change and auto-restart lein basically..might have just found my next project :D |
| 19:51 | technomancy | there's a few of them out there, but you should use a repl |
| 19:52 | technomancy | if you want to get fancy, configure your editor to send a reload command on save |
| 19:55 | amalloy_ | yeah, auto-restarting on file change is not as fun as it sounds. you save files a lot more often than you think, and you have state in your repl that you don't want to accidentally blow away |
| 19:55 | arrdem | technomancy: got a minute? |
| 19:56 | technomancy | arrdem: sorta |
| 19:56 | arrdem | technomancy: would later/tomorrow be better |
| 19:56 | technomancy | yeah, cleaning up after an outage ATM |
| 19:56 | arrdem | kk |
| 19:57 | Jaood | technomancy: did you remove the line where it said that leiningen is like ri, bundler, gems, irb all together? |
| 19:58 | technomancy | Jaood: I never said that, and if someone once said that, I'm glad it's been removed =) |
| 20:00 | Jaood | technomancy: oh its in the tutorial, I knew I saw it somewhere, I exaggerated a little though ;) |
| 20:00 | Jaood | it was RubyGems/Bundler/Rake |
| 20:07 | Jaood | its still true though, from an outsider leiningen really is RubyGems/Bundler/Rake/ri/irb :) |
| 20:16 | bobwilliams | technomancy: thanks again! |
| 21:08 | TimMc | Gotta say, I'm not really seeing the usefulness of this Transit thing. |
| 21:14 | xeqi | anyone know of an instaparse grammar for clojure? |
| 21:20 | gfredericks | TimMc: compared to? |
| 21:20 | TimMc | JSON? |
| 21:22 | gfredericks | TimMc: I think not having so much contextual types everywhere seems like a good thing; same selling point for edn |
| 21:22 | TimMc | The Cognitect post didn't do a very good job of defending the creation of a new format. |
| 21:22 | TimMc | Could've used a real-world example of where it would be superior. |
| 21:23 | TimMc | gfredericks: The self-describing nature sounds better than data-readers, sure... |
| 21:23 | gfredericks | it's the same as data-readers |
| 21:24 | gfredericks | a little less global I guess |
| 21:26 | gfredericks | maybe more tied to system types |
| 21:29 | arrdem | xeqi: there isn't an official one, but I've been working on one as part of http://github.com/oxlang/oxlang |
| 21:30 | arrdem | xeqi: expect to test/debug/improve that one tho, it's got three or four of my 3am exhausted daze hours in it and nothing more. |
| 21:34 | TimMc | gfredericks: There's also some very important stuff missing from the spec. I just raised this issue: https://github.com/cognitect/transit-format/issues/18 |
| 21:34 | TimMc | That could make or break it. |
| 21:35 | gfredericks | TimMc: is string encoding not handled by the underlying transport? |
| 21:35 | gfredericks | e.g., json |
| 21:35 | TimMc | Sort of. |
| 21:37 | TimMc | For instance, JSON can contain "any Unicode character" except for some syntactic ones and the control characters. |
| 21:37 | xeqi | arrdem: neat |
| 21:37 | xeqi | thanks |
| 21:37 | gfredericks | TimMc: so...therefore transit can as well? |
| 21:37 | TimMc | Does this mean that 𐀀 is transmitted in UTF-8, or UTF-16? |
| 21:37 | Balveda | Question; how could I eagerly concatenate a string? |
| 21:37 | arrdem | xeqi: hope it helps... note that there are several known issues with that grammar especially around the #"" literal. |
| 21:37 | gfredericks | TimMc: the JSON parser will worry about that won't it? |
| 21:38 | TimMc | Or will it be encoded in \uXXXX format? And if so, in which format? |
| 21:38 | arrdem | Balveda: (apply str string1 string2) |
| 21:38 | TimMc | gfredericks: It's more a question of the encoder. |
| 21:38 | xeqi | arrdem: I might just wait, considering doing some stuff for yet another side project |
| 21:38 | llasram | TimMc: I'm not a big fan of transit so far, but I don't think that's really an issue |
| 21:38 | TimMc | JSON is a character-oriented format; Transit is byte-oriented. I think. |
| 21:38 | gfredericks | TimMc: I fail to see how this could cause a problem |
| 21:38 | Balveda | thanks |
| 21:38 | gfredericks | TimMc: transit runs on top of json |
| 21:39 | arrdem | xeqi: heh we'll see I may make fixing that grammar tonight's project. |
| 21:39 | arrdem | xeqi: what's this for? |
| 21:39 | llasram | I'm pretty sure Transit strings are in fact character-oriented, just like strings on the JVM |
| 21:39 | TimMc | llasram: The example on transit-clj has it writing to a ByteArrayOutputStream, so that's not obvious to me. |
| 21:39 | gfredericks | TimMc: it converts to json first |
| 21:39 | TimMc | Bottom line: I do not want to have to *assume* it does the right thing. |
| 21:40 | Balveda | also, how do I nuke an entire sexp in paredit? |
| 21:40 | gfredericks | C-k |
| 21:41 | TimMc | gfredericks: And then? After it converts to JSON? |
| 21:41 | xeqi | arrdem: considering modifying marginalia to output differently for a site similar to gobyexample.com, and I'm not sure aobut its current parsing internals |
| 21:41 | llasram | TimMc: That seems like just Java laziness, assuming that the character-oriented JSON round-trips through bytes as UTF-8 |
| 21:41 | gfredericks | TimMc: well you can write it to a byte array output stream just like you can with json |
| 21:42 | TimMc | gfredericks: That requires the use of a transformation format. |
| 21:42 | TimMc | Which one are they using? It's not specified. |
| 21:42 | xeqi | arrdem: and theres already an issue for changing it (parsley mentioned explicitly, but instaparse also could work) |
| 21:42 | xeqi | arrdem: did your oxcart talk get recorded? |
| 21:43 | gfredericks | TimMc: is this a problem with JSON as well? |
| 21:44 | TimMc | JSON ignores this -- a JSON document is a sequence of Unicode code points. |
| 21:45 | gfredericks | okay so the complaint is that they don't specify how the json characters are encoded by their byte writers |
| 21:45 | TimMc | You are permitted to encode any code point, but not required except with C0 (and DEL?), ", and \. |
| 21:46 | TimMc | Sure, although I'm not familiar with MessagePack. |
| 21:50 | gfredericks | how do people get away with not thinking about this when they sling json all over the internet? |
| 21:50 | TimMc | fuck if I know |
| 21:50 | TimMc | I mean... really, they don't. |
| 21:51 | TimMc | At my last job I discovered that ExtJS was just using eval to "parse" JSON. |
| 21:51 | llasram | Because they trust their underlying Unicode-data transport to correctly encode their Unicode characters |
| 21:51 | llasram | Which is exactly what is happening in the transit-clj example, using the default UTF-8 encoding |
| 21:51 | TimMc | llasram: Default, eh? |
| 21:51 | TimMc | Whose default? |
| 21:51 | llasram | The JVM's, right? |
| 21:52 | TimMc | hahahahaha |
| 21:52 | gfredericks | llasram: well you have to coordinate that with others, no? |
| 21:52 | TimMc | I can tell you use a Mac or Linux. |
| 21:52 | gfredericks | or just hope it's everybody's default? |
| 21:52 | bbloom | Balveda: arrdem: you don't need that apply |
| 21:52 | bbloom | ,(str "abc" "xyz") ; Balveda |
| 21:52 | clojurebot | "abcxyz" |
| 21:52 | bbloom | ,(apply str "abc" "xyz") ; same thing but slower |
| 21:52 | clojurebot | "abcxyz" |
| 21:53 | TimMc | llasram: On Windows, the default character encoding -- conveyed from system, to JVM, to your Clojure apps -- is Windows-1252. |
| 21:53 | llasram | TimMc: Ok, could be UTF-16 on Windows? Either way |
| 21:53 | TimMc | I've been there, dude. |
| 21:54 | llasram | Hmm |
| 21:54 | clojurebot | Cool story bro. |
| 21:54 | llasram | Well, I'll believe you, but will hold out some hope that your experience was with Java 1.5 or such :- |
| 21:54 | llasram | :-) even |
| 21:54 | bbloom | isn't the default encoding on the jvm even locale dependent? |
| 21:55 | TimMc | You *must always* specify the character encoding when opening a stream in Java, unless you're using a library (like ztellman/byte-streams) that Does The Right Thing. |
| 21:55 | llasram | But it's bed time EDT. I'll see in the morning what revelations are revealed! |
| 21:55 | TimMc | bbloom: I'm pretty sure, yeah. |
| 21:55 | bbloom | http://www.i18nguy.com/unicode/turkish-i18n.html *cringe* |
| 21:56 | TimMc | fucking Turkısh |
| 21:57 | TimMc | or English. I mean, the Turkish way kind of makes more sense. |
| 21:58 | gfredericks | the transit-java repo does not contain the string "UTF" |
| 22:00 | TimMc | transit-clj has it... in the XML preamble and in the string "outputFile". :-P |
| 22:04 | gfredericks | so if they'd kept their APIs at the character level this would be a non-issue? |
| 22:04 | gfredericks | messagepack is supposedly binary; I have no idea what that means wrt strings |
| 22:06 | TimMc | gfredericks: Yeah, but it's almost certianly better to simply define the character encoding as UTF-8 and be done with it. |
| 22:08 | ivan | In 2010 I tested a bunch of browser APIs and decided to transmit everything as ASCII to avoid problems with XHR and XDomainRequest and Flash |
| 22:08 | gfredericks | TimMc: so the users don't have to bother |
| 22:08 | ivan | XDomainRequest was the weirdest, U+FFFD'ing non-characters |
| 22:09 | TimMc | ivan: Did you b64 everything? |
| 22:09 | ivan | TimMc: I JSON'ed everything with escapes |
| 22:09 | ivan | of course this is not a great solution because you are using 6 bytes and you can't human-read non-English |
| 22:10 | TimMc | Oh, I didn't finish telling about ExtJS -- because it uses eval to parse JSON, it breaks when U+2028 or U+2029 comes down the pike, since those aren't valid whitespace in JS. |
| 22:10 | TimMc | And come down the pike they did, eventually. So yeah, shit just breaks. |
| 22:11 | TimMc | (So kids, remember to escape U+2028/2029 even though the spec doesn't require it...) |
| 22:12 | ivan | Python 2.7.6: |
| 22:12 | ivan | >>> print json.dumps(u"\u2027\u2028", ensure_ascii=False) |
| 22:12 | ivan | "‧ |
| 22:12 | ivan | >>> print simplejson.dumps(u"\u2027\u2028", ensure_ascii=False) |
| 22:12 | ivan | "‧\u2028" |
| 22:12 | gfredericks | TimMc: so back to your original point, if they DO specify a UTF-8 default, that would make transit immediately superior to json in that respect? |
| 22:13 | gfredericks | I remember rich saying "all existing json is automatically valid transit" so that might be problematic |
| 22:13 | gfredericks | but I guess they also said they haven't nailed down the format yet either |
| 22:14 | TimMc | I feel it is important for them to specify a default encoding, yes. |
| 22:15 | TimMc | I suppose they could punt and say "naw, it's just a code-point-level format" -- but if they provide byte-oriented utilities anyhow, they'd *better* use UTF-8. |
| 22:17 | gfredericks | I always thought the "regular json supported too" feature was a little weird |
| 22:19 | TimMc | They don't really give an example of what that would look like, probably because it's ugly and verbose and they don't want people to latch onto that. |
| 22:20 | gfredericks | no I think the idea was the readers could take a typical plain ole json thing and parse it the way you'd want |
| 22:20 | gfredericks | which sounds like a guaranteed ambiguity |
| 22:21 | TimMc | Hmm, it doesn't quite round-trip NaN. |
| 22:22 | TimMc | Double/NaN -> "NaN" |
| 22:23 | gfredericks | it comes back as a string you mean? |
| 22:23 | TimMc | yeah |
| 22:25 | TimMc | gfredericks: OK, that's fucked. The JSON {"foo":"bar"} reads as {"foo" "bar"}; the JSON {"~foo":"bar"} gives NumberFormatException |
| 22:26 | gfredericks | TimMc: that's the ambiguity I referred to :) |
| 22:26 | TimMc | {"~~foo":"bar"} reads as {"~foo" "bar"}, though... |
| 22:26 | gfredericks | yeah ~~ is an escape for ~ I think |
| 22:27 | TimMc | gfredericks: Yeah, just verifying 'cause I hadn't notice that "feature". |
| 22:27 | gfredericks | it might be that the feature is sort of a side effect of supporting the pretty-json format |
| 22:28 | TimMc | "This is useful for configuration files" <-- that's just asking for someone to request comments |
| 22:31 | TimMc | Hmm! From RFC 7159: "JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32." |
| 22:32 | gfredericks | lol |
| 22:33 | TimMc | and then it says the default is UTF-8 |
| 22:41 | gfredericks | messagepack's corresponding documentation would be relevant |
| 22:41 | gfredericks | I guess that would be what it thinks a string is, rather than how to encode it |
| 22:49 | TimMc | gfredericks: Where did you see that it could take plain JSON? |
| 22:51 | amalloy | gfredericks: i know at my last job there were numerous instances of "oh shit, we didn't think about character encoding for our json, and now stuff is broken" |
| 22:51 | Balveda | If I have a variadic function with an apply str, which would be the best way to deal with the n parameters, seeing as how they come in as a list? |
| 22:54 | TimMc | Balveda: Like, you have (fn foo [& args] (apply str args)) ? |
| 22:54 | amalloy | i liked to say that i spent 25% of my time there reminding people that character encodings are hard, and another 25% reminding people that times/dates are impossible |
| 22:54 | TimMc | amalloy: *nod* |
| 22:54 | Balveda | never mind |
| 22:54 | Balveda | just use another apply str |
| 22:58 | gfredericks | TimMc: rich said it in his talk |
| 22:58 | TimMc | Oh phew, it's not java.net.URI |
| 23:02 | kristof | Next clojureconj should be in anchorage |
| 23:04 | amalloy | or in Ångström so they learn to be more careful about character encodings |
| 23:04 | amalloy | is that a place? i think it's a place |
| 23:04 | amalloy | maybe it's just a name. point stands though |
| 23:07 | kristof | Java is... UCS-2 internally, yeah? |
| 23:08 | amalloy | utf-16, i think, which is slightly different |
| 23:08 | amalloy | but maybe not |
| 23:08 | kristof | slighter than slightly |
| 23:10 | TEttinger | ,(int \𐀀) |
| 23:10 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unsupported character: \𐀀> |
| 23:10 | TEttinger | woah |
| 23:10 | TEttinger | ,(map int "𐀀") |
| 23:10 | clojurebot | (55296 56320) |
| 23:11 | TEttinger | ah, multibyte |
| 23:11 | TEttinger | good test char |
| 23:11 | TimMc | amalloy: UCS-2 doesn't have surrogate pairs, IIRC. |
| 23:11 | amalloy | TimMc: right, i went and looked it p |
| 23:12 | TEttinger | looks like a telephone pole |
| 23:12 | TEttinger | ,(long \𐀀) |
| 23:12 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unsupported character: \𐀀> |
| 23:12 | TimMc | gfredericks: At this point I'm thinking that some verbose-json outputs might coincidentally be readable as JSON, but that it's not expected that all JSON can be readable as verbose-json transit. |
| 23:13 | TEttinger | what even... is transit |
| 23:13 | TEttinger | I've seen that it has an IRC channel |
| 23:13 | TimMc | TEttinger: And ##(char 0x10000) |
| 23:13 | lazybot | java.lang.IllegalArgumentException: Value out of range for char: 65536 |
| 23:13 | TEttinger | I saw a clj lib for it |
| 23:13 | TimMc | TEttinger: http://blog.cognitect.com/blog/2014/7/22/transit |
| 23:15 | TEttinger | some big names on that contributor list |
| 23:17 | TEttinger | I've found libgdx's dialect of json to be particularly human-readable. The only difference from regular json is that it isn't valid js because unquoted words are automatically turned into strings |
| 23:19 | johnwalker | is there a standard place for lein plugins to use for configuration ? |
| 23:20 | TimMc | johnwalker: Like, system-wide conf, or project conf? |
| 23:20 | TEttinger | johnwalker, good question. what does yours do? |
| 23:21 | TimMc | Midje allows the use of a config file at the project root, but most plugins just have you attach things to the project.clj. |
| 23:21 | johnwalker | well, plugin configuration |
| 23:21 | johnwalker | this one should be system-wide |
| 23:21 | johnwalker | the plugin adds new dependencies to project.clj's |
| 23:22 | TimMc | Probably in the user's profiles file. |
| 23:23 | TimMc | johnwalker: Is this dynamic injection into projects, or actually modifying the on-disk files? And what kind of dependencies? |
| 23:24 | johnwalker | it's actually modifying disk files |
| 23:24 | johnwalker | so you can do lein plz add cljs and get the latest clojurescript dependency appended to :dependencies |
| 23:24 | TimMc | Yeah, ~/.lein/profiles.clj sounds like a good place. |
| 23:24 | johnwalker | the thing that needs to be in configuration is the map of abbreviations |
| 23:25 | johnwalker | well, thats what i think too |
| 23:25 | xeqi | johnwalker: you want to let the user change the abbrevation map? |
| 23:25 | johnwalker | xeqi: thats right |
| 23:26 | johnwalker | so theres an edn map that goes {:org.clojure/clojurescript #{"cljs" "clojurescript" etc}} |
| 23:27 | johnwalker | TimMc: but the thing thats weird is that the project map passed by leiningen doesn't contain all of whats in profiles.clj |
| 23:27 | xeqi | and I really wanted to use https://clojars.org/clojurescript |
| 23:28 | johnwalker | xeqi: lol, well thats one reason i'm letting the user specify. the other is so you can have reasonable defaults and then go crazy with one character to a project |
| 23:29 | johnwalker | it's really cute. i like it and it works. |
| 23:31 | xeqi | johnwalker: lein will only add based on the profiles its using at the time. Do you have the map under {:user {:abbrevations ...}} or such |
| 23:32 | johnwalker | thats right |
| 23:32 | bbloom | ,(declare foo) |
| 23:32 | clojurebot | #'sandbox/foo |
| 23:32 | bbloom | ,(def foo foo) |
| 23:32 | clojurebot | #'sandbox/foo |
| 23:32 | bbloom | ,foo |
| 23:32 | clojurebot | #<Unbound Unbound: #'sandbox/foo> |
| 23:32 | bbloom | ,@foo |
| 23:32 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.util.concurrent.Future> |
| 23:33 | bbloom | fun |
| 23:33 | xeqi | ,(def bar foo) |
| 23:33 | clojurebot | #'sandbox/bar |
| 23:33 | xeqi | ,@bar |
| 23:33 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.util.concurrent.Future> |
| 23:35 | xeqi | ,bar |
| 23:35 | clojurebot | #<Unbound Unbound: #'sandbox/foo> |
| 23:35 | johnwalker | ahh |
| 23:35 | johnwalker | are you saying i need to add the profile to the plugin ? |
| 23:36 | johnwalker | i only had some data in the system profiles.clj, but didn't do anything in the project's |
| 23:36 | xeqi | no, I just wanted to make sure :abbrevations or whatever wasn't in the top most map |
| 23:36 | johnwalker | oh |
| 23:40 | bbloom | whoa: |
| 23:41 | bbloom | ,(def cool #'cool) |
| 23:41 | clojurebot | #'sandbox/cool |
| 23:41 | bbloom | ,cool |
| 23:41 | clojurebot | #'sandbox/cool |
| 23:41 | brehaut | tying the knot with vars? |
| 23:42 | xeqi | ,@cool |
| 23:42 | clojurebot | #'sandbox/cool |
| 23:42 | bbloom | brehaut: i'm always up to something no-good |
| 23:42 | xeqi | ahh, I thought that was going to blow up |
| 23:42 | brehaut | bbloom: careful, that way lies haskell ;) |
| 23:44 | bbloom | it seems like the DefExpr$Parser creates the var and gives it to the def, so when def is evalutated (or compiled, i guess) the var already exists, even though it's not in the current env of the init yet |
| 23:50 | Balveda | How could I remove a key value pair from a map and keep the rest? |
| 23:54 | xeqi | Balveda: ##(doc dissoc) |
| 23:54 | lazybot | ⇒ "([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)." |
| 23:54 | technomancy | johnwalker: are you using the change task for this? |
| 23:54 | johnwalker | technomancy: no, but it sounds like i should |
| 23:54 | johnwalker | i was using rewrite-clj |
| 23:55 | technomancy | eh; that works too if you're not concerned about dependencies |
| 23:55 | Balveda | Thanks xeqi |
| 23:55 | Balveda | ,(inc xeqi) |
| 23:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: xeqi in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 23:56 | johnwalker | lein change probably takes care of this nasty indentation business |
| 23:56 | Balveda | (inc xeqi) |
| 23:56 | lazybot | ⇒ 12 |
| 23:58 | johnwalker | actually it looks like it's basically the same thing |
| 23:58 | johnwalker | i'll switch and cut off a dependency |