2013-08-15
| 01:17 | ed_g | is it possible to pass a dynamic variable into an agent's context? |
| 01:17 | technomancy | ed_g: you can send it a bound-fn |
| 01:20 | ed_g | does that mean send-off a lambda which has a copy of the dynamic variable? |
| 01:20 | ztellman | ed_g: I'm pretty sure that's the default behavior |
| 01:24 | technomancy | oh yeah; I'm thinking of the 1.2 behaviour |
| 01:24 | callen | other than Incanter, what's a respectable analogue to NumPy for clojure? Ideally equally as performant or better. |
| 01:25 | callen | I'm aware of ztellman's mad scientist oeurve although I can't be sure if any of it is applicable. |
| 01:25 | ztellman | core.matrix seems promising |
| 01:25 | ztellman | not sure how completely realized it is |
| 01:25 | callen | ztellman: thanks :) |
| 03:34 | H4ns | how do i synchronously access the body of a request in a POST handler in http-kit? the documentation says it conforms to the ring spec, but i'm lost in the documentation. |
| 03:37 | H4ns | seems that i need to have a json middleware like ring-json |
| 04:55 | H4ns | is there a function that gives me a count of elements in a seq that satisfy some predicate (i.e. count-if)? |
| 04:56 | Raynes | (count (filter ...)) |
| 04:56 | TEttinger | ,(count (filter pos? ["darn you" "Raynes" 11 -1])) |
| 04:56 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> |
| 04:57 | Raynes | H4ns: This won't make two passes because filter returns a lazy seq. |
| 04:58 | H4ns | Raynes: ah, nice. thanks! |
| 05:27 | H4ns | what's an idiomatic way to call a function for number of elements from a seq and return the results? (the-fn + [1 2 3 4]) => (3 7) |
| 05:27 | supersym | reduce |
| 05:28 | H4ns | thanks |
| 05:29 | H4ns | erm, well, reduce always takes one element. i'll probably have to use group |
| 05:31 | supersym | ,(map #(reduce + %) (partition 2 [1 2 3 4 5])) |
| 05:31 | clojurebot | (3 7) |
| 05:31 | H4ns | ah, partition! thanks! |
| 05:31 | supersym | :) |
| 05:36 | TEttinger | H4ns, reduce is fantastically flexible. you can see some things on clojuredocs that use reduce with a function that takes a vector and an item from the collection you pass it... really potent stuff |
| 05:37 | TEttinger | err, it was somewhere else, but http://clojuredocs.org/clojure_core/clojure.core/reduce |
| 05:42 | TEttinger | ah, it may have been here http://www.learningclojure.com/2010/08/reduce-not-scary.html |
| 05:52 | supersym | TEttinger: yeah... I seemed to keep getting confused by it first |
| 05:53 | supersym | this is my first lisp :P |
| 05:53 | TEttinger | me too |
| 05:53 | TEttinger | and it's the way I think now |
| 05:53 | TEttinger | maybe always has been |
| 05:53 | supersym | yeah once you get it you get it :P |
| 05:53 | TEttinger | I remember programming in lua with tons of functions getting passed around, before I knew clojure |
| 05:54 | TEttinger | lisp is just... cleaner |
| 05:54 | supersym | god... I used to have awesome as my wm before xmonad |
| 05:54 | TEttinger | lua's great though |
| 05:54 | supersym | I remember it exceptionally well for killing my desktop on the slightest typo |
| 05:54 | supersym | yeah |
| 05:55 | supersym | I know.... really powerful embedded scripting/extensions using tables |
| 05:56 | TEttinger | luajit is a masterpiece of compiler tech and easy to use. there was a project called Vortex to add lisp and F# features to lua and have it compile to LuaJIT dialect lua |
| 05:56 | supersym | oh ok :) |
| 05:57 | supersym | I never really tried F#, once I reached that stage in my visual studio adventures, I decided to dump windows for linux |
| 05:57 | TEttinger | I haven't seen much difference in my productivity on windows or linux |
| 05:57 | TEttinger | http://quaker66.github.io/vortex/ |
| 05:58 | TEttinger | but a significant amount of my work is with windows-only multimedia stuff |
| 05:59 | supersym | well productivity, maybe, I was pretty damn at home in VS2010 and that was a really nice (12.000 dollar) tool |
| 05:59 | supersym | but I was tired of all the bloat, the background automated enabling of services, the malware |
| 06:01 | supersym | tbh tho: stuff like git etc isn't the same in windows |
| 06:01 | supersym | and powershell really sucks once you mastered zsh :) |
| 06:06 | arcatan | ugh. i'm not slacking off, i'm waiting for git to checkout my branch on windows. |
| 06:58 | H4ns | is there a way to limit the amount of data that nrepl prints? i'm dealing with large structures which take too long to print in emacs. |
| 07:00 | hugod | H4ns: *print-length* might help |
| 07:01 | H4ns | hugod: thanks, that was precisely what i wanted to have :) |
| 07:06 | H4ns | erm, only that it does not work :( |
| 08:00 | H4ns | is defstruct gone from clojure? i have stuart halloway's book from 2009 which mentions it, but i can't see it on the cheat sheet. |
| 08:04 | jkkramer | H4ns: it's deprecated in favor of defrecord |
| 08:08 | H4ns | jkkramer: and i should not be scared by the "alpha" label that it has? |
| 08:09 | shafire | Hi |
| 08:09 | shafire | Can I prove clojure programs? |
| 08:10 | jkkramer | H4ns: no need to be scared. it's not going anywhere |
| 08:14 | Anderkent[away] | H4ns: it's not going anywhere but it might not work perfectly with dynamic development (lots of code reloading in a repl tends to mess with compiled types like records/protocols) |
| 08:14 | H4ns | okay, i guess i'll just stick with maps and be done with it. |
| 08:14 | jkkramer | it's often a good idea to put your records and protocols in their own ns to avoid such issues |
| 08:15 | jkkramer | yeah, maps are good unless you have a specific need for records |
| 08:30 | hugod | H4ns: looks like nrepl isn't printing the result within the session bindings - possibly a bug in nrepl |
| 08:41 | hugod | H4ns: (set! *print-length* 10) should work |
| 08:42 | hugod | there is also *print-level*, which depending on your data structure, could help |
| 08:42 | ro_st | hugod: are you aware of any way to stop the pprinter from including commas in its output? |
| 08:42 | ro_st | so annoying when using CuCxCe in emacs and getting commas back |
| 08:42 | hugod | ro_st: not that I am aware of |
| 08:42 | ro_st | also, an aside: thanks for crtierium! awesome lib |
| 08:43 | ro_st | criterium, too -grin- |
| 08:43 | hugod | glad you find it useful |
| 08:43 | H4ns | hugod: that seems to work, thanks! i don't quite know what stopped it from working when i tried before. |
| 08:45 | hugod | H4ns: it seems a bit subtle - using `binding` of course doesn't work to set it, as the printing is done outside of the scope of the `binding` form, and alter-var-root doesn't work, as it has a thread-local value, which is what set! modifies |
| 08:47 | H4ns | hugod: is there a good place to put such initialization so that it modifies the right values for the nrepl repl, for all projects? |
| 08:49 | Anderkent | i think if you have a file "user.clj" on your classpath it will be executed whenever your repl starts |
| 08:49 | Anderkent | but if you only want it for repls started by your editor I think the editor must do the work |
| 08:50 | H4ns | Anderkent: i see, thanks. |
| 08:50 | hugod | H4ns: There is also the :init option you should be able to set in your leiningen user profile https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L148 |
| 08:50 | `cbp | H4ns: you can set :global-vars on your project.clj |
| 08:51 | hugod | `cbp: not sure that will work with thread locally bound vars, but worth a try |
| 08:53 | tcrayford | is there a decent clojure testing library with completely parallel testing? |
| 08:53 | tcrayford | I realized recently that literally none of my tests touch any shared globabl resources anymore, so I'd like to run everything in parallel for performance |
| 08:54 | tcrayford | (alternatively if there's a clojure.test plugin that does parallel testing, that'd be fine too) |
| 09:10 | hugod | `cbp, H4ns: :global-vars seems to do the job nicely |
| 09:12 | H4ns | hugod/`cbp: thanks, done :) |
| 09:15 | hugod | ro_st: you could define your own print-method for IPersistentMap that called a modified print-map |
| 09:38 | bdesham | I'm trying to generate a matrix where the i,j element is the result of (f i j). Is there a more idiomatic way than <https://gist.github.com/bdesham/6240709>? |
| 09:39 | ro_st | ,(map + [1 2 3] [4 5 6]) |
| 09:39 | clojurebot | (5 7 9) |
| 09:41 | chouser | bdesham: that's pretty common. See also clojure.math.combinatorics/cartesian-product |
| 09:42 | bdesham | chouser: ok, thanks |
| 09:48 | ro_st | to call a js method in the global scope from cljs would be (.it js/window) right? |
| 09:49 | ro_st | ne'ermind. |
| 09:56 | gvickers | I am working on a project that requires the ability to dynamically load jars and execute them in their own thread. Conceptually, I am having a hard time figuring out the best way to load the namespace and call the functions. Anyone work on something similiar? |
| 09:57 | chouser | gvickers: dynamically loading jars is rather a pain. Generally it means manipulating the Java classpath. You might look at pomegranate |
| 10:02 | mdrogalis | gvickers & chouser: I can second that it's quite a headache. |
| 10:04 | pandeiro | anybody know if lein is broken for glibc 2.18? |
| 10:04 | pandeiro | http://sprunge.us/SCOa |
| 10:04 | shafire | Can I prove clojure programs on correctness? (mh, how to say that) |
| 10:04 | ro_st | like you would with Haskell? |
| 10:05 | ro_st | i don't think so, because Clojure isn't a pure language |
| 10:17 | pandeiro | k my problem is not lein-specific; having to rebuild openjdk due to a gcc/glibc upgrade |
| 10:18 | nDuff | shafire: ...only if you're willing to make a bunch of assumptions. You can certainly have a subset of the program that uses only pure functions, and use formal reasoning around that. |
| 10:19 | H4ns | how can i create a map from a & rest parameter? i want to merge any extra keyword arguments supplied to a function with another map. |
| 10:19 | H4ns | (into map rest) gives me IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom |
| 10:19 | mdrogalis | H4ns: Can I see an example of input/output that you want? |
| 10:20 | fredyr | ,(merge {:a 1 :b 2 :c 3} {:b 9 :d 4}) |
| 10:20 | clojurebot | {:d 4, :a 1, :c 3, :b 9} |
| 10:20 | H4ns | ,(let [[& rest] [:a 1 :b 2]] (into {} rest)) |
| 10:20 | chouser | H4ns: (into map (apply array-map rest)) |
| 10:20 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword> |
| 10:20 | fredyr | H4ns: merge might do the trick? |
| 10:20 | shafire | nDuff: ro_st: thanks |
| 10:21 | H4ns | chouser: thanks! |
| 10:21 | mdrogalis | ,(apply hash-map [:a 1 :b 2]) |
| 10:21 | clojurebot | {:a 1, :b 2} |
| 10:21 | mdrogalis | That sort of thing? |
| 10:22 | H4ns | right |
| 10:22 | chouser | the problem was that into turns its second arg (rest) into a seq and calls conj on each |
| 10:22 | chouser | So you were getting (conj map some-key) and then (conj map some-val), etc. |
| 10:23 | chouser | but conj on a map requires a key-value pair, that is a mapentry or 2-element vector |
| 10:23 | chouser | hence the error |
| 10:23 | H4ns | ok. probably requires some more practice to deduce that from the message :) |
| 10:25 | chouser | Well, the error message told you it wanted a seqable (ISeq) but you were giving it a keyword |
| 10:26 | H4ns | i'm not saying that the message is bad, i'm just too inexperienced to draw the right conclusions from it. |
| 10:27 | Foxboron | H4ns: the biggest challange IMO is the clojure errors. Once you get over that, it's is not that bad |
| 10:27 | H4ns | Foxboron: coming from common lisp, i find the stack traces a bit lacking :) |
| 10:28 | Foxboron | H4ns: go blame java :3 |
| 10:28 | H4ns | Foxboron: but there is a lot good in exchange, so i'm not complaining. |
| 10:32 | chouser | if you looked at the trace you'd see it was conj complaining about that. |
| 10:32 | chouser | So yes, I agree the errors could be a lot better. Also, the errors are currently quite useful if you learn how to use them. |
| 10:34 | Foxboron | chouser: yeah, as i said. It is a little learning curve. Not quite there myself |
| 10:37 | mdrogalis | Eeek. Why are conferences so expensive? |
| 10:38 | mdrogalis | Not even programming-related. Just in general, for any field. |
| 10:38 | ro_st | ask puredanger. he should know :-) |
| 10:38 | Ember- | because those conferences need to cover their expenses? |
| 10:39 | mdrogalis | It's naive, but I'll ask it anyway. Aside from venue, what are their expenses? |
| 10:40 | tbaldrid_ | mdrogalis: and remember, these are fairly small conferences ~350 people, I'd imagine they'd get cheaper if the numbers got higher |
| 10:40 | nDuff | mdrogalis: venue is the really, really big one -- but there's also speakers. |
| 10:40 | chouser | mdrogalis: I think the venue and food (even snacks) are more expensive than you might think. Then they also cover travel and lodging for the speakers, who are otherwise donating their time to produce the talks. |
| 10:40 | ro_st | catering. some confs pay a stipend to speakers. not sure what goes into getting discounted hotels either |
| 10:40 | nDuff | mdrogalis: ...venues are more expensive than you'd think, though. They charge through the nose for things like box lunches, coffee, &c. |
| 10:41 | mdrogalis | Heh, I had no idea. |
| 10:41 | mdrogalis | Yeah, I just noticed it's consistently really expensive across a few different engineering and academic fields. |
| 10:41 | chouser | The conj and strange loop don't pay the speakers beyond travel and lodging. (except maybe the keynote speakers? not sure about them) |
| 10:46 | Mudge | hello |
| 10:53 | NiKo` | hi people |
| 10:53 | NiKo` | trying to use leiningen on osx but it's painfully slow |
| 10:53 | NiKo` | google doesn't bring much help about this :/ |
| 10:54 | NiKo` | I'm using stock jvm provided by osx and a fresh installation of lein through brew |
| 10:54 | NiKo` | hints? |
| 10:55 | NiKo` | (slow == lein help 46,84s user 1,73s system 262% cpu 18,517 total) |
| 10:57 | timvisher | so repl development may have finally hit me last night as far as why anyone would do it. it's the same reason one might use a shell over `M-!` and it's ilk in that you have automatic records of the development of your function as it grows and if you make a mistake you just go back a definition and start again without having to muck about with undo/redo. |
| 10:57 | timvisher | now i don't think it would be too hard to have every form i send to the repl via `C-x C-e` or it's ilk be also displayed in the repl. i feel like someone was already doing work along these lines though. is that the case? |
| 10:58 | Rubix | is there a dead-simple way to ramrod a pojo into a clojure map such that each key is a string representation of the declared data member ? |
| 10:59 | timvisher | Rubi: I think you're thinking of http://clojuredocs.org/clojure_core/clojure.core/bean |
| 10:59 | timvisher | ? |
| 10:59 | timvisher | Rubix: ^^ |
| 10:59 | timvisher | with a bit of help if you really want the string keys |
| 11:00 | Rubix | timvisher: that would be exactly what I want |
| 11:00 | Rubix | oh, snap, is that my n00b showing? |
| 11:00 | timvisher | also note https://github.com/clojure/java.data |
| 11:00 | timvisher | |
| 11:01 | `cbp` | I had to google pojo |
| 11:01 | Rubix | cbp: it sounds dirty to me |
| 11:01 | `cbp | it sounds like chicken in spanish |
| 11:02 | timvisher | `cbp`: i take you're not from a jvm background? or has it just been that blissfully long since you've been paid to write Java? :) |
| 11:02 | Rubix | "spanish chicken" could be dirty too |
| 11:04 | `cbp | timvisher: java was actually my first language but i've never been paid for writing it. I'm mostly a php guy :(. I do get paid to write clojure though in a way. |
| 11:04 | timvisher | `cbp: that's awesome. i had that for about 11 months. it twas a blissful time. :) |
| 11:05 | timvisher | not the php part. i'm enough a snob i suppose to turn my nose up that |
| 11:05 | timvisher | although i have been paid to write it. lol |
| 11:06 | jtoy | hi chunfeng |
| 11:06 | chunfeng | hi |
| 11:14 | mdrogalis | jtoy: Everytime I see you on IRC, I think "Man I should read that neuroscience book he recommended" Someday it will happen. |
| 11:16 | jtoy | mdrogalis: which one?, i've read and recommend a bunch :) |
| 11:16 | mdrogalis | jtoy: I'll look it up in my favorited tweets when the time is right. Can't even remember, ha. |
| 11:17 | pandeiro | do i need to install elasticsearch manually to use the http api with elastisch? anybody know? |
| 11:19 | schmir | pandeiro: I'm also using elastisch with elasticsearch. but I don't quite understand your question. |
| 11:20 | pandeiro | schmir: i am just running thru the getting started guide but it's not clear if elastisch installs elasticsearch or not |
| 11:20 | GeneralMaximus | how does one get rid of those autocomplete frames that Emacs pops up at the bottom of the screen? |
| 11:20 | schmir | pandeiro: elastisch does not install elasticsearch |
| 11:20 | pandeiro | and when i try to run the initial examples, i get a Connection refused, so i assume the server is not running |
| 11:22 | schmir | pandeiro: right. you need to start an elasticsearch instance. but that's quite easy |
| 11:24 | pandeiro | schmir: yeah almost got it |
| 11:30 | pandeiro | huh, doesn't seem to be running |
| 11:31 | sharms | I have a failing test which I would like to take a look at in a repl |
| 11:31 | sharms | do I just do 'lein repl' then paste it all in, or is there a shortcut to have it load the same code it would load during 'lein test' |
| 11:34 | supersym | http://richhickey.github.io/clojure/clojure.test-api.html#clojure.test/run-tests |
| 11:34 | supersym | @sharms |
| 11:35 | bbloom | hmm what's that clojurebot prompt? |
| 11:35 | bbloom | ~github |
| 11:35 | clojurebot | http://github.com/richhickey/clojure/tree/master |
| 11:35 | bbloom | ~richhickey |
| 11:35 | clojurebot | Titim gan éirí ort. |
| 11:36 | bbloom | ~github |
| 11:36 | clojurebot | github is http://github.com/clojure/clojure |
| 11:36 | bbloom | clearly that one |
| 11:36 | supersym | bbloom: I wanted to say a thank-you for backtick...having a blast learning all about quoting :) |
| 11:37 | bbloom | supersym: you're welcome! glad you like it |
| 11:40 | `cbp | GeneralMaximus: I think it doesnt do that if there's _something_ after what you're autocompleting. Like a newline |
| 11:41 | ambrosebs | type checking DOM manipulations with core.typed https://github.com/clojure/core.typed/blob/master/src/test/cljs/cljs/core/typed/test/dom.cljs |
| 11:42 | GeneralMaximus | `cbp: it is usually very intelligent. e.g, if i type "reduc" and hit tab, it pops up a frame with everything starting with those letters. if i go back and delete those letters, it hides the frame. but i have been stuck with that frame on several occasions. |
| 11:42 | GeneralMaximus | `cbp: in that case, i have to switch focus to that frame, delete it, and come back to the frame i was in |
| 11:43 | GeneralMaximus | (or is it called a window? sorry, my memory of Emacs terminology is sketchy.) |
| 11:45 | `cbp | GeneralMaximus: sorry i misunderstood your question. My autocomplete shows the completions automatically but sometimes it inserts like 20 newlines at the end of the file (or nrepl buffer) but doesnt seem to do that when theres something after what it's autocompleting. You can hide the completions with C-g |
| 11:46 | GeneralMaximus | `cbp: when i do C-g, it just beeps and says "Quit" in the minibuffer. doesn't actually close the window. |
| 11:46 | GeneralMaximus | `cbp: putting a space after what it's completing does get rid of the window, thought. |
| 11:46 | GeneralMaximus | *though |
| 11:47 | `cbp | GeneralMaximus: you can try looking at other people's autocomplete configuration. Emacs live has a good default for one |
| 11:48 | GeneralMaximus | `cbp: i will do that. thanks. |
| 11:53 | supersym | huh... what is this tho, found a macro with final argument [s s′] but the quote isn't a backtick or normal quote |
| 11:54 | supersym | as in: (list 'defmacro s′ (str s) ... but here in irc it shows as a regular quote, hmmm. Anyone know what it does, the suffix quoting? |
| 11:56 | mtp | it shows up as a unicode PRIME |
| 11:56 | mtp | for me |
| 11:56 | mtp | codepoint #x2032 |
| 11:56 | supersym | thnx |
| 11:57 | `cbp | ´ |
| 11:57 | `cbp | :-O |
| 11:57 | learner__ | hi, in Clojure when on REPL, how can I see all global variables and their values (like *warn-on-reflection*) ? thanks for your time |
| 11:57 | supersym | yeah I don't think my keyboard has it |
| 11:59 | supersym | ah, the same sign as in minutes, seconds etc... right now I remember thats a different one |
| 12:01 | `cbp | learner__: I guess you could use something like (clojure.repl/apropos #"\*.*\*") |
| 12:02 | `cbp | learner__: If you meant dynamic vars because otherwise every var is global. |
| 12:03 | learner__ | `cbp: Thanks. I want to know the every single global variable and it's value |
| 12:04 | seangrove | Is storing code in database normal? I remember someone doing something like that in php with eval, and thinking it seemed an abomination, but maybe I'm just not open-minded enough. |
| 12:04 | supersym | seangrove: I don't find it normal |
| 12:05 | supersym | though I see floating around sometimes, I've never found it a particularly attractive idea |
| 12:05 | supersym | anyway, clojure code=data, often you find yourself not needed a database at all |
| 12:06 | dnolen | bhauman: btw, that partition thing from yesterday looked good :) |
| 12:07 | dnolen | bhauman: I don't know if you saw but I said I'd be very surprised if making tons of channels and wiring them together was a performance problem. |
| 12:08 | bhauman | dnolen: the partition thing is working great cleans so many things up. |
| 12:08 | dnolen | bhauman: awesome |
| 12:09 | bhauman | dnolen: many channels may-not= bad performance. got it. |
| 12:09 | `cbp | postgresql has stored procedures which can run faster than client code |
| 12:10 | `cbp | never really used them though :) |
| 12:11 | supersym | if you must use sql, stored procedures are wtg |
| 12:12 | `cbp | I guess i should be using them then :-) |
| 12:12 | supersym | or at least in mssql/.net they were rock solid but takes a lot of time to set up and very rigid |
| 12:15 | dnolen | bhauman: I also think in bigger designs it will be normal for channels and go processes to come and go, I'm doing this in my next post and it's pretty amazing IMO. |
| 12:16 | bhauman | dnolen: you are demonstration the creation and collection of lots of channels? |
| 12:16 | supersym | hmm github die for anyone else? |
| 12:16 | bhauman | supersym: yep |
| 12:16 | supersym | aight |
| 12:17 | dnolen | bhauman: I'm doing it one place, hopefully easy to see how it can be applied at a larger scale. |
| 12:18 | dnolen | bhauman: but yes in principle you can create a process that represents some component that fires up a bunch of channels to do it's work and removes the event sources when it's done and exits, allowing all other processes to get GCed. |
| 12:18 | bhauman | dnolen: gotcha |
| 12:18 | dnolen | bhauman: for UI stuff I think this is a good pattern, just remove the sources (removeEventListener) and exit |
| 12:20 | bhauman | dnolen: gotcha, you are referring to while(true) go loops that don't close? |
| 12:21 | egghead | bhauman: I've noticed mostly i've been using go blocks with in/out chans and rarely do I find myself using the go block to deliver the result of some computation |
| 12:21 | egghead | but it seems like that is probably the cleaner thing to do? |
| 12:21 | egghead | I really liked the way bhauman did that in the dots game |
| 12:22 | egghead | actually I might be mistaken, think I'm thinking about the little :draw :draw :draw :drawend pattern |
| 12:22 | supersym | whats the difference between (declare foo) and (def foo)? |
| 12:22 | dnolen | bhauman: say a user clicks in a autocompleter field, you fire up all the channels and hook everything together, user makes a selection then tabs out, on tabout you can just remove listening on the event sources and exit the autocompleter loop |
| 12:23 | bhauman | egghead: I think both are very appropriate. Think one for modifying a stream and another for creating a stream. |
| 12:26 | supersym | oh the dots game looks nice btw :) |
| 12:26 | bhauman | dnolen: nice, but in your case there is a tab event channel that acts like a switch to destroy the autocompleter? |
| 12:26 | coventry | supersym: The source for declare in core.clj suggests that declare is a sequence of defs with {:declared true} as additional metadata. |
| 12:26 | bhauman | supersym: thanks |
| 12:27 | supersym | coventry: thank you |
| 12:28 | supersym | I should really check the source before asking |
| 12:30 | seangrove | bhauman: Enjoyed your core.async dots article! |
| 12:30 | dnolen | bhauman: I listen on blur which handles click elsewhere and and tab out |
| 12:30 | dnolen | bhauman: I've got a cool example where we need a cyclic barrier to deal w/ a browser quirk |
| 12:30 | bhauman | seangrove: thanks, man :) |
| 12:31 | bhauman | dnolen: ^ |
| 12:31 | dnolen | bhauman: cyclic barrier here just means a channel that waits for n other channels to write data before writing out their values in a vector |
| 12:31 | dnolen | bhauman: we need this because f**king browsers blur on mouse down, so we can't wait for click |
| 12:31 | dnolen | anyways the beautiful thing here is this is all quarantined from the actually autocompleter code |
| 12:32 | dnolen | all this crap is at the event layer where it belongs |
| 12:33 | bbloom | blur is extra broken in IE too |
| 12:33 | bbloom | blur events can just magically go missing sometimes |
| 12:33 | bhauman | dnolen: I totally commiserate about the complexity of raw events. I went down a deep rabbit whole drawing. And I'm still not at the bottom. |
| 12:33 | bhauman | "with the drawing" i mean |
| 12:34 | dnolen | bbloom: yeah I plan on doing the requisite IE compat stuff, though I'll probably cut it off at IE 7/8 for for lack of patience |
| 12:34 | dnolen | I expect most of the issues to be CSS, not the event stuff |
| 12:34 | bbloom | oh, nobody should care about 6 any more. fuck 7 too for most purposes. however, 8 has these bugs w/ blur too according to the react.js source |
| 12:34 | dnolen | this has been the case w/ my other posts |
| 12:35 | dnolen | bbloom: I don't doubt it, my revelation here is we don't need to taint a correct process w/ this stuff |
| 12:35 | dnolen | "Quarantining Quirks" |
| 12:35 | bbloom | yes. |
| 12:35 | bbloom | react does a nice job of creating a uniform event layer |
| 12:36 | dnolen | bbloom: cool, do they use queues as well? |
| 12:36 | supersym | bhauman: I was pondering some problems before really diving into cljs |
| 12:36 | supersym | seems like your post/game solved them quite elegantly |
| 12:37 | bhauman | supersym: thanks, I am refactoring some of the examples right now to clean up a major short coming of the method used in that post |
| 12:38 | bbloom | dnolen: in a sense. they just have a bunch of javascript arrays that they use in queue-style and accumulate events up. they then wrap all the browser events in synthetic event objects that prevent a cross-browser interface & all the subscribe/unsubscribe stuff gets de-quirked as much as possible |
| 12:38 | bbloom | if github was working, i'd link you to their ascii architecture diagram |
| 12:39 | bbloom | it's in src/core/ReactEventEmitter.js |
| 12:39 | dnolen | bbloom: and this architecture is cleanly exposed to users who want to adopt the pattern? |
| 12:40 | dnolen | bbloom: one thing I'm seeing is that I rarely want subscribe/unsubscribe nor my early usage of `multiplex` |
| 12:40 | bbloom | dnolen: their dom structure / behavior stuff is relatively decoupled from their reactive stuff, but all 3 rely on an ID assignment scheme & use those IDs to maintain state external to the DOM |
| 12:41 | bbloom | yeah subscribe/unsubscribe is always a bad plan |
| 12:41 | bbloom | if you use react proper, they basically garbage collect after each "frame" |
| 12:41 | egghead | multiplex, more like broadcast amirite :p |
| 12:41 | bbloom | they walk the change set and unhook all event handlers for objects that are no longer in the dom |
| 12:41 | bbloom | they do that in a pass after updating the dom, iirc |
| 12:42 | dnolen | egghead: I not convinced about how often you need broadcast either |
| 12:42 | dnolen | egghead: my hunch it that should be avoided nearly everytime |
| 12:44 | egghead | it's interesting to turn a chan into a fan-out style chan, but I agree that it's the edge case, sometimes you want multiple people to consume the message, what would be the better alternative to broadcast in that situation? |
| 12:45 | bhauman | egghead: the :draw :draw :draw :drawend pattern is not bad but it is weak in that consumers of the stream have to manage and detect each whole draw action. The consumers have to manage that state transition. |
| 12:45 | bbloom | i prefer to coerce events in to state |
| 12:45 | bbloom | then pass state as an argument to a pure function |
| 12:46 | bbloom | then diff output w/ the previous output and coerce the diff in to dom mutations :-) |
| 12:46 | bbloom | that's what react does. it's pretty magical |
| 12:46 | bhauman | egghead: much better to do channel of channels [ [:draw :draw :draw] [:draw :draw :draw]] |
| 12:46 | bbloom | magical in the life changing sense, not in the opaque confusing negative sense |
| 12:46 | egghead | I'm not in love with explicit mapping/filtering of chans I've been doing with cljs stuff since I always end up being subtly bitten by consuming the message before I intend to |
| 12:47 | egghead | maybe that will pas |
| 12:47 | egghead | s |
| 12:47 | dnolen | bbloom: with the DOM mutations, how do they make that consistent, do you have to follow conventions in your template? |
| 12:47 | bhauman | egghead: yeah it's hard to put the message back on the queue without creating a new one |
| 12:48 | pandeiro | is dir no longer required into nrepl by default? |
| 12:49 | tbaldridge | mdrogalis: ping |
| 12:49 | dnolen | egghead: I think subscribe may be OK for multiple views needing to get changes from a data source, but I think worth exploring alternative designs. Maybe writing the changes N times onto a channel for N consumers is simpler? |
| 12:50 | dnolen | egghead: there's lots to think about and invent - exciting stuff in my opinion. I definitely recommend ditching any previous notion of architecture you may have and try lots of stuff. |
| 12:51 | egghead | agreed |
| 12:51 | noncom | how do i access the main class file generated by lein from a java program? i do gen-class for that namespace and I think it must be compiled to a class available from java.. but i am a little confused, there are "core$_main.class" and "core$loading__4910__auto__.class" and "core__init.class" and "core.class" ... which one do i pick? |
| 12:51 | egghead | oh hay github is back |
| 12:52 | noncom | and how do I call it from java anyway? what will be its java fully-qialified name? |
| 12:53 | noncom | oh, manifest says "Main-Class: lein_natives_test.core" |
| 12:54 | noncom | so it breaks java conventions and starts with a lowercase letter.. hmm |
| 12:56 | egghead | noncom: it's relatively common to just include the clj runtime and provide a java class that delegates to your clojure code |
| 12:57 | egghead | ls |
| 12:57 | lazybot | bin etc home lib lost+found opt root sbin srv tmp var |
| 12:57 | egghead | oh thanks lazybot |
| 12:57 | noncom | egghead: is there an exception for that? |
| 12:57 | noncom | s/exception/example? |
| 12:57 | egghead | noncom: take a look at https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/java/jcascalog/Api.java for an example |
| 12:57 | dnolen | clojure-mode indentation is such an eyesore |
| 12:57 | dnolen | http://ragnard.github.io/2013/08/12/datomic-in-the-browser.html |
| 12:57 | Anderkent | I wouldn't do that unless you need to expose stuff to javaland anyway.. |
| 12:58 | seangrove | dnolen: What should it be instead? |
| 12:58 | pjstadig | noncom: also this https://github.com/clojure/clojure/blob/master/src/jvm/clojure/main.java |
| 12:58 | noncom | Anderkent: that is exactly what I need.. :) |
| 12:58 | egghead | along with https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/java/cascalog/Util.java#L36 |
| 12:58 | seangrove | I wouldn't mind seeing a clj-fmt pre-commit hook tool |
| 12:58 | dnolen | seangrove: always 2 space, align only on binding forms and data structure literals |
| 12:58 | `cbp | damn this gandalf theme from emacs live has some impossible to read colors. Does anyone have good light-colored clojure color themes? :-) |
| 12:58 | Anderkent | noncom: oh, okay. I thought you were just looking to run something from a jar - java -cp <jarfile> clojure.main -m my.clojure.namespace is fine then |
| 12:59 | egghead | `cbp: I like http://chriskempson.github.io/base16/ |
| 12:59 | Anderkent | noncom: in that case https://github.com/mikera/clojure-utils/blob/master/src/main/java/mikera/cljutils/Clojure.java might be for you |
| 12:59 | noncom | Anderkent: for technical reasons I need to get the access to the class-file generated by lein... |
| 13:00 | Anderkent | oh ok |
| 13:00 | Anderkent | nvm then |
| 13:00 | Anderkent | was wrong again :P |
| 13:00 | `cbp | egghead: :-) |
| 13:01 | bhauman | dnolen: we should throw some comments on that post eh? |
| 13:02 | Anderkent | dnolen: I don't see anything wrong with that indentation. Aligning call args is the right thing to do.. You can still put a newline right after fn name if it takes you too far right I guess |
| 13:03 | dnolen | Anderkent: I'm sorry it's an abomination plain and simple. My opinion of course. |
| 13:05 | llasram | Isn't it just the traditional way one idents Lisps? |
| 13:05 | Anderkent | so you'd do (f 2 3\n<indent>4 5) ? That's... surprising. For me the intiution of vectors with all members equal and lists with the first member priviledged (i.e skipped for alignment purposes) seems most natural |
| 13:06 | dnolen | llasram: no, this ugliness is a Clojure community innnovation |
| 13:07 | Anderkent | the main thing I find confusing is that some forms are special cased - defn etc. |
| 13:07 | hiredman | dnolen: that is not true, it is how emacs indents lisp |
| 13:07 | llasram | Looks to be standard for Emacs, yah: http://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Indent.html |
| 13:08 | hiredman | you can get emacs to indent random clojure forms like you are saying by telling emacs those forms get defun style indentation |
| 13:08 | hiredman | (defun is not a typo there) |
| 13:10 | hiredman | some scheme style guides also recommend the aligned argument style |
| 13:11 | dnolen | hiredman: ok maybe it is an lisp dialect innovation, it's not something I've seen much in Scheme code |
| 13:11 | Anderkent | well, I guess for me what exact style you use is not that important, as long as you can produce a config that automatically aligns according to that style... Consistency over prettyness. |
| 13:12 | kasterma | Why do you value consistency over readability? |
| 13:12 | hiredman | dnolen: when you google "scheme style guide" the first one has the aligned arguments style |
| 13:13 | hiredman | http://community.schemewiki.org/?scheme-style also |
| 13:13 | hiredman | the only place where it is a issue, and I suspsect this is why you are so annoyed by it, is when you have forms like core.logic's fresh |
| 13:14 | dnolen | hiredman: yes but unsurprisingly no examples of about how catastrophically ugly it is with moderately long function names |
| 13:14 | pjstadig | yeah you need to have clojure-mode indent that like a defun, and you're good |
| 13:14 | Anderkent | dnolen: just put a new line after function name? |
| 13:19 | dnolen | Anderkent: then you get 1 space indent *shakes fist*. I should probably stop complaining and write an elisp defun that does what I want. |
| 13:20 | hiredman | (put-clojure-indent 'fresh 'defun) |
| 13:20 | clojurebot | Gabh mo leithscéal? |
| 13:20 | coventry | nrepl's M-. hits the leningen jar file for clojure source code, which is a bit slow. Is there a way to point it at an uncompressed tree? |
| 13:21 | hiredman | clojurebot: what are you doing? |
| 13:21 | clojurebot | Huh? |
| 13:21 | Anderkent | the one space indent makes sense to me since it's just a list. Otherwise you get indents in (quote (1 \n 2 \n 3)) |
| 13:22 | Anderkent | unless you make your indent scroll a compiler I don't think you can reliably distinguish between list-to-be-executed and list-that-is-just-data |
| 13:22 | Anderkent | so you have to indent them the same way, and the 1 space indent is less ugly :P |
| 14:08 | dnolen | si14: what part about the core.match preallocated exception for backtracking is confusing? |
| 14:10 | bbloom | dnolen: sorry for the delayed response: the way you make that consistent is that you defer all dom operations & represent even the act of creating a node as data. when you write a render function in react, you don't actually create a node. you only create a node descriptor. and then if that descriptor matches the dom, nothing happens. so in effect, by always returning a plan instead of the result of executing the plan, then the runtime |
| 14:10 | bbloom | can enforce consistency for you |
| 14:10 | dnolen | bbloom: so they have some kind of language for all the different ways you can manipulate the dom? |
| 14:11 | bbloom | dnolen: their JSX language is optional. it basically adds XML literals to javascript, but they parse trivially from <Parent x="5"><Child/></Parent> to something like `new dom.Parent({x: "5"}, [new Child()])` |
| 14:12 | bbloom | but that just creates basically a description like: {"type": "Parent", "params": {"x": 5}, "state": {}, "content": [{"type": "Child" .... |
| 14:13 | dnolen | bbloom: yes so they fiddle with that, but how do they handle all the different kinds of dom manip you might do? |
| 14:13 | dnolen | append, prepend, change attribute, HTMLFragment, etc |
| 14:13 | dnolen | bbloom: or do they try to abstract that away? |
| 14:13 | bbloom | you don't do any of that nonsense :-) |
| 14:14 | bbloom | so there are two answers: |
| 14:14 | bbloom | 1) you generally avoid that & instead write pure functions that return a new view. just like if you were rendering the full page server side. the runtime will make that efficient w/ memoization |
| 14:14 | bbloom | 2) but of course you need to react to events |
| 14:14 | dnolen | bbloom: so do they always build DOM? behind the scenes do they do the fasting thing |
| 14:14 | dnolen | clone, HTMLFragment, string + innerHTML? |
| 14:14 | bbloom | yeah |
| 14:14 | seangrove | Woo, destructuring args in javascript |
| 14:14 | dnolen | bbloom: but not pluggable? |
| 14:15 | seangrove | It's not beautiful, but a step forward, I suppose |
| 14:15 | bbloom | for #2, you can call setProps on a child or whatever & that will maintain some stateful components. but all that state is processed transactionally. if you change props or state on yourself or a child, you can't observe the new props or state until the next frame |
| 14:15 | bbloom | all the props & state are applied in a transaction |
| 14:15 | bbloom | then the recursive diffing happens |
| 14:16 | dnolen | bbloom: ok sounds good, but as usually I'm skeptical this covers all the cases I care about |
| 14:16 | bbloom | dnolen: the event system is pluggable, so you can add new event types to play with this system |
| 14:16 | bbloom | you can't do jquery-like aspect-oriented things |
| 14:16 | bbloom | that's the biggest limitation, which could be viewed as a feature for larger apps |
| 14:16 | dnolen | bbloom: yeah I don't really care if you can't eliminate the rendering mapping dilemma |
| 14:16 | dnolen | bbloom: would like a system that could abstract over DOM, WebGL, Canvas etc |
| 14:16 | bbloom | oh, they have an escape hatch |
| 14:16 | bbloom | you can always request the underlying dom node |
| 14:17 | bbloom | and there are callbacks for when you are mounted or unmounted on to a node |
| 14:17 | bbloom | so you can do anything you want, but you just have to manage it yourself |
| 14:17 | bbloom | and you can package that behavior up in to a mixin if you want |
| 14:17 | dnolen | bbloom: that's good, though the point is can you reuse the architecture or not for new surfaces |
| 14:17 | dnolen | if not, it's the same garbage as everything else |
| 14:18 | bbloom | the same *design* can be applied to other things, which is what i'm occasionally working on: getting that to work for HTML, or Canvas, or GL, or Swing, or whatever |
| 14:18 | bbloom | but their implementation is finely tuned for html/dom |
| 14:21 | bbloom | doing this sensibly for an arbitrary backend & supporting a general notion of a "button" or other widget that is both abstract, but customizable per platform is *hard* |
| 14:22 | bbloom | dnolen: you can think of react's diff rendering loop as a little interpreter that's doing symbolic macro expansion and selective evaluation at runtime. hence why i'm talking to kovas about symbolic engines :-) |
| 14:26 | dnolen | bbloom: yeah I got that from your earlier descriptions, I just want support for multiple interpreters :) |
| 14:28 | bbloom | dnolen: me too :-) i started implementing it in an ad-hoc fashion, but there was a TON of boilerplate code & the interpreters were SLOW, but casual analysis showed that a lot of things can be trivially optimized |
| 14:29 | tbaldridge | eric_normand: ping |
| 14:29 | eric_normand | tbaldridge: hey! |
| 14:29 | bbloom | dnolen: i found myself creating/flattening/reduce-ing large trees of s-expression encoded in vectors with keyword tags |
| 14:29 | tbaldridge | hey, I'm interested in the problem you mentioned on twitter. is there something we can do differently to solve your problem? |
| 14:32 | eric_normand | tbaldridge: I doubt it, but maybe. |
| 14:32 | eric_normand | tbaldridge: I converted many callbacks in our code into async channels |
| 14:32 | eric_normand | with go blocks blocked listening for a message |
| 14:33 | tbaldridge | eric_normand: ok, sounds reasonable |
| 14:33 | eric_normand | some of the callbacks I converted were listening on chrome channels (different type of channel) |
| 14:34 | eric_normand | so the callback to add a message on the channel was waking up the event page |
| 14:34 | eric_normand | then it would go into a loop (with setTimeouts) |
| 14:34 | eric_normand | listening for the messages |
| 14:34 | eric_normand | so it would never sleep and took 100% CPU |
| 14:35 | eric_normand | after a few days, the extension would crash |
| 14:35 | eric_normand | it could also be that it was creating a new go block (with infinite loop) per callback |
| 14:35 | eric_normand | I haven't diagnosed it that far |
| 14:36 | tbaldridge | eric_normand: I assume this is the api you are using? http://developer.chrome.com/extensions/messaging.html |
| 14:36 | eric_normand | yes |
| 14:37 | eric_normand | my conclusion was that we should not use core.async for these wakeup callbacks |
| 14:38 | eric_normand | and there is little other reason for core.async in the event page, since the event page is just a kind of relay between the content scripts |
| 14:39 | dnolen | eric_normand: huh reading the twitter convo and following this - I'm not sure I follow the reasoning. |
| 14:39 | tbaldridge | eric_normand: that's the part I don't understand, something seems odd in the fact "listening for the messages" causes a infinite loop. All these apis are callback driven, so this should happen |
| 14:39 | dnolen | eric_normand: sounds like something you could repro in small example if it's as fundamental as you say. |
| 14:39 | eric_normand | easy |
| 14:40 | eric_normand | (go (while true (let [x (<! c)] (.log js/console x)))) |
| 14:40 | eric_normand | then never put message to c |
| 14:40 | eric_normand | don't even need the while loop |
| 14:41 | tbaldridge | I do that exact code all the time, it shouldn't be a problem |
| 14:41 | eric_normand | the problem is that the event page does not sleep |
| 14:41 | eric_normand | it will run forever as long as the browser is open |
| 14:42 | tbaldridge | are there a large number of messages in c? |
| 14:42 | eric_normand | no |
| 14:42 | tbaldridge | if the last reference to c is dropped, this go will be GC'd and the whole thing will go away |
| 14:42 | eric_normand | correct |
| 14:42 | eric_normand | but I cannot drop the reference to c |
| 14:43 | eric_normand | it has to be listening for messages |
| 14:43 | dnolen | eric_normand: so are you saying this is Chrome Extension architecture thing, the event page must be completely restartable or something? |
| 14:43 | eric_normand | dnolen: yes |
| 14:43 | eric_normand | chrome manages the wakeup |
| 14:43 | eric_normand | you register for events when you should wakeup |
| 14:44 | tbaldridge | "listening" in the code sample you gave above is just a callback attached to the channel. I assume you are using the stock core.async channels. i.e. you didn't re-implement the channel protocols |
| 14:44 | eric_normand | yes |
| 14:44 | tbaldridge | how are you getting data into c? |
| 14:45 | eric_normand | let me check |
| 14:45 | dnolen | eric_normand: I just tried you example, I see no calls to setTimeout |
| 14:45 | eric_normand | hmm |
| 14:46 | tbaldridge | I wonder if the problem is on the putting side of c |
| 14:46 | dnolen | eric_normand: I've done quite a bit of basic profiling of core.async under CLJS around memory and event generation and haven't seen this issue. |
| 14:47 | dnolen | eric_normand: might be missing something but it's not coming up under the Chrome Timeline |
| 14:47 | eric_normand | ok, I need to do deeper investigation |
| 14:48 | dnolen | eric_normand: ok there's exactly one call to MessageChannel in Chrome, no others |
| 14:49 | dnolen | eric_normand: we don't event use setTimeout for message sends, setTimeout only comes into play for put! and I think go block wakeup |
| 14:49 | dnolen | tbaldridge might know a bit more |
| 14:49 | eric_normand | there must have been something waking it up |
| 14:50 | dnolen | eric_normand: I'm assuming you can't keep state on the event page because of wakeup? |
| 14:51 | eric_normand | dnolen: right |
| 14:51 | eric_normand | we use local storage |
| 14:51 | dnolen | eric_normand: ok, than it is probably the one message that screws everything up for you. |
| 14:51 | eric_normand | but now I realize that we keep the channel in state |
| 14:52 | eric_normand | so that the callback can put the message onto the correct channel |
| 14:52 | dnolen | eric_normand: initially sounds like the Chrome Extension model is busted to me though - and core.async might be a bad model because event page is a dirty hack |
| 14:52 | dnolen | eric_normand: so yeah you create creating pages that stay awake because of one event |
| 14:53 | eric_normand | it looks like two problems: we keep channel around for the callback, and we don't check if the page is already loaded before initiating another channel |
| 14:53 | dnolen | eric_normand: right |
| 14:53 | eric_normand | I don't know if we can check |
| 14:54 | eric_normand | I basically ported all of our callbacks directly to channels |
| 14:54 | eric_normand | but I failed to realize that the callbacks needed also to register themselves again |
| 14:55 | eric_normand | they need to register each time the page is loaded, or it won't wake up again |
| 14:56 | eric_normand | dnolen: I think you're right. It's just a hack |
| 14:56 | eric_normand | dnolen: the script is meant to run to completion quickly and be run again later |
| 14:56 | dnolen | eric_normand: this is how I think it works |
| 14:57 | dnolen | eric_normand: they run the page expecting it to terminate, your event handler is listening on a queue |
| 14:57 | dnolen | eric_normand: but your code drops and event handler hanging the JS context |
| 14:57 | dnolen | every event will create a new hung event page eventually crashing the browser |
| 14:58 | eric_normand | dnolen: agreed. |
| 14:59 | potetm | Okay, I have a newb question: what does the '#function-name syntax *actaully* mean? |
| 14:59 | amalloy | ,'#'inc |
| 14:59 | clojurebot | (var inc) |
| 14:59 | potetm | Is that just clojure's way of denoting a function reference? |
| 14:59 | potetm | '#inc |
| 15:00 | potetm | ,'#'inc |
| 15:00 | clojurebot | (var inc) |
| 15:00 | potetm | '#'inc |
| 15:00 | eric_normand | dnolen: my solution was to avoid core.async in the event page |
| 15:00 | potetm | ,'#inc |
| 15:00 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 15:00 | eric_normand | potetm: not function reference. it returns the Var |
| 15:01 | dnolen | eric_normand: yes, I think you're conclusion is reasonabe :) |
| 15:01 | tbaldridge | eric_normand: yeah, that makes sense now. |
| 15:01 | dnolen | s/you're/your |
| 15:02 | potetm | eric_normand: okay, so when I say (function-name arg1), in this context "function-name" is a symbol that refers to the var '#function-name |
| 15:03 | potetm | That seems a little convoluted to me… maybe I'm missing some underlying simplicity…? |
| 15:03 | dnolen | eric_normand: I suspect it can be made to work, but I think you'd have to extra careful |
| 15:04 | eric_normand | potetm: vars are there for interactive development |
| 15:04 | eric_normand | dnolen: agreed. |
| 15:05 | juhu_chapa | Is there a way to refer to parent namespace? i.e. (println ../somevar) |
| 15:05 | eric_normand | potetm: they are an efficient way for the compiler to point to something that won't change (the var) but refers to something that will (the function) |
| 15:05 | eric_normand | potetm: afk |
| 15:06 | potetm | eric_normand: afk? you mean afik? |
| 15:06 | channels | afk is a reader macro equivalent to Away From Keyboard |
| 15:07 | potetm | lol |
| 15:07 | potetm | I wasn't sure if he actually meant it because it was directed at me personally. Thanks channels ;) |
| 15:09 | callen | Twitter is great today. |
| 15:10 | eric_normand | potetm: sorry, just had something to attend to |
| 15:10 | eric_normand | potetm: in the middle of the chat |
| 15:10 | callen | ztellman: thanks for the laughs. |
| 15:10 | ztellman | you mean the totally reasonable solutions? |
| 15:10 | potetm | eric_normand: not a problem |
| 15:12 | callen | ztellman: sure, but aphyr's reactions to the exchange were great. |
| 15:12 | ztellman | yeah |
| 15:13 | snake-john | Hi, (let [x 2 y (- x)] (clojure.pprint/pprint ``(~y))) shows in the repl (clojure.core/seq (clojure.core/concat (clojure.core/list user/y))) . But I would have expected (clojure.core/seq (clojure.core/concat (clojure.core/list (-2)))). An anybody explain to me why the (-2) is not shown? |
| 15:13 | callen | ztellman: I've had to write code to monkeypatch test ordering to keep coworkers from relying on stateful, specific-order hand-offs between test-cases before so I'm sympathetic to the problem. |
| 15:13 | ztellman | callen: ha, I've never actually had to do that |
| 15:13 | amalloy | snake-john: not enough ~s |
| 15:14 | callen | ztellman: work with more Python and Ruby programmers - and you will. |
| 15:14 | ztellman | but the tests don't run in the order they're defined in the file, right? |
| 15:14 | ztellman | so how on earth can they rely on the ordering? |
| 15:15 | callen | ztellman: people will use hacks to make it ordered |
| 15:15 | callen | just google around for 'python unittest order' |
| 15:15 | callen | my monkeypatch was a counter-measure. |
| 15:15 | ztellman | fun |
| 15:19 | gtrak | ugh seriously, I'm not mad at clojure for breaking changes, but ugh. |
| 15:19 | gtrak | 1.3-1.4 was way more trivial. |
| 15:20 | snake-john | amalloy: hmmh I would have thought the inner syntax quote gets run first which would yield (-2) and then the second syntax quote gets applied which would use the (-x). But this is probably not how nested quotes work |
| 15:21 | ztellman | gtrak: I dunno, that's a pretty flimsy invariant to rely on |
| 15:21 | gtrak | it's not done on purpose, but I think it ends up being transitive. |
| 15:22 | gtrak | I think the practice of simply copying output as the value you're testing for is the real malpractice. |
| 15:22 | hammer | i need to convince clojure to use one method on a java API, and not the other, one takes an Iterable<Pair<String, byte[]>>, the other takes a Map<String, byte[]> |
| 15:22 | gtrak | I can't go look at it later and see if the order really matters unless I wrote it. |
| 15:22 | ztellman | hammer: hinting as ^Iterable or ^Map should do the trick |
| 15:23 | hammer | it's a both |
| 15:23 | hammer | PersistentArrayMap implements Iterable |
| 15:23 | gfredericks | hammer: yeah but you hint so it knows what to treat it as |
| 15:24 | gtrak | if the map instances randomized its storages, then the tests would never run correctly twice. |
| 15:24 | gtrak | and that's way better. |
| 15:25 | gtrak | instead of acting as timebombs |
| 15:25 | hammer | where would i hint it? I've got map m, and I'm calling Foo.bar(Map<String, byte[]) from java, so I've tried (Foo/bar (^java.util.Map m)) |
| 15:25 | hammer | but that thinks I'm trying to call the function on m |
| 15:25 | hammer | ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:437) |
| 15:25 | gfredericks | hammer: (Foo/bar ^java.util.Map m) |
| 15:26 | cmatheson | /b #e |
| 15:26 | cmatheson | oops |
| 15:27 | hammer | ah awesome |
| 15:27 | gfredericks | cmatheson: that's a secure password because it has two special characters |
| 15:27 | hammer | thanks a bunch |
| 15:28 | cmatheson | gfredericks: haha, just trying to switch channels |
| 15:39 | gzmask | lein uberjar just doesn't work and keeps giving me: could not find load main class error. I am pretty sure I got all the stuff right and it was working a month ago... |
| 15:41 | gfredericks | ztellman: holy snap this potemkin |
| 15:41 | ztellman | gfredericks: ayup |
| 15:42 | callen | gfredericks: I appreciate that he used the word conflate instead of complect in describing import-vars. |
| 15:42 | gfredericks | ztellman: I keep wanting lazy maps everywhere |
| 15:42 | callen | I'm probably going to need potemkin soon because I have a library that is going to get hairy. |
| 15:43 | ztellman | gfredericks: lazy maps? maps with random key order? maps that only give you what you ask for every other time? use potemkin! |
| 15:43 | ztellman | also there's this, which I think is one of the funnier things I've written: https://github.com/ztellman/potemkin/blob/master/src/potemkin/types.clj#L37 |
| 15:43 | amalloy | i feel like ztellman must have recently hired a PR person and handed over his twitter/irc credentials |
| 15:43 | gfredericks | ztellman: I want to create a type which implements every interface in clojure.lang. Can potemkim help me do this? |
| 15:43 | ztellman | watches the protocol var, updates other protocols whenever it changes |
| 15:44 | gfredericks | perhaps defeverything? |
| 15:44 | gtrak | gfredericks: defclojure |
| 15:45 | ztellman | gfredericks; this gets you like 2/3rds of the way there: https://github.com/ztellman/potemkin/blob/master/src/potemkin/collections.clj#L21-L164 |
| 15:45 | ztellman | amalloy: it took me a while to find a PR firm fluent in Clojure, but it was well worth the effort |
| 15:46 | ztellman | gfredericks: https://github.com/ztellman/potemkin#unify-gensyms |
| 15:49 | devn | ztellman: i just played hackey sack, sponsored by Factual |
| 15:51 | ztellman | Factual is renowned as a great patron of the hackey sack |
| 15:58 | noncom|2 | where is weavejester? haven't seen him for a while.. |
| 16:00 | eric_normand | anybody going to play in Clojure Cup? |
| 16:01 | `cbp | :-O are there prizes? |
| 16:02 | timvisher | has anyone heard of an effort to automitically build up var definition history in nrepl without directly interacting with the repl buffer? |
| 16:02 | timvisher | i.e. logging off the form that's evaled whenever one is evaled? |
| 16:03 | noncom|2 | timvisher: no.. and what about you? |
| 16:04 | timvisher | noncom|2: indeed i have not. it finally hit me at the Clojadelphia's meetup last night that the reason you might want to use the REPL directly is to be able to scroll back through the intermediate definitions of a function as you're building it up |
| 16:05 | timvisher | it doesn't seem like it would be that hard to automatically print the evaled form in the REPL before actually evaluating it, so I thought someone else might have cooked one up already |
| 16:05 | hiredman | I think that assumes a style of working that is not universal |
| 16:05 | noncom|2 | timvisher: oh, i think that's what ccw does |
| 16:05 | timvisher | hiredman: ? |
| 16:05 | timvisher | noncom|2: that might be what i'm thinking of |
| 16:06 | hiredman | timvisher: I generally don't build functions in the repl |
| 16:06 | noncom|2 | but personally i use ctrl+up to wind the buffer and find a particular memory from the past |
| 16:06 | timvisher | i also thought that hugo duncan might have mentioned something in his nrepl talk |
| 16:06 | hiredman | if I have a little expression or something I will build that up in the repl |
| 16:06 | travisrodman | ivaraasen: thanks for sharing your code example the other day, about how you consume the clojure code in java. it was in regards to the data importer. very helpful. thanks |
| 16:06 | hiredman | but often I start with (defn f [] ...) in a file, eval the whole file, call (f) in the repl |
| 16:06 | timvisher | hiredman: you're describing how i work, i believe |
| 16:07 | eric_normand | from the home page and the judges, clojure cup will be a game project |
| 16:07 | noncom|2 | hiderman: timvisher: you all say this coz you no use lighttable yet |
| 16:07 | timvisher | you don't just type (f) directly into the file, perhaps in a comment form, and eval it? |
| 16:07 | hiredman | I extremely rarely type a form (defn …) in to the repl |
| 16:07 | timvisher | noncom|2: :) |
| 16:08 | hiredman | timvisher: sure, I've done that too |
| 16:08 | noncom|2 | i do defns in repl when i figure out how to construct that or another sequence of collection-operating àòû |
| 16:08 | timvisher | regardless, i realized last night that what that looses is the intermediate steps of building up my function |
| 16:08 | hiredman | timvisher: but my point is, in that style a history of vars in the repl doesn't seem useful |
| 16:09 | noncom|2 | that never exceeds oneliners though |
| 16:09 | timvisher | it seems like more people than not in the clojure community use the repl directly and then copy fully defed vars into their source file |
| 16:09 | hiredman | timvisher: if you are reloading a hole file, how does your history thing work? |
| 16:09 | timvisher | i don't like that because my repl buffer is not 'savable' |
| 16:10 | bbloom | timvisher: i think most of us write in to source files directly & then use a key combination to send forms to the repl |
| 16:10 | timvisher | hiredman: i'd assume that if a function definition hasn't changed it would not reprint |
| 16:10 | timvisher | bbloom: interesting. maybe i've just gotten an incorrect impression then. :) |
| 16:10 | hiredman | *shrug* |
| 16:10 | noncom|2 | timvisher: usually it does reprint, since the other way requires more analysis |
| 16:10 | hiredman | I am not advocating for something, or saying one thing is more common than another |
| 16:11 | timvisher | noncom|2: in ccw? i would be annoyed by that i think. |
| 16:11 | hiredman | I am saying there are assumptions there that aren't universal |
| 16:11 | timvisher | hiredman: i'm assuming there would be a configuration option with that |
| 16:11 | noncom|2 | timvisher: anyway, tell us what is your vision of the future? |
| 16:11 | hiredman | so go a head and do whatever, just don't be surprised if no one cares :) |
| 16:12 | chronno | timvisher: nrepl-send-to-repl in https://gist.github.com/kingtim/4349847 although I haven't tried it. |
| 16:12 | timvisher | so if you don't want your repl buffer filling up with intermediate definitions then you wouldn't turn the feature on |
| 16:12 | timvisher | chronno: interesting! |
| 16:12 | timvisher | hiredman: duly noted. :\ |
| 16:13 | timvisher | noncom|2: vision is that curretly as i'm building up a form, i have to rely on undo to back off from a bad set of changes to a good state |
| 16:14 | noncom|2 | timvisher: so, per-form history you want? |
| 16:14 | timvisher | if you think of the REPL as a shell, and your function as a complex set of piped together commands, then it would be like piping on 2 new commands, executing it, and realizing you screwed up, and not being able to press ↑ and try again |
| 16:14 | timvisher | instead, you have to press your undo key a bunch of times, remembering what the form looked like before, and hope that you don't go to far |
| 16:15 | hiredman | timvisher: what repl are you using that doesn't have history? |
| 16:15 | noncom|2 | yes it is so currently |
| 16:15 | timvisher | so the vision would be that i can always go to the repl buffer and look through the history of things that i evaled, in order, and pick up where i left off |
| 16:15 | noncom|2 | timvisher: i think you can device this repl youself? |
| 16:16 | noncom|2 | in elisp or swing? depends on your preference.. |
| 16:16 | hiredman | timvisher: you just want to save the history? |
| 16:16 | timvisher | hiredman: nrepl.el does not do this by default (or in any configurable was afaict) |
| 16:16 | noncom|2 | timvisher: once i made such an app. it was in java and for shell commands though. it was an easy task |
| 16:16 | timvisher | if i'm interacting with the repl directly it does, but i prefer to edit source files for basically any kind of editing, even if that's just exploratory |
| 16:16 | hiredman | because for example, in nrepl.el M-p will give you the previously eval'ed code |
| 16:17 | llasram | timvisher: Er, nrepl-history-size etc ? |
| 16:17 | timvisher | hiredman: do you have a source file open? |
| 16:17 | timvisher | if you do, type `(+ 1 1) C-x C-e` and then switch to the nrepl buffer and press `M-p` |
| 16:17 | hiredman | I have many, in emacs buffers locally and remotelly |
| 16:17 | timvisher | `(+ 1 1)` does not show up for me |
| 16:18 | timvisher | only what i actually have typed in the repl buffer is in that history |
| 16:18 | hiredman | sure |
| 16:18 | timvisher | hiredman: so that's the feature i'm talking about desiring. :) |
| 16:18 | hiredman | and what do you want to happen when I hit C-c C-k and then M-p in the repl |
| 16:19 | timvisher | what does `C-c C-k` do? |
| 16:19 | hiredman | loads the whole file |
| 16:19 | timvisher | interestingly, it loads the buffer |
| 16:19 | timvisher | C-c C-l will load the file, but that's beside the point |
| 16:19 | timvisher | i would want to have only vars whose definitions have changed appear in the repl |
| 16:20 | timvisher | but if it was too hard, i'd probably be ok with all the forms being printed as they are evaled |
| 16:20 | llasram | Perhaps you may be interested in inferior-lisp-mode? |
| 16:20 | timvisher | llasram: is this how inferior lisp works? |
| 16:20 | timvisher | i only used that briefly way back in the day and then moved onto slime |
| 16:20 | timvisher | i wouldn't want to miss all of nrepl's features just to get history |
| 16:21 | llasram | Well, then pick and or fork your poison :-) |
| 16:21 | llasram | inferior-lisp just has a process which you can pump forms to |
| 16:21 | timvisher | that's what it's sounding like i'll have to do |
| 16:22 | llasram | So they're all in history, but you can't ask the process anything (like get docstrings) etc |
| 16:22 | timvisher | llasram: yep. that's what i'm looking for but with all of the other nrepl goodness. :) |
| 16:22 | timvisher | this would _definitely_ not be worth the tradeoff of loosing the rest of nrepl |
| 16:22 | timvisher | it's more of an expriment too |
| 16:23 | timvisher | i'm pretty happy with my current dev flow, i just finally realized why some people might develop at the repl rather than in their source files |
| 16:23 | timvisher | and it seems like it would be a good experiment to run |
| 16:25 | `cbp | Am I the only one that goes to the last paren of an expression then does C-x C-e? I feel like I should be able to C-c C-c inside the body like with common lisp :( |
| 16:26 | technomancy | `cbp: C-M-x |
| 16:26 | eric_normand | `cbp: I C-c C-c |
| 16:28 | `cbp | oh what the heck i swear i couldnt do c-c c-c before. Also i didnt know about C-M-x |
| 16:29 | coventry | C-u C-M-x is awfully useful for stepping through elisp. |
| 16:29 | gtrak | `cbp: huh, I still do it that way. thanks for the tip. |
| 16:29 | `cbp | must have been used to an old version of nrepl |
| 16:31 | gtrak | I can neither do c-c c-c nor C-M x |
| 16:31 | gtrak | KDE grabs it I guess |
| 16:32 | gtrak | C-M anything seems not right |
| 16:34 | gtrak | ah, my repl itself is hosed |
| 16:38 | callen | just a reminder to everybody |
| 16:38 | callen | Java's SecureRandom is not secure, nor is any userland CSPRNG |
| 16:38 | callen | I just got done putting in a PR to weavejester's crypto-random to fix it. |
| 16:40 | ivan | callen: why not any userland CSPRNG? |
| 16:41 | gtrak | callen: this wrecks my plans for a SecureRandomPersistentHashMap |
| 16:41 | ivan | callen: also Windows does not have /dev/urandom |
| 16:41 | callen | ivan: CryptGenRandom for best-effort on Windows. |
| 16:41 | callen | but CryptGenRandom has dubious-at-best entropy sources. Do not run things that need to be secure on Windows. |
| 16:41 | callen | don't use SecureRandom on Unix at the very least. |
| 16:42 | callen | or don't use SecureRandom with the expectation of cryptographically secure random bytes. |
| 16:42 | callen | ivan: you cannot implement a cryptographically secure PRNG in userland. |
| 16:42 | callen | you must use the kernel API. |
| 16:42 | ivan | why not |
| 16:46 | callen | ivan: I can't tell if you're asking for a white paper or you want to discuss cryptography system implementation. |
| 16:46 | ivan | callen: I just need a summary of why it's impossible, or some citation |
| 16:46 | ivan | is it because timing attacks due to scheduling? |
| 16:47 | callen | that's one of the reasons |
| 16:49 | callen | there might be, in some perfect universe, a way to implement a secure CSPRNG in userland, but that never happens. So stop using them. |
| 16:49 | callen | or implementing them. Because you'll fuck up. |
| 16:50 | gzmask | anyone use core.typed? how would you use it? |
| 16:50 | ivan | claiming that something is impossible requires stronger support than that |
| 16:51 | callen | ivan: it's a pretty standard understanding of CSPRNG |
| 16:51 | technomancy | ivan: what have you got against arguments from authority bro? |
| 16:51 | callen | technomancy: security is too fragile for amateur hour "good enough" |
| 16:52 | callen | technomancy: particularly when secure options exist. it's stupid and unnecessary. |
| 16:52 | xicubed | i once interviewed at a lottery company, they had a server room with some radioactive substance who's decay provided the random seed... |
| 16:52 | callen | It also requires a lot of background to really be able to do anything without deeply fucking up. |
| 16:52 | technomancy | callen: of course. that doesn't mean you can't back up your claims. |
| 16:53 | callen | technomancy: I'm not really in the mood to go white paper hunting, I was scrambling to fix crypto-random and put the word out. |
| 16:53 | callen | another problem with security is that there's a lot of out-of-date/wrong information that still comes up via Google |
| 16:54 | callen | like OWASP's out of date recommendation to use SecureRandom without specifying impl. |
| 16:55 | seangrove | callen: People are basically good. |
| 16:55 | seangrove | Just use a dialog to ask them if they agree to be good people, and don't bother with security |
| 16:56 | callen | seangrove: cute. Did you see http://amber-lang.net/ ? |
| 16:56 | seangrove | Yeah, remember seeing this awhile ago, looks really great. Never got as far into smalltalk as I would have liked |
| 16:57 | callen | seangrove: I was actually thinking about a hybrid of that plus client-side (only) datomic with CLJS source maps |
| 16:57 | callen | visually exploring your data and each object's history. |
| 16:58 | seangrove | What do you mean client-side only datomic - no datomic server? |
| 16:58 | gzmask | anyone has experience with core.typed? does it type check on lein run or do you have to run some function in repl to type check? |
| 16:58 | ivan | heh "This class generates cryptographically secure pseudo-random numbers. It is best to invoke SecureRandom using the default constructor. This will provide an instance of the most cryptographically strong provider available" https://developer.android.com/reference/java/security/SecureRandom.html |
| 16:58 | callen | ivan: not actually true :\ |
| 16:59 | callen | and like I said, there is out of date information out there. |
| 16:59 | callen | since I'm the only one that tracks security issues: http://android-developers.blogspot.com/2013/08/some-securerandom-thoughts.html |
| 16:59 | callen | the Android bitcoin client was broken because of faults in SecureRandom's implementation. |
| 16:59 | callen | the bitcoin client itself was not at fault. |
| 17:00 | callen | ivan: satisfied? |
| 17:02 | gzmask | has anyone use core.typed before? does it do type checking during repl-function-calls or runtime? |
| 17:04 | llasram | gzmask: It's not widely used (yet?). The project-creator ambrosebs is frequently around this channel, but apparently not at the moment |
| 17:05 | gzmask | llasram: hrmm, thanks... I kinda assume anthing has a core. prefix is wildly hip |
| 17:05 | supersym | gzmask: https://github.com/clojure/core.typed/wiki/User-Guide |
| 17:06 | bbloom | gzmask: type checking w/ core.typed is explicitly invoked |
| 17:06 | supersym | assertion seems to take place at the REPL |
| 17:06 | supersym | as well |
| 17:08 | bbloom | yeah, via calling cf (check form) or check-ns |
| 17:09 | TimMc | callen: So what's actually wrong with SecureRandom? I see something about "improper initialization", but no details. |
| 17:10 | TimMc | The vague impression I've got is that it's not so much Java that's at fault, but the native code Java is calling into on Android. |
| 17:10 | Raynes | tpope: Can I make vim-fireplace not try to start up a repl automatically? |
| 17:10 | Raynes | It takes forever to load files in projects where `lein repl` fails because of it. |
| 17:10 | Raynes | Because it tries every time. |
| 17:11 | callen | TimMc: Android's SecureRandom impl wasn't compliant. I don't think OpenJDK's was either. |
| 17:11 | hiredman | well, that is you call the runtime system on android "java" |
| 17:11 | hiredman | if |
| 17:12 | TimMc | callen: :-( |
| 17:13 | callen | TimMc: I believe it had to do with the entropy sources used in the creation on the initialized seed. I could be wrong on that point. |
| 17:14 | callen | I'm trying to figure out a wrapper for enforcing the use of "/dev/urandom" || CryptGenRandom right now |
| 17:15 | TimMc | I was hoping this was just limited to Android. |
| 17:16 | ivan | wrapping /dev/urandom with some kind of buffer is a good idea if you don't want to pay a huge performance penalty |
| 17:16 | TimMc | Depends on the system, no? |
| 17:16 | ivan | well, you can only open /dev/urandom, read, close, a few thousand times per second |
| 17:17 | TimMc | Oh, I see. |
| 17:17 | TimMc | There's also an issue where on a *few* systems, /dev/urandom will block until it has more of the good stuff (juiced entropy from system timings.) |
| 17:18 | callen | that's sorta the point |
| 17:18 | callen | you can stuff lower quality entropy in if you want, but you should stop pretending it's secure then. |
| 17:19 | callen | the stuff that is supposed to be secure should stay so, and if you have some service or "thing" generating a ton of securely random bytes, it's time to get specialty hardware to provide extra entropy. |
| 17:21 | TimMc | /dev/random is the one that's supposed to block, right? |
| 17:21 | callen | yeap. |
| 18:00 | justin_smith | I wonder if anyone has used a shortwave radio on a adc to generate entropy |
| 18:01 | justin_smith | https://github.com/pwarren/rtl-entropy |
| 18:02 | justin_smith | they have a todo to add entropy to the system pool |
| 18:03 | callen | justin_smith: I know a good person to ask about that, they do work on ham radio drivers for FreeBSD |
| 18:03 | justin_smith | cool, it seems promising |
| 18:03 | callen | it's a nifty idea. |
| 18:18 | justin_smith | actually, lower tech, you could probably do a lot with a reverse biased zener diode connected to an adc |
| 18:24 | justin_smith | if I have two nrepl buffers open, how do I specify which one a given source buffer is connected to? |
| 18:27 | `cbp | why not just multiple emacs :-P |
| 18:30 | justin_smith | `cbp: that could be an option I guess, but I am doing one project that shares many properties with an older project: easier to be able to have both open in one emacs - until I deal with the "which of the repls does evaluation in this file connect to" issue |
| 18:30 | justin_smith | ie. m-x ediff |
| 18:30 | justin_smith | between old core.clj and the new one |
| 18:38 | justin_smith | looks like I need to run nrepl-connections-make-default before evaluating code that goes with that connection |
| 18:40 | justin_smith | this is tied to nrepl-connection-browser |
| 18:41 | justin_smith | it looks like there is support for "projects" but only via nrepl-jack-in? |
| 18:43 | glosoli | Hmm |
| 18:49 | seangrove | justin_smith: You can switch to the nrepl buffer you want to be default, and then run nrepl-make-repl-connection-default |
| 18:49 | seangrove | I don't know if there's a per-buffer association |
| 18:50 | seangrove | justin_smith: Sorry, just saw you already wrote that |
| 18:50 | justin_smith | no problem |
| 18:50 | justin_smith | do you know anything about the "project" feature referenced here and there? |
| 18:50 | justin_smith | that seems promising, but I am not seeing the big picture |
| 18:51 | seangrove | No, I've been running several nrepls recently and would like something like that |
| 19:26 | glosoli | How does one clear red overlay when something fails in code in Emacs Clojure Mode ? |
| 19:38 | technomancy | glosoli: clojure-test-mode? |
| 19:38 | technomancy | should be C-c k or something? |
| 19:39 | glosoli | technomancy: yeah for example I am in the file which has main method and some routes (compojure) defined, and I accidently press C-c k an it outputs some errors and adds the overlay |
| 19:39 | glosoli | :? |
| 19:40 | technomancy | you're running clojure-test-mode on a file containing compojure routes? |
| 19:40 | technomancy | that's weird |
| 19:40 | hiredman | technomancy: could just be clojure-mode with compilation errors |
| 19:41 | technomancy | hiredman: huh; does nrepl.el emit overlays now? |
| 19:41 | glosoli | hiredman: yeah this one |
| 19:41 | hiredman | glosoli: have you fixed the errors and recompiled? |
| 19:41 | hiredman | technomancy: I dunno |
| 19:41 | hiredman | I never make errors :P |
| 19:42 | `cbp | cough |
| 19:43 | justin_smith | one can walk the face overlays in an emacs buffer, find the offending item, and delete it - it is like a weird emacs parallel version of the dom |
| 19:44 | justin_smith | I forget the details at the moment, but I have done it before |
| 19:44 | justin_smith | of course the facility that generated the overlay *should* provide a way to remove it |
| 19:53 | TakeV | LightTables is still in active development, yes? |
| 19:53 | Raynes | Certainly. |
| 19:54 | sinistersnare | hasnt seen an update in a little while i think |
| 19:54 | sinistersnare | judging from chris grangers blog still being about that cancer and startups thing after a few montsh |
| 19:55 | glosoli | sinistersnare: There was some post in Github from him saying it should be released second week of the current month with no promises |
| 19:55 | sinistersnare | oh cool then! |
| 19:56 | glosoli | Dunno it\s been easier for me to switch to Emacs than waiting for LightTable to improve lol |
| 19:58 | justin_smith | it was a nefarious conspiracy; lighttable was just a decoy to get people using clojure in emacs |
| 20:02 | sinistersnare | ive been using Nightcode! |
| 20:02 | sinistersnare | some random IDE a guy made and released a couple nights ago |
| 20:03 | patchwork | I really think we need some more code editors |
| 20:04 | patchwork | There just aren't enough |
| 20:04 | brehaut | i cannot tell if you are being sarcastic or sincere |
| 20:05 | justin_smith | I've been thinking of running a bunch of different window managers on my virtual terminals, and running a different editor under each window manager, and on each one I would listen to music in a different music player. |
| 20:05 | sinistersnare | i think competition is great |
| 20:06 | patchwork | brehaut: I can't tell either |
| 20:26 | s4muel | i'm curious as to what most people here are using to develop clojure, or is that a long-hackneyed debate here |
| 20:27 | patchwork | s4muel: Emacs |
| 20:27 | plainman | emacs |
| 20:27 | patchwork | But editors are religion |
| 20:27 | jcsims | Emacs + nrepl |
| 20:28 | s4muel | my experience with vim/fireplace etc has been off-putting in comparison to even just the default clojure-mode in emacs (autocompletion, etc) but i am just so used to vim |
| 20:28 | patchwork | There is a vim mode in emacs |
| 20:28 | jcsims | s4muel: I was exactly the same way |
| 20:28 | s4muel | the aptly named evil mode |
| 20:28 | patchwork | So you can use all of your vim bindings from emacs |
| 20:28 | patchwork | I know quite a number of people in your boat, and it seems to work for them |
| 20:28 | cmatheson | is anyone using evil-mode? i tried it out and it seemed great, but i was oncerned about how it interacted with the various minor modes |
| 20:29 | plainman | I started as a vi person, and I probably use it more than emacs, but I found it worthwhile to work at getting the emacs commands down into my fingers rather than try to use the vi mode |
| 20:29 | s4muel | I think part of it is also the repl-development 'ecosystem' as it were |
| 20:30 | s4muel | which is just bonkers with vim |
| 20:31 | juhu_chapa | Hi guys! |
| 20:31 | s4muel | and try as i might i cannot get vim to do two things, and i know emacs does one: i want syntax highlighting for (defn my-symbol-i-want-highlighted-elsewhere [] ()), and doc strings for namespace/method outside of core |
| 20:32 | patchwork | s4muel: Yeah, use emacs |
| 20:32 | patchwork | if you can overcome the blasphemy! |
| 20:32 | sinsnare | How is repl development a thing though? It doesn't get saved anywhere, how does it work? |
| 20:32 | TEttinger | I use Light Table, which has had some issues with evaluating anything longer than a paragraph of code in the instarepl... but otherwise does what I need it to do. |
| 20:33 | justin_smith | sinsnare: there is repl history, and really you should be writing functions in your source, and playing with them in the repl (to experiment with variations, see what they do with various inputs, etc.) |
| 20:33 | s4muel | sinsnare: reloading your code -- the beauty of functional stateless-ness. For example I'm working on a lamina/aleph processing/plexer thing. I reload the namespace, pass in a message, and see what happens. |
| 20:33 | TEttinger | gah you can reload namespaces? I've honestly been using lein repl, quit, lein repl as my workflow D: |
| 20:33 | justin_smith | and yes, redefining everything and seeing what it does next time |
| 20:34 | sinsnare | That's a really interesting thought. Never thought of it like that |
| 20:34 | justin_smith | (require '[foo.bar] :reload) |
| 20:34 | s4muel | some stuff requires state to be set up, example i have to prepare/enqueue dummy messages on a channel, but that's easy with some helpers like expectations run-before |
| 20:34 | patchwork | TEttinger: The greatest part of using clojure |
| 20:34 | patchwork | modify function in source code, send the definition to the running repl, repl now uses updated code |
| 20:34 | sinsnare | I'm fairly new to repl stuff. Ive mostly done python repl as a calculator :p |
| 20:34 | patchwork | Now I can't live without it |
| 20:34 | TEttinger | I knew people were doing it, but I had no idea how |
| 20:35 | sinsnare | So excuse ignorance |
| 20:35 | cespare | TEttinger: any workflow that requires you to run lein commands all the time is no good, it's slow as balls |
| 20:35 | patchwork | Just C-M-x somewhere in the function definition, repl is now using new code |
| 20:35 | s4muel | TEttinger: it gets complex when you have side-effect things like tcp servers that need to be restarted on reload |
| 20:35 | TEttinger | cespare, yeah. I figured that part out myself. |
| 20:35 | patchwork | BAM! |
| 20:36 | sinsnare | that's cool stuff |
| 20:36 | patchwork | s4muel: In that case I have the servers referring to #'function-name (a reference to the var rather than the function itself) |
| 20:36 | TEttinger | the other issue is with my code using Swing, and main needing to be in a UI thread |
| 20:36 | patchwork | Then when I update it, the server is now using my new code |
| 20:38 | s4muel | patchwork: I am also doing that with a multimethod dispatch, cool that you can apply it there! |
| 20:38 | patchwork | Developed webservers that way, irc bots, socket servers etc |
| 20:38 | s4muel | patchwork: I am doing something like this to manage the tcp server from repl https://gist.github.com/shalicke/6246155 |
| 20:39 | abp | http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded |
| 20:39 | s4muel | Seems ghetto now. |
| 20:40 | patchwork | s4muel: Yeah, that is somewhat elaborate, but it works |
| 20:40 | patchwork | Not entirely necessary if you are using nrepl and emacs |
| 20:41 | s4muel | I have (usually) a vim window open, lein autoexpect, and lein repl |
| 20:45 | TEttinger | so... I made a small swing app with clojure, but when I wanted a friend to run it, he didn't have java installed. I thought it was going to be rare, but a fair amount of end-users seem to be avoiding installing a JVM these days... What do you think about clojurescript for an application meant for less-technical users? |
| 20:45 | s4muel | That's another discussion, tdd workflow -- I'm new & landed on expectations / lein-autoexpect, the other camp(s) seem to be Midje or speclj, any thoughts from the peanut gallery? |
| 20:46 | technomancy | clojure.test is great |
| 20:46 | technomancy | expectations seems the least crazy of the options you listed though |
| 20:46 | s4muel | Yeah I needed something that would ... not be too much of a learning curve, really, and automatic |
| 20:47 | s4muel | Midje seems like that camp of almost-bdd where it's a journey to write the tests themselves (think webrat/selenium/argh) |
| 20:47 | technomancy | right; the main advantage of clojure.test is that basic usage involves a total of two macros; advanced usage typically only adds one more |
| 20:48 | callen | Midje is silly and was written by silly people emulating the efforts of nihilists. |
| 20:48 | callen | None of them are to be trusted. |
| 20:48 | s4muel | author of Midje is probably in this channel somewhere. Don't get me wrong, better developers than me use it, I'm just saying it seems like a real commitment :) |
| 20:49 | hiredman | unlikely |
| 20:51 | callen | he's not here. |
| 20:52 | callen | s4muel: very thoughtful of you, but ad hominem is pretty valid when you're relying on their software. Pass. |
| 20:52 | callen | Cf. Rich Hickey vs. Rasmus Lerdorf. |
| 20:52 | s4muel | callen: true. |
| 20:53 | cespare | > ad hominem is pretty valid when you're relying on their software |
| 20:53 | cespare | wat |
| 20:53 | callen | for any that might care, pending testing, I'll probably reverse my position on c.j.j vs. Korma due to the new API. |
| 20:53 | callen | cespare: unless you're willing to audit all of the code, you have to extrapolate from their track record and their judgment. |
| 20:53 | patchwork | callen: The new api for c.j.j or korma? |
| 20:53 | callen | patchwork: the new API for c.j.j |
| 20:53 | cespare | callen: != ad hominem |
| 20:53 | callen | it's greatly improved. |
| 20:54 | patchwork | Ah, haven't heard that |
| 20:54 | patchwork | I'll check it out |
| 20:54 | callen | cespare: it really is. The person that wrote the software can invalidate my willingness to consider the software. |
| 20:54 | patchwork | Yeah korma has not been updated in a while |
| 20:54 | callen | cespare: concordantly, the point of ad hominem is to use the person behind the argument to invalidate the argument. |
| 20:54 | cespare | callen: what you're describing is not an ad hominem argument |
| 20:54 | callen | you are seriously misunderstanding me. |
| 20:54 | patchwork | cespare: Well, callen says so so it must be wrong |
| 20:55 | callen | I am saying ad hominem is a reason to ignore software from certain people. I'm explaining how it's parallel to the use of ad hominem in arguments. |
| 20:55 | callen | Arguments can be evaluated on their merits completely within the context of a single discussion, code typically isn't that easy to box up. |
| 20:55 | s4muel | reputation as code |
| 20:56 | callen | As a result, evaluating the quality of the source becomes a potentially valid and definitely more efficient way to evaluate software from afar. |
| 20:56 | callen | I really do not think it was a very subtle or difficult point to make |
| 20:56 | callen | I figured the Rasmus/Hickey thing would make it obvious. I guess not. |
| 20:56 | callen | going back the original point, anybody who reads the mailing list knows what I'm talking about. |
| 20:59 | patchwork | callen: I missed out on the mailing list discussion. Has midje been discredited? |
| 20:59 | patchwork | I have never used it |
| 21:00 | callen | There are people that use clojure.test because they don't care, people that use midje because they don't care, people that use clojure.test because they "been there, broke that" with testing frameworks like Midje and are duly terrified, and people that use Midje because they forgot to leave the Ruby at the door. |
| 21:01 | callen | it's my personal opinion that syntax/DSL is a matter of "least concern" when it comes to testing and instead automating/managing things like fixtures, functional testing, integration testing is a lot more valuable and "labor saving" |
| 21:01 | patchwork | So midje uses rubyisms? Hmm… I always thought ruby used lispisms. Well, and smalltalkisms |
| 21:01 | patchwork | Ah, so it emphasized DSL over actual functionality |
| 21:01 | patchwork | Got it |
| 21:01 | callen | Ruby is syntactically Perl, semantically a mutable OOP lang, and the Smalltalk has been beaten vicious and put in the closet. |
| 21:02 | callen | but because any jackass of the street can believe themselves to be capable of evaluating the readability of syntax, that's what everybody wants to fuck with when it comes to testing. |
| 21:02 | patchwork | Ha. Poor smalltalk |
| 21:02 | callen | ain't nobody want to do the subtle, more difficult work of making tests more useful or comprehensive. |
| 21:02 | callen | or more interesting things like auto-generating test cases against defined constraints and input spaces. |
| 21:03 | s4muel | That would be very handy for testing channels and inputs. |
| 21:03 | callen | s4muel: google, "haskell quickcheck" |
| 21:03 | patchwork | callen: So is there a clojure testing library that does tackle that? |
| 21:03 | patchwork | Count me as in the "uses clojure.text because they don't care" camp |
| 21:03 | patchwork | *test |
| 21:04 | callen | there are implementations of QuickCheck for Clojure which is a good start. I just use clojure.test and write tooling to wrap the ugly of whatever I'm working on. |
| 21:04 | patchwork | QuickCheck, interesting... |
| 21:04 | callen | I've had to work on algorithms with non-deterministic/unverifiable output once the solution space gets large enough, so I basically had to write a fuzzing library. |
| 21:06 | callen | there's also just typical web apps. Vanilla unit testing is not very well suited to verifying web apps these days. |
| 21:06 | callen | fucking with syntax won't change that. |
| 21:08 | `cbp | callen: hi |
| 21:08 | s4muel | Yes. Although I think the problem lies at a lower level with simply managing side effects of tests and state in regards to that. Serving an http request is nothing special per se, it's the management of the state of the client, dbs, services, etc. that are ugly, IMO |
| 21:08 | `cbp | callen: any more projects i can help with? :-) I need some clojure in my spare time or ill go insane |
| 21:08 | s4muel | s/are/is/ |
| 21:10 | callen | `cbp: I have many. Some hairier than others. |
| 21:10 | callen | `cbp: I'm working on bulwark right now, it's a bit fiddly and early stage though. |
| 21:10 | callen | s4muel: That's a part of the ugly in terms of implementation details, but I feel like the whole problem is waiting for a nice "gift-wrapped" clean-up like Leiningen was for packaging. |
| 21:11 | callen | s4muel: I work on a lot of services/web app type stuff, so half of my shit that can break isn't even technically Clojure code. Being able to sanely test/mock that stuff without a ton of trouble would be nice. |
| 21:17 | callen | `cbp: my todo-list includes: Bulwark (Rack::attack for Clojure), proxy+ with JVM annotation bytecode support, pomegranate "sync with project.clj", clj-time API rewrite, Rewriting Selmer with Instaparse as an experiment, possibly quickcheck for Clojure if the existing impls suck, and selmer leiningen plugin for testing batch compliation and reporting any errors if applicable |
| 21:17 | callen | `cbp: want in on any of that? |
| 21:20 | `cbp | yeah sure |
| 21:20 | callen | `cbp: also fun bit of evil: https://www.refheap.com/17695 |
| 21:21 | callen | `cbp: are you familiar with how proxy works? |
| 21:21 | xeqi | callen: can you expand on pomegranate "sync with project.clj" |
| 21:22 | callen | xeqi: what it says on the tin. Like what Ritz can do. |
| 21:22 | callen | walks up the directory path until it finds a project.clj, checks the dependencies against what's in the classpath as well as the any possibly provided maven repos in the project.clj |
| 21:22 | callen | adds things that need added, removes things that need removed. |
| 21:23 | callen | `cbp: the pomegranate sync with project.clj or proxy+ thing would be good places to start since they're less fiddly than the other options. |
| 21:24 | `cbp | callen: if youre asking me how a proxy server works sure, if proxy is a noun for something else then nope :-P |
| 21:24 | callen | `cbp: hoo boy. You're in for it now. |
| 21:24 | callen | `cbp: http://clojure.org/java_interop#Java%20Interop-Implementing%20Interfaces%20and%20Extending%20Classes-%28%20proxy%20[class-and-interfaces]%20[args]%20fs+%29 |
| 21:25 | `cbp | OH that proxy |
| 21:25 | callen | yeah, it doesn't support annotations. |
| 21:25 | callen | it needs to. |
| 21:25 | callen | so a library form of proxy+ with annotations is what's desired. |
| 21:25 | callen | this is so things like Netty can be properly wrapped. |
| 21:26 | `cbp | oh yeah i get it |
| 21:27 | callen | good news, a test case is easy enough to slap together |
| 21:27 | callen | bad news is, you'll probably end up balls deep in Clojure's Annotation*.java |
| 21:32 | `cbp | so the pomegranate stuff would let people add dependencies without leaving the repl? That sounds nice |
| 21:34 | callen | `cbp: well it already does that, but the idea is to not force them to use pomegranate's somewhat tedious and obviously stateful API |
| 21:34 | callen | and instead just make the workflow "edit project.clj => (pom/sync!)" |
| 21:34 | `cbp | just modify project.clj and come back to the repl? |
| 21:34 | callen | yep! |
| 21:34 | TEttinger | `cbp, I've done it. it's cool. but as I established earlier, I have no idea how to properly use a REPL... |
| 21:35 | callen | I'm tired of restarting my lein repl |
| 21:35 | callen | it's fucking annoying. |
| 21:35 | callen | I lose all my stuff and end up making temp buffers of intermediate state/code for testing in a REPL |
| 21:35 | callen | just so I can restart the REPL for dependencies |
| 21:35 | callen | I could use pomegranate, but I find the API tedious even if it works fine. |
| 21:37 | `cbp | ok i'll se what i can do :-) |
| 21:46 | technomancy | callen: I think maybe the ritz project.clj stuff exists in its own lib? |
| 21:46 | technomancy | alembic or something |
| 21:46 | technomancy | haven't gotten a chance to try it |
| 22:40 | cjfrisz | 500-some people and we're all too shy |
| 22:40 | cjfrisz | Or else everyone else figured out all the secrets of programming, and I'm alone in my ignorance |
| 22:41 | cjfrisz | That is pretty much the scariest world I can imagine |
| 22:45 | cjfrisz | ping dnolen |
| 22:46 | eric_normand | callen: better: https://gist.github.com/ericnormand/6246733 |
| 23:12 | hugod | alembic isn't quite the ritz project.clj stuff, though it does use lein, so it would be straightforward to add support for incrementally reloading the project.clj file. It is only really possible to add dependencies to the classpath though, not change them or remove them. |