2013-07-25
| 00:30 | aaelony | what's the best way to read a small edn format file entirely into memory? |
| 00:33 | brehaut | aaelony: (clojure.edn/read-string (slurp file-or-filename)) ? |
| 00:34 | aaelony | brehaut: thank-you, but that only yields the first line |
| 00:34 | brehaut | aaelony: the first line or first form? |
| 00:34 | aaelony | e.g. (count (clojure.edn/read-string (slurp data-file)) ) ;; gives 2 |
| 00:35 | alandipert | (clojure.edn/read-string (str "(" (slurp f) ")")) is a quick fix |
| 00:35 | aaelony | brehaut: It's likely my fault, there is a edn structure on each line and I need all the lines |
| 00:35 | tomjack | you'd have to call read repeatedly |
| 00:36 | aaelony | alandipert: thank-you! that works :) |
| 00:37 | tomjack | https://www.refheap.com/7fac4581dac79e910dbbba793 |
| 00:37 | tomjack | the less quick fix.. |
| 00:38 | tomjack | https://www.refheap.com/67eedfdc3b75112b6cacc9a26 grrr |
| 00:38 | aaelony | tomjack: that's cool thanks. I googled a bunch of explanations, (such as http://stackoverflow.com/questions/15234880/how-to-use-clojure-edn-read-to-get-a-sequence-of-objects-in-a-file) but none of them fit exactly. thanks for everyones help |
| 00:38 | hiredman | I wish clojure would just throw an exception when it encounters def not at the top level |
| 00:39 | tomjack | eh |
| 00:39 | tomjack | so one macro -> one def? |
| 00:39 | aaelony | errors |
| 00:40 | tomjack | or is the body of a top-level do also top-level? |
| 00:40 | tomjack | hmm (partial not= foo), that's cool |
| 00:40 | tomjack | I can't decide whether I like that or (complement #{foo}) better |
| 00:41 | hiredman | which ever, I am just tired of seen people try to use def like schemes define |
| 00:41 | alandipert | hiredman: but what about my defcoolthing macros :-( |
| 00:42 | brehaut | no cool things allowed. this is clojure. we only do serious computing |
| 00:42 | tomjack | inside let basically? or what? |
| 00:42 | aaelony | I'm still waiting for some macro named defleopard... |
| 00:42 | hiredman | (defn make-memo [fn] (def table ...) (fn [& args] do stuff with table)) |
| 00:42 | alandipert | hiredman: in seriousness, i think i agree. i was investigating static compilation and a def in a closure makes compiling defns to java methods super trixty |
| 00:42 | brehaut | aaelony: thats only allowed in common lisp (and other languages from the 80s) |
| 00:42 | aaelony | haha |
| 00:43 | tomjack | ah right |
| 00:45 | hiredman | alandipert: I have a lisp -> go source compiler that ends up having to hoist lots of stuff like that in to the top level |
| 00:45 | alandipert | hiredman: do your generated methods take an env arg? |
| 00:46 | hiredman | yes |
| 00:46 | hiredman | I end up generate the go equiv of what clojure does with IFn's |
| 00:46 | alandipert | cost of doing business w/ inner defs i suppose |
| 00:46 | hiredman | class and method(s) per function object |
| 00:50 | hiredman | we need an urclojure like, uh, whatever that is that shenanigans has |
| 00:50 | hiredman | er |
| 00:50 | hiredman | "shen" |
| 00:50 | hiredman | klambda |
| 00:50 | hiredman | but with more protocols and reify |
| 00:51 | futile | hey guys, remember when OOP was brilliant? |
| 00:53 | alandipert | hiredman: yes, into it. also the AIM 514 'lisp-based processor' thing |
| 00:54 | hiredman | look, the thing I said could actually happen :) |
| 00:56 | alandipert | hiredman: oh, you have explored the AIM 514 stuff? i'm tempted to learn VHDL on account of it |
| 00:56 | hiredman | I haven't, but it seems unlikely that lisp machines will make a come back |
| 00:58 | alandipert | they will, on my machine |
| 01:17 | aaelony | another silly question. I have a nice doseq that outputs lines to a file, but I want to label the line number of the line the data came from. I've tried (let [i 0] (doseq [row data] (let [i (inc i)] … but that doesn't seem to do it. |
| 01:19 | alandipert | aaelony: maybe (doseq [row data, i (range)] ...) |
| 01:19 | tomjack | that would be interesting |
| 01:19 | tomjack | (doseq [[i row] (map vector (range) data)] ...) ? |
| 01:20 | aaelony | alandipert: I think that works! |
| 01:20 | aaelony | alandipert: thanks :) |
| 01:20 | tomjack | &(for [row [1 2 3] i (range)] [row i]) |
| 01:20 | lazybot | Execution Timed Out! |
| 01:20 | aaelony | cool |
| 01:21 | alandipert | or rather, (doseq [[i row] (map-indexed vector data)] ...) |
| 01:21 | tomjack | I think it's weird you can't use doseq-like bindings for zippy mode |
| 01:22 | aaelony | actually, that works then goes overboard… i'll need to bound the (range) ;) |
| 01:22 | zRecursive | ,(range) |
| 01:22 | clojurebot | (0 1 2 3 4 ...) |
| 01:24 | alandipert | ,(for [[i row] (map-indexed vector "stuff")] [i row]) |
| 01:24 | clojurebot | ([0 \s] [1 \t] [2 \u] [3 \f] [4 \f]) |
| 01:26 | tomjack | (for+ :zip [row data i (range)] ...) ? |
| 01:28 | alandipert | tomjack: fancy |
| 01:30 | aaelony | tomjack: what is for+ … having trouble researching that... |
| 01:30 | tomjack | it's hypothetical |
| 01:30 | aaelony | ah! |
| 01:42 | aaelony | ok, I gave up and am using an agent instead... |
| 01:43 | tomjack | ..for the index? |
| 01:46 | ddellacosta | what's the idiomatic way to compare hash-maps for equality? I'm just doing = and that's not working how I want. |
| 01:47 | ddellacosta | I guess I should be specific: I want to compare two clojure.lang.PersistenArrayMaps. |
| 01:47 | ddellacosta | PersistentArrayMap |
| 01:47 | tomjack | what is an example of = not working how you want? |
| 01:47 | egghead | ,(= {:foo :bar} {:foo :bar}) |
| 01:47 | clojurebot | true |
| 01:47 | aaelony | tomjack: yes |
| 01:48 | egghead | = is by value instead of ref |
| 01:48 | egghead | what is ref equality in clj |
| 01:49 | amalloy | egghead: identical? |
| 01:49 | egghead | ah nice, thanks amalloy |
| 01:50 | ddellacosta | thanks folks. I realized I'm being dumb and actually the maps I'm working with are not, in fact, equal, which is why it's telling me they are not equal. D'oh. |
| 01:50 | tomjack | clojure.data/diff |
| 01:51 | callen | ddellacosta: you really wanna use diff as a sanity check :) |
| 01:52 | ddellacosta | tomjack, callen: thanks! I didn't know about that one. |
| 01:54 | ddellacosta | oh that is SO much nicer than how I was doing it |
| 01:55 | callen | ddellacosta: don't thrash around, ask. :) |
| 01:56 | ddellacosta | callen: totally…the problem is that it doesn't even occur to me to ask sometimes. I wouldn't have thought to have asked the appropriate question, which was, "how can I best find the diff between two hash-maps?" |
| 01:56 | ddellacosta | hence the thrashing |
| 02:29 | ddellacosta | what are people using to measure test coverage for their Clojure codebase? |
| 03:05 | tsdh | Hi. I have 2 deftypes A and B which have mutual (instance? A/B ...) checks in some protocol implementation methods. Is there a way to make that compile other than splitting the instance checks in functions A? and B? and adding forward declarations? |
| 03:35 | ucb | many ohais |
| 03:40 | Uakh | ohaïs were had |
| 03:40 | hyPiRion | ohai |
| 04:07 | tsdh | Uh, is it intended that different clojure.core.cache types require different usage patterns? I.e., SoftCaches update in-place with (miss ...) whereas the other's return a new cache one has to use in place of the old one. |
| 04:11 | hiredman | tsdh: I'd checkout core.memoize |
| 04:12 | hiredman | (if you are looking at core.cache, because core.cache on it's own has never made sense to me) |
| 04:13 | tsdh | hiredman: I already use its SoftCaches in my project, so I thought I use its BasicCaches at another place, too. But now I simply use an (atom {}) which is as good for my use-case. |
| 04:57 | darkest_pod | Which concurrency primitive is best to share state between two working threads? |
| 05:00 | hiredman | http://wiki.gungfu.de/uploads/Main/clojure-conc.png |
| 05:00 | hyPiRion | (inc hiredman) |
| 05:00 | lazybot | ⇒ 21 |
| 05:01 | echo-area | (def hiredman (atom 20)) |
| 05:01 | echo-area | Why does lazybot ignore me |
| 05:03 | hyPiRion | that's not legal lazybotian |
| 05:03 | hyPiRion | ,(let [hiredman (atom 20)] (swap! hiredman inc)) |
| 05:03 | clojurebot | 21 |
| 05:04 | darkest_pod | hiredman: Thanks! |
| 05:40 | tsdh | Is there a nrepl.el command that lets me load the current buffer and reload all required namespaces, too? |
| 05:40 | ucb | tsdh: https://github.com/clojure/tools.namespace |
| 05:40 | ucb | that might come in handy |
| 05:42 | hyPiRion | tsdh: you may want to look into Stuart Sierra's setup, it's thought out by a smart man |
| 05:42 | tsdh | ucb: That looks great, and it's motivated by the same problem I have. Compile a ns with protocols, now you need to recompile all ns with types implementing these protocols. |
| 05:43 | ucb | also what hyPiRion said |
| 05:43 | hyPiRion | tsdh: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded |
| 05:45 | tsdh | hyPiRion: Yes, very useful. Thanks. |
| 06:04 | noncom | what is the current fashion for cljs analog for clj-time? |
| 06:04 | noncom | i need a full-scale date manipulations with cljs |
| 06:43 | dnolen | noncom: probably worth taking a look at what's available via Google Closure |
| 06:44 | noncom | dnolen: yeah, looks like will have to. also found this http://stackoverflow.com/questions/17041115/clojurescript-date-time-library so not so out-of-the-box, but still not alone :) |
| 06:44 | g3ntleman | hey, everybody! |
| 06:44 | g3ntleman | Did anyone successfully build clojurec on os x? |
| 06:44 | dnolen | noncom: I would personally avoid anything that cannot be Closure optimized |
| 06:45 | g3ntleman | I'm running into compile problems. |
| 06:45 | noncom | dnolen: ok, this makes sense, i will make the priority |
| 06:47 | dnolen | noncom: which means there's an opportunity for a nice wrapper about the Closure date stuff if someone is so inclined. |
| 06:49 | dark_element | dnolen noncom, maybe even name it cljs-time |
| 06:50 | noncom | yes.. |
| 06:50 | noncom | dark_element: i'm still not in twitter, btw :D but gonna be soon, also gonna make audiovizs things and will share |
| 06:50 | dark_element | noncom hey. I am now looking at webgl video filters for visualisations |
| 06:51 | noncom | did you go about shadertoy? |
| 06:51 | dark_element | noncom i am soon going to push the project and you will most probably reuse the code and just write plugins for viz |
| 06:51 | noncom | wow! |
| 06:53 | dark_element | noncom plugins are nothing fancy. just new namespaces and you will have to provide basic functions for viz. |
| 06:54 | dark_element | noncom shadertoy is fun place. i am looking into both shaders and applying filters on the output |
| 07:08 | noncom | dark_element: so r u using shadertoy or on your own? |
| 07:12 | noncom | doh, forging an entire time-date library for cljs is a big task.. |
| 07:15 | dnolen | noncom: and unrealistic, which is why I suggested Closure + clj-time approach, just implement basics and over time (heh) people will likely submit enhancements |
| 07:16 | dnolen | so does leiningen plugins and tasks use the JVM settings specified in project.clj? |
| 07:17 | hyPiRion | dnolen: almost |
| 07:17 | dnolen | hyPiRion: what do you mean? |
| 07:18 | hyPiRion | Give me a moment, I'll find the ticket related to this |
| 07:18 | Somelauw | Too bad that error messages don't include the lines in which my clojure code actually gives an error. |
| 07:18 | Somelauw | ClassCastException java.lang.Character cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:619) |
| 07:19 | Somelauw | That could be anywhere |
| 07:19 | hyPiRion | dnolen: technomancy/leiningen#1230 contains information about how :jvm-opts works, the patch will be in 2.3.0 which is right around the corner |
| 07:19 | lazybot | Set default :jvm-opts in :base profile to :displace -- https://github.com/technomancy/leiningen/issues/1230 is closed |
| 07:21 | dnolen | hyPiRion: yeah that's mostly about the project, I'm wondering about plugins and tasks |
| 07:23 | hyPiRion | dnolen: right. Those won't use the jvm settings specified within project.clj. You'd have to use the environment variable JVM_OPTS for extra opts |
| 07:23 | hyPiRion | even then, I would've inspected what the leiningen shell script adds, because it is quite... configured |
| 07:30 | dnolen | hyPiRion: hrm, yeah the reason I'm looking at this is that CLJS compiler is nearly twice as slow for auto builds if you don't use server settings |
| 07:33 | instilled | What validation libraries is the most popular among clojurians? i'm looking for a general purpose validation library not tied to web, e.g. Sandbox. The other libraries (listed on clujure toolbox) all seem very similar and still actively developed. Any thoughts? |
| 07:33 | hyPiRion | yeah, we do some tweaks to speed JVM+Clojure loading up, at the cost of hotspot speed |
| 07:34 | dnolen | hyPiRion: is it possible to override? |
| 07:34 | dnolen | https://github.com/technomancy/leiningen/blob/master/bin/lein#L120 |
| 07:37 | hyPiRion | dnolen: hrm, not the way the arguments are ordered, unfortunately |
| 07:37 | dnolen | grr |
| 07:40 | hyPiRion | I'll put up an issue on it and see if we can find a way around it, may be that we can put something in for 2.3.0 if we figure out it's safe. |
| 08:24 | squidz | what options do I have when dealing with the datastructure differences between javascript and clojurescript? is there a good way to have our clojurescript sequences converted 'automagically'? |
| 08:26 | squidz | any libraries or anything that enable me to skip on using clj->js |
| 08:27 | dnolen | squidz: it's not possible |
| 08:27 | squidz | okay so it is just something that we have to pay attention to |
| 08:28 | squidz | dnolen: do you think that could be something that could be brought to clojurescript, or is there a fundamental limitation in the language that prevents it? |
| 08:28 | dnolen | squidz: ES 6 Proxy's could be used to work around this problem, but adoption seem unlikely |
| 08:29 | squidz | adoption of proxies? |
| 08:29 | squidz | in ES 6? |
| 08:30 | dnolen | squidz: yes |
| 08:30 | dnolen | squidz: what library are you trying to interact with where marshaling is a big issue? |
| 08:40 | squidz | dnolen: I am using D3 |
| 08:43 | g3ntleman | Did anyone successfully build clojurec on os x? |
| 08:51 | tbaldridge | squidz: there was a Clojure/West talk about doing this (I think even using D3), it guy went to a ton of trouble to make cljs/js interop better. |
| 08:51 | tbaldridge | squidz: let me see if I can find his library |
| 08:53 | tbaldridge | squidz: the lib https://github.com/dribnet/mrhyde |
| 08:53 | tbaldridge | squidz: and a D3 wrapper using mrhyde https://github.com/dribnet/strokes |
| 08:56 | squidz | tbaldridge: okay. Do you know if the video is available to watch anywhere? |
| 08:57 | tbaldridge | squidz: the Clojure/West video schedule says it comes out on 7/29 |
| 08:57 | tbaldridge | squidz: and that'll be on InfoQ |
| 09:01 | Somelauw | Is there a _ in clojure.core? Or what could the _ refer to in ClassCastException clojure.core$_ cannot be cast to java.lang.Number clojure.lang.Numbers.multiply (Numbers.java:146)? |
| 09:06 | squidz | cool can't wait to see it |
| 09:06 | Bronsa | Somelauw: ##(class -) |
| 09:06 | lazybot | ⇒ clojure.core$_ |
| 09:06 | Bronsa | ,(* -) |
| 09:06 | clojurebot | #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.core$_ to java.lang.Number> |
| 09:07 | Bronsa | Somelauw: you probably missed a paren somewhere |
| 09:10 | Somelauw | Bronsa: Okay, but what does it mean? Is _ a minus sign? |
| 09:11 | Somelauw | I found the error I was doing (for [x [1 - 1]]) instead of (for [x [1 -1]]) |
| 09:11 | Bronsa | Somelauw: class names get munged ##(munge '-) |
| 09:11 | lazybot | ⇒ _ |
| 09:12 | Bronsa | Somelauw: java don't premit dashes and other symbols in class names |
| 09:12 | Bronsa | so clojure has to convert them to other things |
| 09:12 | Bronsa | - becomes _ |
| 09:22 | Somelauw | Is there also a unmunge or something? |
| 09:23 | Bronsa | ,(clojure.repl/demunge "clojure.core$_") |
| 09:23 | clojurebot | "clojure.core/-" |
| 09:24 | hyPiRion | be wary though, munging and demunging is not one-to-one |
| 09:24 | hyPiRion | ,(map munge ["-" "_"]) |
| 09:24 | clojurebot | ("_" "_") |
| 09:25 | Somelauw | Bronsa: thanks |
| 09:25 | hyPiRion | ,(let [identity (comp clojure.repl/demunge munge)] (identity "_")) |
| 09:25 | clojurebot | "-" |
| 09:26 | Somelauw | hyPiRion: does that mean that I can't have both a function - and _ in a namespace? |
| 09:26 | Somelauw | because they both get munged the same |
| 09:26 | Bronsa | Somelauw: no, namespaces don't need to munge vars |
| 09:27 | Bronsa | it's only the class name that'll be the same |
| 09:27 | Bronsa | it's probably not going to work when AOT'ing though |
| 09:29 | Bronsa | yeah, if you AOT compile (defn a- []) and (defn a_ []) you overwrite a- with a_ |
| 09:32 | Somelauw | But (def - 5) and (def _ 6) can conflict? |
| 09:32 | Somelauw | I'm not sure I completely understnad yet, but I'll avoid having both a_ and a- anyway. |
| 09:32 | Bronsa | no, defs don't break |
| 09:33 | Bronsa | it's fns that break when AOT |
| 09:33 | Bronsa | Somelauw: yeah, just avoid having the same name with - and _ and you'll be fine |
| 09:33 | Somelauw | oh, because functions are compiled to classes and classes can't have - in their name? |
| 09:33 | Bronsa | yes |
| 09:34 | Bronsa | so both a_b and a-b get compiled to the.ns%a_b.class |
| 09:34 | Bronsa | s/%/$ |
| 09:44 | chrisrossi | I came across this: http://clojure.org/streams |
| 09:44 | chrisrossi | just wanted to say +1 |
| 09:44 | chrisrossi | i'm coming from python and find python generators to be extremely useful. |
| 09:49 | noncom | did anyone ever read an mp4 with opencv and clojure? |
| 09:50 | noncom | i did that in java, but interested if someone had good experience with clojure oto |
| 09:51 | noncom | also there were many changes to opencv-java and javacv... |
| 09:52 | learner_ | Hello All, a newbie question. What does "list comprehension" mean ? |
| 09:55 | squidz | hyPiRion: is it possilbe to use leiningen into an already existing non-clojure project? |
| 09:57 | squidz | learner_: list comprehensions are kind of like mathemetical set definitions |
| 09:57 | squidz | so something like the set of x where x is greateer than 10 and less then 20 {x | x > 10 : x < 20} |
| 09:58 | squidz | which is [11,12,13,14,15,16,17,18,19] |
| 10:01 | Somelauw | Is there something like a .leiningenrc or .clojurerc file, so I can always require pprint when starting a repl? |
| 10:02 | Somelauw | chrisrossi: python generators are a poor man's stream. |
| 10:03 | Somelauw | learner_: You can create them in clojure with the for macro. |
| 10:07 | Somelauw | ok, I found I can put stuff in user.clj |
| 10:09 | hyPiRion | dnolen: false alarm, you can in fact override the default settings. I am just not able to properly read bourne-again shell scripts. |
| 10:10 | hyPiRion | dnolen: it's just LEIN_JVM_OPTS="your settings here" |
| 10:10 | nDuff | ...random aside, coming from #bash: LEIN_JVM_OPTS="foo" is probably the _worst_ way to pass a list of arguments around |
| 10:11 | nDuff | ...as you can't include something like -f "filename with space" inside that argument list without forcing use of eval |
| 10:11 | nDuff | ...and if you use eval, then arbitrary code inside that environment variable is necessarily executable |
| 10:11 | nDuff | and a great deal of work (which most folks writing scripts don't know how to do) is necessary to sanitize arguments being passed in. |
| 10:11 | nDuff | It's seriously bad news, and it's also completely endemic among shell scripts used to start Java processes for some reason. |
| 10:12 | hyPiRion | nDuff: We'd love improvements, fork Leiningen and send a pull request |
| 10:17 | futile | ,(doc ffirst) |
| 10:17 | clojurebot | "([x]); Same as (first (first x))" |
| 10:17 | futile | neat |
| 10:18 | futile | ,(doc rrest) |
| 10:18 | clojurebot | It's greek to me. |
| 10:18 | futile | :D |
| 10:19 | hyPiRion | ,(doc nnext) |
| 10:19 | clojurebot | "([x]); Same as (next (next x))" |
| 10:21 | futile | ha |
| 10:21 | futile | ,(doc fffirst) |
| 10:21 | clojurebot | Gabh mo leithscéal? |
| 10:21 | futile | ,(doc fnext) |
| 10:21 | clojurebot | "([x]); Same as (first (next x))" |
| 10:21 | futile | ha! |
| 10:21 | futile | oh man, caddddr all over ahead |
| 10:21 | futile | *agan |
| 10:21 | futile | *again |
| 10:23 | futile | Are there any Clojure libs that complement Datomic? |
| 10:24 | mmarczyk | futile: sure: https://github.com/rkneufeld/conformity https://github.com/halgari/fafnir |
| 10:25 | futile | Thanks mmarczyk :) |
| 10:25 | mmarczyk | :-) |
| 10:25 | chrisrossi | Somelauw: I'll withhold judgement but "poor man's" seems overly pejorative at first glance. i understand the dangers inherent in stateful iteration, but the allergy to it seems a little extreme to me. usually the scope a stateful iterator is used in is local, nonconcurrent, and entirely safe. |
| 10:40 | pyrhho | What's the clojure equivalent of MyClass.class ? |
| 10:41 | clgv | pyrhho: MyClass |
| 10:41 | clgv | ,String |
| 10:41 | clojurebot | java.lang.String |
| 10:41 | clgv | ,(type String) |
| 10:41 | clojurebot | java.lang.Class |
| 10:41 | pyrhho | ok. so I don't need to call anything to turn it into a class object.. |
| 10:41 | clgv | ,(type java.util.List) |
| 10:41 | clojurebot | java.lang.Class |
| 10:41 | futile | ,(.new String) |
| 10:41 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: new for class java.lang.Class> |
| 10:41 | futile | i dunno |
| 10:42 | pyrhho | ,(new String) |
| 10:42 | clojurebot | "" |
| 10:42 | futile | ,(String/new) |
| 10:42 | clojurebot | #<CompilerException java.lang.NoSuchFieldException: new, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:42 | clgv | pyrhho: a class name is automatically resolve to a class symbol in the examples above |
| 10:42 | futile | ok fine |
| 10:42 | pyrhho | ah ok. |
| 10:42 | tolitius | ,(String.) |
| 10:42 | pyrhho | thanks |
| 10:42 | clojurebot | "" |
| 10:42 | futile | yeah that |
| 10:42 | clgv | pyrhho: delete the "symbol" ^^ |
| 10:42 | futile | ,`~String |
| 10:42 | clojurebot | java.lang.String |
| 10:43 | futile | ,``~~String |
| 10:43 | clojurebot | java.lang.String |
| 10:43 | pyrhho | So, when I have a java method with the type signature methodName(Class<? extends C> arg1), I could just do (.method obj MyClass), then, right? |
| 10:43 | futile | OH NO |
| 10:43 | futile | ,`````~~~~~String |
| 10:43 | clojurebot | java.lang.String |
| 10:43 | clgv | ,(type `~String) |
| 10:43 | clojurebot | java.lang.Class |
| 10:43 | clgv | ,(type `String) |
| 10:43 | clojurebot | clojure.lang.Symbol |
| 10:43 | clgv | ^^ |
| 10:43 | futile | ,(= java.lang.String String) |
| 10:43 | clojurebot | true |
| 10:43 | clgv | pyrhho: yes |
| 10:44 | pyrhho | ok cool thanks |
| 10:44 | clgv | pyrhho: try out your current scenario on the REPL |
| 10:48 | silasdavis | Any convention/idiom for use of 'single' and "double" quoted strings? |
| 10:49 | Somelauw | chrisrossi: I'm not allergic to stateful iteration. It's more that streams can do more than generators. For example, when doing s = generator(), you can only iterate through s once in python, but if s were a stream, it can be iterated multiple times. |
| 10:49 | chrisrossi | ok, gotcha. |
| 10:49 | silasdavis | oh ignore that last comment |
| 10:50 | silasdavis | question rather - too long away from clojure, forget what everything does |
| 10:50 | chrisrossi | one thing i'm missing from the streams writeup is any example of what generator code might look like. |
| 10:51 | chrisrossi | the python 'yield' makes writing those things really nice. anything similarly clever here? |
| 10:51 | Somelauw | chrisrossi: concat and keep? |
| 10:52 | Somelauw | and mapcat |
| 10:53 | futile | I bet Python generators could usually be done with plain old lazy sequences. |
| 10:53 | Somelauw | there is no direct equivalent to yield. But using concat, keep, mapcat and (for :when) you can get equivalent functioning code. |
| 10:54 | nDuff | chrisrossi: see http://clojuredocs.org/clojure_core/clojure.core/lazy-seq |
| 10:55 | nDuff | chrisrossi: ...core.async actually results in code that looks very, very much like Python generators, but that's rather a different thing. |
| 10:55 | chrisrossi | nDuff: yeah i was looking at core.async yesterday. tickles some of the same brain cells, but still different. |
| 10:56 | chrisrossi | i came to core.async looking for a gevent work alike, then realized it doesn't help with io. |
| 10:57 | nDuff | chrisrossi: eh? helps perfectly well with async IO. |
| 10:57 | nDuff | chrisrossi: ...and Java has had async APIs ever since NIO was introduced, which was ages ago. |
| 10:59 | chrisrossi | hmm, maybe i still haven't grokked something essential, but it looks like the only time in core.async that you yield back to the go loop is when you push or pop from a channel. if there were io channels... |
| 11:00 | nDuff | chrisrossi: if you kick off an IO operation with a on-receive callback that feeds into a channel... |
| 11:01 | chrisrossi | ok, sure. that's doable. you still have to use callbacks to do that--something gevent or core.async is designed to allow you to avoid doing explicit callbacks and write synchronous style code. |
| 11:02 | tolitius | chrisrossi: |
| 11:02 | tolitius | (go |
| 11:02 | tolitius | (let [c (chan)] |
| 11:02 | tolitius | (future (>!! c (blocking-io-read some-stream))) |
| 11:02 | tolitius | (let [msg (!< c) |
| 11:02 | tolitius | (do-something-with msg)))) |
| 11:04 | chrisrossi | yep, that'd work, but it's still not the same. now you have a thread dedicated to one file/socket/etc... |
| 11:09 | pyrhho | So, I have a proxied Object, and I'm trying to call a method it got by extending an abstract class, but am seeing "IllegalArgumentException Can't call public method of non-public class" |
| 11:11 | pyrhho | Sorry, it's not a proxied object, actually.. |
| 11:12 | pyrhho | I have a "public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel>", but am trying to call a method it gets from AbstractBootstrap. |
| 11:12 | pyrhho | Is it the generics, maybe? |
| 11:14 | pyrhho | I get the error when I do: "(doto (new ServerBootstrap) (.channel MyChannel))" |
| 11:17 | tolitius | chrisrossi: true, but hopefully a very sort lived thread |
| 11:18 | tolitius | can be wrapped in a cached thread pool |
| 11:19 | alexgunnarson | hey everyone - i was wondering… what are some options for clojure iOS development? |
| 11:19 | alexgunnarson | i know of some instances where clojurescript has been used |
| 11:20 | alexgunnarson | but clojure… the jvm doesn't run on ios |
| 11:20 | chrisrossi | looks like clojure.java.shell doesn't support streaming to/from subprocs. some 3rd party libraries do. any favorites? |
| 11:20 | gfredericks | does anybody know what was meant here about reader metadata & IReference? https://groups.google.com/forum/#!topic/clojure-dev/mAHFtuaEXRk |
| 11:21 | tolitius | chrisrossi: what are streaming from shell? |
| 11:21 | tolitius | (e.g. that can't be streamed from JVM) |
| 11:22 | tolitius | *what are you |
| 11:23 | chrisrossi | i just want to call out to shell prog, get an output stream that can be used to write to the subproc's stdin and/or an input stream that can be used to read from a subproc's stdout. |
| 11:24 | chrisrossi | just a pipe, basically. |
| 11:26 | nDuff | alexgunnarson: I've seen some folks working on an ObjC compilation target for that reason. |
| 11:27 | alexgunnarson | nDuff: any success with it? |
| 11:27 | nDuff | alexgunnarson: ...that's something closer to cljs than Clojure proper, though. |
| 11:27 | tolitius | chrisrossi: https://github.com/Raynes/conch might do what you want. check it out |
| 11:27 | nDuff | alexgunnarson: Don't know -- haven't tracked it closely. |
| 11:28 | alexgunnarson | nDuff: okay. thanks :) |
| 11:28 | chrisrossi | tolitius: i was actually looking at that one. thanks. have you used it? |
| 11:29 | tolitius | chrisrossi: e.g. (grep "ssh" {:in (ps "-e" {:seq true})}) |
| 11:29 | tolitius | no, did not have a need, but I am looking for an excuse to :) |
| 11:30 | tolitius | chrisrossi: Raynes is solid though, so I would expect it to work as doced |
| 11:33 | chrisrossi | cool. i see the low-level api gives you :out as an input stream, just like i want. ;) |
| 11:33 | chrisrossi | and the method of composing pipelines is pretty cool. |
| 11:34 | egghead | we're using conch for a little task runner, works well |
| 11:34 | tolitius | chrisrossi: yep, very clean |
| 11:41 | jvc | hi, I wrote this help mode for clojure https://github.com/judevc/clojure-here |
| 11:46 | mmarczyk | gfredericks: going by the code, objects implementing IReference would have their metadata reset to the leftmost metadata item specified in the source |
| 11:46 | mmarczyk | gfredericks: ^:foo ^:bar ^:quux iref -> iref with {:foo true}, but not :bar or :quux |
| 11:46 | futile | jvc: can you put it in melpa? |
| 11:48 | mmarczyk | gfredericks: the relevant concrete classes are Namespace, Agent, Atom, Ref, Var -- not exactly read in very often -- so not a terribly big deal |
| 11:48 | jvc | futile: i put it in marmalade |
| 11:48 | jvc | I haven't put anything in melpa, let me have a try. |
| 11:48 | gfredericks | mmarczyk: how do you read them? |
| 11:49 | futile | jvc: melpa is awesome |
| 11:50 | gfredericks | mmarczyk: oh I see: (meta (read-string "^{:foo 12} ^{:bar 15} #=(atom nil)")) => {:foo 12} |
| 11:52 | mmarczyk | gfredericks: right |
| 11:52 | mmarczyk | gfredericks: no way to read these in besides read-eval that I can think of off the top of my head |
| 11:55 | egghead | can I have a macro that behaves differently in cljs than clj somehow? |
| 11:56 | egghead | just want to reference 'go' by clojure.core.async/go and cljs.core.async.macros/go depending on the env its used for |
| 11:57 | dnolen | egghead: there's not really a simple way to do that |
| 11:57 | egghead | c'est la vie |
| 11:57 | bgilbert | egghead: maybe two separate macros under different namespaces, and shared functions in a common namespace |
| 11:57 | egghead | currently i'm just not qualifying it and assuming that 'go' will be available at expand time |
| 11:57 | nDuff | (feature tags? something that made the language implementation queryable) |
| 11:58 | egghead | ya two namespaces is probably a better way to do it |
| 11:58 | egghead | thanks |
| 11:58 | mmarczyk | dnolen: egghead: haven't tried this, but checking whether there's a dynamic binding in place for *cljs-ns* (in cljs.analyzer) might be a way to do it |
| 11:59 | mmarczyk | and incidentally I think it would be nice to have a supported way to do this |
| 12:01 | dnolen | mmarczyk: sounds like feature expressions to me :) |
| 12:03 | mmarczyk | dnolen: sure :-) |
| 12:03 | mmarczyk | dnolen: I'd still like to have *clojure-version* bound to something sensible when compiling cljs |
| 12:04 | mmarczyk | would be super funny if a compiler macro then used *clojure-version* to determine which Clojure-side facilities are available though |
| 12:04 | mmarczyk | oh well. |
| 12:06 | mmarczyk | oh wow, confluence uses some sort of rich text editor? no markup? :-( |
| 12:07 | dnolen | mmarczyk: I think it's possible to support Markdown, not sure Clojure Confluence does |
| 12:08 | futile | POCT = plain old Clojure tricks |
| 12:08 | futile | POCT is great. libs should encourage POCT instead of reinventing them |
| 12:10 | mmarczyk | dnolen: oh great, help mentions some markup too, so that's encouraging... I'll find out soon enough if we've got it enabled |
| 12:10 | ChongLi | http://dev.clojure.org/display/design/Feature+Expressions |
| 12:11 | ChongLi | this is a nice article |
| 12:11 | dnolen | ChongLi: pretty sure it's on the table for Clojure 1.6 - we'll see |
| 12:11 | ChongLi | sweet |
| 12:13 | futile | dnolen: im probably way uninformed.. but would it make more sense to just define a stdlib-interface that each platform has to conform to? |
| 12:13 | futile | then each program wouldnt care where its running, its just written one way. |
| 12:13 | learner_ | squidz: Thanks for your answer about List comprehension. Really appreciate it |
| 12:13 | ChongLi | no |
| 12:13 | ChongLi | one of the core philosophies of clojure is platform power |
| 12:14 | ChongLi | by wrapping the platform in a standard interface, you lose that |
| 12:14 | futile | touche |
| 12:14 | futile | yeah, it would require wrapping every single platform feature. thats not realistic |
| 12:14 | dnolen | futile: it only sound good in theory, platforms tend to differ in dramatic ways |
| 12:15 | llasram | Also, that kind of stuff is hard to get right. If you do it well, it saves users a ton of time. If you do it wrong, you get the Java process API |
| 12:15 | futile | ah right, exceptions/types/concurrency/etc |
| 12:15 | ChongLi | it pushes you into a "lowest common denominator" standard platform |
| 12:15 | ChongLi | feature expressions help you to detect and leverage your platform specifically |
| 12:26 | mmarczyk | design page re: recur to enclosing loop: http://dev.clojure.org/display/design/Named+loops+with+recur-to |
| 12:26 | mmarczyk | (incl. links to clojure-dev discussion and cljs proof of concept) |
| 12:58 | callen | Dear #clojure, this is your daily reminder that https://github.com/uncomplicate/fluokitten exists. |
| 13:02 | futile | I thought I wanted comp, but that wasn't right. Then I thought it was iterate, that's not right either. |
| 13:02 | futile | I guess I want (f1 (f2 (f3 f4))) or something. |
| 13:03 | futile | It's kinda like iterate, but with different functions each time, from a list of functions. |
| 13:03 | futile | How would you do this? |
| 13:04 | futile | Maybe reduce... |
| 13:05 | futile | ,(not (zero? (inc 3))) |
| 13:05 | clojurebot | true |
| 13:05 | justin_smith | ((apply comp fn-list) input) |
| 13:05 | futile | ,((apply comp [not zero? inc]) 3) |
| 13:05 | clojurebot | true |
| 13:05 | futile | Oh. |
| 13:06 | futile | Thanks justin_smith :) |
| 13:06 | futile | (inc justin_smith) |
| 13:06 | lazybot | ⇒ 3 |
| 13:07 | futile | Yeah that makes a lot of sense suddenly. |
| 13:09 | justin_smith | another option: (defmacro ->vec [input fns] `(-> ~input ~@fns)) |
| 13:09 | futile | Well even so, I think I'm doing it all wrong. |
| 13:09 | justin_smith | I don't think the bot will do macros, but that will work like -> but take the fns in a list/vector |
| 13:09 | futile | I'm trying to implement around-each fixtures. |
| 13:10 | futile | (but it's all wrong) |
| 13:10 | Bronsa | ,(get (sorted-set 1) :foo) ;; this was surprising to me |
| 13:10 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Keyword> |
| 13:11 | justin_smith | a fixture should be a function that takes the action it wraps as an argument, and it can decide whether to do it's action to the functions input or output or both |
| 13:11 | futile | justin_smith: can you show me in code (refheap)? |
| 13:11 | justin_smith | that way you can compose fixtures (similar to ring handlers for example) |
| 13:11 | futile | cuz im confused by what you mean |
| 13:12 | justin_smith | I have a meeting in four minutes, but remind me sometime later if I forget |
| 13:12 | futile | justin_smith: oh ok |
| 13:13 | futile | for anyone else following along, this is my plan so far: https://www.refheap.com/16903 |
| 13:19 | amalloy | mmarczyk: neat! |
| 13:20 | bbloom | mmarczyk: another current "solution": trampolines |
| 13:21 | amalloy | trampolines solve everything in real life; why not in clojure too? |
| 13:24 | bbloom | hmmm… the letfn comment about loop layers is interesting |
| 13:24 | bbloom | in theory, if you have mutually recursively defined functions, couldn't you recur from tail position to another function in the letfn block? |
| 13:25 | amalloy | bbloom: in scheme you could. in clojure it's not possible, and i don't think mmarczyk can change that |
| 13:26 | amalloy | i mean, i guess he could conceivably code-walk the letfn and transform it to a single function, but it would be as much work as core.async's go macro |
| 13:26 | bbloom | yeah, i guess you'd need to inline all the mutually recursive functions into each other, in case you were to let such a fn escape |
| 13:27 | bbloom | i *really* like the explictness of recur |
| 13:27 | bbloom | super useful to have that checked for you at compile time |
| 13:27 | futile | Oh man, I think I have to use recursin. |
| 13:32 | callen | bbloom: https://github.com/bmillare/dj.compose |
| 13:33 | callen | sigh, did he ignore me again? |
| 13:33 | callen | can somebody copy-paste my message to him please? |
| 13:33 | callen | that repo might help him. |
| 13:34 | Bronsa | 19:19:53 <callen> bbloom: https://github.com/bmillare/dj.compose |
| 13:34 | llasram | futile: (reduce #(partial %2 %1) test-fn [fixture-1 fixture-2 fixture-3]) |
| 13:34 | futile | llasram: ah! |
| 13:34 | llasram | I'm not sure if that's *really* what you want, but produces what you mentioned |
| 13:34 | futile | why do you think its not? |
| 13:35 | callen | Bronsa: thank you. |
| 13:35 | bbloom | Bronsa: i heard him :-P |
| 13:35 | llasram | futile: Just seems odd, but thinking about it for a second, I see what you're going for |
| 13:35 | futile | llasram: yeah, each fixture receives a function it should call, which is either the test function, or another wrapped fixture. |
| 13:36 | futile | llasram: this does that perfectly without forcing the users to wrap all fixture bodies in an anon func |
| 13:36 | bbloom | callen: this is interesting. thanks. in generally, i'm deeply interested in this sort of composition |
| 13:36 | bbloom | i frequently lament about the fact that extend is useless b/c all the core abstractions are still interfaces :-/ |
| 13:38 | callen | bbloom: glad it was useful. good luck. |
| 13:38 | callen | bbloom: here's a puzzler, is there a way to generate java annotations with Clojure without using AOT/gen-class? |
| 13:38 | callen | bbloom: ideally with proxy? |
| 13:39 | callen | I saw the clojure.asm and AnnotationVisitor |
| 13:39 | callen | doesn't seem like there's anything shake-n-bake. |
| 13:39 | llasram | callen: This came up a few days ago... I'm not sure it actually worked out for aphyr, but can invoke the internals of gen-class w/o AOT, and give the results to the same class-loader used by deftype |
| 13:39 | callen | composing proxy could be annoying. |
| 13:39 | callen | llasram: he was in here last night and it still hadn't been resolved. |
| 13:40 | llasram | Oh, well, there we go |
| 13:40 | llasram | (checks some logs) |
| 13:40 | callen | I think realistically it's going to require rewriting/wrapping proxy and using the AnnotationWriter/AnnotationVisitor.java stuff in clojure.asm. |
| 13:41 | llasram | Hmmm, I wonder why the reach-into-internal stuff didn't work for him |
| 13:42 | stuartsierra | callen: deftype supports annotations. |
| 13:42 | stuartsierra | https://github.com/clojure/clojure/blob/229bf8fe9a751e4f48bb2b7ea57e27ebc43d26ae/test/clojure/test_clojure/annotations/java_6.clj |
| 13:44 | callen | stuartsierra: I tihnk it's needed for proxying classes from Netty. |
| 13:44 | callen | stuartsierra: I'm pretty sure aphyr already knows he can use annotations with deftype. |
| 13:44 | callen | That's not the issue. |
| 13:45 | stuartsierra | Oh, sorry, I tuned in halfway through. |
| 13:45 | callen | stuartsierra: Netty uses/requires annotations and it's making his life difficult. Proxy needs to support annotations for better java interop. |
| 13:46 | stuartsierra | I recall using Netty in the past (version 3.x?), and I didn't need any annotations then. |
| 13:46 | callen | stuartsierra: aphyr is out on the hairy edge apparently. |
| 13:47 | stuartsierra | Often annotation-based APIs have an alternative, lower-level API that doesn't require annotations. |
| 13:47 | callen | stuartsierra: http://docs.jboss.org/netty/3.1/api/org/jboss/netty/channel/ChannelPipelineCoverage.html http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/class-use/ChannelHandler.Sharable.html |
| 13:47 | callen | stuartsierra: I'm sure, given the signs of madness he was exhibiting, if such a thing were possible he would've done so. |
| 13:47 | callen | proxy needs to support annotations. |
| 13:48 | stuartsierra | OK, I'm not disputing that. |
| 13:49 | stuartsierra | When faced with an annotation-heavy Java API, I usually recommend writing wrapping Clojure functions in Java to do the annotation stuff. |
| 13:49 | stuartsierra | s/writing// |
| 13:50 | callen | I'd rather fix proxy. |
| 13:50 | futile | What's that function that lets "defsomething" macros keep the metadata users gave it? |
| 13:55 | futile | Saw it a lot in clojure.core functions, can't remember which ones though. |
| 13:56 | gfredericks | futile: if the macro passes the symbol through then it's normally not an issue I think |
| 13:56 | pbostrom` | futile: name-with-attributes? |
| 13:57 | futile | sounds right |
| 13:57 | futile | except i thought whatever it was was in core |
| 13:58 | futile | gfredericks: oh i think im just losing metadata because my macro uses with-meta instead of vary-meta |
| 13:58 | futile | you're right. thanks. |
| 14:07 | miwa | I went to bed too late last night after having started to explore the world of clojure.. I dreamed of rainbow coloured parantheses o.O |
| 14:07 | seangrove | miwa: There's an emacs mode for that |
| 14:08 | miwa | well, I'm a vim user =P |
| 14:08 | callen | miwa: sorry to hear that. |
| 14:08 | seangrove | Well, heaven have mercy |
| 14:08 | seangrove | Does your family know? |
| 14:08 | miwa | hah, I've even converted one or two emacs users actually ;) |
| 14:08 | seangrove | miwa: vim's good stuff, no worries :) |
| 14:09 | seangrove | https://github.com/kien/rainbow_parentheses.vim |
| 14:09 | zilti | I once tried to use vim, I didn't even manage to set it up for clojure |
| 14:09 | miwa | well, setting it up is the hard part unfortunately zilti |
| 14:10 | zilti | Though I'd miss elisp too much. |
| 14:10 | futile | welp |
| 14:10 | ChongLi | vim is great for editing tasks |
| 14:10 | zilti | And orgmode |
| 14:10 | futile | writing good macros is hard |
| 14:10 | ChongLi | emacs is great for running processes like repls and stuff |
| 14:10 | miwa | well, I hear there's a vi mode in emacs for those who are so inclined :P |
| 14:10 | ChongLi | yeah evil |
| 14:10 | futile | ive been impressed by the architecture of Sublime Text |
| 14:11 | futile | its like Emacs but for 2013 instead of 1982 |
| 14:11 | miwa | yeah, Sublime Text seems pretty cool.. it's a bummer it isn't free though =/ |
| 14:11 | ChongLi | yeah that's a dealbreaker |
| 14:11 | futile | thats what employers are for, to pay for it |
| 14:11 | zilti | But it's not using lisp... bah |
| 14:11 | futile | zilti: so? |
| 14:11 | ChongLi | it's not about the money |
| 14:11 | futile | ChongLi: oh, libre? |
| 14:11 | zilti | Sublime is free, isn't it? It's "just" not open |
| 14:11 | ChongLi | yes |
| 14:12 | futile | ChongLi: yeah, i dont care about that anymore. look what good libre did to emacs. |
| 14:12 | futile | its stuck in 1983 thanks to libre |
| 14:12 | ChongLi | that does not follow |
| 14:12 | futile | and look at linux vs mac. libre isnt doing anything for me, the user. |
| 14:12 | zilti | Well, I'd not want Emacs to change much |
| 14:12 | ChongLi | I'm sorry you feel that way |
| 14:13 | futile | ChongLi: i believe you |
| 14:13 | llasram | Yeah....... RMS's fears of non-free software polluting Emacs through runtime shared library loading aren't exactly a necessary property of libre software |
| 14:13 | futile | i used to care about libre on principle, but pragmatially, it gives me no real power as a user. |
| 14:13 | ChongLi | clojure is libre as well |
| 14:13 | nDuff | futile: speaking as an end-user, I feel hamstrung whenever I use a system I can't get into the guts of and modify. |
| 14:13 | nDuff | futile: ...and, to be clear, I _do_ use that capability with some frequency. |
| 14:13 | llasram | (inc nDuff) |
| 14:13 | lazybot | ⇒ 4 |
| 14:13 | ChongLi | if it weren't, most of us likely wouldn't be here |
| 14:14 | futile | i think that xkcd about scripting linux to keep the screen from going black sums up my argument against any supposed benefit of libre |
| 14:14 | fowlslegs | I am having a problem with the clojure.java.javadoc api |
| 14:14 | fowlslegs | The javadoc function is rendering incromprehensibly |
| 14:14 | futile | "oh she got dressed and left only 30 minutes into me reading the manual on scripting the cursor" |
| 14:15 | futile | or however it goes |
| 14:15 | fowlslegs | Is there a way to fix this or should I investigate alternative java documentation? |
| 14:15 | seangrove | fowlslegs: Sorry, haven't used the javadoc pieces at all |
| 14:15 | ChongLi | futile: you could repeat the same exercise with pretty much any proprietary software product |
| 14:15 | nDuff | futile: last month, I patched Ivy to add SSH agent support; to fix revision mapping support, and... eh, something else. |
| 14:15 | ChongLi | it does nothing to support your point |
| 14:15 | nDuff | futile: if the source had been closed, I would have had no recourse at all. |
| 14:15 | seangrove | I don't get the feeling that it's used all that much |
| 14:15 | futile | ChongLi: right. meaning libre or not makes no difference. |
| 14:15 | fowlslegs | seangrove: thanks! |
| 14:16 | ChongLi | futile: convenience is not the goal of free software |
| 14:16 | ChongLi | freedom is |
| 14:16 | futile | nDuff: not true. if the demand is high enough, a competitor comes out that gives you what you really want, and kills out the other guy |
| 14:16 | fowlslegs | anyone else know about the javadoc fxn? |
| 14:16 | nDuff | futile: that's in the long run. In the long run, as they say, we're all dead. |
| 14:16 | futile | ChongLi: freedom is a means to an end, not an end in itself |
| 14:16 | nDuff | futile: The short run matters. |
| 14:16 | futile | nDuff: no, in the short run too. datomic for example. |
| 14:16 | ChongLi | without freedom, you may lose everything |
| 14:17 | nDuff | futile: in the short run, I can't typically afford switching costs. |
| 14:17 | fowlslegs | Or does anyone know of a doc library that's good and contains java? |
| 14:17 | futile | ChongLi: thats an exaggeration |
| 14:17 | futile | datomic isnt libre and its wonderful compared to postgres and mongo which are libre |
| 14:17 | nDuff | futile: ...and, by the way, the licensing on datomic hurts it a lot. |
| 14:17 | ChongLi | futile: tell that to the users of google reader |
| 14:17 | futile | nDuff: time will tell if it actually does hurt it or if thats just a false opinion |
| 14:17 | nDuff | futile: I haven't been able to use it in any of the places I've worked since it came out due to the licensing |
| 14:17 | futile | nDuff: even datomic free? |
| 14:18 | nDuff | futile: ...because we weren't willing to put down $$$ until we knew it was worth it, and we couldn't evaluate without risking lockin. |
| 14:18 | zilti | I don't mind using non-libre software sometimes, but as a future software developer I'll do everything I can to make my money with libre software |
| 14:18 | nDuff | futile: go with free, and you're betting transition costs on the product being worthwhile. |
| 14:18 | nDuff | futile: that's a hard sell to management. |
| 14:19 | futile | nDuff: yeah, so some corporations lose out in the shortest-term due to that. but maybe thats actually a good thing. if you'd jumped in and found out it wasnt performant, youd have lost that valuable time. better for everyone to wait til it proves itself, not just people who dont wanna pay |
| 14:19 | futile | ChongLi: i dont know any users of google reader |
| 14:19 | seangrove | nDuff: same concerns over lock-in with datomic as well |
| 14:20 | nDuff | futile: "better for everyone to wait" gets you things like the Python2->Python3 transition, where it's years after 3.0 is called preferred by the dev team but everybody is waiting for someone else to go port libraries over first. |
| 14:21 | futile | nDuff: thats a library concern, not analogous to datomic's issue. once datomic proves itself, everyone can jump in without hesitation. python3 isnt adopted because every lib author needs to wait for every other lib author. |
| 14:22 | nDuff | futile: how in the world is datomic going to prove itself is the strong majority of its userbase aren't willing to consider it because it's unproven and too risky to use the free version for a pilot that might need to scale? |
| 14:22 | nDuff | futile: if people _do_ use it successfully, you have things like Viaweb's use of Common LISP |
| 14:22 | nDuff | -- a competitive advantage they keep to themselves and don't publicize. |
| 14:22 | nDuff | ...so others don't *know* that it's been used successfully until years after the fact. |
| 14:23 | futile | nDuff: thats only assuming every one of them needs that competitive advantage, which im sure they wont. |
| 14:23 | futile | if we were to use datomic where i work, im sure we wouldnt mind publicizing that fact, we dont have many competitors. |
| 14:23 | futile | our niche is something else, not how well we scale. |
| 14:23 | nDuff | futile: Right. Fact of the matter is that the Clojure community is limited in size. There are only so many potential adopters you can afford to drive off. |
| 14:24 | futile | nDuff: isnt datomic just java? tons more people can use it than just us. |
| 14:24 | nDuff | futile: Not everyone's projects are going to work out -- many to most will fail for reasons completely unrelated to the datastore. |
| 14:24 | futile | not to mention it uses rest lately, so even rails guys can use it |
| 14:24 | nDuff | futile: it's "just Java", but it's not nearly as usable from Java. |
| 14:24 | futile | nDuff: heh, nothing is :) |
| 14:24 | nDuff | ...is the impression I got last time I looked. |
| 14:24 | nDuff | As in, hard enough to use from Java that nobody would want to. |
| 14:24 | zilti | futile: You still have to write the requests in EDN aka Clojure if you use it from Java |
| 14:25 | futile | zilti: edn isnt hard for java devs to learn for this small purpose |
| 14:25 | futile | look, we're way off topic |
| 14:25 | nDuff | futile: anyhow, any shop using Java is a place prioritizing being able to replace their staff over making their staff productive |
| 14:25 | zilti | So in Clojure you can use data structures but in Java you have to put together Strings |
| 14:25 | nDuff | those aren't the places that are going to be using Datomic anyhow. |
| 14:25 | futile | my main point was that Sublime Text looks like its emacs-done-right. and thats pretty cool. |
| 14:25 | futile | main thing holding me from switching altogether is that its paredit-mode is lacking some important keys |
| 14:26 | futile | zilti: just like sql |
| 14:26 | futile | which they've managed fine so far ;) |
| 14:27 | futile | anyway, writing good macros is hard. |
| 14:27 | zilti | Damn, today is the first time I hate clojurescript for not having runtime macros... |
| 14:27 | futile | oh? |
| 14:28 | amalloy | does anyone happen to know what the jvm does when it receives a signal (sigterm, sigint, etc)? it seems to be doing basically what i want (giving InterruptedException to my running threads, then shutting down), but i wonder if that's actually what's going on, and whether that's promised behavior |
| 14:29 | hyPiRion | amalloy: Starts a new thread with max priority, and handles the Signal through a SignalHandler |
| 14:29 | zilti | I'm working on a project where it should be possible to just define forms for database editing with basically no logic to be inside, and have to somehow get that form out, modify it and listen to everything. Would have been way easier with some clojure.walk magic in a macro |
| 14:31 | hyPiRion | What happens with the specifics one, I'm not sure. Most of them are implemented natively, for whatever reason. |
| 14:34 | futile | ,(let [list [:foo :bar "baz" :quux :yay], [a [b & c]] (split-with (complement string?) list)] [a b c]) |
| 14:34 | clojurebot | [(:foo :bar) "baz" (:quux :yay)] |
| 14:34 | futile | sweet |
| 14:34 | futile | is that terrible code, or fine? |
| 14:36 | seangrove | futile: the code seems fine, but the intent seems terrible |
| 14:36 | futile | seangrove: whyzat? |
| 14:36 | seangrove | But I don't know what you're trying to do, so maybe it makes sense |
| 14:36 | futile | well, im writing a horrible macro. |
| 14:36 | Raynes | "That sounds like a terrible idea! I don't know what it is, but I bet it's horrible!" |
| 14:36 | futile | :D |
| 14:36 | futile | im making this work (deftest "testing foo" ...body...) |
| 14:37 | futile | except, since it uses a string instead of a symbol, you cant put metadata before that string, since it wont compile |
| 14:37 | futile | so im going to just let people put a list of keywords there that will act like ^:kw |
| 14:37 | seangrove | Raynes: Far too many bangs |
| 14:38 | futile | ie (deftest :foo :bar "testing something" ...body...) |
| 14:38 | futile | which i admit is "terrible, just terrible". but i dont have a better idea yet. |
| 14:38 | seangrove | futile: That's not so bad |
| 14:38 | seangrove | It just wasn't clear why you'd be splitting/destructuring like that from the a b c example |
| 14:39 | futile | the inconsistency between ^:foo and :foo is bad |
| 14:43 | squidz | zilti: how would you do it with javascript? |
| 14:44 | zilti | squidz: Oh, I won't touch javascript, I'll stick to clojure :) Sure there's a way, but runtime macros would have made it simpler. |
| 14:44 | futile | is there a better way to do this? &(into {} (map vector [:a :b :c] (repeat true))) |
| 14:44 | futile | oops i meant &&(into {} (map vector [:a :b :c] (repeat true))) |
| 14:44 | futile | oh man whatever. |
| 14:44 | futile | ,(into {} (map vector [:a :b :c] (repeat true))) |
| 14:45 | clojurebot | {:a true, :b true, :c true} |
| 14:45 | hyPiRion | ,(zipmap [:a :b :c] (repeat true)) |
| 14:45 | clojurebot | {:c true, :b true, :a true} |
| 14:45 | SegFaultAX | arohner: Ping. |
| 14:45 | arohner | pong |
| 14:45 | SegFaultAX | arohner: Circle is awesome. |
| 14:45 | arohner | thanks :-) |
| 14:45 | SegFaultAX | Is github integration on the roadmap? |
| 14:46 | fowlslegs | (.printStackTrace *e) is giving me nil |
| 14:46 | arohner | WDYM, integration? |
| 14:46 | fowlslegs | but an exception was just thrown |
| 14:46 | SegFaultAX | I want to replace our CI with circle, but my team needs github commit status api. |
| 14:46 | arohner | we already do that |
| 14:46 | SegFaultAX | :O |
| 14:46 | SegFaultAX | Docs? |
| 14:46 | squidz | zilti: exactly |
| 14:46 | fowlslegs | any ideas on where the error is? |
| 14:47 | callen | SegFaultAX: what are they using right now? |
| 14:47 | SegFaultAX | arohner: Also, I really enjoyed your talk on infoq. |
| 14:47 | arohner | SegFaultAX: you shouldn't need to configure anything |
| 14:47 | SegFaultAX | arohner: Orly? |
| 14:47 | arohner | if we run the build, it updates commit status |
| 14:48 | SegFaultAX | arohner: Weird, the initial tests we did didn't seem to do that. But maybe we missed it since we're also testing codeship |
| 14:48 | arohner | thanks! you might also enjoy https://www.youtube.com/watch?v=9wgsDosgWhE . I was going to do that talk, then it interfered with my honeymoon |
| 14:48 | SegFaultAX | arohner: Are you in SF? |
| 14:48 | arohner | most of the time |
| 14:48 | SegFaultAX | arohner: You open to lunch sometime? |
| 14:48 | arohner | absolutely |
| 14:51 | ToxicFrog | How do I take the sqrt of an integer? The docs I can find all refer to 'clojure.contrib.math or 'clojure.math.numeric-tower, neither of which I seem to have (in 1.4) |
| 14:51 | futile | is remove-ns expensive? |
| 14:51 | ToxicFrog | Should I just make it a double and use java interop? |
| 14:52 | llasram | ToxicFrog: It should auto-coerce to a double when you call `Math/sqrt` |
| 14:52 | zilti | clojure.contrib is "dead" since 1.3 |
| 14:52 | llasram | ToxicFrog: Or are you looking for an exact answer for when the square root is an integer? |
| 14:53 | ToxicFrog | llasram: nah, I don't need an exact answer |
| 14:54 | SegFaultAX | ,(Math/sqrt 16) |
| 14:55 | clojurebot | 4.0 |
| 14:55 | futile | ,(gensym) |
| 14:55 | clojurebot | G__31 |
| 14:55 | futile | ,(gensym "foo") |
| 14:55 | clojurebot | foo60 |
| 14:55 | futile | neat. |
| 15:01 | stuartsierra | Huh. clojure.lang.Range isn't used anywhere. |
| 15:02 | bbloom | stuartsierra: `git rm` is my favorite command :-) |
| 15:02 | egghead | hmm, is there any utility around to split a command line string into an argument vector? |
| 15:02 | amalloy | stuartsierra: i always assumed it was an early prototype before lazy-seqs made (range) possible |
| 15:03 | stuartsierra | amalloy: That's my guess too. Probably left for backwards compatibility. |
| 15:03 | egghead | seems like a tricky problem, things like "foo -x 'bar 23' --foo bar" |
| 15:03 | amalloy | egghead: well, your shell will do the "hard" part there, of making "bar 23" a single arg |
| 15:03 | amalloy | tools.cli isn't bad |
| 15:04 | egghead | amalloy: I'm taking in command strings as input, so I have to do it myself :( |
| 15:04 | bbloom | stuartsierra: but backwards compatibility inhibits my ability to git rm freely..... |
| 15:04 | egghead | unless I just forward it to sh -c or something |
| 15:05 | seangrove | stuartsierra: Isn't that something codeq could tell you? |
| 15:06 | stuartsierra | seangrove: I don't think codeq has a Java parser yet. |
| 15:06 | fowlslegs | Can someone help me understand a REPL error I am having? |
| 15:07 | seangrove | stuartsierra: Ah, good point |
| 15:07 | fowlslegs | It should be quite simple for most here I'm sure. |
| 15:08 | llasram | fowlslegs: Questions are welcome, so need for ceremony before asking :-) |
| 15:08 | llasram | s,so need,so no need, |
| 15:08 | fowlslegs | So I have this fxn: http://paste.ubuntu.com/5912118/. |
| 15:09 | llasram | Ok |
| 15:10 | fowlslegs | And when I try to use java.lang.Math methods I get this error "CompilerException java.lang.RuntimeException: Unable to find static field: hypot in class java.lang.Math, compiling:(NO_SOURCE_PATH:1:1)". |
| 15:10 | llasram | Oh, that's because JVM object static methods aren't Clojure functions |
| 15:10 | fowlslegs | For example, (f-values Math/hypot 5 5) gives me this. |
| 15:10 | llasram | Right. ##(class Math/hypot) |
| 15:10 | lazybot | java.lang.RuntimeException: Unable to find static field: hypot in class java.lang.Math |
| 15:11 | llasram | That's a method, which isn't a "thing" you can pass around |
| 15:11 | llasram | You need to wrap it in a function, which can be anonymous, like (f-values #(Math/hypot %) 5 5) |
| 15:12 | llasram | Because then: ##(class #(Math/hypot %)) |
| 15:12 | lazybot | java.lang.IllegalArgumentException: No matching method: hypot |
| 15:12 | llasram | Hah |
| 15:12 | llasram | Because then: ##(class #(Math/sqrt %)) |
| 15:12 | lazybot | ⇒ sandbox11278$eval15202$fn__15203 |
| 15:12 | llasram | Anyway |
| 15:12 | llasram | You get the idea |
| 15:15 | fowlslegs | Hmmm maybe I need to read up on methods |
| 15:15 | fowlslegs | I don't really understand how they differ from functions. |
| 15:16 | gfredericks | they're interop things |
| 15:16 | gfredericks | has anybody written an intro-to-the-jvm-for-clojure-programmers yet? |
| 15:16 | fowlslegs | (Math/hypot 1 1) works |
| 15:16 | gfredericks | I might volunteer if not |
| 15:16 | seangrove | gfredericks: That would be wonderful |
| 15:17 | gfredericks | okay that's on my todo list |
| 15:17 | gfredericks | maybe this weekend |
| 15:18 | fowlslegs | So why does it work in this single instance, but not when I use the for macro to use it generate the third value of each vector in my lazyseq |
| 15:18 | gfredericks | fowlslegs: are you still tripping on (f-values Math/hypot 5 5)? |
| 15:18 | zerokarmaleft | gfredericks: jvm = vm internals or core libraries often used via interop? |
| 15:19 | fowlslegs | yes |
| 15:19 | gfredericks | zerokarmaleft: not vm impl -- like the object model (what are methods? interfaces? etc?), the classpath, properties... |
| 15:20 | gfredericks | suggestions welcome |
| 15:20 | gfredericks | fowlslegs: try (f-values #(Math/hypot %1 %2) 5 5) |
| 15:22 | gfredericks | also should it be a blog post or something more communal? |
| 15:22 | llasram | gfredericks: Inner classes (because it's such a commonly asked question). Probably how `.method` and `Constructor.` are builtin pseudo-macros (or whatever the official name is) |
| 15:22 | zerokarmaleft | gfredericks: that sounds more like a communal effort |
| 15:22 | zerokarmaleft | there's a lot of rabbit trails |
| 15:22 | gfredericks | should check that clojure-doc site |
| 15:22 | llasram | Maybe something on clojure-docs |
| 15:22 | llasram | clojure-doc even |
| 15:23 | llasram | Huh, which seems to be in a sadness-state right now |
| 15:23 | llasram | Oh, there already is one: http://clojure-doc.org/articles/language/interop.html |
| 15:23 | gfredericks | by which you mean it's missing its stylesheets? |
| 15:24 | llasram | And having encoding issues |
| 15:24 | gfredericks | I feel like an interop guide should be a separate thing |
| 15:25 | llasram | A separate thing from what? |
| 15:25 | gfredericks | an intro to the jvm |
| 15:25 | llasram | Ah |
| 15:25 | gfredericks | you can tell somebody "here's how you call a static method" and that's interop, but if they don't know what a static method is in the first place... |
| 15:25 | llasram | That does seem reasonable |
| 15:25 | zerokarmaleft | gfredericks: I remember handling those gaps by just shoehorning myself into java for awhile |
| 15:25 | gfredericks | I didn't have them since I had done java enough |
| 15:26 | gfredericks | zerokarmaleft: you wrote java code? |
| 15:26 | zerokarmaleft | only in an academic setting, years before I started clojure |
| 15:26 | zerokarmaleft | which is to say, not really |
| 15:26 | fowlslegs | gfredricks: thanks very much. I just read up on the #() reader form. |
| 15:28 | gfredericks | zerokarmaleft: I was referring to your "shoehorning myself into java for awhile" |
| 15:28 | gfredericks | fowlslegs: np |
| 15:29 | gfredericks | fowlslegs: equivalent would be (fn [a b] (Math/hypot a b)) |
| 15:30 | ltw | Can Clojure libraries be made interoperable with Java? |
| 15:30 | zerokarmaleft | gfredericks: oh yes, I did some stuff with hadoop in java even though I knew about cascalog |
| 15:31 | konr | haha, so amazing; I managed to get our scala programmer excited about clojure just by showing my test suite :) |
| 15:33 | fowlslegs | gfredericks: So I still don't understand *why.* Should I read up on Java? |
| 15:33 | fowlslegs | gfredericks: So I still don't understand *why.* Should I read up on Java? |
| 15:33 | zerokarmaleft | gfredericks: it was more like revisiting an old language I was already familiar with and applying it to some useful albeit small scope |
| 15:34 | gfredericks | ltw: you're asking about java code calling clojure libs? |
| 15:34 | ltw | gfredericks: yeah, I want to write a library that will be called from Clojure and Java, but I want to write it in Clojure. |
| 15:35 | gfredericks | ltw: yeah you can go one of two ways depending on how easy you want to make it from the java side |
| 15:35 | gfredericks | anything you can do in clojure can be done clunkily from java via the RT class |
| 15:35 | gfredericks | so in that sense any clojure lib trivially qualifies |
| 15:35 | zerokarmaleft | fowlslegs: you can read up on Java a la carte as you run into jvm concepts that are unfamiliar |
| 15:35 | gfredericks | but you can also generate classes with methods, which makes it much cleaner from java |
| 15:36 | ltw | gfredericks: oh, like using gen-class? |
| 15:36 | gfredericks | that certainly works |
| 15:37 | gfredericks | I think I wrote a lib once for exporting a whole namespace as a java class with static methods |
| 15:37 | gfredericks | https://github.com/fredericksgary/lib-2367#export-ns |
| 15:37 | gfredericks | it uses gen-class |
| 15:37 | gfredericks | but is minimal effort |
| 15:37 | ltw | I think I'll go that way if it's reasonably non-trivial. |
| 15:38 | fowlslegs | thanks, will do |
| 15:38 | callen | Raynes: that's what you get for writing Haskell. |
| 15:38 | ToxicFrog | I'm running into something really weird with a recursively defined lazy infinite seq: http://hastebin.com/duforatapi.lisp |
| 15:38 | ltw | gfredericks: I think you've just solved the only problem I saw with the gen-class method approach. |
| 15:38 | ltw | it's a client library wrapping a service, so there was going to be many function definitions |
| 15:38 | gfredericks | my work here is done |
| 15:39 | Raynes | callen: I'm not writing Haskell. Just observing how horrible the support for it in Vim is. I mean, I can use Emacs for it, but Christ. After all these years I would have expected it to at least be able to indent Haskell half-assed. |
| 15:39 | ToxicFrog | I would expect that (0 1 2) are in the seq (because they are < 3), and then 3 and 4 should be also (because by the time it's calling (tasty? 3) it's realized the list head and discovered that is (= 0) |
| 15:40 | ToxicFrog | Instead it seems to be the case that (first tasty) is something other than 0 until it calls (tasty? 32) and then suddenly it is 0. |
| 15:40 | ToxicFrog | Is this a weird interaction with (declare)? Am I not understanding something fundmental about how lazy seqs work? |
| 15:41 | gfredericks | ToxicFrog: this is super weird |
| 15:41 | ToxicFrog | (this is 1.4.0, btw) |
| 15:41 | gfredericks | I get it in 1.5.1 too |
| 15:42 | ToxicFrog | Also I'm glad it's not just me who thinks it's weird |
| 15:42 | gfredericks | ToxicFrog: this has something to do with chunking |
| 15:42 | gfredericks | which you can tell by replacing (range) with (iterate inc 0) |
| 15:43 | ltw | is there an existing convention on how to name Clojure libraries that are interoperable with Java? (I have a Ruby library for this functionality already) |
| 15:43 | gfredericks | but I haven't figured out why that should be relevant though |
| 15:43 | Raynes | Not really, because nobody writes libraries that are interoperable with Java. |
| 15:43 | Raynes | They value their sanity. |
| 15:43 | Raynes | :p |
| 15:43 | stuartsierra | ToxicFrog, gfredericks: You're running into chunked lazy sequences there. |
| 15:44 | stuartsierra | The 32 is a giveaway. |
| 15:44 | gfredericks | stuartsierra: oh definitely |
| 15:44 | gfredericks | stuartsierra: that's what I just said -- it's just not clear why it's relevant |
| 15:44 | gfredericks | as best I can tell, the act of computing a chunk of a chunked lazy seq is calling first on itself |
| 15:45 | gfredericks | which is not throwing an exception but is instead returning something weird |
| 15:45 | ltw | Raynes: ha, I'd rather write it once in Clojure and make it interop than have to write it in Java. |
| 15:46 | ToxicFrog | Adding a (println) says that it's nil until the first 32 elements have been evaluated, then 0 |
| 15:47 | gfredericks | looks like (first my-chunked-seq) is nil during the computation of the first chunk |
| 15:47 | gfredericks | oh you just found out the same thing |
| 15:47 | ToxicFrog | Is there any documentation on chunked sequences? The docs for (range) don't mention that it chunks, nor that this optimization(?) may break things. |
| 15:47 | gfredericks | ToxicFrog: yeah I'd say a self-referential chunked lazy seq is a bad idea :) |
| 15:47 | gfredericks | ToxicFrog: in general a self-referential lazy seq probably shouldn't be necessary I don't think |
| 15:48 | ToxicFrog | gfredericks: necessary, no, but it's a convenient way to write some things |
| 15:48 | ToxicFrog | (I ran into this when making a simple prime generator as practice; when testing to see if the next number is prime it's useful to be able to refer to earlier primes) |
| 15:49 | ToxicFrog | (there are undoubtedly non-toy applications for this technique) |
| 15:49 | jcromartie | there needs to be a Jekyll for Clojure… |
| 15:49 | jcromartie | this is happening |
| 15:49 | gfredericks | jcromartie: somebody was working on that a week or so ago |
| 15:50 | ToxicFrog | gfredericks: in any case it should probably be mentioned in the docs for functions that generate chunked sequences that they do so and are thus not safe for recursion. |
| 15:51 | ToxicFrog | I would not normally expect replacing (range) with (iterate inc 0) to change the results of my code. |
| 15:52 | stuartsierra | Most of the core sequence functions used chunking when possible as an optimization. |
| 15:52 | stuartsierra | s/used/use/ |
| 15:53 | stuartsierra | In general, Clojure's lazy sequences make no guarantees about *when* a particular part of the seq is realized. |
| 15:53 | ToxicFrog | I think the underlying surprise here is that I thought it was guaranteed that (first foo) would be realized before (rest foo) |
| 15:54 | ToxicFrog | When this is not actually the case. |
| 15:54 | futile | So, |
| 15:54 | futile | the other night, I did "lein deploy", typed in my credentials, and it Just Worked™ |
| 15:54 | futile | today i try again, and it gives me a confusing msg |
| 15:54 | ToxicFrog | IT seems likely that this guarantee isn't actually stated anywhere, but it's still super surprising. |
| 15:57 | futile | Ah. I really did "lein deploy clojars" last time. |
| 15:57 | futile | Works like a charm. |
| 15:58 | ToxicFrog | gfredericks, stuartsierra: to make it even more confusing, (chunked-seq? tasty) returns false in both versions |
| 15:59 | ToxicFrog | As does (chunked-seq? (take 5 tasty)) |
| 16:01 | SegFaultAX | ToxicFrog: It just occured to me that I know you from #lua. |
| 16:01 | stuartsierra | chunked-seq? isn't documented, probably an internal function. |
| 16:01 | atyz | Hey all - I'm doing the following (with kormasql) https://www.refheap.com/16907 and getting an error saying I cannot use Can not issue data manipulation statements with executeQuery(). I've done some research and It would require me using executeUpdate() . Is there a way to get around this? |
| 16:02 | futile | ok |
| 16:02 | futile | nevermore 0.0.1 released, its official :) |
| 16:02 | ToxicFrog | SegFaultAX: yep |
| 16:03 | ToxicFrog | stuartsierra: anyways - is there literature on sequence chunking, which functions I should beware of, etc? |
| 16:04 | stuartsierra | ToxicFrog: Not that I'm aware of. Assume any core function which generates a sequence may use chunking. |
| 16:04 | ToxicFrog | :( |
| 16:05 | llasram | ToxicFrog: What's the actual ultimate problem? |
| 16:05 | gfredericks | he wants to use haskell-style laziness-backed self-reference |
| 16:05 | ToxicFrog | ^ that |
| 16:05 | stuartsierra | Then use Haskell. |
| 16:06 | llasram | Oh. You can always explicitly unchunk your sequences |
| 16:06 | ToxicFrog | Sadly my underlying assumption that the n'th value in the seq won't be realized until after the (n-1)th value has been turns out to be false. |
| 16:06 | bbloom | ToxicFrog: decompile the problem into a lazy traversal and a state machine |
| 16:06 | bbloom | s/decompile/decompose |
| 16:06 | ToxicFrog | llasram: how? (and how did you learn about chunking?) |
| 16:07 | bbloom | if you need linear execution, just loop over a sequence and conduct your side effects in the loop |
| 16:07 | ToxicFrog | bbloom: there are no side effects. |
| 16:07 | bbloom | ToxicFrog: evaluation is a side effect |
| 16:07 | ToxicFrog | I'm just trying to compute an infinite lazy sequence where the value of later values in the sequence is an expression of values earlier in the sequence. |
| 16:07 | SegFaultAX | IIRC chunked seqs are implemented in such a way that they should be transparent. |
| 16:08 | ToxicFrog | If evaluation is a noticeable side effect your abstraction is leaking, IMO. |
| 16:08 | bbloom | ToxicFrog: this is why people complain about understanding space complexity in haskell, b/c you can get UNBOUNDED lookahead w/ laziness |
| 16:08 | llasram | ToxicFrog: I read about it in /Joy of Clojure/ very early in my Clojure-programming. /JoC/ has this function: https://www.refheap.com/16909 |
| 16:08 | SegFaultAX | Should being the operative term. They exist only as a performance optimization. |
| 16:08 | ToxicFrog | SegFaultAX: the genesis of this discussion is that they are actually not; I have code that returns different values when using a chunked seq vs. a non-chunked one. |
| 16:08 | bbloom | you can achieve what you want, but you must be explicit about your buffering |
| 16:09 | SegFaultAX | ToxicFrog: Bummer :/ |
| 16:09 | ToxicFrog | bbloom: I would prefer unbounded lookahead (and thus terrible performance, OOMs, etc) to getting the wrong answers quickly. |
| 16:09 | llasram | It still depends on the implementation detail that `lazy-seq` recursion is evaluated one thunk at a time, but in practice it works |
| 16:09 | ToxicFrog | llasram: thank you. |
| 16:10 | bbloom | ToxicFrog: the answer is right, your assumption about the semantics are wrong :-P if you want to achieve haskell-like semantics, you need to implement either A) fully lazy evaluation or B) a particular data structure for your use case |
| 16:10 | bbloom | this is why i'm suggesting: use a state transducer |
| 16:11 | SegFaultAX | Probably option b is easier. |
| 16:11 | llasram | ToxicFrog: Note that the docstring (which I wrote when I stole the function) isn't actually right -- it doesn't de-chunk the input seq, but returns a new seq which isn't chunked. So you wrap your input, not the seq your producing (if that wasn't obvious) |
| 16:11 | SegFaultAX | bbloom: Can you define that term? |
| 16:11 | bbloom | https://github.com/brandonbloom/transduce |
| 16:12 | llasram | oooh |
| 16:12 | ToxicFrog | bbloom: so, the objection I'm arriving at here is that chunking is an optimization that (a) does not seem to be documented outside JoC and (b) when applied can result in actual functional changes even in pure code |
| 16:12 | ToxicFrog | There is no indication which library functions produce chunked sequences, or even that chunked sequences are a thing, and if an optimization is meant to be that completely invisible it had better not change the results of code that triggers it! |
| 16:13 | SegFaultAX | bbloom: Ah, neat. |
| 16:13 | llasram | omg, bbloom, these are great |
| 16:13 | ToxicFrog | Alternately, a warning like "don't try to use self-referential lazy sequences, they will produce garbage due to internal optimizations used by clojure's lazy seq implementation" would be nice,. |
| 16:13 | bbloom | SegFaultAX: llasram: thanks! |
| 16:14 | zerokarmaleft | why is set! restricted against local vars? |
| 16:14 | bbloom | ToxicFrog: i just joined the conversation a tad late, so i need to look at your particular paste & understand the problem |
| 16:14 | llasram | ToxicFrog: The problem is that there really isn't a good way to tell when you're building a self-referential lazy-seq. If there were, I'd agree there should be a warning |
| 16:14 | SegFaultAX | bbloom: That's really useful. I'm sad to only just be learning about this library. |
| 16:14 | ToxicFrog | bbloom: http://hastebin.com/duforatapi.lisp |
| 16:15 | alandipert | zerokarmaleft: i take it you mean lexical bindings? it's because there isn't a mutable reference type (Var) behind them |
| 16:15 | ToxicFrog | bbloom: If you replace (range) with (iterate inc 0) it works. |
| 16:15 | SegFaultAX | ToxicFrog: The whole point of range chunking is that it's more efficient to generate groups of numbers rather than single values. |
| 16:15 | alandipert | zerokarmaleft: it can be achieved via macros though, see https://github.com/ztellman/proteus |
| 16:16 | SegFaultAX | If you're ok with the potential performance hit, though... |
| 16:16 | zerokarmaleft | alandipert: well, a bit more context, I'm simply trying to mutate a DOM element |
| 16:16 | bbloom | ToxicFrog: neither range nor iterate is bugged. your example is using declare to create mutual recursion but you're missing one level of indirection |
| 16:16 | ToxicFrog | SegFaultAX: which is fine. But it's a performance optimization that can change program behaviour and thus should be more visible than it is. |
| 16:16 | zerokarmaleft | e.g. (set! (.-innerHTML el) "foo") |
| 16:16 | ToxicFrog | bbloom: how/where? |
| 16:16 | alandipert | zerokarmaleft: oh, you probably want 'aset' |
| 16:17 | alandipert | (aset el "innerHTML" "foo") |
| 16:18 | ToxicFrog | What should I have done instead to avoid this? What should I have read to know I was meant to do that? |
| 16:18 | zerokarmaleft | alandipert: perfect, thanks |
| 16:18 | zerokarmaleft | odd that set! seemed to compile and run fine intermittently |
| 16:18 | bbloom | ToxicFrog: (first tasty) is going to be a constant |
| 16:19 | bbloom | or should be |
| 16:19 | llasram | ToxicFrog: I don't think there was anything official you could have read. It's come up a few times on the mailing list, but AFAIK is basically tribal knowledge |
| 16:19 | ToxicFrog | bbloom: this is just a minimal test case; in practice (first tasty) might be some more complicated expression involving, say, (take limit tasty) where limit is some function of n. |
| 16:20 | bbloom | ToxicFrog: change (first tasty) to (doto (first tasty) prn) and you'll see what's happening |
| 16:20 | bbloom | you're getting 32 nils |
| 16:20 | ToxicFrog | I already know that |
| 16:20 | bbloom | b/c (first UNDEFINED-VAR) is bad |
| 16:21 | gfredericks | bbloom: he knows what's happening he thinks it should not happen or be better documented |
| 16:21 | bbloom | if you want mutual recursion, you must define things simultaneously |
| 16:21 | bbloom | i dunno what he want's documented |
| 16:21 | gfredericks | "don't use self-referential chunked seqs" |
| 16:21 | gfredericks | and also "chunked seqs exist" |
| 16:21 | ToxicFrog | ...how do I do that? Because last time I looked for "how do I do mutual recursion in clojure" the answer I got was "(define) one of the things first" |
| 16:21 | xpe | in choosing a JDK for Clojure, is there a significant difference between 7 and 8? |
| 16:21 | bbloom | no, it's don't use mutual recursion without a layer of indirection |
| 16:21 | ToxicFrog | bbloom: what gfredericks said. |
| 16:21 | xpe | or runtime? |
| 16:21 | bbloom | it's more than just chunked sequences |
| 16:21 | ToxicFrog | Ok, what layer of indirection? You keep saying I'm missing one and I'm asking what |
| 16:22 | bbloom | you're trying to evaluate tasty? while tasty is being defined |
| 16:22 | bbloom | that's undefined behavior b/c it's mutually recursive |
| 16:22 | bbloom | you need to add a delay or a fn call |
| 16:23 | bbloom | and if you do that, you'll get a stack overflow, which is precisely what your function is trying to do :-P |
| 16:23 | gfredericks | now we need documentation saying "Don't be mutually recursive because it's undefined" |
| 16:23 | gfredericks | bbloom: it works perfectly well w/o chunking |
| 16:23 | bbloom | by luck |
| 16:23 | ToxicFrog | ...well, no, because by the time (tasty?) needs to evaluate part of tasty, the parts of tasty it's referring to are already realized non-recursively |
| 16:23 | bbloom | b/c of some internal order of execution |
| 16:24 | gfredericks | bbloom: if "some internal order of execution" means "evaluating lazy seqs in order one item at a time" then yeah |
| 16:25 | ToxicFrog | The first three values of tasty (0 1 2) are evaluated without any recursion; 3 onwards require evaluation only of (head tasty). It does not seem controversial that "the elements of a lazy seq are realized in order" is a reasonable assumption to make, and that the fact that this assumption is wrong should be documented. |
| 16:25 | gfredericks | for the record I don't think we should write code like this; but I think it's reasonable that he had different expectations and that this will happen to others |
| 16:25 | bbloom | i agree with that gfredericks |
| 16:26 | gfredericks | ToxicFrog: they _are_ realized in order, just some of them in parallel |
| 16:26 | ToxicFrog | Yeah, I would also be ok with the answer to "how do I do mutual recursion in clojure" being "don't", even if that is a really aggravating restriction in some cases |
| 16:26 | ToxicFrog | As long as that was actually documented somewhere. |
| 16:26 | bbloom | gfredericks: parallel == "observably simultaneously" ? |
| 16:26 | gfredericks | bbloom: I think so yes |
| 16:26 | gfredericks | bbloom: certainly I didn't mean wrt threads and such |
| 16:27 | supersym | is it me or do other ppl find defrecord a bit unwieldy as well |
| 16:27 | amalloy | ToxicFrog: that's not really true, though; the thing that's discouraged is self-recursive data structures |
| 16:27 | amalloy | mutually-recursive functions are fine, although because we lack TCO you have to be careful |
| 16:28 | ToxicFrog | gfredericks: that doesn't really count as "in order" to me; "in order" implies that, at the moment the n'th element of the sequence is realized, all prior elements have already been realized. |
| 16:29 | gfredericks | ToxicFrog: okay; definitions I guess |
| 16:30 | ToxicFrog | gfredericks: basically the assumption of mine that was violated was that s[n] will always be realized after realization of s[n-1] is complete (and thus, by implication, that a definition of s[n] that depends on s[m] where m<n is safe). |
| 16:32 | bbloom | ToxicFrog: that assumption is valid, what assumption is invalid is that the evaluation of s[n] and s[n-1] will necessarily occur at alternating locations in the stack frame |
| 16:33 | bbloom | in theory, chunking could maybe recognize and correct this |
| 16:35 | gfredericks | bbloom: but probably wouldn't if it makes it slower |
| 16:36 | bbloom | gfredericks: probably |
| 16:36 | bbloom | all this discuss, incidentally, motivates my total lack of interest in the academic obsession with non-termination |
| 16:37 | bbloom | the fact that evaluation TAKES TIME is a lie that haskell programmers wish would go away :-P |
| 16:37 | bbloom | is IS NOT a lie & that |
| 16:37 | bbloom | i failed to say that in any way that makes sense, but somebody will understand wtf i'm talking about |
| 16:38 | futile | is it a terrible idea to do (alter-meta!) on #'some-var which will be thrown away in a minute anyway? |
| 16:40 | gfredericks | you're throwing away vars? |
| 16:41 | futile | gfredericks: via (remove-ns) |
| 16:41 | futile | ,(clojure.string/join "," [1 2 3]) |
| 16:41 | clojurebot | "1,2,3" |
| 16:42 | futile | ,(do (remove-ns 'clojure.string) (clojure.string/join "," [1 2 3])) |
| 16:42 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string> |
| 16:42 | futile | ,(clojure.string/join "," [1 2 3]) |
| 16:42 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string> |
| 16:42 | futile | oops |
| 16:42 | futile | ,(require 'clojure.string) |
| 16:42 | clojurebot | nil |
| 16:42 | futile | ,(clojure.string/join "," [1 2 3]) |
| 16:42 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string> |
| 16:42 | futile | ,(require :reload 'clojure.string) |
| 16:42 | clojurebot | nil |
| 16:42 | futile | ,(clojure.string/join "," [1 2 3]) |
| 16:42 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string> |
| 16:47 | futile | dont worry ill figure this out |
| 16:51 | futile | ok yeah i give up |
| 16:51 | futile | i broke it. im sorry. |
| 16:52 | llasram | ,(do (require 'clojure.string) (clojure.string/join "," [1 2 3])) |
| 16:52 | clojurebot | "1,2,3" |
| 16:52 | futile | but.. but.. |
| 16:52 | futile | i tried that, didnt i? |
| 16:52 | futile | ,(clojure.string/join "," [1 2 3]) |
| 16:52 | clojurebot | "1,2,3" |
| 16:53 | PuercoPop | Oi, in order to use select from enlive do I have to transform the html string into an specific representaion? |
| 16:54 | squidz | is it possible to create and use source maps now wwith clojurescript? |
| 16:54 | ToxicFrog | bbloom: what? |
| 16:55 | bbloom | ToxicFrog: what about what? |
| 16:55 | ToxicFrog | If, during evaluation of s[n], the value of s[n-1] is nil, it is not the case that s[n-1] has been realized (even if the value has been computed internally and is being buffered somewhere invisible to my code) |
| 16:56 | ToxicFrog | And I'm not sure what you mean by "alternating locations in the stack frame" |
| 16:56 | gfredericks | I also don't know what he meant by that |
| 16:57 | futile | llasram: thanks for fixing it somehow :) |
| 16:58 | llasram | Computers just like me |
| 16:58 | bbloom | it's the difference between (do (realize! s n) (observe! s n) (realize! s m) (observe! s m)) vs (do (realize! s n) (realize! s m) (observe! s n) (observe! s m)) |
| 16:58 | squidz | together with lein cljsbuild i mean |
| 16:59 | bbloom | actually, it's worse than that |
| 16:59 | ToxicFrog | bbloom: except in either case (realize! s m) is called after (realize! s n) completes, and thus (observe! s n) should succeed if (realize! s m) calls it. |
| 17:00 | ToxicFrog | When, in fact, it doesn't. |
| 17:01 | bbloom | let me clarify a few things: 1) i'm not saying clojure is PERFECT here. surely it may be possible to improve this behavior to meet your expectations w/o violating anybody else's 2) i think it's perfectly reasonable for this behavior to be undefined |
| 17:02 | bbloom | now, with that said, the issue is more subtle than what i said, b/c it's really |
| 17:02 | bbloom | …. |
| 17:02 | bbloom | (realize-cps! s n callback) |
| 17:02 | bbloom | or rather k for continuation |
| 17:02 | bbloom | (realize-cps! s n k) |
| 17:02 | bbloom | and when k gets called is important |
| 17:03 | bbloom | i'm saying that it's currently undefined when it gets called, you're saying there is a reasonable definition |
| 17:05 | bbloom | does that explain my comment? |
| 17:06 | ToxicFrog | Not really; I don't know realize-cps!. Documented? |
| 17:06 | bbloom | i just made it up |
| 17:06 | bbloom | that's just realize with a callback |
| 17:06 | bbloom | cps = continuation passing style |
| 17:06 | ToxicFrog | Aah |
| 17:07 | llasram | cps vs csp -- fight! |
| 17:07 | bbloom | llasram: both! |
| 17:08 | llasram | heh |
| 17:08 | bbloom | llasram: that's like saying "space vs time -- fight!" |
| 17:08 | bbloom | :-) |
| 17:09 | bbloom | ToxicFrog: make sense now? |
| 17:10 | bbloom | ToxicFrog: also, i should add… if you can write a patch that doesn't hurt perf, break anything else, and fixes this, you should submit it! |
| 17:10 | ToxicFrog | I don't feel like my brain is entirely here right now, but AIUI you're basically just saying that it is undefined in what order the elements of a lazy seq are evaluated? |
| 17:11 | bbloom | i'm saying it's undefined how sequence realization and sequence observation will be intertwined |
| 17:12 | bbloom | lazy sequences are little stateful machines that consumers take on the responsibility of executing, if unrealized |
| 17:12 | bbloom | there is no rule that says the producer can't execute the machine a little bit before passing it along |
| 17:13 | ToxicFrog | Right. |
| 17:13 | ToxicFrog | Which is exactly what's happening here: it's evaluating the first 32 elements before making the results of any of those evaluations available. |
| 17:14 | bbloom | right, and this issue is only visible b/c you're at the top level |
| 17:14 | bbloom | you would be UNABLE to write the program you write using let, b/c let doesn't allow mutual recursion, so you'd need to use letfn |
| 17:14 | bbloom | or use mutation |
| 17:15 | bbloom | letfn would require you call () to dereference the function name |
| 17:15 | bbloom | which would create infinite recursion |
| 17:15 | bbloom | which is one of two possible outcomes in your (broken) program: infinite recursion, or incorrect termination |
| 17:15 | bbloom | you got incorrect termination |
| 17:15 | ToxicFrog | It seems that this should not create infinite recursion; it will eventually hit the base case (s[n] <= 3) and terminate correctly. |
| 17:16 | bbloom | ToxicFrog: there exists some set of operation semantics for which your program will not create infinite recursion |
| 17:16 | bbloom | :-D |
| 17:16 | bbloom | def's semantics are different than promises, are different than manual use of set! are different from function calls are different from deref calls |
| 17:17 | ToxicFrog | That said, when I get home I'll rewrite this using function calls (and it won't infinitely recur) |
| 17:17 | bbloom | yeah, do that |
| 17:17 | bbloom | def is mutation |
| 17:17 | bbloom | declare, def, def == 3 mutations |
| 17:17 | bbloom | letfn will give you observably simultaneous mutations |
| 17:17 | ToxicFrog | wait wait wait, where's the third def? |
| 17:18 | bbloom | declare, defn, def |
| 17:18 | ToxicFrog | Aah. |
| 17:18 | ToxicFrog | I thought you meant three defs of tasty specifically. |
| 17:18 | bbloom | no |
| 17:18 | bbloom | letfn will make it seem like all those mutations happen simultaneously |
| 17:18 | bbloom | it acheives that by forcing an indirection on all definitions (that indirection is a function call) |
| 17:18 | ToxicFrog | Anyways, the main reason I wanted an infinite seq for this is that then it doesn't need to re-calculate earlier values repeatedly, which it will with fns. |
| 17:19 | ToxicFrog | I guess I could explicitly memoize. |
| 17:19 | bbloom | you want to write a corecursive function :-) |
| 17:19 | bbloom | http://squirrel.pl/blog/2010/07/26/corecursion-in-clojure/ |
| 17:20 | ToxicFrog | I do, and thanks |
| 17:21 | mmarczyk | ToxicFrog: (defn unchunk [xs] (lazy-seq (cons (first xs) (unchunk (rest xs))))) |
| 17:21 | bbloom | my pleasure, explaining that helped me understand it too :-) |
| 17:21 | ToxicFrog | Although based on what just happened it seems like that definition of fib should explode if chunking happens to occur, so either the example is bad or I still don't understand what's going on :( |
| 17:21 | mmarczyk | ToxicFrog: if you wrap (range) in unchunk, result will be as you expect |
| 17:21 | bbloom | that's why i hang out here. teaching is a great way to learn! |
| 17:21 | mmarczyk | not that it answers all the points raised |
| 17:22 | ToxicFrog | Anyways, tests run, CLs out for review, to the bus! |
| 17:22 | bbloom | mmarczyk: you're the rrb guy, right? awesomeness! just studied that a bit yesterday |
| 17:22 | mmarczyk | bbloom: wow, cool :-) |
| 17:23 | bbloom | mmarczyk: just so i understand correctly… this would enable vectors to have efficient push/pop on both sides? |
| 17:23 | mmarczyk | bbloom: right |
| 17:23 | mmarczyk | bbloom: although I should say, regular conj (at end) will still be the "natural", fast, zero-cost option |
| 17:23 | bbloom | mmarczyk: right b/c you pay some extra cost on the left, but only if you use left push/pop, right? |
| 17:24 | mmarczyk | bbloom: whereas conj to front has a certain cost attached in that you'll end up with a less regular tree |
| 17:24 | mmarczyk | bbloom: right |
| 17:24 | bbloom | so i read the abstract, but didn't really dig into the paper |
| 17:24 | bbloom | basically reading/writing to the left (or middle, or splitting, whatever) will somehow manage to preserve amortized costs? |
| 17:24 | mmarczyk | bbloom: one of the things I've got on the roadmap is making it so the "new" ops |
| 17:24 | bbloom | ie i can't like perma-fuck-up my vectors? |
| 17:24 | mmarczyk | bbloom: do a little bit of extra work to try and return regular trees whenever possible |
| 17:25 | noncom|2 | hi, i am writing a thin wrapper for a java lib and i find myself thin-wrapping lots of getters and setters. Id it okay that all setters names are with exclamation marks? An how do you usually go about naming getters? |
| 17:25 | mmarczyk | bbloom: basically there's a limit to how much "damage" there can be, yes |
| 17:25 | bbloom | mmarczyk: and even with that damage, the constant factors should beat 2-3 finger trees? |
| 17:26 | mmarczyk | bbloom: oh absolutely |
| 17:26 | bbloom | killer. |
| 17:26 | mmarczyk | bbloom: shouldn't be slower by more than a factor of 2 |
| 17:26 | mmarczyk | bbloom: paper indicates less |
| 17:27 | mmarczyk | bbloom: actually there's a tradeoff here between concat speed and loss of lookup (etc.) speed |
| 17:27 | bbloom | mmarczyk: https://github.com/brandonbloom/fipp/issues/6 |
| 17:27 | mmarczyk | bbloom: a regular vector is a tree whose shape is completely determined by the lookup algorithm, with the minor tweak of having a separate tail |
| 17:28 | mmarczyk | bbloom: wow, great! thanks for the link |
| 17:28 | bbloom | mmarczyk: i only need left/right push/pop |
| 17:28 | mmarczyk | bbloom: I've been chatting with Jozef Wagner lately |
| 17:28 | bbloom | mmarczyk: don't need to thank me. thank you for creating cool stuff |
| 17:29 | lpetit | Hello, any adventurous Counterclockwise user, willing to give feedback on a new feature I've been developing recently? |
| 17:30 | bbloom | mmarczyk: i don't know Jozef Wagner |
| 17:30 | mmarczyk | bbloom: heh, I'm rather a fun of fipp and sort of wanted to write factjor myself, so glad to be reciprocally useful :-) |
| 17:30 | mmarczyk | bbloom: he's been benchmarking cljs recently |
| 17:30 | bbloom | mmarczyk: oh cool |
| 17:30 | mmarczyk | bbloom: there's a thread on the mailing list |
| 17:31 | mmarczyk | bbloom: also, there's a ticket of his in cljs jira re: arrayvectors |
| 17:31 | bbloom | mmarczyk: fipp and factjor are both part of my master plan… mwahaha |
| 17:31 | mmarczyk | bbloom: so he's done some benchmarking with 2-3 finger trees |
| 17:31 | mmarczyk | bbloom: I imagine they would be :-) |
| 17:31 | mmarczyk | bbloom: and apparently there's no contest |
| 17:32 | mmarczyk | bbloom: in fact, funny thing, core.rrb-vector is faster for conj than PV in cljs (so I'll be fixing PV in near future :-P) |
| 17:32 | bbloom | mmarczyk: killer. |
| 17:32 | mmarczyk | bbloom: that's without any unbalanced trees, but the cost in that should be a small constant factor |
| 17:32 | bbloom | mmarczyk: if jonase doesn't take a try for rrb in fipp, i'll do it |
| 17:32 | mmarczyk | bbloom: fantastic! also very happy to cooperate on this |
| 17:33 | lpetit | mmarczyk: do you envision a point in time where rrb could replace PV in clojure proper? |
| 17:33 | bbloom | mmarczyk: after that, i need to port to cljs and explore reducers vs core.async on cljs side b/c i've got a core.async branch that makes fipp multithreaded :-) |
| 17:33 | mmarczyk | bbloom: I've noticed the c.async branch, very cool :-) |
| 17:33 | bbloom | but the ioc threads variant on jvm is much slower than the reducers variant |
| 17:33 | mmarczyk | lpetit: that's possible, but actually getting comparable perf in pure Clojure is a bit of a research project ATM |
| 17:34 | mmarczyk | lpetit: part of the purpose of core.rrb-vector is to do that research, I think |
| 17:34 | lpetit | mmarczyk: okay. What's the gross constant difference for usual usages? |
| 17:34 | bbloom | mmarczyk: you mean compared to the java implementation of PV, right? |
| 17:34 | mmarczyk | bbloom: right |
| 17:34 | bbloom | mmarczyk: so gvec is slower than APersistentVector |
| 17:34 | mmarczyk | bbloom: it is |
| 17:35 | mmarczyk | bbloom: lpetit: by about a factor of 2 IIRC |
| 17:35 | bbloom | mmarczyk: but if you can get gvec == APV, then you can get RBB == APV ? |
| 17:35 | mmarczyk | bbloom: lpetit: core.rrb-vector is on a par with gvec, with an important caveat |
| 17:35 | lpetit | mmarczyk: I must confess I don't know much about gvec |
| 17:35 | mmarczyk | bbloom: lpetit: the caveat is that that's only true as long as you only use rrb vectors of objects or rrb vectors of primitives, not mixed |
| 17:36 | mmarczyk | bbloom: lpetit: I'm going to fix this one way or another... my understanding of what's going on is a bit of a conjecture at this point anyway |
| 17:36 | bbloom | and on cljs, there is no host-native-impl, only the cljs-impl, so rrb can definitely == pv, right? |
| 17:36 | mmarczyk | bbloom: lpetit: (but I'll take this opportunity to point out that jvm rrb vectors already support both objects and primitives at leaves and interoperate happily with both PV and gvec ;-)) |
| 17:36 | mmarczyk | bbloom: right |
| 17:36 | bbloom | glorious |
| 17:36 | bbloom | mmarczyk: great work man |
| 17:36 | mmarczyk | bbloom: or at least with a very small extra overhead |
| 17:36 | bbloom | looking forward to developments. i'll let you know if/when i switch fipp over |
| 17:37 | mmarczyk | bbloom: well the idea and feasibility research is due to Bagwell & Rompf |
| 17:37 | mmarczyk | bbloom: I totally think they've done a great job :-) |
| 17:37 | bbloom | of course. can't forget to thank the smarty pants dudes who write the papers |
| 17:37 | mmarczyk | :-) |
| 17:37 | bbloom | i'm always glad to see citations in readmes |
| 17:37 | bbloom | i try to make it a habit |
| 17:38 | lpetit | mmarczyk: impressive |
| 17:39 | mmarczyk | bbloom: lpetit: it's important to note that in contrast to regular vectors, rrb trees' tree shape is not fully determined |
| 17:39 | mmarczyk | bbloom: lpetit: so there's room for tweaking concat speed vs. lookup & Co. speed |
| 17:39 | bbloom | mmarczyk: which is also in contrast to 2-3 trees, too... |
| 17:39 | mmarczyk | bbloom: right |
| 17:40 | mmarczyk | bbloom: lpetit: my plan is to do some extra work in slice/concat to preserve regular tree shape whenever possible (or very nearly so) |
| 17:40 | bbloom | if i only need left/right push/pop, can i do better than arbitrary splicing? |
| 17:40 | mmarczyk | bbloom: ah, so that's something which I'm planning to work on in near future |
| 17:40 | lpetit | mmarczyk, bbloom : you guys seem to know your stuff, I'm a bit lost. Anyway, that's what I like about this community, so much more to learn! |
| 17:40 | bbloom | lpetit: i didn't know SHIT about this < 1 year ago |
| 17:41 | mmarczyk | bbloom: direct impls of "prepend", "insert-at", "remove slice" |
| 17:41 | bbloom | lpetit: http://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki |
| 17:41 | mmarczyk | bbloom: I'm totally in the market for good names for these functions, by the way |
| 17:41 | bbloom | start with Okasaki, then go to that thread :-) |
| 17:41 | callen | lpetit: yeah, Okasaki is the place to start. |
| 17:41 | mmarczyk | bbloom: hah! that's my favourite stack exchange thread ever :-) |
| 17:41 | callen | lpetit: you can derive the essentials yourself if you try to figure out how to make efficient immutable data structures without tons of copying. |
| 17:41 | arrdem | bbloom: that's an awesome thread |
| 17:41 | lpetit | bbloom: I had started once, but not knowing Standard ML was really slowing me down |
| 17:41 | bbloom | mmarczyk: i often write conjX functions for fnil things, like (def conjs (fnil conj #{})) |
| 17:42 | bbloom | mmarczyk: but left/right/push/pop would be nice to have very clearly |
| 17:42 | mmarczyk | lpetit: "I'm lost", says the a guy who built complex systems in assembly :-) |
| 17:42 | bbloom | haha |
| 17:42 | bbloom | mmarczyk: may i suggest left/right, prepend, and append? |
| 17:42 | mmarczyk | bbloom: yeah, I'd sort of like to have standardized names for these |
| 17:43 | bbloom | right == fast last |
| 17:43 | mmarczyk | bbloom: left/right access, prepend/append insertion? |
| 17:43 | bbloom | i guess left == first |
| 17:43 | bbloom | yeah |
| 17:43 | bbloom | but left/right as the protocol makes some sense |
| 17:43 | noncom|2 | in clojure how do i know if a mapping is a (def) or (defn) ?? |
| 17:43 | lazybot | noncom|2: What are you, crazy? Of course not! |
| 17:43 | mmarczyk | bbloom: yeah, sounds reasonable |
| 17:43 | mmarczyk | bbloom: still good to brainstorm a bit |
| 17:44 | mmarczyk | bbloom: also, I'd sort of like a standardized set of names |
| 17:44 | noonian | noncom|2: defn is just sugar for def |
| 17:44 | bbloom | well i guess there are THREE things you need |
| 17:44 | mmarczyk | bbloom: for example there's a cool confluently persistent deque |
| 17:44 | bbloom | peek/pop/push |
| 17:44 | bbloom | peek/pop/push-left/right |
| 17:44 | bbloom | blargh. |
| 17:44 | mmarczyk | bbloom: I think concat there is actually constant-time |
| 17:44 | bbloom | haha |
| 17:44 | mmarczyk | :-) |
| 17:44 | noonian | noncom|2: (defn my-fun [] ...) == (def my-fun (fn [] ...)) |
| 17:44 | bbloom | ill brb in a bit |
| 17:44 | noncom|2 | noonian: yes, but maybe there is some simple way... like what is it bound to? like (instance? clojure.lang.IFn)...? |
| 17:45 | mmarczyk | ok, see you around |
| 17:45 | mmarczyk | amalloy: do I understand correctly that you like recur-to? :-) |
| 17:45 | bbloom | +1 recur-to |
| 17:45 | noonian | noncom|2: yeah, you could probably do (fn? my-fn) to test if its a function |
| 17:45 | bbloom | ok going.. really..! |
| 17:45 | noonian | ,(doc fn?) |
| 17:45 | clojurebot | "([x]); Returns true if x implements Fn, i.e. is an object created via fn." |
| 17:46 | justin_smith | ,(doc ifn?) |
| 17:46 | clojurebot | "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn" |
| 17:46 | noonian | justin_smith: nice, I didn't know about that |
| 17:46 | noncom|2 | noonian: gonna try it now.. |
| 17:46 | noncom|2 | ifn seems wider than fn |
| 17:47 | justin_smith | yes, I use it to see if something can have an arg applied to it, basically |
| 17:47 | noncom|2 | yeah |
| 17:47 | noncom|2 | well, fn works for my case |
| 17:47 | ToxicFrog | noncom|2: yeah, IFn is basically "can be called like a function", which includes many things which are not actually functions. |
| 17:48 | noncom|2 | i think this is very beautiful that we have both fn? and ifn? |
| 17:48 | noncom|2 | and why we have them |
| 17:48 | lpetit | bbloom: ok, I need one or two sabbatical years, just to read&digest okasaki + the marvelous stack exchange link with tons of undecipherable names :-) |
| 17:50 | mmarczyk | lpetit: bbloom: I'll add that IIRC slowdown with mixed object/primitive rrb vectors in single jvm image is ~3x compared to PV, ~1.5x compared to gvec; perhaps actually a bit less; that's with regular trees though, before concats |
| 17:51 | mmarczyk | but this should be fixable |
| 17:52 | noncom|2 | in clojure, is there a function to execute a function? |
| 17:52 | mmarczyk | if need be, I'll make it so different node types use different containing vector types -- actually I'll probably want to do the things required to make this less of a hassle for unrelated reasons |
| 17:52 | noncom|2 | so that i can do like (-> f EXEC) |
| 17:52 | noncom|2 | where f is fn |
| 17:53 | noncom|2 | i mean defined with fn |
| 17:53 | mmarczyk | noncom|2: functions are callable, so you can say (.call f) |
| 17:53 | mmarczyk | noncom|2: there's also apply, but that requires a seq of args |
| 17:53 | mmarczyk | noncom|2: no "call" function, but you can write one: (defn call [f] (f)) |
| 17:53 | noncom|2 | so (-> f .call) does it! |
| 17:53 | noncom|2 | i just checked |
| 17:54 | noonian | also (apply f []) |
| 17:54 | noncom|2 | yeah, cool! |
| 17:54 | mmarczyk | you can also say (f) ;-) |
| 17:54 | noonian | lol |
| 17:54 | lpetit | First version of Counterclockwise with "fix indentation as you type" feature is available in the "auto shift" branch |
| 17:54 | lpetit | Update Site : http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/ |
| 17:54 | noncom|2 | yeah, but my point was that i cant say (-> f ()) |
| 17:54 | lpetit | Standalone apps: http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/products/ |
| 17:55 | noncom|2 | although i remember i was in wonder a few times in the past when realized that all i need is (f) without complications :D |
| 17:55 | mmarczyk | lpetit: awesome! |
| 17:55 | lpetit | mmarczyk: still very alpha. Feedback required ! |
| 17:56 | mmarczyk | lpetit: pulling ahead of Emacs in Clojure support feels vaguely indecent ;-) |
| 17:56 | lpetit | (the standalone version can be downloaded and discarded easily ;-) ) |
| 17:56 | noonian | mmarczyk: what is? |
| 17:56 | noncom|2 | lpetit: hi! is the option to enable full-blown leiningen available in the new builds? |
| 17:57 | lpetit | noncom|2: no, I have split it into a branch, it was too unstable, and I needed more hammock time |
| 17:57 | noncom|2 | okay! i'll be waiting :) |
| 17:57 | mmarczyk | noonian: ? |
| 17:58 | noonian | mmarczyk: what is ahead of emacs for clojure support? |
| 17:58 | mmarczyk | noonian: lpetit's Counterclockwise pulling ahead in this particular area |
| 17:59 | noonian | mmarczyk: ah, cool thanks |
| 18:01 | lpetit | The first person to download and find a bug in the "fix indentation as you type" feature will get …. many thanks from me! ;-) |
| 18:02 | lpetit | Standalone version installs in a blink: http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/products/ |
| 18:04 | lpetit | mmarczyk: note, it's not just calling "reindent" on each line. It's shifting all children lines of the form being pushed to the right or the left while typing, plus all its right sibling forms, plus all the right sibling forms of the parent form if the parent form's tail has been shifted along the way, etc. until reaching a line which is not shifted |
| 18:05 | lpetit | mmarczyk: so this preserves, as much as possible, manual indentation such as in 'cond |
| 18:07 | lpetit | Next on the todo list: extend this behavior after paredit commands (so that e.g. "raise over" really works as expected), and also between copy/cut/pastes inside Eclipse (requires serializing the current "column" and not just the selected text) |
| 18:08 | lpetit | mmarczyk: I *think* this is doable in emacs, I've seen some options to do that. But Counterclockwise's advantage is that it works with a real parse-tree: multiline strings are handled correctly, for instance |
| 18:09 | bbloom | lpetit: everybody should take a 1 to 2 year sabbatical every 10 to 15 years :-) at minimum! it's good for you |
| 18:09 | lpetit | bbloom: sure! Let's save some money then …. ;-) |
| 18:09 | bbloom | worked for me :-) |
| 18:10 | zerokarmaleft | does core.async have anything like golang's panic? |
| 18:11 | bbloom | zerokarmaleft: both JVM and JS have exceptions |
| 18:11 | bbloom | zerokarmaleft: is there something particularly interesting about panic you're looking for? |
| 18:11 | zerokarmaleft | rather, does it facilitate looking at the state of the goroutines/blocks |
| 18:12 | bbloom | i believe the state is currently opaque, short of implementation details |
| 18:12 | bbloom | tbaldridge is the man to summon :-) |
| 18:12 | zerokarmaleft | i.e. it's blocked waiting for a put! on such and such channel |
| 18:14 | bbloom | in general, you don't want to be able to query the state of channels or the little channel reading/writing machines |
| 18:14 | bbloom | doing so can lead to race conditions |
| 18:14 | bbloom | now, if i want it for debugging purposes, that's a different story |
| 18:14 | zerokarmaleft | that's precisely where I was heading mentally |
| 18:15 | zerokarmaleft | e.g. in a long-running app, how can I know whether or not I have a bunch of go blocks spinning b/c I forgot to clean them up properly |
| 18:15 | bbloom | i'd like to see some sort of tracing/logging functionality, but i don't think it makes sense to expose much else for prying into the internals |
| 18:16 | zerokarmaleft | and to debug deadlocks |
| 18:16 | bbloom | maybe some aggregate values, like metrics |
| 18:16 | bbloom | http://blog.golang.org/race-detector |
| 18:16 | zerokarmaleft | yea, something like that would be nice :D |
| 18:16 | bbloom | the core.async announcement post expressed some interest in that sort of thing |
| 18:26 | dfarmer | Hey all, I've got kind of silly practical question. Is there any way to turn off ANSI color in nrepl? I run 'lein repl' in an admittedly clunky term and every output line is preceded by "[14G[8G[15G, etc" |
| 18:31 | lpetit | Do you know a good resource to learn enough Standard ML to be able to read & understand the code examples in Okasaki? |
| 18:32 | lpetit | and/or to be able to quickly mount a dev environment to really "run" the examples? (emacs not an option : one "hill" at a time ;-)) |
| 18:33 | yogert | Hey, are there any Vim users here that could offer a beginner some help in getting situated with Clojure? : ) |
| 18:33 | yogert | I've been finding a lot of conflicting instructions on the web regarding how to bet integrate the repls and such |
| 18:34 | yogert | best integrate |
| 18:35 | yogert | no Vim users eh? |
| 18:35 | futile | used to be one |
| 18:35 | futile | but i got tired of having to hit so many keys just to move up a line |
| 18:36 | yogert | Heh, well im not looking to argue about the merits of your favorite editor, I'm just looking to try out clojure |
| 18:36 | futile | ah, misunderstood |
| 18:37 | futile | guys, how would you benchmark two different types of databases without writing your whole application in both? |
| 18:37 | brehaut | yogert: im not a vim user, but i understand that integration is a bit in flux there |
| 18:37 | brehaut | yogert: if you are just learning clojure, start with a lein repl and text editor seperately, rather than getting lost in an integration quagmire |
| 18:38 | futile | or just clojurebot |
| 18:38 | brehaut | ಠ_ಠ |
| 18:38 | futile | ,(dotimes 3 [i] (println i)) |
| 18:38 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: dotimes requires a vector for its binding in sandbox:> |
| 18:38 | futile | oh |
| 18:38 | brehaut | how about a web based repl or private messaging the bot |
| 18:39 | futile | but then how can we show him cool ways of doing the same thing? |
| 18:39 | yogert | ok, I've never used a lisp before, but I've been told that integration with repls etc is a very attractive feature |
| 18:39 | brehaut | yogert: certainy is nice |
| 18:39 | yogert | not crucial tho? |
| 18:39 | futile | ,(reduce + [1 2 3]) |
| 18:39 | clojurebot | 6 |
| 18:39 | brehaut | not when you are starting out |
| 18:40 | futile | yogert: in terms of running programs, you can use clojure just like you use ruby |
| 18:40 | brehaut | it makes you a lot more productive when you are already productive, but its just a side show to start with |
| 18:40 | futile | or whatever |
| 18:40 | yogert | ok |
| 18:41 | futile | ,(reduce + (take 3 (repeat 5))) |
| 18:41 | clojurebot | 15 |
| 18:41 | brehaut | yogert: if you use a lein repl, you can easily (require 'my.namespace :reload) to relaod your code |
| 18:41 | futile | thats a shortcut for (* 3 5) |
| 18:41 | brehaut | :reload-all will also reload the dependancies too |
| 18:41 | futile | yogert: yeah just `lein repl` is fun too |
| 18:42 | futile | ,(reduce + (take 3 (iterate 99 dec))) |
| 18:42 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 18:42 | futile | oops |
| 18:42 | futile | ,(reduce - (take 3 (iterate dec 99))) |
| 18:42 | clojurebot | -96 |
| 18:42 | futile | so confusing. |
| 18:42 | yogert | okay. I should watch some videos or something demonstrating the repl integration. I honestly don't have a clue what it is exactly, just that it is great. Is the repl itself any different than GHCI or Python's? |
| 18:42 | futile | yogert: same as python's |
| 18:43 | futile | yogert: install leiningen (via homebrew or whatever) and type `lein repl` and then type (+ 1 2) in it |
| 18:43 | brehaut | Not via homebrew |
| 18:43 | yogert | just that its in your editor... |
| 18:43 | futile | brehaut: why not? |
| 18:43 | yogert | not via homebrew? |
| 18:43 | yogert | i already did |
| 18:43 | yogert | … |
| 18:43 | futile | yogert: i did too, no harm in it |
| 18:43 | yogert | osx package management sucks |
| 18:43 | brehaut | ideally you just grab the version from the lein website |
| 18:44 | futile | brehaut: thats what they all say. |
| 18:44 | brehaut | you dont need to package manage lein because it doesnt install globally |
| 18:44 | futile | (inc homebrew) |
| 18:44 | lazybot | ⇒ 1 |
| 18:44 | brehaut | lein manages its own updates |
| 18:44 | futile | brehaut: homebrew isnt about globally or not. |
| 18:44 | futile | brehaut: homebrew is about me not having to type boring crap in the terminal :) |
| 18:44 | justin_smith | homebrew stinks |
| 18:44 | futile | literally just `brew install leiningen` and im done. |
| 18:44 | futile | (or is it lein?) |
| 18:44 | futile | justin_smith: whats with the homebrew hate today? |
| 18:45 | brehaut | futile: stop talking out your arse; lein is simple to install without a package manager |
| 18:45 | futile | brehaut: yeah it is simple. you're right about that. |
| 18:45 | futile | but its even simpler with homebrew. |
| 18:45 | justin_smith | it is literally one file, homebrew makes it MORE complicated |
| 18:45 | justin_smith | as usual for homebrew |
| 18:45 | futile | justin_smith: it may complicate HOW its done, but not WHAT i do to install it |
| 18:46 | brehaut | futile: ease vs simplicity |
| 18:46 | futile | brehaut: yep |
| 18:46 | brehaut | artificial ease now that sacrificies simplicity is asking for problems later |
| 18:46 | futile | and in this case i like easy better. |
| 18:46 | justin_smith | compare: create ~/bin/lein vs. install homebrew and brew install $(lein || leiningen whichever works) |
| 18:47 | futile | justin_smith: `brew install leiningen` and im done. to create ~/bin/lein i need to open Chrome and go find the dang file |
| 18:47 | futile | then i need to download it. how? curl, wget, or just use my browser? |
| 18:47 | futile | then i have to move it. |
| 18:47 | justin_smith | and then deal with brew when you want to update lein (vs. just letting lein autoupdate) |
| 18:47 | futile | man, just `brew install leiningen` |
| 18:47 | futile | justin_smith: not true. itll update all the same |
| 18:48 | justin_smith | nope, it fucked up my coworker's install, in the middle of a workshop he was trying to run |
| 18:48 | futile | justin_smith: all `brew install leiningen` does is downloads the same trampoline file that you would normally download manually, and puts it somewhere on your path for you |
| 18:48 | justin_smith | brew is a mess, and you don't need it for something as simple as lein |
| 18:48 | futile | oh come on, you dont have to go making everyone leave irc just cuz you disagree with me |
| 18:49 | futile | ;) |
| 18:49 | noonian | homebrew may be a mess, but not using it on a mac is even messier in my experience |
| 18:49 | futile | (inc noonian) |
| 18:49 | lazybot | ⇒ 1 |
| 18:50 | justin_smith | noonian: my solution was to stop using my mac, and getting a system76 box |
| 18:50 | bbloom | justin_smith: all package managers are a mess, but brew is 100X more pleasant than any other mac package manager i have ever encountered |
| 18:50 | bbloom | it's perfect for "eh, i just want to try it real quick" |
| 18:50 | futile | (inc bbloom) |
| 18:50 | lazybot | ⇒ 10 |
| 18:50 | noonian | justin_smith: I'd just get a thinkpad but I need a mac for iOS stuff |
| 18:50 | futile | glad im not the only one who's perfectly ok with homebrew |
| 18:51 | justin_smith | noonian: I have a mac sitting on my desk, work gave it to me, I open the lid about once a week |
| 18:51 | futile | ok looks like i cant upgrade leiningen via homebrew. |
| 18:51 | futile | that does suck. |
| 18:51 | bbloom | all the other package managers should take a lesson from homebrew on how to run a project tho |
| 18:51 | bbloom | holy hell those guys rock |
| 18:51 | bbloom | `brew edit foo` is trivial & pleasant |
| 18:51 | justin_smith | and a big part of that reason is there is no non-shit package manager under macos |
| 18:51 | bbloom | and they homebrew ppl are extremely responsive to tickets |
| 18:51 | bbloom | `brew doctor` works magic |
| 18:51 | bbloom | it's a damn well run project |
| 18:52 | bbloom | they have all kinda of auto-build, CI github bot voodoo too |
| 18:52 | technomancy | homebrew's quality control leaves a lot to be desired |
| 18:52 | justin_smith | my biggest problem with brew is /usr/local is MINE and no system tool should fucking touch it, ever |
| 18:52 | justin_smith | pisses me off |
| 18:52 | clojurebot | Gabh mo leithscéal? |
| 18:52 | callen | technomancy: they don't have any |
| 18:52 | futile | justin_smith: ah, you're a linux user. |
| 18:52 | futile | im not. |
| 18:52 | callen | they just axe bad formulae occasionally, that's it. |
| 18:52 | technomancy | that said, using a computer without a package manager is madness |
| 18:52 | futile | i mean in spirit of course |
| 18:53 | callen | futile: Macs have a /usr/local too. |
| 18:53 | callen | futile: which is what homebrew runs on. Macintoshes. |
| 18:53 | futile | callen: thanks for the reminder |
| 18:53 | justin_smith | futile: switched back to linux, mainly because I missed package management |
| 18:53 | justin_smith | I have an unused osx machine sitting right here |
| 18:53 | technomancy | clojurebot: macports? |
| 18:53 | clojurebot | macports is not a package manager, it's a satire about package management. |
| 18:53 | arrdem | technomancy: TIL windows is sparta. |
| 18:53 | bbloom | lol. |
| 18:53 | technomancy | clojurebot: botsnack |
| 18:53 | callen | technomancy: aye. |
| 18:53 | clojurebot | Thanks! Can I have chocolate next time |
| 18:54 | futile | its probably not perfectly accurate, but people who get upset with mac stuff often closely resemble http://imgs.xkcd.com/comics/command_line_fu.png |
| 18:55 | brehaut | just what we need; more broad sweeping insults based on operating system choice. high five ◔_◔ |
| 18:55 | bbloom | not to start an OS war, but i've never seen anyone succeed w/ linux+projector on the first try before |
| 18:56 | bbloom | software sucks. |
| 18:56 | bbloom | next topic! |
| 18:56 | brehaut | bbloom: operating systems are about as shit as text editors and command shells |
| 18:56 | arrdem | bbloom: .. this is a software channel |
| 18:56 | futile | yeah, i basically hate all software. |
| 18:56 | arrdem | bbloom: and yes I have succeeded with a projector on the first shot before |
| 18:56 | futile | but when i can repress it for a period, i dont mind most of it. |
| 18:56 | isaacbw | woo, koans complete |
| 18:57 | isaacbw | I don't feel enlightened, lol |
| 18:57 | bbloom | futile: knowing when and for how long to hold your nose is a key skill for programmers |
| 18:57 | futile | my colleague switched to linux for a year or so, and literally switched back to mac because of a projector problem during a talk at a user group or conference, i forget which. |
| 18:57 | futile | bbloom: +1 |
| 18:57 | jkj | just know your xrandr :P |
| 18:58 | arrdem | (inc jkj) |
| 18:58 | lazybot | ⇒ 1 |
| 18:58 | isaacbw | ubuntu could probably use a projector plug n play |
| 18:58 | arrdem | isaacbw: you would think that, wouldn't you. |
| 18:59 | arrdem | isaacbw: as with most things ubuntu it works 85% of the time right off, but when it doesn't you're in deep |
| 18:59 | technomancy | seriously though, the whole editing x.org config files stereotype is so 2007 |
| 18:59 | isaacbw | I'm not an ubuntu user, but as far as linux goes it's the closest to a "just works" experience |
| 19:00 | arrdem | isaacbw: understood and agreed, I'm just making the point that there really is no such thing as "just works" |
| 19:00 | arrdem | as far as the linux world goes at least. |
| 19:01 | noonian | I would prefer to use linux, but it always takes me a week at least to get a proper setup when I want to get a linux box working and configured to be productive with |
| 19:01 | technomancy | "just works" just comes down to "spend a bit of time researching before you buy" |
| 19:02 | brehaut | technomancy: yeah; i researched and came back with a mac and virtual box ;) |
| 19:04 | arrdem | hum.. anyone have a better DSL design than this? the general case of an ASM op is ["ADD" "EAX" "EDX"] or some such, but this gets funky when you want to use inline constants or chase pointers because you wind up with modifiers on the operands. |
| 19:04 | arrdem | The current fix is that modifiers are macros, so you pre-expand the operand into its encoding |
| 19:04 | callen | as an XMonad user, things like projectors emphatically DO NOT just work. |
| 19:05 | technomancy | callen: I don't think xmonad has anything to do with that |
| 19:05 | jkj | my solution before mac was Arch Linux. just the eeepc i was running it on was quite horrid. never got used to the keyboard and it had just 1GB of mem. |
| 19:05 | technomancy | it's just a matter of knowing which brands of video card to avoid |
| 19:06 | jkj | and do think xmonad doesn't get on your way with projectors as long as you are willing to xrandr yourself |
| 19:06 | arrdem | but that means you loose data about your instruction sequence at read time, making any subsequent (prints) or other inspection less meaningfull/symbolic |
| 19:06 | technomancy | jkj: that hasn't been my experience; on debian and ubuntu you just plug it in and it rearranges everything |
| 19:07 | technomancy | it's probably more complicated on arch; archies love to make things complicated |
| 19:07 | arrdem | technomancy: ah but at least our complicated has good wiki manuals and flat text file configs! |
| 19:07 | jkj | appreciating my mac now |
| 19:08 | jkj | but i actually liked arch. it was easy in the form of not having intrusive automation that just tries to work but ends up doing something stupid |
| 19:09 | noonian | thats how I felt after trying to get my Arch UI setup to work on Ubuntu |
| 19:10 | justin_smith | regarding linux and "just works", best to compare apples to apples (so to speak) - get a linux box, built to run linux with a distro pre-configured by the manufacturer |
| 19:11 | justin_smith | I mean imagine judging macos based on hackintosh |
| 19:11 | seangrove | nrepl really does seem nice |
| 19:12 | seangrove | I was skeptical it would be better than swank/slime, but having multiple repls, one evaling in clojure, the other in the browser, and having them communicate and seamlessly update defs... very nice |
| 19:12 | Raynes | And being able to make use of it from vim with reasonable ease is useful as well |
| 19:13 | te | it has continued to get better |
| 19:13 | seangrove | Raynes: good point |
| 19:13 | te | i was skeptical too and dragged my feet for awhile |
| 19:13 | brehaut | seangrove: isnt the canonical spec for swank 'whatever the head of cvs currently does'? its not too surprising that nrepl is better than that ;) |
| 19:13 | technomancy | it's still missing a bunch of stuff; hopefully now that nrepl.el is maintained we can move forward with new features via nrepl-discover |
| 19:14 | technomancy | (inspector, tracing, etc) |
| 19:14 | jkj | arrdem: have you tried just having ops be funs/macros themselves? |
| 19:14 | jkj | (asm/add :eax [:edx]) |
| 19:14 | jkj | arrdem: which cpu or generic? |
| 19:17 | callen | technomancy: I can't even get YourKit or jvisualvm to work in Xmonad. |
| 19:18 | callen | technomancy: attaching an external display upsets Xmonad sometimes, it's usually otherwise multi-display friendly. |
| 19:18 | futile | xmonad was the one thing i liked about linux |
| 19:18 | futile | so i wrote a kind-of port for mac |
| 19:18 | futile | i mean, i tried to hit the right balance between what xmonad is and what mac allows |
| 19:19 | futile | anyone want a binary of it? im handing them out for free. |
| 19:19 | jkj | futile: sure! |
| 19:19 | futile | hold on, let me strip out the licensing code |
| 19:24 | futile | sweet, it still builds |
| 19:25 | pcarrier | is there a pmap with custom parallelization factor? |
| 19:28 | futile | jkj: ok https://www.dropbox.com/s/8dzp2irtn8ssuvy/AppGrid.zip |
| 19:28 | futile | jkj: if it doesnt load, let me know. code signing certificate crap sometimes pretends to work for me but not for others. |
| 19:30 | Derander | for anyone who remembers the moron trying to shuffle vast quantities of shit through clojure yesterday: it seems like java actually is fast enough for it |
| 19:30 | Derander | decided to implement in java in the name of stack homogeneity and it's shuffling along pretty close to as fast as gnu awk |
| 19:30 | Derander | (aka roughly 50x as fast as clojure) |
| 19:30 | Derander | this implies (to me) that I was probably doing something wrong. |
| 19:31 | jkj | futile: fuking splendid! |
| 19:31 | futile | jkj: thx |
| 19:31 | futile | jkj: i have a custom build that lets me attach random keyboard shortcuts to shell commands and stuff, but it needs polishing up. interested? |
| 19:31 | futile | btw, if anyone else wants to use this app, let me know and ill give you a link |
| 19:32 | jkj | futile: yes, very |
| 19:32 | futile | i think its jkj-approved |
| 19:32 | futile | jkj: actually do you just want the fully scriptable one? |
| 19:32 | futile | its scriptable via JS (or coffeescript) |
| 19:33 | futile | i hate it cuz im getting tired of scripting everything. |
| 19:33 | futile | i want my computer to just think for me. |
| 19:33 | jkj | futile: sure. don't mind testing either |
| 19:34 | futile | jkj: https://github.com/evanescence/zephyros |
| 19:35 | futile | im thinking of ripping out all the scripting though. only like 5 people ever liked it. |
| 19:35 | futile | not that it costs me anything to keep it, but, its just like, whats the point if only 5 people use it? |
| 19:35 | futile | i dunno anymore. |
| 19:43 | brehaut | futile: are you taking credit for zephros? |
| 19:43 | futile | brehaut: yeah, i wrote it |
| 19:43 | brehaut | not matt gemmell? |
| 19:43 | futile | not him. |
| 19:43 | futile | i think i caused too much confusion by asking him to house it for me |
| 19:44 | futile | i think ill just ask for it back. |
| 19:46 | callen | futile: you hadn't mentioned you were a cocoa dev. |
| 19:46 | futile | callen: you told me not to talk about myself! |
| 19:46 | futile | (over and over again) |
| 19:47 | callen | Usually it's blubbery self-deprecation or personal stuff. Talking about one's work is another matter. |
| 19:48 | futile | callen: noted |
| 19:49 | rebcabin | ,'(reduce 'or (list true false)) |
| 19:49 | clojurebot | (reduce (quote or) (list true false)) |
| 19:50 | rebcabin | ,(reduce 'or (list true false)) |
| 19:50 | clojurebot | false |
| 19:50 | arrdem | jkj: right now it's for platform specific assemblers |
| 19:51 | arrdem | the hope is to build a macro abstraction atop them that's portable |
| 19:51 | rebcabin | ,(reduce 'and (list true false)) |
| 19:51 | clojurebot | false |
| 19:51 | amalloy | rebcabin: 'or and 'and are symbols, not functions |
| 19:51 | arrdem | jkj: as to making the notation fns or macros in itself I think that's the approach I settled on while driving home. |
| 19:52 | amalloy | symbols happen to also be callable as functions, but they don't do anything like what you're hoping |
| 19:52 | rebcabin | darn :) |
| 19:53 | rebcabin | i just saw someone in a video do this, and i didn't believe it then :) |
| 19:53 | rebcabin | video is by tmarble at linux australia |
| 19:54 | noonian | did it work in the video? |
| 19:54 | rebcabin | he does (reduce 'or (map even? '(1 2 3 4 5))) and purports that it works :) |
| 19:54 | noonian | ,(reduce and (list true false))) |
| 19:54 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)> |
| 19:54 | noonian | ,(reduce and (list true false)) |
| 19:54 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)> |
| 19:54 | rebcabin | ,(reduce 'or (map even? '(1 2 3 4 5))) |
| 19:54 | clojurebot | false |
| 19:55 | noonian | ah |
| 19:55 | rebcabin | so dunno might have been some earlier version of Clojure or a jacked version |
| 19:55 | noonian | ,(ifn? 'foo) |
| 19:55 | arrdem | ,(type and) |
| 19:55 | clojurebot | true |
| 19:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)> |
| 19:55 | rebcabin | http://www.youtube.com/watch?v=ii-ajztxALM |
| 19:55 | noonian | ,(type or) |
| 19:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(NO_SOURCE_PATH:0:0)> |
| 19:55 | rebcabin | around 36:36 |
| 19:56 | clojurenewb | Raynes: hi do you have time for a laser question ? |
| 19:57 | rebcabin | he's using emacs org-mode in his video, and runs other things in the live repl -- but this one he just has a repo transcript |
| 19:57 | alexgunnarson | are we talking about las3r or laser? |
| 19:57 | jkj | futile: thank you for the software. you got me hooked. these are features mac os x is really missing |
| 19:57 | futile | jkj: appreciated |
| 19:57 | futile | im getting some more apps out in a second |
| 19:57 | futile | just cleaning it up |
| 19:58 | clojurenewb | alexgunnarson: laser as far as I know |
| 19:58 | alexgunnarson | clojurenewb: okay |
| 19:58 | futile | ok, anyone else want an xmonad-like app for Mac OS X? last chance. |
| 19:58 | clojurenewb | now I am intrigued by what las3r is |
| 19:58 | rebcabin | i like monads :) |
| 19:59 | jkj | futile: everybody needs it, but not many know they do i quess :) |
| 19:59 | callen | futile: sizeup is fine. |
| 19:59 | bbloom | i prefer monoids |
| 19:59 | futile | callen: if you say so |
| 19:59 | futile | jkj: thats how i felt. i avoided sizeup/divvy/etc for a long time. |
| 20:00 | rebcabin | size up is great; "optimal layout" is pretty good too |
| 20:00 | futile | turns out, it wasnt the idea i was against, but their execution |
| 20:00 | alexgunnarson | clojurenewb: las3r is basically a clojure interface/wrapper for actionscript/flash |
| 20:00 | futile | i like AppGrid because its "composable". |
| 20:00 | futile | you just remember a few key commands, and you can do a whole lot with them |
| 20:00 | alexgunnarson | clojurenewb: it's cool but even though i love flash functionality i just hate flash player… |
| 20:00 | rebcabin | i'll take a look at app grid -- can you tell us about monad, futile? |
| 20:01 | rebcabin | xmonad rather |
| 20:01 | noonian | futile: I'll probably checkout out zephyros when I have the time |
| 20:01 | clojurenewb | alexgunnarson: yeah I don't like proprietary plugins at all really |
| 20:01 | rebcabin | something is helping my spelling i want to turn it off! |
| 20:01 | alexgunnarson | clojurenewb: me neither |
| 20:01 | futile | AppGrid is just Zephyros with a hard-coded config, so you dont have to write one |
| 20:02 | futile | i personally dont wanna write 100 lines of CoffeeScript (or JS) to configure a wm |
| 20:02 | futile | and i know some people who feel the same |
| 20:02 | futile | but i also know some people who love tinkering |
| 20:02 | futile | rebcabin: xmonad is a dead-simple tiling window manager for linux. |
| 20:02 | noonian | futile: has anyone got zephyros working with clojurescript? |
| 20:02 | futile | noonian: i tried really hard for like 2 hours, couldnt figure it out |
| 20:02 | futile | please be the first :) |
| 20:03 | noonian | futile: heh, I'll probably give it a shot but it took me a while getting it working in a simple clojure webapp so no promises :P |
| 20:03 | futile | oh nevermind then |
| 20:03 | futile | its not a high priority |
| 20:03 | futile | just would be really cool |
| 20:03 | noonian | yeah |
| 20:03 | futile | possibly not even that practical |
| 20:03 | rebcabin | anything that saves me a trip to the mouse is a win |
| 20:04 | futile | here's the source to AppGrid if you want: https://github.com/evanescence/grs |
| 20:04 | futile | \cc jkj |
| 20:06 | alexgunnarson | hey everyone - so i'm considering developing a clojure app. obviously i'd like it to be write-once-deploy-everywhere but there's no "silver bullet" in terms of platform/VM/whatever for it to be deployed on. between Clojure+JVM+JavaFX, Clojure+Flex+AIR+Flash Player, and ClojureScript+Pedestal+HTML5+CSS, I'm not really sure where to go. |
| 20:07 | alexgunnarson | everyone thinks HTML5 is the future of everything but it's way behind flash and java libraries in terms of functionality |
| 20:07 | futile | alexgunnarson: i personally just use Clojure + HTML (via Hiccup lib) + CSS (via Garden lib) + JS (via ClojurScript) and dont care how it runs, just using lein-ring |
| 20:07 | alexgunnarson | and plus the HTML5 specs haven't even been hammered out yet |
| 20:07 | futile | alexgunnarson: yeah but there are other priorities besides just functionality. like searchability and runnability |
| 20:07 | jkj | AppGrid is probably better for most users as it makes a statement how things should work and is self documenting |
| 20:08 | noonian | I'm using Clojure for the backend and HTML5 + javascript on the frontend using handlebars for templating. Wasn't ready to commit to ClojureScript |
| 20:08 | alexgunnarson | well of course i would do a website with clojurescript + HTML5 |
| 20:08 | futile | jkj: i agree. some people find it too limiting but i think its just what most people really want even if they dont know it yet |
| 20:08 | alexgunnarson | but an RIA? clojurescript is not quite what i want... |
| 20:09 | alexgunnarson | futile: lein-ring does what again? async? |
| 20:09 | jkj | futile: maybe zephyros could also preconfigure itself to resemble AppGrid and have some presets bundled? |
| 20:09 | futile | alexgunnarson: magically runs your ring app for you. ring is a web server type thing. |
| 20:09 | jkj | not it's bound to repel some people as it requires configuration (minimal though) out of the box |
| 20:09 | alexgunnarson | oh. okay that makes sense |
| 20:09 | futile | well, its a spec really, i think. lein-ring uses jetty by default. |
| 20:10 | futile | jkj: i think even with a preconfiguration, its way too scary for most people. |
| 20:10 | jkj | futile: true |
| 20:10 | futile | jkj: even if it comes with its own zephyros.coffee file, itll still be like 80 lines |
| 20:10 | futile | jkj: i have another idea. |
| 20:10 | alexgunnarson | what's the idea? |
| 20:11 | futile | jkj: i was thinking of a middle-ground between zephyros and appgrid, where you can configure it within the app, using a custom interface |
| 20:11 | futile | jkj: it obviously wouldnt be as flexible as straight-up JS would be, but more flexible than appgrid. |
| 20:11 | futile | jkj: then every type of user could use it. |
| 20:11 | futile | i mean, there would be options for everyone. |
| 20:11 | alexgunnarson | well i'm not looking for an out-of-the-box thing necessarily… i'm willing to put up with coding hell |
| 20:11 | jkj | futile: true |
| 20:11 | bttf | i wrote a private function in my ring app that gets called by one of my handler functions ...the handler fn and private fn are in the same ns, but im getting errors at compile time |
| 20:11 | alexgunnarson | just as long as it gets easier |
| 20:12 | futile | alexgunnarson: sorry, this is off topic and its probably confusing you. |
| 20:12 | bttf | erros about so-and-so not a public function |
| 20:12 | futile | jkj: if you want to keep chatting about it feel free to come to #zephyros |
| 20:12 | bttf | wots the deal |
| 20:12 | alexgunnarson | futile: i'm not much of a server genius really |
| 20:12 | futile | alexgunnarson: sorry, those were two different conversations. |
| 20:12 | alexgunnarson | futile: ah okay |
| 20:13 | futile | alexgunnarson: ok about lein-ring. basically you just install lein-ring and it runs your Clojure web app for you. |
| 20:13 | futile | alexgunnarson: you wont have to deal with how it does it, it just does it. |
| 20:13 | futile | alexgunnarson: its really handy. https://github.com/weavejester/lein-ring |
| 20:13 | alexgunnarson | futile: that sounds awesome |
| 20:14 | alexgunnarson | futile: but i'm not really looking to run something in a browser… it'll be an app really |
| 20:14 | jkj | arrdem: do you have some intermedia presentation for the ops behind the notation? |
| 20:14 | alexgunnarson | futile: it might theoretically have some sort of limited functionality able to run in a browser, but that wouldn't be the focus |
| 20:15 | futile | alexgunnarson: it wouldnt run in the browser |
| 20:15 | futile | alexgunnarson: are you familiar with Rails? |
| 20:16 | alexgunnarson | futile: so when you say web app you don't mean SaaS you mean like an app that uses the web like a social app or a weather app |
| 20:16 | alexgunnarson | futile: not too familiar, no |
| 20:16 | futile | alexgunnarson: what are you familiar with? |
| 20:16 | alexgunnarson | futile: not very much - pretty much java and scheme… i'm still making inroads into clojure |
| 20:17 | futile | alexgunnarson: have you ever written any kind of website, like php or anything else? |
| 20:17 | alexgunnarson | futile: yes but i did the frontend only |
| 20:17 | alexgunnarson | futile: i never set up any servers or really messed around with the back-end |
| 20:17 | futile | alexgunnarson: oh. i ee. |
| 20:17 | futile | alexgunnarson: yeah im not sure what a good way to get started with doing that in Clojure would be. |
| 20:17 | futile | alexgunnarson: i would almost recommend getting your feet wet with Ruby on Rails |
| 20:18 | alexgunnarson | futile: why is that? |
| 20:18 | futile | alexgunnarson: pretty much every lib ive seen for clojure assumes you know all about that kind of thing. |
| 20:19 | futile | alexgunnarson: so html-generating libs assume you know all about html, etc |
| 20:19 | alexgunnarson | futile: well i know some HTML, CSS, etc. but i'm no expert yet |
| 20:19 | futile | alexgunnarson: if you arent super familiar with how http works, ring and compojure might seem a little confusing |
| 20:19 | alexgunnarson | futile: i'm really trying to determine the direction i want to go in so i can dive in to whatever solution is best |
| 20:20 | futile | alexgunnarson: ah. sorry, i got off topic again |
| 20:20 | alexgunnarson | sorry i've gotta go but keep me updated |
| 20:20 | futile | uhh |
| 20:20 | futile | ok? |
| 20:20 | clojurebot | grok is a little hard to juxt but it's the best thing ever |
| 20:20 | alexgunnarson | bye :/ |
| 20:20 | futile | bye |
| 20:47 | callen | alexkira: if you want to do a web app you might want to look at Luminus. |
| 20:49 | callen | er |
| 20:49 | callen | god dammit. |
| 21:27 | yedi | best way to use bcrypt from clojure? |
| 21:28 | yedi | nvm |
| 21:33 | yedi | can someone help me understand this line: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/signup_and_redirect.clj#L77 (specifically: `{{:keys [username password confirm] :as params} :params :as req`}) |
| 21:34 | yedi | i know it sets those vars to the corresponding keys in (:params req), but how exactly does the :as work |
| 21:38 | `cbp | Does anyone have a link to that blogpost "understanding clojure's persistent vector implementation", I can't seem to find it anywhere nor can I remember the author :-P |
| 21:42 | `cbp | yedi, it's destructuring a map that has a shape like {:params {:username "foo" :password "bar" :confirm "baz"}} |
| 21:42 | `cbp | :as binds the whole map |
| 21:43 | `cbp | ,(let [{{:keys [a b c] :as p} :p :as r} {:p {:a 1 :b 2 :c 3}}] [a b c r]) |
| 21:43 | clojurebot | [1 2 3 {:p {:a 1, :c 3, :b 2}}] |
| 21:45 | `cbp | ,(let [{{:keys [a b c] :as p} :p :as r} {:p {:a 1 :b 2 :c 3}}] [a b c p r]) |
| 21:45 | clojurebot | [1 2 3 {:a 1, :c 3, :b 2} {:p {:a 1, :c 3, :b 2}}] |
| 22:54 | futile | quiet night |
| 22:56 | brehaut | afternoon talios |
| 22:56 | talios | oh hai |
| 22:56 | brehaut | hows north of the hills |
| 22:57 | talios | grey, threatening rain |
| 22:57 | brehaut | likewise |
| 23:01 | yedi | why is the=is bcrypt fn returning different values after hashing the same thing? https://gist.github.com/yedi/9f219c53d6e5db95519c |
| 23:01 | futile | i think Clojure cant be appreciated fully until you first know C |
| 23:02 | futile | yedi: im guessing its using an algorithm that adds some randomization |
| 23:03 | callen | yedi: that's what makes bcrypt useful dude |
| 23:03 | callen | yedi: you can't store passwords with something that lets you precompute the value->hash relationship. |
| 23:05 | yedi | wait what? then how do you expect to do equivalence testing for passwords / auth when someone logs in? i though the whole point of a hashing function was quick deterministic 1 way hashing |
| 23:06 | callen | it's not that simple. |
| 23:06 | callen | yedi: http://codahale.com/how-to-safely-store-a-password/ |
| 23:06 | callen | do NOT use generic hash algorithms for storing passwords. |
| 23:06 | callen | Use scrypt, bcrypt, or PBKDF2 |
| 23:07 | TimMc | Aw, I missed all the fun? |
| 23:16 | yedi | ok, so callen, how do you test that a password is equivalent to a bcrypt hash? im just confused about that part |
| 23:20 | bbloom | yedi: normally, i'm all for teaching stuff and letting people make mistakes while they learn.. but security, and cryptography in general, is a different story: let somebody who knows that they are doing do it. use a well tested library for this! and if you do want to learn, then there are LOTS of good articles about this topic, b/c it's something people get wrong A LOT |
| 23:21 | bbloom | yedi: with that disclaimer out of the way... |
| 23:21 | bbloom | there are different hash functions for different use cases |
| 23:21 | bbloom | you don't want password hash functions to be super fast |
| 23:22 | bbloom | if you are trying to hash a lot of files for bulk equality testing later, then yeah! go w/ the fastest hash that fits your other needs |
| 23:22 | bbloom | but don't do that for passwords :-P |
| 23:22 | bbloom | b/c the only person bulk-testing passwords, are hackers |
| 23:22 | bbloom | if a user needs to wait an extra 1 to 100ms to login, that's no big deal b/c they do that so infrequently |
| 23:23 | yedi | ok yea i get it, but i just want to get bcrypt to work for my authenticate users function. I don't conceptually understand how to test for password = hash equality if bcrypt hashing isn't deterministic. |
| 23:23 | yedi | brb wiki |
| 23:25 | seangrove | Is bcrypt non-deterministic? |
| 23:26 | brehaut | its probably doing something like salting the phrase |
| 23:26 | brehaut | but its consistently slow |
| 23:26 | seangrove | Ah, yes |
| 23:26 | yedi | https://gist.github.com/yedi/9f219c53d6e5db95519c -- yea i feel like i'm missing something really dumb |
| 23:26 | bbloom | i am NOT AN EXPERT, but iirc, it's intentionally non-deterministic |
| 23:26 | bbloom | and you have to run a number of iterations |
| 23:27 | bbloom | and statistically, you'll get a matching hash eventually |
| 23:27 | callen | yedi: don't use friend |
| 23:27 | bbloom | but the number of iterations determines how slow it is |
| 23:27 | callen | yedi: understand what you're using. |
| 23:27 | callen | if bcrypt had predictable output for a given input, it wouldn't be useful. |
| 23:27 | futile | i just use openid and let google deal with it |
| 23:28 | bbloom | futile: i have fixed so many openid implementations, it's not even funny |
| 23:28 | seangrove | bbloom: Makes sense |
| 23:28 | bbloom | the 3 leg thing or whatever, people fuck up 2.5 legs of it :-P |
| 23:28 | futile | bbloom: yeah. im sure ive messed it up too. |
| 23:28 | futile | we all do. |
| 23:28 | futile | no such thing as security, amirite? |
| 23:28 | brehaut | yedi: im pretty sure you want to use bcrypt-verify to compare a password to a hashed password btw |
| 23:29 | brehaut | oh, my bad. the docs explicitly say to use bcyrpt-credential-fn; bcrypt-verify is just an implementation detail |
| 23:30 | brehaut | yedi: cryptography lesson one: read the docs on the library you are using ;) |
| 23:31 | bbloom | lesson 2: don't do it yourself :-P |
| 23:31 | bbloom | it's at least NON_DETERMINISTIC -ly harder than concurrency :-P |
| 23:31 | brehaut | bbloom: maybe these lessons are out of order |
| 23:32 | yedi | bbloom: know of a good library for it? |
| 23:32 | yedi | and ok, thanks guys |
| 23:32 | bbloom | *shrug* |
| 23:32 | brehaut | yedi: well, friend for http authentication. the stuff you linked to is already wrapping up all the internals |
| 23:33 | zRecursive | ,(sqrt 10000000000) |
| 23:33 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sqrt in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 23:33 | callen | yedi: I generally advise people against Friend unless they know pretty far ahead what they need and want. |
| 23:34 | brehaut | yedi: btw, i think cemerick has a clojure-sec mailinglist somewhere in the depths of google groups |
| 23:35 | yedi | callen: is there something you'd suggest instead? for like a user management system in a webstore |
| 23:35 | callen | yedi: if it's a simple web app, just use bcrypt and a secure cookie store for sessions. |
| 23:36 | brehaut | or, if you arent planning to use https, just dont even both with passwords |
| 23:36 | callen | you'll spend more time fighting Friend than writing your web app if you're not building something big/elaborate with a lot of auth-flow corner-cases and don't know what you're doing all that well. |
| 23:36 | brehaut | s/both/bother/ |
| 23:36 | callen | Clojure noobies trying to make a web app should almost never be using Friend unless they're participating in a large enterprise migration project. |
| 23:37 | callen | how you poor bastards end up on Chas's doorstep I'll never know. |
| 23:39 | callen | yedi: actually yeah I'd like to know, what made you try to use Friend? |
| 23:44 | TimMc | bbloom: What's this about bcrypt being non-deterministic? |
| 23:44 | TimMc | That sounds entirely wrong. |
| 23:50 | callen | TimMc: deterministic with respect to hashing refers to the ability to arrive at the same hash from the same value. |