2015-01-31
| 00:00 | justin_smith | Mr0rris0: there is a gestalt effect where once you get past a certain threshold it all starts to synergize |
| 00:01 | justin_smith | (yes, I intentionally used ubscurantist phrasing for that :P) |
| 00:01 | rhg135 | really, justin_smith? unperceivable fault in verbiage. |
| 00:02 | Mr0rris0 | cool |
| 00:03 | Mr0rris0 | i put nnscript on here earlier today, looks like it tells you when the day switches over |
| 00:14 | Mr0rris0 | so how far along are you guys into this world/path/skill level |
| 00:16 | ianhedoesit | what do you mean? |
| 00:16 | Mr0rris0 | yeah |
| 00:16 | Mr0rris0 | ... |
| 00:16 | Mr0rris0 | i dunno |
| 00:16 | Mr0rris0 | the more advanced areas |
| 00:17 | Mr0rris0 | its relative i guess |
| 00:17 | Mr0rris0 | ive been on computers nearly all my life but nothing advanced or of much use |
| 00:18 | justin_smith | I'm level 100, still working on my elite suit of armor |
| 00:18 | Mr0rris0 | lol |
| 00:19 | Mr0rris0 | so going by that logic im at level .5 |
| 00:19 | rhg135 | i've been on certain chans where the programmers are lv. 0.001 |
| 00:19 | rhg135 | don't be discouraged |
| 00:19 | Mr0rris0 | yeah of course |
| 00:20 | justin_smith | go grind on some low level 4clojure problems, make a small project, you'll level up fast enough |
| 00:20 | Mr0rris0 | ok |
| 00:20 | rhg135 | clojure makes it easier to level up imo |
| 00:22 | Mr0rris0 | im about 26 been on computers since about 5. its been easy to use them without learning an awefull lot |
| 00:22 | TEttinger | justin_smith is at level... |
| 00:22 | TEttinger | (identity justin_smith) |
| 00:22 | TEttinger | clojurebot? |
| 00:22 | clojurebot | clojurebot has a poetic soul |
| 00:22 | rhg135 | lazybot is... lazy |
| 00:22 | rhg135 | oh |
| 00:22 | rhg135 | wrong bot lol |
| 00:22 | TEttinger | $karma justin_smith |
| 00:22 | TEttinger | right it is lazybot |
| 00:22 | justin_smith | oh wow, lazybot is out |
| 00:22 | TEttinger | and lazybot is missing |
| 00:22 | TEttinger | yep |
| 00:23 | Mr0rris0 | compared to say my grandma or my mom, im an expert but compared to you guys im like them compared to me |
| 00:23 | rhg135 | you'd be surprised |
| 00:23 | justin_smith | TEttinger: oh, were you going to compare karma to experience level? |
| 00:23 | Mr0rris0 | i think you would lol |
| 00:23 | Mr0rris0 | it takes alot to know what you dont know |
| 00:23 | TEttinger | justin_smith, yeah your helpful level is over 9000 |
| 00:23 | rhg135 | i havent written a single line in weeks cuz life |
| 00:24 | justin_smith | TEttinger: the secret is figuring out how to help other people is a great way to get better myself |
| 00:24 | TEttinger | yep! |
| 00:24 | TEttinger | but you have 4x my karma! |
| 00:24 | justin_smith | rhg135: starting around the new year I got super scatterbrained / distracted, had a hard time getting any real programming work done |
| 00:25 | justin_smith | only in the last week or so is the magic juice starting to flow again |
| 00:25 | justin_smith | it's weird how it happens |
| 00:25 | justin_smith | I think it might have been a sleep quality thing... |
| 00:25 | Mr0rris0 | could be |
| 00:25 | rhg135 | it is, justin_smith. but in my case it's completely by choice |
| 00:25 | Mr0rris0 | if the infomercials are correct a lack of sleep causes toxins to build up |
| 00:25 | ianhedoesit | 30.2118 < rhg135> clojure makes it easier to level up imo |
| 00:26 | Mr0rris0 | i saw that once late in the night |
| 00:26 | rhg135 | i'm past the withdrawl i think |
| 00:26 | ianhedoesit | rhg135: I agree. I just started with Clojure in the last couple weeks and it's changed my life. |
| 00:26 | rhg135 | definitely |
| 00:26 | Mr0rris0 | your kidding, thats a testimonial right there |
| 00:26 | Mr0rris0 | :D |
| 00:26 | justin_smith | clojure's design makes many of the right choices a lot easier to make |
| 00:26 | rhg135 | it was 'what am i doing' later |
| 00:26 | Mr0rris0 | ive lost like 20 lbs just reading about clojure |
| 00:27 | justin_smith | haha |
| 00:27 | justin_smith | "and I feel great!" |
| 00:27 | Mr0rris0 | :D |
| 00:27 | rhg135 | I used to write python, part of my code folder disgusts me |
| 00:27 | ianhedoesit | not only do the right choices become easier to make, but complex and difficult problems because much easier to understand, I think. |
| 00:28 | Mr0rris0 | what helped you absorb it so fast ian? |
| 00:28 | Mr0rris0 | knowing other languages already? |
| 00:28 | rhg135 | it's completely natural |
| 00:28 | TEttinger | Maxazax, from the makers of Dexazam |
| 00:28 | ianhedoesit | well I'm not exactly a beginner with computers anyway (around a decade of programming), but Clojure is just so nice. I have a hard time putting it into words |
| 00:28 | TEttinger | I think I might still have the clojure prescription drug name generator |
| 00:29 | rhg135 | it exists? |
| 00:29 | Mr0rris0 | i found a old book in my loft in the barn about Basic the language |
| 00:29 | ianhedoesit | Clojure is exactly the opposite of everything I've done up until now and I feel like I see things clearly now |
| 00:29 | ianhedoesit | (the rain is gone) |
| 00:29 | Mr0rris0 | ever tried about 1000mg of Fukitoll? |
| 00:30 | Mr0rris0 | i cant do more than one |
| 00:30 | Mr0rris0 | but i was a name generator champion back in the day |
| 00:30 | Mr0rris0 | band name is whats popular in someplaces |
| 00:30 | Mr0rris0 | those generators can be funny |
| 00:34 | TEttinger | heh, I'm proud of the heavily obfuscated/compressed cthulhu text generator |
| 00:34 | Mr0rris0 | whats that cthulhu |
| 00:34 | TEttinger | unfortunately it needs lazybot to be effective. |
| 00:34 | TEttinger | (let[a #(apply str(flatten %))r repeatedly p partition N rand-nth n #(a(N(concat(repeat %"")(mapcat p[1 2 3]%&))))v #(n 0"aioeu""iaai")w(fn[](let[b(n 6"!.""""...")s[(n 0"STKNYPKLG""GlThShNyFt""ZvrCth")(r(N[1 2])#(do[(v)(n 9(map str"'-"(r 2 v)))(n 0(concat"lpstnkgx"[(N["h""gl""gr""nd"])(v)])"rlthggghtsltrkkhshng")]))]][b(if(seq b)[" "s][(n 3",")" "(.(a s)toLowerCase)])]))](re-find #"[A-Z].+"(a[(r 500 w)"."]))) |
| 00:35 | TEttinger | since clojurebot won't paste to refheap |
| 00:35 | TEttinger | ,(let[a #(apply str(flatten %))r repeatedly p partition N rand-nth n #(a(N(concat(repeat %"")(mapcat p[1 2 3]%&))))v #(n 0"aioeu""iaai")w(fn[](let[b(n 6"!.""""...")s[(n 0"STKNYPKLG""GlThShNyFt""ZvrCth")(r(N[1 2])#(do[(v)(n 9(map str"'-"(r 2 v)))(n 0(concat"lpstnkgx"[(N["h""gl""gr""nd"])(v)])"rlthggghtsltrkkhshng")]))]][b(if(seq b)[" "s][(n 3",")" "(.(a s)toLowerCase)])]))](re-find #"[A-Z].+"(a[(r 10 w)"."]))) |
| 00:35 | clojurebot | "Thiathiagh... Gek." |
| 00:35 | justin_smith | that's a lot of truncation |
| 00:36 | TEttinger | that's with 10 words generated and starting at the first that meets certain criteria, IIRC |
| 00:38 | TEttinger | https://www.refheap.com/96713 there we go |
| 00:40 | TEttinger | I have a bad scifi alien name generator, in the vein of George Lucas https://www.refheap.com/96714 |
| 00:42 | TEttinger | the one that started it all, a fake greek word generator https://www.refheap.com/96715 |
| 00:43 | ianhedoesit | TEttinger: neat! |
| 00:43 | TEttinger | it's fun stuff |
| 00:43 | ianhedoesit | yeah |
| 00:43 | TEttinger | I also used it for an indie game idea generator |
| 00:44 | TEttinger | output below http://ideone.com/0MG8ED |
| 00:45 | TEttinger | ranging from "sports game where you destroy clothing" to "semi-autobiographical 4x game where you guide travelers through a house of horrors" |
| 00:47 | ianhedoesit | TEttinger: did you post that on reddit at some point? |
| 00:48 | justin_smith | "minimalist interactive-fiction/ball-and-paddle/strategy game where you rescue executives" haha |
| 00:50 | justin_smith | I would totally play "chesslike game where you command puppies" because I like puppies. |
| 00:52 | justin_smith | "gore-drenched dating-sim game where you gamble on Russian roulette" has a remarkable amount of coherency to it as a proposal |
| 00:53 | ianhedoesit | justin_smith: maybe someone will stumble upon those game ideas and implement them with play-clj! |
| 01:01 | krat0sprakhar | hi all, i spent some time working through this awesome tutorial of building a crud app with compojure.. |
| 01:02 | krat0sprakhar | http://www.jarrodctaylor.com/posts/Compojure-Address-Book-Part-1/ |
| 01:02 | krat0sprakhar | is there something like this for clojurescript |
| 01:02 | krat0sprakhar | ? |
| 01:02 | justin_smith | krat0sprakhar: there is a clojurescript todo app example out there |
| 01:02 | justin_smith | krat0sprakhar: I would probably start with figwheel |
| 01:02 | krat0sprakhar | on that blog you mean? |
| 01:03 | justin_smith | http://swannodette.github.io/todomvc/labs/architecture-examples/om/ |
| 01:03 | krat0sprakhar | i don't know react :( |
| 01:03 | krat0sprakhar | i can cljs w/o om right? |
| 01:03 | justin_smith | the tutorial covers it, you don't use react directly |
| 01:04 | justin_smith | you don't need to use om, but that tutorial is a really good one |
| 01:04 | krat0sprakhar | so to use om / reagent dont you need to know react? |
| 01:04 | krat0sprakhar | oh ok |
| 01:04 | justin_smith | https://github.com/swannodette/om/wiki/Basic-Tutorial |
| 01:04 | ianhedoesit | justin_smith: "An indie game where you haunt the world and it's WAY retro." |
| 01:04 | justin_smith | nice |
| 01:05 | krat0sprakhar | justin_smith: to be productive with om / reagent, does know need to learn react? |
| 01:07 | justin_smith | krat0sprakhar: I don't really think so. and om isn't super complex. even if you did need to learn it, react is just a js framework (better designed than many) |
| 01:07 | krat0sprakhar | ohk.. |
| 01:07 | krat0sprakhar | and you mentioned figwheel |
| 01:07 | krat0sprakhar | where does that fit in? |
| 01:08 | justin_smith | yeah, if you were starting a project from scratch, that simplifies a lot of the clojure / clojurescript setup |
| 01:08 | justin_smith | so you can get a browser repl etc. |
| 01:08 | krat0sprakhar | so thats compojure for the backend and om on the frontend? |
| 01:08 | justin_smith | yeah |
| 01:09 | krat0sprakhar | if you dont mind me asking .. how does your dev env look like? |
| 01:09 | krat0sprakhar | emacs? |
| 01:09 | clojurebot | emacs is "it has them, they are tricky to use" |
| 01:10 | justin_smith | krat0sprakhar: I use emacs, with inferior-lisp-mode to embed the repl |
| 01:10 | krat0sprakhar | ah ok.. great... |
| 01:10 | justin_smith | most people prefer cider though, but it has too many moving parts for me |
| 01:10 | Jaood | justin_smith: there is a inferior-clojure-mode |
| 01:11 | justin_smith | Jaood: oh, I had no idea |
| 01:11 | krat0sprakhar | i just connect vim to a running repl |
| 01:11 | justin_smith | krat0sprakhar: with fireplace.vim? |
| 01:11 | Jaood | justin_smith: https://github.com/clojure-emacs/inf-clojure |
| 01:11 | krat0sprakhar | justin_smith: yeah! |
| 01:12 | krat0sprakhar | tim pope is just awesome.. :D |
| 01:12 | justin_smith | Jaood: next time I want to waste time setting up emacs I may try it |
| 01:12 | Jaood | krat0sprakhar: you should read about react on their website if you are going to play with om, at least to understand its concepts and approach to the virtual dom |
| 01:12 | justin_smith | Jaood: the reason I use inferior-lisp is it is super simple and just works |
| 01:12 | krat0sprakhar | Jaood: ah .. thought so.. |
| 01:13 | Jaood | justin_smith: yeah, that its almost like inferior-lisp just a bit more clojureish |
| 01:13 | krat0sprakhar | i saw a few videos on egghead.. and wanted to ask.. if react is V in mvc |
| 01:13 | krat0sprakhar | what are people using for m and c? |
| 01:14 | krat0sprakhar | backbone? |
| 01:14 | clojurebot | backbone is awful |
| 01:14 | krat0sprakhar | lol :D |
| 01:14 | Jaood | justin_smith: you don't need the cider-nrepl dep |
| 01:14 | rhg135 | model's been datascript and c custom for me |
| 01:14 | justin_smith | Jaood: to be honest seeing the author is enough to scare me away from it, but I may try it eventually. |
| 01:15 | krat0sprakhar | justin_smith: haha.. whats wrong with Batsov? |
| 01:15 | krat0sprakhar | rhg135: datascript? whats that |
| 01:16 | rhg135 | krat0sprakhar, an in mem db for cljs |
| 01:16 | justin_smith | he's the guy behind cider. in over a decade using emacs it's only been with cider that I have truly hated using emacs. |
| 01:17 | JustinusIII | cursiveclojure |
| 01:17 | justin_smith | yes, cursive is really good if I could give up my emacs habit :) |
| 01:17 | krat0sprakhar | or, if i could give up my vim bindings :P |
| 01:17 | krat0sprakhar | also nightcode is pretty cool |
| 01:18 | justin_smith | doesn't idea have vi bindings? or are they just not good enough |
| 01:18 | JustinusIII | i think, you can set emacs keybinding in intellij |
| 01:18 | justin_smith | JustinusIII: I don't use emacs keybindings, I use evil mode inside emacs. I use emacs for the features not the UI. |
| 01:20 | krat0sprakhar | JustinusIII: any good tutorial for cursive.. i have some free time this weekend.. will try setting it up.. :D |
| 01:20 | cfleming | krat0sprakhar: Try IdeaVim for IntelliJ, it's not perfect but it's meant to be pretty good. |
| 01:21 | cfleming | krat0sprakhar: It has some problems with the Cursive REPL editor unfortunately. |
| 01:21 | krat0sprakhar | cfleming: thanks, will give that a shot |
| 01:21 | Jaood | I would say lein repl is good enough and just use whatever editor you like |
| 01:21 | cfleming | krat0sprakhar: There aren't a lot of good tutorials, but the doc is reasonable: https://cursiveclojure.com/userguide/ |
| 01:21 | cfleming | krat0sprakhar: Ping me here or by email if you have questions |
| 01:22 | Jaood | lein repl with tmux actually :) |
| 01:23 | krat0sprakhar | cfleming: Oh, didnt realize you are Colin Fleming! I've seen your talk.. really liked it! :D |
| 01:24 | cfleming | krat0sprakhar: Thanks! Glad you liked it. |
| 01:25 | cfleming | krat0sprakhar: tbaldridge also has some videos on getting started with Cursive here: https://tbaldridge.pivotshare.com/search/cursive/videos |
| 01:25 | tomjack | cursive is the only reason I have any hope that I may be able to use clojure in production before my next job |
| 01:25 | Jaood | if Hickey could get away with just the 'jave -cp clojure.jar clojure.main' repl at the beginning then we should too :P |
| 01:26 | cfleming | tomjack: How's that? |
| 01:27 | krat0sprakhar | cfleming: thanks for the link.. seems like a lot of great videos at a reasonable price |
| 01:27 | tomjack | if I'm trying to convince a coworker to try clojure and cursive doesn't exist, what am I supposed to say? |
| 01:27 | tomjack | "use sublime and `lein repl`?" |
| 01:28 | cfleming | krat0sprakhar: Yeah, definitely. The first Cursive one is free though. |
| 01:28 | tomjack | "learn emacs"? "light table"? |
| 01:28 | krat0sprakhar | tomjack: yeah.. what so bad in that? |
| 01:28 | cfleming | tomjack: Yeah - I'm hopeful Cursive will help drive Clojure adoption. |
| 01:28 | Jaood | cfleming: are you going to release a paid version this year? |
| 01:28 | tomjack | "install cursive" is the only answer I can give with a straight face |
| 01:28 | justin_smith | tomjack: ed, and java -cp clojure.jar clojure.main |
| 01:28 | tomjack | :) |
| 01:29 | cfleming | justin_smith: Just poke the bytes in, man |
| 01:29 | justin_smith | I am gonna make ed.clj |
| 01:29 | cfleming | Jaood: Yes, I am |
| 01:29 | justin_smith | so you don't need to leave the repl |
| 01:30 | tomjack | cfleming: huh, do you make cursive? if so, thank you :) |
| 01:30 | cfleming | tomjack: I do indeed - you're welcome! |
| 01:31 | Jaood | cfleming: does cursive supports connecting to a remote repl? |
| 01:31 | cfleming | Jaood: Yep |
| 01:32 | cfleming | Jaood: https://cursiveclojure.com/userguide/repl.html |
| 01:32 | tomjack | do you get locals printed inline in the code with 14? |
| 01:32 | cfleming | tomjack: Sadly, no, although I'm working on the debugger right now. Expression eval finally works, though, which is awesome. |
| 01:32 | tomjack | I just upgraded to 14 and installed cursive, but don't have it set up (working on a java project with .edn) |
| 01:33 | cfleming | tomjack: At least with Clojure, you do with Java obviously |
| 01:33 | tomjack | right |
| 01:33 | Jaood | cfleming: nice, are going to support boot or wait for the hype to settle and see if it catchs on? |
| 01:33 | cfleming | tomjack: Unfortunately to do that in Clojure means macroexpanding everything |
| 01:34 | cfleming | Jaood: I'm definitely planning support, hopefully soon - I'd like to use it to build Cursive itself. |
| 01:34 | tomjack | I'll make a quixotic attempt to have a few or more buyers lined up when it's for sale |
| 01:34 | tomjack | ah |
| 01:34 | cfleming | tomjack: That sounds like a fine objective to me :) |
| 01:34 | tomjack | I haven't actually tried riddley yet, but my hope is that it makes that kind of thing feasible |
| 01:35 | cfleming | tomjack: Cursive's new macroexpander is actually a hacked around riddley |
| 01:35 | tomjack | hacked around, as in you hacked around it? |
| 01:36 | cfleming | tomjack: Whether or not I can get that inline painting working for debugging, I can definitely use it for LightTable-style inline REPL eval |
| 01:36 | cfleming | tomjack: Yeah https://github.com/cursiveclojure/riddley/blob/master/src/cursive/riddley.clj#L182-L249 |
| 01:37 | cfleming | tomjack: The Cursive macroexpander is actually pretty nice now - you can expand interactively but it still properly respects &env |
| 01:38 | tomjack | I didn't know there was a macroexpander. cool |
| 01:38 | jonathanj | is there a more idiomatic way of writing: (or (:a {:a nil}) 42) |
| 01:38 | cfleming | tomjack: It's new as of a couple of weeks ago |
| 01:38 | Jaood | cfleming: do you know if Hickey has tried cursive? :) |
| 01:38 | cfleming | tomjack: No doc yet, sadly, but should hopefully be fairly intuitive |
| 01:38 | justin_smith | jonathanj: not if {:a nil} is an expected possible value |
| 01:39 | tomjack | jonathanj: no |
| 01:39 | justin_smith | otherwise there is (:a {:b 1} 42) |
| 01:39 | cfleming | Jaood: Yeah, he's slowly moving over to it |
| 01:39 | cfleming | Jaood: Once I have a non-nREPL REPL he'll be on it full time |
| 01:39 | tomjack | hah |
| 01:40 | cfleming | Jaood: Stuart Halloway is using it too |
| 01:40 | tomjack | what are some reasons someone might want a non-nREPL REPL? |
| 01:40 | Jaood | cfleming: that's pretty awesome |
| 01:41 | cfleming | tomjack: https://gist.github.com/levand/b1012bb7bdb5fcc6486f |
| 01:41 | cfleming | (Luke Vanderhart also uses Cursive, and is bugging me for a non-nREPL REPL) |
| 01:41 | cfleming | tomjack: Reduced complexity, basically - middleware is a bit of a nightmare |
| 01:43 | tomjack | now that I think about it, a lot of stuff about cider drives me nuts |
| 01:44 | tomjack | e.g. error buffers as in the gist |
| 01:46 | cfleming | tomjack: https://gist.github.com/cursiveclojure/593ee7421e765d1b0dba (from the 0.1.44 release email) |
| 01:46 | Jaood | cfleming: why did you support nrepl first instead of just clojure.repl? or you building some repl from scratch? |
| 01:53 | cfleming | Jaood: actually, initially I had a clojure.repl REPL, but then I migrated to nREPL because basically everyone uses it, and it's easier to develop against. |
| 01:53 | Jaood | yeah, I can see how its easier for IDE integration |
| 01:57 | cfleming | No doubt |
| 01:57 | cfleming | Still, a surprising number of people don't like the complexity and are moving back |
| 01:59 | krat0sprakhar | cfleming: how can i see inline doc and source |
| 01:59 | krat0sprakhar | in cursive? |
| 02:00 | cfleming | krat0sprakhar: https://cursiveclojure.com/userguide/documentation.html |
| 02:01 | JustinusIII | krat0sprakhar: If you have used IntelliJ, Ctrl + Alt + A will do the magic for all actions |
| 02:02 | krat0sprakhar | you mean cmd + shift + A? |
| 02:02 | krat0sprakhar | thanks cfleming |
| 02:02 | JustinusIII | yes, shift |
| 02:02 | cfleming | krat0sprakhar: On OSX, yeah |
| 02:03 | tomjack | hmm, macroexpansion doesn't seem to work for me |
| 02:04 | tomjack | but, I'm still using emacs for clojure. I'll check it out more another day |
| 02:04 | cfleming | tomjack: You need a REPL running, and you need the current namespace loaded into the REPL |
| 02:05 | tomjack | yes, got that |
| 02:05 | cfleming | tomjack: Do you get an error or something? |
| 02:06 | tomjack | https://www.refheap.com/657f9d68355dc3c0d0f024fa8 |
| 02:06 | tomjack | that was when I tried inside the ns's file |
| 02:07 | tomjack | I don't seem to get an error when trying inside the repl prompt |
| 02:07 | cfleming | tomjack: Interesting, thanks - I saw that once or twice but thought I had fixed it. |
| 02:07 | cfleming | I think you'll have to do it from the ns's file |
| 02:07 | cfleming | And you have the editor focused when doing this? |
| 02:08 | cfleming | Which platform are you on? |
| 02:08 | tomjack | ah |
| 02:08 | tomjack | when I used the menu bar, it worked |
| 02:08 | cfleming | tomjack: Weird |
| 02:08 | tomjack | but with, uh, that command which lets you type whatever, I got the error |
| 02:08 | tomjack | I'm on ubuntu using xmonad |
| 02:08 | tomjack | which does make intellij generally unhappy |
| 02:09 | cfleming | tomjack: Interesting, I wonder if in that case the command popup still has the focus - I should be able to reproduce that, thanks. |
| 02:09 | cfleming | tomjack: Normally you'd have that bound to a key and run it from within the editor - that should work, as will the menu |
| 02:10 | cfleming | tomjack: I'm planning to highlight the form you just expanded too, since it can be a little confusing to see what happened |
| 02:11 | tomjack | hmm |
| 02:12 | tomjack | this is when I try to step forward https://www.refheap.com/aaa4a8bc0c1ab0cbe67da84a8 |
| 02:12 | tomjack | yeah, bound a key |
| 02:13 | tomjack | hmm, but only on my macro |
| 02:13 | cfleming | tomjack: Hmm, do you have the caret within the macro form, or after it? |
| 02:14 | tomjack | also, https://www.refheap.com/2161643929b2c26a5ce4701fb |
| 02:14 | tomjack | ("error during macroexpansion") |
| 02:14 | tomjack | not sure if that's you or me, but my form works when eval'd |
| 02:14 | tomjack | s/during/performing/ |
| 02:15 | cfleming | tomjack: Oh, it'll be me - not sure what's going on there, though |
| 02:15 | tomjack | (the form expands to a keyword) |
| 02:15 | cfleming | Can you check the log (Help->Show log in <whatever it is on Linux>) and paste the full stacktrace? |
| 02:15 | cfleming | tomjack: Ah, interesting - I didn't know you could do that. |
| 02:16 | cfleming | tomjack: That'll be the problem, then - the expander adds metadata to all the forms it expands so I know what it did. |
| 02:17 | cfleming | ,(do (defmacro x [] :test) (x)) |
| 02:17 | clojurebot | :test |
| 02:17 | cfleming | Ok, I'll fix that |
| 02:17 | tomjack | can do, lemme try to figure out where to start |
| 02:17 | tomjack | do I need to worry about sensitive content in the logs? :/ |
| 02:18 | cfleming | tomjack: No worries, I can reproduce now that I know the macro expands to a keyword - that's definitely the problem. |
| 02:18 | tomjack | I haven't gotten it to expand my macro yet, even when it doesn't expand to a keyword |
| 02:18 | cfleming | Can you expand a defn or something like that? |
| 02:18 | tomjack | one thing is that sometimes the forms I pass to my macro contain non-standard usages of ~ |
| 02:18 | tomjack | yeah, core stuff has worked |
| 02:18 | tomjack | (and it's really cool, btw) |
| 02:19 | cfleming | Thanks - I think it'll be good once the kinks are worked out |
| 02:19 | cfleming | I'd expected more feedback on it, but I haven't heard anything |
| 02:19 | cfleming | So this is really helpful, thanks |
| 02:20 | cfleming | So on your macro, you always get that NPE? |
| 02:21 | tomjack | segment of idea.log https://www.refheap.com/6734006ed9455289a5819d595 |
| 02:21 | cfleming | Actually, looking at the code, I have a few places where I assume that the expansion is a list |
| 02:21 | tomjack | ah |
| 02:21 | tomjack | for me it's always either a keyword or a vector |
| 02:21 | tomjack | keyword threw the metadata problem, vector seems to do nothing I guess |
| 02:21 | cfleming | tomjack: That would explain it - I'll fix that for the next build |
| 02:22 | tomjack | nice, luckily I picked a strange macro :) |
| 02:22 | tomjack | (or unluckily) |
| 02:22 | cfleming | Heh, no doubt |
| 02:23 | cfleming | Yeah, this was actually really hard to do well. It's amazingly tricky to correctly correlate elements in the editor with elements in the expansion |
| 02:23 | cfleming | All those NPEs I see in your log will be the non-list problem, I think |
| 02:24 | cfleming | Two different incarnations of it |
| 02:29 | cfleming | tomjack: Ok, I think I can fix that reasonably easily - hopefully I'll get that fix in the next drop. Thanks for all the help! |
| 02:29 | tomjack | random feature request: tidy qualified keywords. sorry, now I'll stop. |
| 02:29 | tomjack | but relatedly, I once made a patch to EdnReader which provided a way to configure substitutions for keyword namespaces while reading |
| 02:30 | tomjack | my eventual tentative conclusion was that the problem of bearable well-qualified Named things should be solved by the tools, not the reader |
| 02:32 | tomjack | 'namespace folding' I guess |
| 02:35 | cfleming | tomjack: Yeah, that should be easy - I already do it for symbols |
| 02:36 | cfleming | tomjack: Cursive already automatically shortens keywords in the actual editor when completing, renaming and so forth |
| 02:38 | cfleming | tomjack: And don't stop, feature requests are always good |
| 02:38 | tomjack | hmm, I just want it in edn as well |
| 02:38 | cfleming | How would that work? |
| 02:38 | tomjack | unclear :) |
| 02:38 | tomjack | would need some config I guess |
| 02:39 | cfleming | I mean, how can you have macros in EDN? |
| 02:39 | tomjack | I mean, I want to use well-qualified keywords (and reader literals, maybe symbols) in .edn files |
| 02:39 | tomjack | but not have my eyes bleed |
| 02:40 | tomjack | not sure how to make that happen, but I vaguely suspect it should be in the editor |
| 02:40 | cfleming | tomjack: Ah, sorry, I thought we were still talking about macros - I see. I can easily code-fold them in Cursive. |
| 02:41 | cfleming | But I'd have to know which prefixes to fold. |
| 02:41 | tomjack | I hadn't realized qualified keywords complete in .clj, though, that is pretty sweet |
| 02:41 | tomjack | yeah |
| 02:42 | cfleming | You can find usages on keywords, too - try Ctrl-Alt-F7 on a keyword |
| 02:43 | cfleming | That finds usages of the keyword anywhere in your project, and also local bindings destructured from then using :keys |
| 02:44 | cfleming | You can rename keywords too, which will also rename destructured bindings |
| 02:45 | cfleming | So for EDN, would you want to configure the prefixes per file, or per project? |
| 02:45 | tomjack | yeah, I dunno |
| 02:45 | tomjack | it's tricky |
| 02:45 | cfleming | I could automatically take them from prefixes you've used in code, as long as they're consistent |
| 02:45 | tomjack | should the config go in the editor too? or might we adopt a convention which describes aliases in the edn itself? |
| 02:46 | cfleming | Sure, if there's a convention I can use it. |
| 02:46 | cfleming | One gotcha with code folding is that it will mess up your formatting in some cases |
| 02:46 | cfleming | Since formatting doesn't take the foldings into account |
| 02:46 | tomjack | (describing aliases in the edn seems tricky because edn (rough Rich quote) "has object-at-a-time, not document, semantics") |
| 02:47 | cfleming | Well, have a think about how you'd like it to work and let me know, it seems like a generally useful feature |
| 02:48 | tomjack | it's been a recurring thought for quite some time, unlikely to find a satisfying answer |
| 02:49 | tomjack | (the feature request was just keywords inside macroexpansion, which seems more straightforward design-wise) |
| 02:50 | cfleming | Yeah, that one's trivial |
| 02:53 | tomjack | I guess the most satisfying answer right now is "put your edn in .clj files" |
| 02:53 | tomjack | ..and then you're stuck with data_readers.clj. humm |
| 02:54 | cfleming | Yeah, and Cursive will try to interpret your EDN as code, which will drive you bonkers |
| 02:55 | cfleming | But I'm assuming that per-file, you would want a consistent mapping of namespaces to prefixes, right? |
| 02:55 | tomjack | (well, it would sortof be code, I mean like this: https://github.com/Datomic/codeq/blob/master/src/datomic/codeq/core.clj#L22 ) |
| 02:57 | cfleming | So there, you'd want e.g. :db.cardinality/one displayed as ::card/one? |
| 02:58 | tomjack | well, I don't know even that |
| 02:59 | cfleming | That makes fulfilling your desires a little tricky :) |
| 03:00 | cfleming | It's tough, I actually have a similar problem at the moment - I need to get some declarations from code out into EDN |
| 03:00 | tomjack | yes, I meant to stick a paragraph break between cursive and "how to use reverse-DNS without going insane" |
| 03:02 | cfleming | And currently it's fairly eye-bleeding. I'm considering having an :impl-ns some.long.ns and :aliases [[some.other.ns :as ns1] [yet.another.ns :as ns2]], and then interpreting that myself after reading the EDN in |
| 03:02 | tomjack | then what goes in the EDN with that out-of-band bit in place? |
| 03:03 | tomjack | :ns2/foo |
| 03:03 | tomjack | ? |
| 03:03 | cfleming | Yeah - they're symbols in my case, so foo -> some.long.ns/foo and ns1/bar -> some.other.ns/bar |
| 03:04 | tomjack | the only problem I have with that approach (besides the cost of walking the data an extra time, which probably won't often matter) is that it won't necessarily work inside arbitrary reader literals |
| 03:04 | tomjack | but then I'm not even really sure if that's a problem |
| 03:05 | tomjack | motivating examples include datomic's db/id and db/fn |
| 03:05 | cfleming | Yeah, fortunately in my case the data is a) broken up into small bits, so I'll just read the whole file in and work on it in memory, and b) is reasonably simple, i.e. I have no need of reader literals |
| 03:07 | cfleming | This is a mini-IoC container for Cursive extensions |
| 03:09 | tomjack | extensions as in user supplied clj code? |
| 03:12 | cfleming | Yeah |
| 03:12 | tomjack | I was wondering about that today, glad to hear it's planned |
| 03:13 | cfleming | I'm gradually working towards that, at first so that users can support symbol resolution for macros in libs they develop or use, and then later for more things |
| 03:13 | tomjack | huh |
| 03:13 | tomjack | I have been wondering how I to approach a dev env for a toy language |
| 03:14 | tomjack | someday, maybe, as editor extensions, with the toy language code directly in the clj |
| 03:16 | cfleming | I actually have users who are interested in adding support to Cursive for internal DSLs, so that they can then ship Cursive to their users to edit the DSL |
| 03:16 | cfleming | For financial modelling |
| 03:16 | tomjack | I'd also wondered if someday I may be able to spawn custom repls, in the same spirit as cljs stuff |
| 03:16 | tomjack | ah, interesting |
| 03:17 | cfleming | Custom REPLs is trickier, I'm actually about to abstract my REPL code to support more REPL types, not sure if/when I'd expose that to users though |
| 03:17 | tomjack | I know a financial modeller who'd be very interested to hear that |
| 03:17 | tomjack | though they use emacs |
| 03:17 | cfleming | Something like Pixie would be a good usecase for it though |
| 03:18 | Mr0rris0 | why |
| 03:18 | tomjack | hadn't seen pixie |
| 03:18 | cfleming | tomjack: Get him to drop me a mail if he's interested |
| 03:19 | cfleming | Plenty of people have come over to Cursive from Emacs, although a lot of people still use both I think, depending on what they're doing |
| 03:20 | tomjack | "hint to the JIT that certain values are constants, that certain functions are pure, etc. This can all be done from inside RPython..." |
| 03:21 | Mr0rris0 | someday im gonna understand all of this i swear to god almighty |
| 03:21 | tomjack | why should we have to hint? pixie + purity seems interesting |
| 03:23 | cfleming | tomjack: IIRC there's a monad-style effects control system being considered |
| 03:24 | tomjack | inspired by eclj? |
| 03:24 | tomjack | (which I really hope there will be a talk about) |
| 03:25 | tomjack | (because I don't understand it at all) |
| 03:26 | cfleming | Yeah, I haven't spent the time trying to understand that yet |
| 03:27 | tomjack | I wish the link wasn't to oleg, I never understand oleg |
| 03:29 | cfleming | Yeah, there's no-one like him to make you feel dumb |
| 03:41 | blockzombie | I'm trying to use zippers with xml. using clojure.xml and clojure.zip seems to work but I thought I could make nice path query style forms... is this an external lib? clojure.data.xml ? |
| 03:41 | blockzombie | (-> z zip/right zip/right zip/node) etc. works well |
| 03:42 | blockzombie | but I want (-> z :tagname :tagname ...) |
| 08:16 | imanc | if I add (:gen-class) to an (ns) and an associated :main myproj.core in the project.clj I get: $ lein run |
| 08:16 | imanc | Exception in thread "main" java.lang.RuntimeException: No such var: clojure.core |
| 08:16 | imanc | any ideas why? |
| 08:18 | imanc | oh wow, newb error! |
| 08:22 | sashton_ | is there a way to find out how many items are in an async chan? I'm trying to add some monitoring to my app, and would like to know the progress of some work. |
| 08:22 | sashton_ | or is there a better way? |
| 08:45 | luxbock | I'd like to be able to evaluate local bindings in my editor inside a let-form when I code |
| 08:47 | luxbock | so my plan is to create a function that takes a quoted Clojure let-form as its argument, extracts the bindings, runs it through clojure.core/destructuring, and then separate the gensym'd locals from the local bindings I'm after |
| 08:51 | luxbock | then eval the gensym'd symbol->value pairs, and replace each occurance of a gensym'd symbols inside the local-bindings of the destructuring result |
| 08:53 | luxbock | actually I'm not sure if this makes a lot of sense to even myself yet |
| 09:04 | Mr0rris0 | sounds interesting lux |
| 09:04 | Mr0rris0 | your ahead of me atleast, im not sure what any of that is yet |
| 09:04 | hellofunk | luxbock: i don't think you can count the number of pending items on a channel, but you could of course update a count every time your put! and decrement the count every time you take! |
| 09:05 | luxbock | hellofunk: hmm? I'm not using channels/core.async at all |
| 09:05 | hellofunk | luxbock: i'm sorry i meant that reply for sashton_ |
| 09:05 | justin_smith | sashton_: not unless you make your own custom chan impl |
| 09:05 | luxbock | ah |
| 09:06 | luxbock | I want to be able to do two things actually |
| 09:06 | justin_smith | sashton_: that is, you would need a custom chan impl for querying the count of the chan |
| 09:07 | luxbock | take a let-form, and simplify so that all the value-side of the expressions are evaluated, and return that |
| 09:07 | luxbock | so that I can do that inside my editor to see what each local-binding is evaluating to |
| 09:07 | hellofunk | luxbock: what editor are you using? |
| 09:07 | luxbock | Emacs |
| 09:08 | hellofunk | luxbock: doesn't the emacs tool for evalue the form at point do what you need? it's a part of cider, but of course you'd have to be using cider to use it |
| 09:08 | luxbock | sending code from Emacs to Clojure and back is easy enough with cider |
| 09:08 | hellofunk | *evaluate |
| 09:09 | luxbock | hellofunk: that would get me the evaluation result for the body of the let-form |
| 09:09 | justin_smith | hellofunk: there's form at point, but not for getting an arbitrary value of a local |
| 09:10 | hellofunk | hm, i'm confused. can't you evaluate any form, not just a top-level let, but anything with cider? i think i can. I can type (let [x (+ 1 1)]..) and just see the evaluation of 1 + 1 if I want |
| 09:11 | justin_smith | hellofunk: in (let [a 0 b (inc a) c (+ b b)]) can you get the value of c? |
| 09:11 | hellofunk | i was just thinking that after i typed it. i haven't tried. perhaps i should this moment |
| 09:12 | luxbock | I'm toying around with ideas for trying to reduce the REPL-based feedback loop of writing code -> seeing results even further |
| 09:14 | luxbock | I already have a function that expands a function-call with the body of the function getting called, which I find amazingly useful when you can use that in-place in my editor |
| 09:14 | hellofunk | i see what you are after now and no you can't do what justin_smith proposed with cider. interestingly, this seems like a frightening feature: Invoke clojure.walk/macroexpand-all on the form at point and display the result in a macroexpansion buffer. |
| 09:15 | luxbock | I think if I can combine this with the let-related stuff I was talking about then it'd be incredibly powerful |
| 09:15 | hellofunk | lol when i first read that i thought it said display the macroexpand-all in the mini-buffer! lol |
| 09:15 | lodin | luxbock: I've been sketching on the same thing. |
| 09:15 | hellofunk | that would be one heck of a mini buffer output |
| 09:15 | luxbock | lodin: cool, do you have anything out there yet? |
| 09:15 | hellofunk | luxbock: what you describe sounds like how the light table tools work |
| 09:15 | lodin | luxbock: Nope. |
| 09:16 | luxbock | hellofunk: I think expanding in-place is much better since then you can manipulate that code even further |
| 09:16 | luxbock | hellofunk: with these ideas my work flow is transitioning from the REPL to the *cider-scratch* buffer |
| 09:17 | hellofunk | luxbock: i've never seen a cider-scratch buffer before |
| 09:18 | luxbock | I end up with tons of code in there, which helps me think about the problem further |
| 09:18 | luxbock | the Clojure compiler in my head is not strong enough where I could just lie in my hammock and solve problems like Rich Hickey :) |
| 09:19 | luxbock | *cider-scratch* is basically just a dummy Clojure-buffer that evaluates to the currently active ns |
| 09:19 | luxbock | it has some extra features as well but I don't use those much, so it's much the same as just creating your own dummy-buffer |
| 09:21 | Glenjamin | has anyone used https://github.com/chlorinejs/chlorine ? |
| 09:24 | sashton_ | hellofunk: yeah, a thought i had was to inc and dec an agent if there wasn't a built-in way to get the pending count |
| 09:24 | hellofunk | luxbock: i'm pretty sure the hammock idea is about having NO compiler in front of you, and no computer for that matter |
| 09:25 | hellofunk | if you are properly practising the Hammock, then to others you should appear to be asleep, in Rich's words. |
| 09:27 | hellofunk | man i think i'm asleep, talking about sleep. luxbock just saw your clause "in my head" |
| 09:41 | matt` | I'm trying to do a running total, but it doesn't seem to be totalling :D Can anyone spot my doofus mistake? http://pastebin.com/BPB6U3T2 |
| 09:42 | justin_smith | matt`: dotimes is calculating things that do not change total |
| 09:42 | justin_smith | (+ total x) does not increase total |
| 09:42 | justin_smith | it just calculates an addition (that dotimes then throws away) |
| 09:42 | matt` | Bugger |
| 09:43 | justin_smith | matt`: I think you want (apply + (repeatedly number-of-rolls #(die-roll sides))) |
| 09:43 | justin_smith | that does some number of die rolls, and adds them all up |
| 09:43 | matt` | :-O |
| 09:44 | matt` | Wow thanks, I'm off to look up 'repeatedly' too, I came across that on clojuredocs but it didn't seem appropriate |
| 09:45 | matt` | Thanks again for your help |
| 09:45 | justin_smith | np |
| 09:47 | matt` | That worked btw justin_smith |
| 09:48 | justin_smith | oh, good |
| 09:52 | Glenjamin | anyone got a favourite hickey talk which isn't on this list? http://thechangelog.com/rich-hickeys-greatest-hits/ |
| 09:58 | matt` | Is a # in front of a function a way to access the object instad of the returned value that the object would produce? |
| 10:00 | fairuz | matt`: do you mean something like #(...) ? |
| 10:01 | matt` | yes, that's right |
| 10:01 | justin_smith | matt`: #() is a shortcut for fn |
| 10:01 | fairuz | it's the same thing as (fn [args] ...) |
| 10:01 | justin_smith | ,'#(+ % %) |
| 10:01 | clojurebot | (fn* [p1__25#] (+ p1__25# p1__25#)) |
| 10:01 | lodin | matt: #(...) is a function, it's sugar for (fn [] ...) in this case. |
| 10:02 | matt` | that's great, thanks, just trying to get my head around it |
| 10:02 | justin_smith | matt`: do you know how (fn [] ...) is used? |
| 10:03 | lodin | matt: You could also write (map die-roll (repeat sides)) to get an infinite list of die-rolls. Then you use (take) to get the number of rolls you want. |
| 10:03 | matt` | justin_smith: It's an anonymous (lambda) function right? |
| 10:04 | justin_smith | yes |
| 10:04 | justin_smith | like defn but without creating a global definition |
| 10:04 | matt` | I take it an infinite amount of rolls like that wouldn't run the function infinitely? |
| 10:04 | justin_smith | matt`: no, because of laziness |
| 10:05 | matt` | I've heard that term quite a few times now - it's lazy because it doesn't acutally do it until it's required? |
| 10:05 | justin_smith | ,(apply + (take 3 (map #(inc (rand-int %)) (repeat 6)))) |
| 10:05 | clojurebot | 10 |
| 10:05 | justin_smith | ,(apply + (map #(inc (rand-int %)) (repeat 3 6)))) |
| 10:05 | clojurebot | 8 |
| 10:06 | lodin | ,(take 3 (repeat 6)) |
| 10:06 | clojurebot | (6 6 6) |
| 10:06 | lodin | Oops. |
| 10:06 | lodin | :-) |
| 10:06 | justin_smith | ,(repeat 3 6) |
| 10:06 | clojurebot | (6 6 6) |
| 10:06 | lodin | justin_smith: Just showing the concept. |
| 10:06 | justin_smith | ,(apply + (repeatedly 3 #(inc (rand-int 6)))) |
| 10:06 | clojurebot | 8 |
| 10:06 | justin_smith | right |
| 10:07 | justin_smith | wow, terrible rolls! |
| 10:07 | justin_smith | this would be like the worst d&d character ever |
| 10:07 | matt` | I'm having a little trouble tbh, I come from C - I can see the awesome power of functional programming but it's pretty alien to me |
| 10:07 | justin_smith | ,(reduce + (repeatedly 3 #(inc (rand-int 6)))) |
| 10:07 | clojurebot | 13 |
| 10:07 | matt` | Lol! That's what this is for |
| 10:07 | matt` | Kinda |
| 10:07 | matt` | I'm writing some functions to help me run a dungeonworld game |
| 10:08 | justin_smith | here's 4d6, drop the lowest: |
| 10:08 | justin_smith | ,(reduce + (rest (sort (repeatedly 3 #(inc (rand-int 6)))))) |
| 10:08 | clojurebot | 9 |
| 10:08 | justin_smith | oh wait |
| 10:08 | matt` | I did one of those in lisp, I'll post my code |
| 10:08 | justin_smith | ,(reduce + (rest (sort (repeatedly 4 #(inc (rand-int 6)))))) |
| 10:08 | clojurebot | 13 |
| 10:09 | matt` | (defun stat () |
| 10:09 | matt` | ;; Generate 4 d6 results, discard the lowest |
| 10:09 | matt` | (apply #'+ (rest (sort (list (d 6) (d 6) (d 6) (d 6)) #'<)))) |
| 10:09 | lodin | matt: Use let binding generously and it becomes easier to grasp. |
| 10:09 | matt` | Tnx lodin |
| 10:09 | justin_smith | matt`: that is like literally the code for the last thing I printed |
| 10:09 | justin_smith | if d is inc rand-int |
| 10:10 | matt` | Hah, maybe I am getting functional programming after all :) |
| 10:10 | justin_smith | matt`: the only real difference is that you literally spell out every call to d, and I use repeatedly to specify how many times it is done |
| 10:12 | matt` | I'm going through your code examples, Clojure can be elegant |
| 10:13 | lodin | matt: Also, as soon as possible, understand how to use (-> ...) and (->> ...). |
| 10:16 | justin_smith | ,(->> #(inc (rand-int 6)) (repeatedly 4) rest (apply +)) |
| 10:16 | clojurebot | 8 |
| 10:17 | lodin | It's nicer when it's aligned vertically. :-) |
| 10:18 | matt` | lodin: I've been looking at ->, isn't it just for readability? |
| 10:18 | justin_smith | matt`: -> / ->> make some code much clearer, yes |
| 10:18 | lodin | matt: Sure. |
| 10:18 | justin_smith | and make certain errors much less likely |
| 10:19 | lodin | matt: But it's a good alternative to using let bindings where you just repeat the name on the next line. |
| 10:19 | matt` | Right. Gotcha. |
| 10:19 | matt` | Much tidier |
| 10:21 | lodin | I particularly like (-> ...) over nesting the functions since the name and the rest of the arguments don't get spread apart (in contrast to (->> ...)). |
| 10:22 | justin_smith | lodin: ->> works with collection functions, -> works for functions on associatives |
| 10:22 | matt` | I've heard nesting functions is frowned upon, I can see why. |
| 10:26 | lodin | justin_smith: -> would be more useful with reduce if three argument reduce took the initial value first. Coincidentally, usually have a reduce' that does just that. :-) |
| 10:26 | justin_smith | lodin: it's intentional that functions on collections all take the collection as the last arg |
| 10:27 | lodin | justin_smith: reduce works well with ->>, but not ->. I'm only talking about the initial value (which sometimes is associative). |
| 10:31 | Glenjamin | reduce is fairly low level, if i was doing a reduce within a threading form i think i'd extract into a named function |
| 10:37 | lodin | Glenjamin: The same would probably apply for map. |
| 10:37 | Glenjamin | map is generally a bit higher level than reduce |
| 10:37 | Glenjamin | it depends what you're doing i guess |
| 10:37 | Glenjamin | (reduce +) is pretty straightforward |
| 10:38 | lodin | Glenjamin: Yeah. In my use cases it's more like map. I have a set of stuff I want to reduce into another object through a function, and you'd just end up creating plural versions of the function. |
| 10:38 | lodin | Like map would be move into a plural version. |
| 10:39 | Glenjamin | i'm not sure what you mean by that |
| 10:48 | lodin | Glenjamin: If you have (-> x (foo a) (foo b) (foo c)) you can rewrite that into a reduce, (reduce foo x [a b c]). |
| 10:48 | Glenjamin | the threading form is much clearer there imo |
| 10:49 | lodin | Glenjamin: except something you can't use the threading form, because you really have (let [ys ...] (reduce foo x ys)) |
| 10:50 | lodin | And want you also had initially was a threading form doing other stuff to x, and want to get the reduce in there. |
| 10:51 | lodin | s/want/what/ |
| 10:52 | lodin | So now you either create a foo-all function so you can have that in your threading form, or write (#(reduce foo % ys)). |
| 10:53 | lodin | But that second option is not good if you happened to have a #() form where foo is. |
| 10:53 | lodin | So you might rewrite using partial is possible, or spell out the fn form. |
| 10:54 | lodin | Or you use your own reduce' which takes the initial value first, and you're done. :-) |
| 10:54 | Glenjamin | can you give a concrete example? i'm still not really following |
| 10:55 | lodin | s/is poss/if poss/ |
| 10:56 | lodin | Glenjamin. OK, hold on. |
| 10:56 | Glenjamin | thanks |
| 11:15 | crack_user | hello guys |
| 11:15 | arav93 | Has the android app for clojure repl been updated? |
| 11:16 | crack_user | I am looking at reagent and I constantly see this code "(-> % .-target .-value)" in :on-field, but I don't find in any place what does it means |
| 11:17 | crack_user | someone can explain or show where is it in documentation? |
| 11:17 | clojurebot | Huh? |
| 11:18 | crack_user | for example " :on-change #(reset! value (-> % .-target .-value))" |
| 11:19 | lodin | Glenjamin: http://pastebin.com/yhFK5Lyf |
| 11:20 | Glenjamin | crack_user: http://clojuredocs.org/clojure.core/-%3E |
| 11:20 | Glenjamin | that bit of code is roughly equivalent to "e.target.value" in javascript |
| 11:21 | crack_user | humm, I already know about the threads functions, my doubts is more about the .- and % syntax |
| 11:22 | TMA | crack_user: #(... % ...) is equivalent to (fn [%] (... % ...)) |
| 11:22 | lodin | crack_user: % is the first argument in the function created by #(...). |
| 11:23 | crack_user | I get it |
| 11:24 | lodin | Glenjamin: Does that example make it clearer? |
| 11:24 | Glenjamin | lodin: yes, it does |
| 11:24 | Glenjamin | i'd probably say define (defn add-edges [g es] (reduce #(apply dep/depend %1 %2) g es)) because `add-edge` isn't actually that useful |
| 11:26 | Glenjamin | although i'm not sure the threaded version is worth using at all |
| 11:26 | lodin | Glenjamin: I knew you would say that, so assume that there's more going on in the thread. |
| 11:26 | Glenjamin | unless you're combining the top version with the bottom version |
| 11:26 | lodin | :-) |
| 11:26 | Glenjamin | yeah, i guessed there might be |
| 11:26 | lodin | Glenjamin: For instance, first you might want to remove some edges. |
| 11:26 | Glenjamin | but yeah, add-edge doesn't seem bit enough to extract |
| 11:27 | Glenjamin | *big enough |
| 11:27 | Glenjamin | but add-edges (with the reduce inside) is |
| 11:27 | clojurebot | Excuse me? |
| 11:27 | lodin | Glenjamin: I just added it because it get's tiresome to write apply all the time. |
| 11:27 | Glenjamin | right, but you're only using apply because you have a pair |
| 11:27 | Glenjamin | and you only have a pair because you have a list of pairs |
| 11:27 | Glenjamin | if you only had one, you'd just use dep/depend |
| 11:27 | lodin | Glenjamin: So assume that the API had add-edge, or that depend takes a pair. |
| 11:29 | lodin | But you see, the reduce form is very similar to a map form. |
| 11:29 | Glenjamin | right, but reduce is more of a black box |
| 11:30 | Glenjamin | you know what's going on with a map, a reduce could do anything - which i think is why i find it a bit "weird" in a thread like that |
| 11:30 | Glenjamin | i dunno, might just be me |
| 11:36 | imanc | is there a decent step through debugger for clojure? (I'm using vim) |
| 11:36 | profil | Does it exist a lisp which is similiar to clojure but is compiled to machine code just like common lisp? |
| 11:52 | profil | or is it possible to compile clojure so that it is not dynamic? |
| 12:06 | r4vi | profil: pixie is the clojure inspired lisp that compiles to native code |
| 12:08 | r4vi | well kind of; it generates it's own native vm |
| 12:14 | profil | r4vi: ah, nice.. To bad its not entirely native. I was looking for something to write small apps like a window manager without having to touch common lisp or scheme |
| 12:15 | r4vi | ah so you want a no deps clojure |
| 12:15 | r4vi | I seem to remember something that cross compiled clojure -> scheme -> native |
| 12:16 | r4vi | profil: not sure how mature but here it is https://github.com/takeoutweight/clojure-scheme |
| 12:17 | profil | I guess I could learn scheme, I like the minimalism, but I have read that its hard to write portable scheme programs.. |
| 12:27 | imanc | ,(apply (fn [x & more] (prn x more)) [1 2 3 4 5]) |
| 12:27 | clojurebot | 1 (2 3 4 5)\n |
| 12:28 | imanc | why?? |
| 12:28 | imanc | why is rest passed back into the fn? |
| 12:29 | imanc | and given it does that, how does (apply str [1 2 3 4 5]) work? |
| 12:30 | Glenjamin | (apply str [1 2 3]) === (str 1 2 3) |
| 12:31 | Graawrimatiger | hi ! I'm a little baffled: how come (flatten (vector <list of maps>) is almost instant, while (flatten <list of maps>) seems linear ? Both yield same result, it seems |
| 12:31 | imanc | oh man |
| 12:31 | imanc | n00b mistakes |
| 12:31 | profil | ,((fn [x & more] (prn x more)) 1 2 3 4 5) |
| 12:31 | clojurebot | 1 (2 3 4 5)\n |
| 12:31 | profil | imanc: ^ |
| 12:32 | Glenjamin | Graawrimatiger: how are you measuring them? |
| 12:32 | Glenjamin | also |
| 12:32 | Glenjamin | ~flatten |
| 12:32 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 12:32 | imanc | OK, this now makes perfect sense .. thanks! |
| 12:34 | Graawrimatiger | Glenjamin: I measure them with the built-in "time" function. Also, (mapcat identity) or (concat) instead of flatten both yield same results : "slow" if I use it directly on a list of maps, really quick if I apply `vector` first |
| 12:35 | Glenjamin | $source flatten |
| 12:35 | Glenjamin | bah |
| 12:35 | Glenjamin | where's lazybot :( |
| 12:35 | profil | ,(source flatten) |
| 12:35 | clojurebot | Source not found\n |
| 12:35 | profil | :( |
| 12:37 | Glenjamin | i can't see any obvious reason for that in the source Graawrimatiger, maybe try using criterium (a more detailed benchmarking tool) to compare them |
| 12:38 | Glenjamin | flatten seems to use tree-seq, which just uses lazy-seq and mapcat |
| 12:38 | Graawrimatiger | hum |
| 12:39 | Graawrimatiger | maybe it has something to do with lists being linked-lists while vectors are arrays ? |
| 12:39 | Glenjamin | that shouldn't really make much of a difference for a straightforward linear walk like that |
| 12:39 | Graawrimatiger | ha |
| 12:43 | Graawrimatiger | all in all, I'm not missing some hidden trap there, right ? Vector will maintain the order of the list if i'm correct, so both results should always be identical ? |
| 12:43 | Glenjamin | well, lists can be lazy |
| 12:43 | Glenjamin | or, more accurately, vectors can only be eager |
| 12:43 | Graawrimatiger | I'm not using laziness here |
| 12:45 | Glenjamin | can you post some code samples? |
| 12:46 | Graawrimatiger | just re-tried something, seems I was mistaken : mapcat identity doesn't flatten the list inside the vector (it only removes the vector, which seems logical) ; if I want the same results, I have to use flatten on the vector |
| 12:48 | Graawrimatiger | (i'm uploading some code samples) |
| 12:53 | Graawrimatiger | Glenjamin: here is the original map I use for the tests (some instaparse AST in enlive format) : http://pastebin.com/E5d5Q72q |
| 12:54 | Glenjamin | it's possible that some part of the procedure is doing lazy work at a different point, maybe try using the profiler to find out if it's important to you |
| 12:55 | csd_` | In the context of accumArray, what would the symbolic representation of the accumulation function (\/), where this represents an upside down carrot, mean? |
| 12:56 | csd_` | caret |
| 12:57 | Graawrimatiger | O_o i don't get it : if I store this list in a var, for exemple "mylist", (flatten mylist) and (flatten (vector mylist)) take the exact same time (really quick); if I do the same comparison while using the 'inline' result of the list (ie obtaining the result from function calls and flatten it directly from it), there is this big speed difference >< |
| 12:57 | Graawrimatiger | (well it's not really important, I was just a bit puzzled by this) |
| 13:00 | lodin | Graawrimatiger: How would a flattening for perform? (for [xs xss, x xs] x) |
| 13:01 | justin_smith | which is identical to nested mapcats btw |
| 13:01 | Graawrimatiger | lodin: sorry, I don't quite grasp how to flatten with for... ? |
| 13:02 | lodin | Sorry, gotta go. |
| 13:03 | justin_smith | ,(for [xs [{:a 0 :b 1 :c 2} {:d 3 :e 4}] x xs] x) |
| 13:03 | clojurebot | ([:c 2] [:b 1] [:a 0] [:e 4] [:d 3]) |
| 13:03 | Graawrimatiger | oh |
| 13:03 | justin_smith | ,(for [xss [{:a 0 :b 1 :c 2} {:d 3 :e 4}] xs xss x xs] x) |
| 13:03 | clojurebot | (:c 2 :b 1 :a ...) |
| 13:05 | Graawrimatiger | it performs "quickly", not "badly linearly" (^^") |
| 13:06 | justin_smith | Graawrimatiger: were you consuming the individual results when benchmarking? because a vector would definitely be slower if not |
| 13:06 | justin_smith | compared to something potentially lazy |
| 13:07 | Graawrimatiger | justin_smith: I benchmarked while saving (time (def <name> (<several calls to get the original list I linked on pastebin>))) |
| 13:09 | justin_smith | ,(def n (flatten (repeatedly range))) |
| 13:09 | clojurebot | #'sandbox/n |
| 13:09 | justin_smith | Graawrimatiger: n is infinite |
| 13:09 | justin_smith | Graawrimatiger: it wasn't evaluated at all |
| 13:09 | justin_smith | doing the def did no work |
| 13:10 | justin_smith | so of course that is instant |
| 13:10 | justin_smith | this is why one should use criterium for benchmarking, it makes these mistakes less likely |
| 13:11 | Graawrimatiger_ | (sorry, disconnected) |
| 13:11 | justin_smith | Graawrimatiger: did you see the def of n? |
| 13:11 | Graawrimatiger_ | (felt like I wasn't clear so (time (def x (flatten original_list))) ;=> 90msecs, and (time (def y (flatten (vector original_list)))) ;=> 0.38msecs ; at the end, (= x y) ;=> true |
| 13:12 | justin_smith | ,(def n (map println (flatten (repeatedly range)))) |
| 13:12 | clojurebot | #'sandbox/n |
| 13:12 | justin_smith | it returns instantly |
| 13:12 | justin_smith | nothing prints |
| 13:12 | justin_smith | no work was done |
| 13:12 | justin_smith | it should have printed a series of numbers up to the maximum possible integer, over and over |
| 13:12 | justin_smith | (if it had done anything) |
| 13:12 | justin_smith | timing a def of a flatten is not a fair coparison |
| 13:12 | justin_smith | *comparison |
| 13:13 | Graawrimatiger_ | oh |
| 13:13 | justin_smith | flatten is lazy |
| 13:13 | justin_smith | it doesn't calculate anything until you consume the output |
| 13:13 | Glenjamin | ahah |
| 13:14 | Graawrimatiger_ | but then again, after doing the defs above, (time x) and (time y) both take the same time (almost nothing). Wouldn't one of them be way longer if it needed to be realized ? |
| 13:14 | justin_smith | Graawrimatiger_: this is why you shouldn't use time to benchmark things btw, there is a lib called criterium that makes these mistakes less likely |
| 13:14 | justin_smith | Graawrimatiger_: (time x) does not force the result |
| 13:14 | Graawrimatiger_ | oh |
| 13:15 | justin_smith | Graawrimatiger_: you need to consume the contents, or use something like "doall" or "dorun" on it |
| 13:15 | Graawrimatiger_ | so all in all, there's no "magical way" to flatten a list of lists in O(1), I guess... ? |
| 13:15 | justin_smith | absolutely not |
| 13:15 | Graawrimatiger_ | :/ |
| 13:15 | whomp | so is let just a concise way of doing a bunch of defs? |
| 13:15 | justin_smith | you have multiple lists, the lower bound is O(n) for the number of lists |
| 13:16 | justin_smith | whomp: that was all that got tested, was creating the defs |
| 13:16 | l3dx | in compojure, is it possible to map just a subset of the routes with a given middleware? |
| 13:16 | justin_smith | l3dx: yes, a middleware is just a function that takes a handler and returns a new handler |
| 13:16 | whomp | justin_smith, ? |
| 13:16 | justin_smith | l3dx: use the middleware on the routes you want wrapped |
| 13:17 | justin_smith | whomp: all that got timed was running def - the contents of hte things def'd were not forced, so at least in the case of a list input are not evaluated |
| 13:17 | justin_smith | whomp: the laziness of flatten would mean that the work would get done later as the elements are accessed |
| 13:18 | justin_smith | (which was not timed) |
| 13:18 | whomp | justin_smith, so def is lazy, let is not? |
| 13:18 | justin_smith | whomp: no, that's not what I am saying at all |
| 13:18 | whomp | lol maybe i'll just read some more |
| 13:18 | Graawrimatiger_ | justin_smith: okay; so if I have this structure ( a_list a_list a_list ...) from doing a map (of an instaparse parser function) on a list of strings, there's no way to optimize something in between to avoid the "long" flatten at the end ? |
| 13:18 | justin_smith | whomp: if you do (time (def n (something lazy))) all you have timed is the amount of time it takes to run def |
| 13:19 | whomp | justin_smith, ok ty |
| 13:19 | justin_smith | Graawrimatiger_: mapcat the instaparse instead of map / flatten |
| 13:19 | Glenjamin | flatten/concat/mapcat are "optimised" in the sense that they are all lazy |
| 13:19 | Graawrimatiger_ | justin_smith: hum, whomp asked you something else entirely; I think your last answers were for me... ? |
| 13:19 | justin_smith | Graawrimatiger_: no |
| 13:19 | Graawrimatiger_ | oh, nevermind so ^^" |
| 13:19 | justin_smith | Graawrimatiger_: except the one I directed at you |
| 13:20 | hellofunk | l3dx: one easy way to group those routes you want effected into a single defroutes, then use the middleware on that group. you can combine this resulting handler with other route groups you've defined w/o middleware into one big handler. |
| 13:20 | justin_smith | (inc hellofunk) |
| 13:20 | justin_smith | that's a much better way of saying what I was trying to say |
| 13:20 | l3dx | cool. thanks! I'll give it a try :) |
| 13:21 | hellofunk | l3dx: here's an example: https://github.com/hellofunk/hellofunk-lein-template/blob/master/resources/leiningen/new/hellofunk/src/h/examples.clj |
| 13:22 | Graawrimatiger_ | justin_smith: oh well, mapcating the instaparse yields the desired result in only one step, thanks ! it's also linear time (time (mapcat...), no defs) so I guess that's the best I can get like you said |
| 13:22 | Graawrimatiger_ | thanks a lot :) |
| 13:22 | justin_smith | Graawrimatiger_: (time (mapcat ...)) does not force the laziness either! |
| 13:23 | justin_smith | you need to consume the result, or no work is done |
| 13:23 | justin_smith | the easy way is doall / dorun |
| 13:23 | justin_smith | (time (dorun (mapcat ...))) |
| 13:23 | Glenjamin | although note that neither recurse deeply |
| 13:23 | justin_smith | (time (mapcat f coll)) won't even call f once |
| 13:24 | Graawrimatiger_ | justin_smith: hm (time (dorun (mapcat ...))) and (time (mapcat ...)) both take the same time |
| 13:24 | justin_smith | Graawrimatiger_: that's surprising |
| 13:24 | justin_smith | maybe I am wrong in this case... |
| 13:24 | Glenjamin | how many items are in this list? |
| 13:24 | justin_smith | ,(time (range)) |
| 13:24 | justin_smith | d'oh |
| 13:25 | clojurebot | "Elapsed time: 0.047057 msecs"\n(0 1 2 3 4 ...) |
| 13:25 | justin_smith | AHA! |
| 13:25 | Glenjamin | aha? |
| 13:25 | justin_smith | yeah, that call to (range) was "infinite" |
| 13:25 | Glenjamin | ,(doc time) |
| 13:25 | clojurebot | "([expr]); Evaluates expr and prints the time it took. Returns the value of expr." |
| 13:25 | Graawrimatiger_ | justin_smith: I'm using the 'lein-ultra' plugin to run a repl, which changes a lot of things (only visual though), could it be that one feature is interfering here ? |
| 13:25 | justin_smith | Glenjamin: so if you don't consume the result inside the time form, you don't force any laziness |
| 13:25 | Glenjamin | yeah |
| 13:26 | justin_smith | Graawrimatiger_: no |
| 13:26 | justin_smith | Graawrimatiger_: you can't accurately calculate the time a lazy thing took without explicitly consuming its results (recursively if it has nested laziness) |
| 13:26 | justin_smith | flatten and mapcat are both lazy |
| 13:27 | justin_smith | criterium is a benchmarking library that makes that mistake less likely though |
| 13:27 | justin_smith | (and gives much more accurate timing results) |
| 13:27 | hellofunk | justin_smith: if using time at the REPL, i would think it would try to realize the whole sequence since REPL printouts are a form of consumption |
| 13:28 | justin_smith | hellofunk: unless you have print-length limited as clojurebot does, sure |
| 13:28 | Graawrimatiger_ | oooh |
| 13:29 | justin_smith | hellofunk: also time will not end up timing the realization |
| 13:29 | justin_smith | hellofunk: because the forcing of the lazy result will happen after time returns the lazy object |
| 13:29 | justin_smith | hellofunk: so the whole thing gets realized, but your timing is fictional |
| 13:29 | hellofunk | oh intersting. |
| 13:30 | hellofunk | justin_smith: here is a rather intersting tidbit i came across once, on the subject of time: https://gist.github.com/hellofunk/7d424d173125b5dc9640 |
| 13:30 | justin_smith | hellofunk: just think about the order of execution: you time the generation of the lazy-seq (no work done), that lazy seq is returned, time calculates its result and prints it, your repl consumes and prints the lazy seq, and then *finally*, after the time is calculated, the seq is forced |
| 13:31 | hellofunk | justin_smith: that makes sense |
| 13:31 | Graawrimatiger_ | justin_smith: oh, that would explain the whole thing I guess |
| 13:31 | Graawrimatiger_ | going to try criterion then |
| 13:31 | justin_smith | *criterium |
| 13:32 | Graawrimatiger_ | woops |
| 13:32 | Graawrimatiger_ | yeah, meant that x) |
| 13:32 | justin_smith | also, as I mentioned before, doall or dorun would have helped too (and are still useful sometimes in criterium) |
| 13:32 | Graawrimatiger_ | justin_smith: yeah but since I have the same results with or without doall/dorun, something is still missing |
| 13:32 | imanc | ,(take 3 (repeat (/ (+ (rand-int 255) 255) 2)))) |
| 13:32 | clojurebot | (147 147 147) |
| 13:33 | imanc | I'm assuming that (repeat... is causing the output of rand-int to be repeated, rather than calling the evaluating the function on each iteratoin |
| 13:34 | l3dx | hellofunk: worked perfectly! |
| 13:34 | Glenjamin | ,(doc repeatedly) |
| 13:34 | clojurebot | "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it" |
| 13:35 | hellofunk | l3dx: glad to hear it! |
| 13:38 | imanc | ahh repeatedly did it - thanks Glenjamin |
| 13:39 | justin_smith | Graawrimatiger_: so you did (time (dorun (mapcat f ...))) |
| 13:39 | Graawrimatiger_ | justin_smith: yes |
| 14:43 | justin_smith | ,(time (map #(*' % % % % % % %) (range))) |
| 14:43 | clojurebot | "Elapsed time: 0.148038 msecs"\n(0 1 128 2187 16384 ...) |
| 14:43 | justin_smith | ,(time (doall (map #(*' % % % % % % %) (range)))) |
| 14:43 | clojurebot | eval service is offline |
| 14:44 | justin_smith | ,(time (doall (map #(*' % % % % % % %) (range 100)))) |
| 14:44 | clojurebot | "Elapsed time: 0.754953 msecs"\n(0 1 128 2187 16384 ...) |
| 14:44 | tcrayford____ | justin_smith: reminder that in compiling that code, cleaxjure is writing a class file to disk, so it'd likely be faster in a real server |
| 14:44 | justin_smith | tcrayford____: I'm showing the difference in time taken |
| 14:45 | justin_smith | tcrayford____: related to the excange with Graawrimatiger_ above |
| 14:45 | tcrayford____ | oh |
| 15:03 | hellofunk | ,(doall (time (map #(*' % % % % % % %) (range 100)))) |
| 15:04 | clojurebot | "Elapsed time: 0.103278 msecs"\n(0 1 128 2187 16384 ...) |
| 15:06 | hellofunk | ,(time (doall (time (map #(*' % % % % % % %) (range 100))))) |
| 15:06 | clojurebot | "Elapsed time: 0.105691 msecs"\n"Elapsed time: 1.933527 msecs"\n(0 1 128 2187 16384 ...) |
| 15:33 | whomp | how is it that (take 5 (map identity (range)) doesn't go on forever? |
| 15:34 | tcrayford____ | whomp: laziness |
| 15:34 | whomp | ah i see now, tcrayford____, ty |
| 15:34 | tcrayford____ | whomp: did that completely answer it? I was writing a longer answer (that one was super glib) |
| 15:35 | whomp | yeah cuz it reminded me of lazy seqs lol, i'm re-learning the language |
| 15:35 | tcrayford____ | haha ok then :) |
| 15:35 | tcrayford____ | happy I could help |
| 15:44 | patrkris | hi folks. I am trying to add customer encoders to cheshire, but do I need to do it in every namespace I use cheshire? can it be added globally somehow for my whole library? |
| 15:44 | tcrayford____ | patrkris: adding an encoder is a global change |
| 15:44 | tcrayford____ | so you can put them all in a namespace or something, and as long as that's required somewhere |
| 15:44 | tcrayford____ | then you're good |
| 15:44 | patrkris | tcrayford____: I believe I tried that, but let me just try again |
| 15:45 | tcrayford____ | patrkris: for sure |
| 15:48 | patrkris | tcrayford____: seems you were right. must've done something stupid before :) thanks |
| 15:52 | tcrayford____ | patrkris: dope! Glad I could help out :) |
| 15:52 | tcrayford____ | patrkris: I've been running like that in production for like, 2 years haha |
| 15:56 | michaelr525 | hi |
| 15:58 | dweave | Anyone have trouble getting stack trace not to show on every error in cider? It’s extremely useless |
| 15:59 | dweave | only seems to do so for some errors |
| 16:01 | AeroNotix | dweave: specific exceptions? Repeatable? |
| 16:01 | AeroNotix | Which version of CIDER? |
| 16:01 | AeroNotix | also, #clojure-emacs |
| 16:01 | dweave | doesn’t seem repeatable trying to figure that out though. |
| 16:01 | dweave | version 0.8.2 |
| 16:02 | AeroNotix | dweave: perhaps the exception buffer is getting hidden |
| 16:02 | dweave | i have this warning: WARNING: CIDER's version (0.8.2-snapshot) does not match cider-nrepl's version (0.8.1) |
| 16:02 | tcrayford____ | dweave: check your JVM doesn't have -XX:+OmitStackTraceOnFastThrow as well |
| 16:02 | dweave | AeroNotix: I want the error buffer to get hidden |
| 16:03 | dweave | tcrayford____ how do i check that |
| 16:03 | AeroNotix | dweave: I'm gonna say that you don't have the above setting |
| 16:03 | AeroNotix | unless you've put it there manually. |
| 16:03 | dweave | what setting AeroNotix |
| 16:03 | dweave | I have this: (setq cider-show-error-buffer nil) |
| 16:03 | AeroNotix | dweave: what do you think that setting does? :) |
| 16:04 | tcrayford____ | AeroNotix: that setting is on by default on the jvm ;) |
| 16:04 | michaelr525 | will be starting a fresh new web app. thinking of starting with chestnut (figwheel, om, weasel, ring) and then adding system (component) and sente. anything else/instead you'd recommend? |
| 16:04 | dweave | “Configure whether the error buffer with stacktraces should be automatically shown on error:” |
| 16:04 | AeroNotix | tcrayford____: aha, ok then. |
| 16:05 | tcrayford____ | AeroNotix: it only affects specific exceptions, and I don't think it's the problem here though |
| 16:05 | AeroNotix | right |
| 16:05 | tcrayford____ | seems like #clojure-emacs kinda thing to me |
| 16:05 | dweave | i’m confused which setting are we talking about |
| 16:06 | dweave | i’ll try clojure-emacs thanks |
| 16:13 | michaelr525 | will be starting a fresh new web app. thinking of starting with chestnut (figwheel, om, weasel, ring) and then adding system (component) and sente. anything else/instead you'd recommend? |
| 16:15 | tcrayford____ | michaelr525: depends on what your app's doing really |
| 16:16 | michaelr525 | oh and friend and liberator :) |
| 16:17 | michaelr525 | tcrayford____: ui, crud, authentication, ElasticSearch as datastore |
| 16:18 | tomjack | I can't afford the modeline cost of #clojure-emacs :) |
| 16:19 | tcrayford____ | michaelr525: I'm probably a bit more conservative than you here - I tend to only add libraries as I *need* them for things |
| 16:20 | michaelr525 | tcrayford____: all web applications need this common base: ui, client-server communication, security, web services, data layer |
| 16:20 | michaelr525 | on top of that you'd want good architecture and some development sugar, thus component, figwheel |
| 16:21 | michaelr525 | tcrayford____: so this list is only the base stuff which 100% will be used |
| 16:23 | tcrayford____ | michaelr525: yea. I tend to start with a much smaller set of things at the start (but then again my current app has ~80 direct dependencies) |
| 16:25 | raspasov | michaelr525: ElasticSearch as datastore? |
| 16:25 | michaelr525 | tcrayford____: xcactly :) |
| 16:26 | tcrayford____ | echoing raspasov there, I don't trust elasticsearch as far as I can throw it |
| 16:26 | michaelr525 | raspasov: the app will be around querying stuff from ES so we though of using it as the operational DB as well for app CRUD |
| 16:27 | michaelr525 | don't trust it in what sense? |
| 16:27 | raspasov | only put data in ES that you're 100% sure you're ok to completely lose |
| 16:27 | tcrayford____ | ^^ |
| 16:27 | tcrayford____ | it loses data |
| 16:27 | michaelr525 | oh really |
| 16:27 | michaelr525 | interesting |
| 16:27 | raspasov | https://aphyr.com/posts/317-call-me-maybe-elasticsearch |
| 16:27 | raspasov | read this |
| 16:27 | michaelr525 | ok, thanks |
| 16:27 | tcrayford____ | note that they've done a *lot* of work since that post |
| 16:28 | tcrayford____ | but our ES cluster at work (which is only for logstash) still throws away it's data every few weeks (without us telling it to) |
| 16:28 | raspasov | ^^ lol |
| 16:29 | michaelr525 | heh |
| 16:29 | michaelr525 | tcrayford____: are you on the latest version? |
| 16:29 | raspasov | yea I was running ES in prod on just two nodes, not good experience |
| 16:29 | tcrayford____ | michaelr525: yeah, we were |
| 16:29 | tcrayford____ | (I've been on vacation for 3 weeks, so things might have changed) |
| 16:30 | raspasov | maybe another re-write happened since then? :D |
| 16:30 | tcrayford____ | haha :( |
| 16:31 | tcrayford____ | (https://github.com/elasticsearch/elasticsearch/issues/3145#issuecomment-27455667 is still open haha) |
| 16:31 | raspasov | my advice is: use MySQL or PostgreSQL if your data is within a few TB, and use Riak or Dynamo if it's bigger than that, you can use ES to load data from those sources for searching |
| 16:32 | raspasov | but never as a primary store of data |
| 16:32 | tcrayford____ | raspasov: agree with that |
| 16:32 | raspasov | I made that mistake once and not doing it again lol |
| 16:34 | raspasov | someone needs to re-write ES in Clojure, it will prob be 10x less code and 10x less bugs lol |
| 16:37 | michaelr525` | hmm.. ' |
| 16:37 | michaelr525` | have I missed anything? |
| 16:38 | tcrayford____ | http://clojure-log.n01se.net/ |
| 16:38 | michaelr525` | 10x |
| 16:56 | imanc | if a function relies on some global var that isn't passed in explicitly, is the function then impure / tainted? |
| 16:56 | tcrayford____ | imanc: guess so, on some levels |
| 16:56 | tcrayford____ | imanc: though like, if your function calls `map`, it's relying on a var ;) |
| 16:57 | imanc | yeh |
| 16:57 | tcrayford____ | generally if it calls another pure function, imo that's ok |
| 16:57 | raspasov | if that var is never modified, in a way, no (I guess lol) |
| 16:57 | Bronsa | the solution is easy |
| 16:57 | tcrayford____ | raspasov: right, but if you reload it at the repl you've modified it ;) |
| 16:57 | Bronsa | (let [map map] (defn my-f [..] ..)) |
| 16:58 | raspasov | well but if you reload with the same value, you haven't? :) |
| 16:58 | imanc | hm, i've been messing with quil and doing some animation stuff to get acquainted with clojure. But most functions need to rely on a global vars for screen width/height, and it seems clunky to pass these in each time. Obviuosly these are constants, but I'm wondering if this then taints the function |
| 16:58 | Bronsa | now my-f won't be affected by var redef :P |
| 16:59 | tcrayford____ | imanc: I'd typically pass those in always |
| 16:59 | tcrayford____ | it gets a bit more verbose, but you win in being able to test/maintain/etc |
| 16:59 | raspasov | yea generally I agree ^^ |
| 16:59 | imanc | tcrayford____: yeh, I've been wondernig about how to write unit tests for these also |
| 16:59 | imanc | makes sense |
| 17:00 | Bronsa | imanc: just pass in an opts arg to all your functions and use a map {:width .. :height ..} |
| 17:00 | danlentz | thanks to those that pointed out a potential race condition in my monotonic timestamp generator last night. I rewrote it based on the comments recieved: https://gist.github.com/danlentz/301a0f056ffd9c6605a9 |
| 17:01 | imanc | @Bronsa cool, that sounds like a solution. |
| 17:01 | Bronsa | danlentz: why are you using MapEntry? |
| 17:02 | danlentz | i wanted a single cons cell |
| 17:02 | danlentz | ie a pair |
| 17:02 | tcrayford____ | seems better to just deftype or defrecord it |
| 17:02 | tcrayford____ | (if that was for perf) |
| 17:02 | Bronsa | danlentz: (defrecord Pair [k v]) |
| 17:02 | danlentz | i believe records are slower than types, no? |
| 17:03 | Bronsa | no |
| 17:03 | tcrayford____ | depends how much it matters |
| 17:03 | danlentz | it matters |
| 17:03 | Bronsa | danlentz: they are not slower |
| 17:03 | tcrayford____ | Bronsa: yeah they are ;) |
| 17:03 | danlentz | i need a two slot tuple, i dont need a record with a map interace |
| 17:03 | raspasov | I believe deftype is more barebones than defrecord |
| 17:03 | tcrayford____ | danlentz: in which case (deftype Pair [k v]) |
| 17:03 | danlentz | im pretty sure deftype |
| 17:04 | Bronsa | tcrayford____: no they are not. they just implement more abstractions |
| 17:04 | danlentz | but i dont quite understand the reasoning why a mapentry would not be as fast |
| 17:04 | danlentz | as a custom deftype |
| 17:04 | tcrayford____ | danlentz: that one isn't a perf arg |
| 17:04 | tcrayford____ | just that it seems "odd" or "weird" |
| 17:04 | danlentz | oh |
| 17:04 | danlentz | yeah, yes weird |
| 17:05 | danlentz | im a common lisper I yearn for a cons cell :) |
| 17:05 | tcrayford____ | Bronsa: records implement IMeta, so they inherit at least an additional function call on every `assoc` for example |
| 17:05 | Bronsa | danlentz: also there are key and val functions that work on mapentry anyway, no need to use .key/.val directly |
| 17:05 | tcrayford____ | Bronsa: that's also very slightly slower ;) |
| 17:05 | Bronsa | tcrayford____: moot argument, deftypes don't support assoc at all out of the box |
| 17:06 | raspasov | I've done something like this https://gist.github.com/raspasov/c3a45a669b74de717050 |
| 17:06 | raspasov | (this will never return the same number) |
| 17:06 | danlentz | not thread safe |
| 17:06 | danlentz | is it? |
| 17:07 | tcrayford____ | it is |
| 17:07 | tcrayford____ | `synchronized` |
| 17:07 | tcrayford____ | but uh, that involves a lock vs a CAS like your one does, so it might be slower |
| 17:07 | raspasov | yea I haven't benchmarked, but locks on longs are pretty damn fast I think |
| 17:08 | Bronsa | tcrayford____: all I'm arguing is that it makes no sense to say "records are slower than types", they share the same implementation. the way one uses records might be slower than the way one uses types (i.e. (:foo x) vs (.foo x)) but you can still use the .foo syntax with records if you need that |
| 17:08 | tcrayford____ | Bronsa: roughly agreed haha. If you start digging, they are *for sure* slower, even if you use the same syntax, but in most applications that ain't gonna matter so much |
| 17:08 | Bronsa | and keyword lookup on records is really fast anyway |
| 17:09 | danlentz | raspasov: i forked that gist tho thanks |
| 17:09 | raspasov | danlentz: if you care for the utmost performance you should benchmark the atom's CAS vs (locking) macro in Clojure or some Java solution like I posted |
| 17:09 | tcrayford____ | (you're starting to look at things like the extra memory allocation because defrecords store two extra pointers compared to deftype etc at that point though) |
| 17:10 | raspasov | danlentz: np, cheers :) |
| 17:10 | tcrayford____ | Bronsa: just depends how deep you're gonna dig, and at that point you should prolly be using C or C++ or Rust or something without a GC |
| 17:10 | danlentz | well, there is some value is trying to be more idiomatic clojure rather than ‘locking’ or dropping to java |
| 17:10 | raspasov | yea def |
| 17:10 | Bronsa | tcrayford____: whatever, I don't believe that instantiating two extra fields null will make any difference |
| 17:11 | raspasov | this is pretty much the only bit of Java I've used lol |
| 17:11 | tcrayford____ | Bronsa: I don't trust myself to benchmark at that level of performance ;) |
| 17:11 | danlentz | i just finished a weight balanced binary tree which was very very very sensitive to allocation |
| 17:11 | danlentz | i tried clj-tuple |
| 17:11 | danlentz | object array |
| 17:11 | danlentz | and deftype |
| 17:11 | raspasov | danlentz: what are you working on - some sort of storage/database? |
| 17:11 | danlentz | so, deftype and clj-tuple were about equivalent |
| 17:12 | tcrayford____ | danlentz: note that clj-tuple had a new release yesterday evening that rewrites it in java |
| 17:12 | tcrayford____ | (and zach says it's noticeably faster) |
| 17:12 | danlentz | but, with deftype i was able to declare the last element as ^long, and i saved considerably, |
| 17:12 | tcrayford____ | (not for any class/deftype reasons though - the code's better) |
| 17:12 | danlentz | ah |
| 17:12 | tcrayford____ | but yea, the type hint is a huge win there |
| 17:12 | danlentz | probably due to my nagging and griping :) |
| 17:13 | tcrayford____ | nah, I was griping at him haha ;) |
| 17:13 | danlentz | http://github.com/danlentz/clj-wbtree |
| 17:13 | danlentz | im still working on it but its within 10% of sorted-set |
| 17:13 | tcrayford____ | danlentz: post your benchmarks in that repo |
| 17:13 | raspasov | cool! |
| 17:14 | tcrayford____ | (and yea - looks dope) |
| 17:14 | danlentz | wbtree only typically will beat rbtree for very large collections, and also I have an extra cost because I have a “universal” ordering relation |
| 17:14 | danlentz | ive really been learning a lot its been a really good exercise |
| 17:15 | tcrayford____ | danlentz: how are you measuring performance? |
| 17:15 | danlentz | well, specifically for building trees |
| 17:16 | danlentz | i dont have rigorous benchmarks, that is just a very rough estimation |
| 17:17 | danlentz | going to play with criterium |
| 17:17 | justin_smith | danlentz: criterium is not hard to use |
| 17:17 | tcrayford____ | would highly recommend it :) |
| 17:17 | tcrayford____ | it's as easy as calling `time` from core |
| 17:17 | tcrayford____ | just like, the numbers are kinda real |
| 17:17 | danlentz | but first I had to get it at least in the ballpark — up until now it was like 20x slower than sorted set so my priority was on big fixes not high confidence measurement |
| 17:17 | raspasov | yea use Criterium https://github.com/hugoduncan/criterium it's very nice |
| 17:17 | tcrayford____ | danlentz: that's mostly what I was asking there. Measuring performance on the JVM even somewhat accurately is near impossible ;) |
| 17:18 | justin_smith | guys, I think we need at least six people to tell danlentz to use criterium, if anyone else can pitch in |
| 17:18 | tcrayford____ | things I've seen: run the same benchmark twice in the same JVM: second time is 4000x slower (note: *exactly* the same JVM) |
| 17:18 | danlentz | hey anybody know of a good library i can use? |
| 17:18 | danlentz | :) |
| 17:18 | tcrayford____ | (that was specific to that benchmark) |
| 17:18 | raspasov | justin_smith: yes I think so :D |
| 17:20 | tcrayford____ | (lesson there: if you use criterium, you need a new JVM per benchmark, or the numbers will lie) |
| 17:20 | danlentz | the monotonic timestamp is for my clj-uuid library so I needed that to be really fast so I can generate v1 uuid’s on multiple cores really fast |
| 17:20 | danlentz | http://github.com/danlentz/clj-uuid |
| 17:21 | danlentz | or reasonably fast anyway. |
| 17:27 | justin_smith | haha, a var called +tick-resolution+ - you really do miss common lisp |
| 17:27 | imanc | is there a decent debugger for clojure? Or do people generally resort to printing stuff to stdout? :) |
| 17:27 | justin_smith | imanc: best experience will likely be cursive |
| 17:28 | imanc | ahh |
| 17:28 | imanc | googling |
| 17:28 | cfleming | imanc: https://cursiveclojure.com/userguide/ |
| 17:28 | justin_smith | cursive is an editor plugin for doing clojure in the intellij idea ide |
| 17:29 | cfleming | imanc: I've just been working on the debugger recently, it works pretty well now. More improvements in the next release (in a week or so probably) |
| 17:29 | imanc | cool - i use pycharm (intellij) so it should be easy to use |
| 17:29 | cfleming | Yeah, it should all be familiar |
| 17:30 | cfleming | Cursive can't plug into PyCharm unfortunately, although it might be able to in the future |
| 17:30 | imanc | presumably i can instlal a vanilla intellij and use that? |
| 17:31 | cfleming | Yes |
| 17:31 | cfleming | Works fine with the community edition |
| 17:31 | imanc | awesome |
| 17:32 | imanc | do you guys generally use midje for writing tests? |
| 17:32 | justin_smith | clojure.test |
| 17:33 | cfleming | What justin_smith said |
| 17:33 | cfleming | Go for simple, IMO |
| 17:33 | imanc | koay |
| 17:36 | glosoli | Hey. when I am in cider repl mode, I seem to get company mode completion every time I type some text, yet it doesn't seem to work that way when I am in cider mode, any ideas how to get the same thing in cider mode ? |
| 17:37 | danlentz | justin_smith: i do love CL deeply but Clojure is my adopted home and I like it here |
| 17:37 | justin_smith | danlentz: :) |
| 17:38 | danlentz | the tooling is still a little painful |
| 17:38 | justin_smith | it's true, there are some rough edges compared to a decent cl |
| 17:38 | danlentz | everyone I encourage you to go to gittip and donate a few dollars a month to bhatsov |
| 17:39 | danlentz | the better the tooling, the more viable our language becomes to a wider marketplace |
| 17:39 | justin_smith | danlentz: my experience has been better since I stopped using stuff by bbatsov actually |
| 17:39 | danlentz | he does cider, no? |
| 17:39 | justin_smith | right |
| 17:39 | o0rebelious0o | I'm fairly new to using clojure having used it briefly over summer for a (pretty basic) DSL implementation but it's been really nice to look at and play with |
| 17:39 | o0rebelious0o | I hear #clojure is a pretty nice community unlike some other language IRCs |
| 17:40 | danlentz | i believe cider can overtake slime because it is architecturally more sound |
| 17:40 | danlentz | but it has a way to go |
| 17:40 | sobel | o0rebelious0o: in my experience, it's comparable with #postgresql which is about as good as it gets on IRC |
| 17:41 | danlentz | in particular, although I never particularly loved the slime debugger, it was really really helpful as compared to clojure/cider’s error reporting |
| 17:41 | tomjack | when I switched to cider some months back, I thought I was very late wrt trends |
| 17:41 | cfleming | Sorry, I missed this earlier: danlentz, you should be using criterium |
| 17:42 | danlentz | oh, criterium. right. totally forgot. |
| 17:42 | imanc | o0rebelious0o: yeh, I have noticed that. People are cool on here. |
| 17:42 | justin_smith | haha |
| 17:42 | danlentz | no i use cider |
| 17:42 | o0rebelious0o | sobel: can't say I've ever used it |
| 17:42 | danlentz | but for CL i used slime obviously |
| 17:42 | danlentz | slime for clojure was not very good by comparison |
| 17:43 | justin_smith | danlentz: clojure breakpoint / step debugging is possible, but I think cursive is the only environment that really has it conveniently available. |
| 17:43 | danlentz | i never used it because it was mutually exclusive with my common-lisp slime installation. That actually prevented me from playing with clojure for a very long time |
| 17:43 | danlentz | cursive, huh? |
| 17:43 | danlentz | thats the intellij plugin? |
| 17:44 | danlentz | hmm |
| 17:44 | danlentz | people seem to like intellij |
| 17:44 | sobel | o0rebelious0o: if you end up needing postgresql support, you might just be glad to know there's a great channel for it |
| 17:44 | cfleming | danlentz: Yeah, IntelliJ is really pretty amazing. Of course, it's a full-blown IDE which isn't to everyone's taste. |
| 17:45 | danlentz | cider has made dramatic improvement though. I think there has been a lot of time up front establishing a good framework |
| 17:45 | cfleming | danlentz: But JetBrains are amazing when it comes to dev tooling |
| 17:45 | danlentz | abandoning legacy slime-derived approach |
| 17:45 | sobel | JetBrains have been doing great tooling for a very long time |
| 17:45 | sobel | their tools make Eclipse look like amateur hour tbh |
| 17:46 | danlentz | I used it for about 4-5 months during a scala gig over the summer. I don’t think emacs is even usable doing scala and I tried. Its awful |
| 17:46 | sobel | and i'm no eclipse hater |
| 17:46 | rcbevans | I've used intellij for java and python with pycharm, intrigued by c-lion too |
| 17:46 | cfleming | sobel: I hear Eclipse has come a long way in recent years, but I was traumatised by early versions - I haven't touched it for years |
| 17:46 | rcbevans | and android studio is based on it and that seems to work pretty great |
| 17:46 | imanc | pycharm is nice- though I felt like a quitter ditching vim to use it |
| 17:47 | cfleming | imanc: There's nothing wrong with moving to pain-free tools |
| 17:47 | rcbevans | lars vogel seems to be doing a lot of work to push the eclipse foundation forward |
| 17:48 | rcbevans | I think they realised they were a bit long in the tooth in comparison |
| 17:48 | rcbevans | intellij seemed to not suffer from some of the sore spots I had with eclipse |
| 17:49 | tbaldridge | I often wonder if Eclipse just suffers from the fact that it's not a commercial product |
| 17:50 | cfleming | tbaldridge: That, and it also really helps that all the JetBrains products are made by one company with a consistent vision - it's all really coherent. |
| 17:50 | rcbevans | cfleming: +1 |
| 17:51 | cfleming | rcbevans: We use inc round here :) |
| 17:51 | cfleming | (inc rcbevans) |
| 17:53 | rcbevans | inc cfleming ah sorry, I'm pretty new to IRC, don't really know what I'm doing ^^ |
| 17:53 | rcbevans | (inc cfleming) ah sorry, I'm pretty new to IRC, don't really know what I'm doing ^^ |
| 17:53 | sveri | phpstorm lead me to intellij, pretty awesome too |
| 17:53 | rcbevans | oh wow, failing hard here |
| 17:53 | cfleming | Hehe, no worries, it's more of an in-joke than anything |
| 17:53 | Bronsa | rcbevans: no the bot is dead :( |
| 17:53 | cfleming | Bronsa: That too |
| 17:55 | pandeiro | funny i just opened intellij for the firstish time |
| 17:55 | Bronsa | cfleming: don't worry I'll write a note on paper, you'll get your inc |
| 17:55 | pandeiro | totally overwhelmed |
| 17:55 | imanc | sveri: yeh, I've used phpstorm also - hope to never use php again though. Causes outbreak of hives. |
| 17:55 | rcbevans | on clojure related stuff :), where is a good place to get started? I've been doing some project euler questions by myself, but I have no idea if the clojure I'm writing is really even good clojure for what i'm doing |
| 17:56 | rcbevans | are there any good resources to go through, I have the joy of clojure and O'Reilly clojure cookbook |
| 17:56 | rcbevans | i've seen 4clojure mentioned some places too |
| 17:56 | imanc | rcbevans: I'm reading the JoC atm, and messing around with a nice gfx library called quil. |
| 17:57 | raspasov | rcbevans: I personally like http://clojurekoans.com/ |
| 17:57 | justin_smith | rcbevans: for automated exercises, 4clojure and the clojure koans are decent |
| 17:57 | raspasov | rcbevans: also Aphyr's blog "Clojure from the ground up" series are excellent https://aphyr.com/posts/301-clojure-from-the-ground-up-welcome |
| 17:58 | raspasov | just go through the blog and find "clojure from the ground up" - there's a bunch |
| 17:58 | rcbevans | that looks ace |
| 17:58 | rcbevans | hadn't seen clojurekoans |
| 17:58 | rcbevans | I'll def give that a look |
| 17:59 | rcbevans | I was on the train friday and wanted to download an offline version of 4clojure, cloned a couple of 4clojure-offline type repos |
| 17:59 | rcbevans | neither seemed to work all that well though |
| 17:59 | justin_smith | rcbevans: 4clojure itself is open source |
| 17:59 | justin_smith | though you wouldn't likely want to run it on your phone |
| 18:00 | rcbevans | well I was on a laptop |
| 18:00 | rcbevans | does it have a repl type version? or just run a web stack and local copy of the site? |
| 18:00 | justin_smith | rcbevans: it's literally the code that runs the site |
| 18:01 | rcbevans | orly |
| 18:01 | rcbevans | probs shoul have looked at that |
| 18:01 | rcbevans | ah "Setup instructions for running locally" |
| 18:02 | rcbevans | *facepalm* |
| 18:03 | andyf | Anyone have recommendations for books or web sites that teaches about various aspects of web server development like: what is a session? where is it typically stored in a server and why? what is carried across a TCP socket that indicates the session, how secure is it, and why? between the level of a TCP socket and the web server, what do different web server containers/platforms do between them, and what are the relative |
| 18:03 | andyf | advantages of each? |
| 18:03 | justin_smith | andyf: all of that could be cleared up by reading the code for ring |
| 18:03 | justin_smith | andyf: good question regarding an actual book though, that would be interesting to see |
| 18:05 | imanc | andyf: maybe reading the source of some frameworks would answer those questions. E.g. sessions identifiers are stored in cookies, which are sent back to the browser on each request. The session data is then stored in whatever backend storage is configured - a file, a database, etc. |
| 18:05 | andyf | So ring has one 'standard' method it uses for representing sessions, and it is good enough for most purposes? Or it allows multiple different implentations depending upon unique needs someone may have? |
| 18:06 | justin_smith | andyf: wrap-session is a middleware that attaches a hash-map to the request, under the key :session |
| 18:07 | andyf | imanc: Sessions tend to last over one to several dozen requests, typically? Is it important to store them in persistent storage on the server because they can last even longer? Or because of load balancing over different physical servers for different requests from the same user? |
| 18:07 | justin_smith | andyf: it can use configurable storage backends (I believe there is a protocol you can implement?) but the defaults are cookie or in-memory and in either case you can have an optional encryption key for the cookie |
| 18:08 | justin_smith | andyf: the default in-memory session storage is an atom (for ring's wrap-session) and maps from an identifier in the user's cookie to the data |
| 18:08 | justin_smith | andyf: the code to wrap-session, and the various things it calls, are relatively straightforward |
| 18:08 | imanc | andyf: if you're load balancing then you need to remove any state from the appers. Often a medium such a memcached or redis, or a plain database running on external servers is used to persist session information |
| 18:09 | sveri | imanc: hehe and a lot of other things :D |
| 18:09 | imanc | * from the app servers |
| 18:09 | imanc | sveri: yeh indeed |
| 18:10 | andyf | Are there web servers that don't bother storing sessions in persistent storage, keeping it only in memory? |
| 18:10 | justin_smith | andyf: sure, for things like login state |
| 18:11 | justin_smith | andyf: not onerous to require a user to log in again if the server restarts and you only have one server |
| 18:11 | favetelinguis | are there any tools i can use to read a XML file and generate clojure code? |
| 18:11 | justin_smith | andyf: typically the "log in" |
| 18:11 | justin_smith | will map some data from the db into app memory |
| 18:11 | justin_smith | which keeps further request times lower |
| 18:12 | justin_smith | favetelinguis: generate code, or clojure data structures? clojure.xml is good for the latter |
| 18:13 | favetelinguis | justin_smith: no i want to genereta arbitrary code |
| 18:13 | justin_smith | favetelinguis: you'd have to design your own DSL for that I think. |
| 18:13 | justin_smith | but I would use clojure.xml to implement it |
| 18:14 | cfleming | Bronsa: Awesome, thanks! I need all I can get. |
| 18:15 | Xack | hm, currently modifying a leiningen template, wondering how i can test it without uploading to clojars |
| 18:15 | justin_smith | Xack: lein install |
| 18:16 | Xack | ahhh, thanks! |
| 18:17 | Bronsa | cfleming: I too have been robbed of my internet points because of lazybot being offline in the past, nobody deserves this. |
| 18:17 | justin_smith | clearly my improvements were not sufficient |
| 18:17 | justin_smith | we need a distributed lazy-bot array |
| 18:17 | justin_smith | with redundant laziness in waiting |
| 18:18 | Bronsa | justin_smith: you failed us |
| 18:18 | justin_smith | (dec justin_smith) |
| 18:20 | imanc | installing oracle java on ubuntu is a PITA |
| 18:20 | justin_smith | imanc: really? |
| 18:20 | justin_smith | (not in my experience) |
| 18:21 | justin_smith | imanc: any particular difficulty? |
| 18:21 | imanc | maybe i'm doing it wrong - I had to remove all trace of openjdk, download it into /usr/bin/java or something, and I'm now adding a PATH to porfile |
| 18:21 | justin_smith | imanc: that is like multiple layers of wrong |
| 18:22 | imanc | yeh? |
| 18:22 | justin_smith | imanc: there is a directory called /etc/alternatives |
| 18:22 | imanc | I'd hoped to be able to do apt-get install oraclejava :) |
| 18:22 | justin_smith | it's not free, so that's not an option |
| 18:22 | imanc | so what do I need to do with etc/alternatives? |
| 18:22 | justin_smith | imanc: it contains symlinks. If you replace the symlink called java, with one pointing to the java you want, that becomes the default java command |
| 18:22 | cfleming | Bronsa: There's no justice in this world. From what I can tell, it's all justin_smith's fault. |
| 18:23 | imanc | ahh OK |
| 18:23 | imanc | so it overrides anything else |
| 18:23 | justin_smith | imanc: /etc/alternatives/ allows multiple versions of anything to be installed, but it establishes which one is the default |
| 18:23 | danlentz | justin_smith: the correct answer was definitely use a custom type because i can declare both slots primitive |
| 18:23 | justin_smith | imanc: yeah, I have 5 jvms installed right now |
| 18:23 | justin_smith | danlentz: oh, cool |
| 18:23 | danlentz | (deftype Pair [^short k ^long v]) |
| 18:23 | imanc | OK, that sounds cool |
| 18:24 | danlentz | https://gist.github.com/danlentz/301a0f056ffd9c6605a9 |
| 18:24 | justin_smith | imanc: there is also an "update-alternatives" command, but all that does is automate the process of replacing the symlinks in /etc/alternatives to one pointing to the locations you want |
| 18:24 | danlentz | fwiw |
| 18:24 | imanc | how does that work with your JAVA_HOME and JRE_HOME env variables? |
| 18:25 | justin_smith | imanc: tbh I never set those, never have |
| 18:25 | Bronsa | danlentz: FWIW the type-hint at line 32 on the argvec is totally useless |
| 18:25 | Bronsa | danlentz: also deftype defines a ->Pair function, no need for `pair` |
| 18:25 | imanc | i guess if java is in a public path, then there's no ned |
| 18:26 | danlentz | ok, wait |
| 18:26 | justin_smith | imanc: if you do "ls -l /usr/bin/java" you'll see it is a symlink to "/etc/alternatives/java" |
| 18:26 | danlentz | the ^Pair on the argvec avoids reflection on .k, .v no? |
| 18:26 | justin_smith | imanc: by replacing "/etc/alternatives/java" you decide which java gets run |
| 18:27 | Bronsa | danlentz: the type hint on current-state does, the one on [^Pair current-state] is useless |
| 18:27 | justin_smith | (and as I mentioned before, /etc/alternatives/java is also a symlink) |
| 18:28 | cfleming | Bronsa: type hints are exclusively used for removing reflection in interop, right? There are no other subtle uses of them? |
| 18:28 | danlentz | the ^Pair on the return val of the fn does not avoids reflection when adding the .k and .v of the result of swap? |
| 18:28 | cfleming | Bronsa: I'm hoping to be able to mark unused hints in Cursive |
| 18:28 | Bronsa | danlentz: type hints on return value of fn only work in the context of defn |
| 18:29 | danlentz | ok b/c new-state is Pair anyway |
| 18:29 | danlentz | Bronsa: oh. |
| 18:30 | danlentz | good tip. |
| 18:30 | Bronsa | cfleming: eh, uhm they also affect method matching + primitive usage |
| 18:30 | cfleming | Bronsa: Oh, right, the primitive hints work differently. |
| 18:31 | Bronsa | I hate type hints. |
| 18:31 | cfleming | I hate metadata in general. |
| 18:31 | Bronsa | that too |
| 18:31 | Bronsa | and its weird evaluation semantics |
| 18:31 | cfleming | Especially during macroexpansion |
| 18:39 | imanc | how do you install cursive? |
| 18:42 | justin_smith | imanc: https://cursiveclojure.com/userguide/ |
| 18:45 | andyf | imanc: It is perfectly possible to install Oracle Java in your home dir on Ubuntu, and not worry about /etc/alternatives, /usr/bin, etc. But to do that you will need to set JAVA_HOME env variable, and add ${JAVA_HOME}/bin to your PATH. |
| 18:46 | imanc | andyf: presumably $JAVA_HOME/jre/bin is also needed? |
| 18:46 | imanc | as JRE_HOME |
| 18:46 | andyf | I've never needed to do that. |
| 18:46 | imanc | ahh - i followed some instuctions and did that |
| 18:47 | andyf | imanc: I guess I should say that when I've installed Oracle Java on Ubuntu this way, I was only using it from the command line, not from a web browser. |
| 18:51 | andyf | imanc: In the Oracle Java 1.8.0 JDK I have installed, jre/bin is a strict subset of what is in bin |
| 19:00 | lodin | I just realized that (defprotocol P (m [x])) (defrecord R [] Object (m [x] "m") P) (m (R.)) works. |
| 19:01 | justin_smith | lodin: is there a misplaced paren in that? |
| 19:02 | justin_smith | wait, why does P happen after the protocol impl for m? |
| 19:02 | lodin | justin_smith: Exactly. |
| 19:03 | justin_smith | lodin that makes my brain cry |
| 19:03 | lodin | You can put the interfaces anywhere, as long as the first things in an interface. |
| 19:03 | lodin | s/things/thing/ |
| 19:03 | lodin | err, can. not. type. |
| 19:04 | lodin | "is an". |
| 19:05 | lodin | justin_smith: It makes sense from a Java perspective, I guess. |
| 19:08 | justin_smith | I guess the ordering I have always seen was just a convention for clarity |
| 19:28 | lodin | justin_smith: Yeah. My first assumption was that defrecord does what extend-type does. |
| 19:44 | lodin | justin_smith: The sneaky thing is that you can write (defrecord R [...] P1 P2 (m ...)) if m is in both P1 and P2 and should be the same. (Of course, it's more likely that it shouldn't be the same, and then you have to use extend-type.) |
| 19:44 | justin_smith | weird |
| 19:45 | lodin | justin_smith: defrecord also defines Java methods (.m in this case), and there can only be one Java method m. |
| 19:46 | lodin | Or can it nowadays? Haven't look at Java for several years. |
| 20:25 | tcrayford____ | lodin: it's one method m per type signature |
| 20:25 | tcrayford____ | you can have m(Object, Object) and m(Object) just fine |
| 20:27 | lodin | tcrayford: Yeah, sure. Meant that you can't qualify the name with an interface (as you can in e.g. C# if I'm not mistaken). |
| 20:30 | tcrayford____ | yeah, you cannot |
| 20:30 | tcrayford____ | wouldn't be surprised if that went all the way down to the bytecode spec even ;) |
| 20:42 | justin_s3ith | justin_s3ith: that sure is a weird irc client you have |
| 21:22 | cfleming | tomjack: I've fixed those bugs for the next drop |
| 21:47 | tomjack | cool |
| 21:47 | tomjack | thanks! |
| 22:12 | cfleming | tomjack: No problem, if you'd like to try a dev build with the fixes before I release let me know |
| 23:09 | riceandbeans | question |
| 23:10 | riceandbeans | I hear of more and more things moving to clojure, and I'm going to need to support it, but I find the JVM abhorrent, are there any viable implementations of clojure NOT in the JVM? |
| 23:10 | dyreshark | riceandbeans: clojureCLR? |
| 23:10 | justin_s3ith | riceandbeans: clr, or js (but that still needs to compile via the jvm) |
| 23:11 | justin_s3ith | riceandbeans: any particular reason for not liking the jvm? |
| 23:13 | riceandbeans | aside from security issues and inherent memory leaks, it also has same nasty networking tendencies that cause it to break in certain operating systems where it supports ipv6 only by tunneling through ipv4 |
| 23:15 | justin_s3ith | citation needed on inherent memory leaks, I have web servers stay up for months, and likey they would have stayed up for years except for restarting for code updates |
| 23:16 | dyreshark | ^^ |
| 23:16 | riceandbeans | JVMs leak, it's pretty much a feature |
| 23:16 | justin_s3ith | least leaky vm I know of |
| 23:16 | dyreshark | how have you determined that they leak memory? |
| 23:17 | riceandbeans | because you tell them a max amount of heap memory and they go 5x over and never stay within their bounds |
| 23:17 | riceandbeans | in all my years of SA work, never once seen a JVM stay within its bounds |
| 23:17 | justin_s3ith | riceandbeans: then you are saying you don't understand java's command line flags? |
| 23:17 | rhg135 | also do native code even have limits? |
| 23:18 | riceandbeans | JVMs can have hard limits |
| 23:18 | justin_s3ith | rhg135: sure, OS imposed limits are always possible |
| 23:18 | dyreshark | rhg135: they do -- the OOM killer is a pretty hard limit to bypass ;) |
| 23:18 | riceandbeans | whether or not they respect them is another thing |
| 23:18 | rhg135 | oh well yeah, but that covers the jvm too lol |
| 23:18 | justin_s3ith | riceandbeans: in my experience, my vm dies when it is forced past the hard limit, and I have seen no exception to that |
| 23:19 | riceandbeans | I've just seen in take down servers in a cluster |
| 23:19 | justin_s3ith | also the security concerns are when you are client side running unknown code, it's quite solid compared to the alternatives on the server side |
| 23:20 | justin_s3ith | and client side running unknown code is a crapshoot no matter what |
| 23:20 | justin_s3ith | anyway, yeah, clojure can run on the clr, but isn't as mature for that target |
| 23:20 | riceandbeans | you have to submit to oracle, who's in bed with the us govt |
| 23:20 | justin_s3ith | it can compile to js, but from within a jvm process |
| 23:20 | riceandbeans | most people lock at very specific jvm requirements |
| 23:21 | riceandbeans | most people never patch their jvms |
| 23:21 | justin_s3ith | you don't need oracle's jvm, there is openjdk, an open source project. |
| 23:21 | riceandbeans | oracle doesn't like to patch their jvms |
| 23:21 | riceandbeans | which comes from oracle |
| 23:21 | justin_s3ith | and I promise, that javascript engines you will find and the clr are less reliable and less secure than any recent jvm |
| 23:21 | justin_s3ith | seriously |
| 23:21 | riceandbeans | openjdk is a product of oracle |
| 23:22 | justin_s3ith | it's an open source, community project, with backing from oracle |
| 23:22 | riceandbeans | clr means I'll have to run mono, which is hardly usable |
| 23:22 | justin_s3ith | riceandbeans: I guess you probably shouldn't use clojure at all |
| 23:22 | rhg135 | clojureclr, riceandbeans but be warned |
| 23:23 | riceandbeans | openjdk is a product of oracle, it's free, it's owned by them, it's partly gpl, but also has closed source and commercial parts in it too |
| 23:23 | riceandbeans | the only official developer of the code is oracle |
| 23:23 | justin_s3ith | openjdk is 100% open source |
| 23:23 | justin_s3ith | debian ships it |
| 23:23 | TEttinger | riceandbeans: there's always Common Lisp, which also received a ton of Department of Defense funding back in the day |
| 23:24 | justin_s3ith | debian won't even ship the emacs manual in the regular repos, because the license isn't permissive enough |
| 23:24 | riceandbeans | openjdk is not in base |
| 23:24 | riceandbeans | it's in non-free |
| 23:24 | rhg135 | icedtea compiles from source for me |
| 23:25 | p_l | SBCL is public domain, that's enough for "freedom"? |
| 23:25 | riceandbeans | in order to submit code to be part of openjdk you have to sign a waiver that you forfeit right to your code and surrender it to oracle and sun, and it has to be approved by oracle before it can be accepted |
| 23:25 | dyreshark | FWIW, twitter apparently uses OpenJDK with a few tweaks for their prod servers https://engineering.twitter.com/university/videos/twitter-scale-computing-with-openjdk |
| 23:25 | justin_s3ith | riceandbeans: I just went into aptitude, openjdk is not in nonfree |
| 23:25 | dyreshark | so if twitter chose to use it, chances are it's not *that bad* as a platform |
| 23:25 | TEttinger | I've personally been curious about alternative JVMs, like Avian, but that one's a pain to compile so that the standard lib has enough to run clojure |
| 23:26 | riceandbeans | twitter doesn't care about security |
| 23:26 | TEttinger | lol |
| 23:26 | scottj | https://packages.debian.org/sid/openjdk-6-jdk |
| 23:26 | justin_s3ith | riceandbeans: that's a contributor agreement for inclusion in the official repo, not a condition for modifying the code |
| 23:26 | dyreshark | whatever you say riceandbeans :) |
| 23:26 | riceandbeans | they're as much in bed with feds as oracle and facebook |
| 23:26 | dyreshark | have a nice night |
| 23:27 | TEttinger | we sure end up with our fair share of conspiracy theorists here in #clojure. remember that one guy who wouldn't run any code that he couldn't read himself? |
| 23:27 | riceandbeans | if your basis for the argument is the larry ellison is a great guy and his company is awesome, so it's a great product, you're not going to convice me of anything |
| 23:27 | justin_s3ith | riceandbeans: similarly clojure has a contributor agreement that must be signed before they will consider including your code in the official codebase. It is open source, and you can fork and distribute it all you like without said agreement. |
| 23:27 | justin_s3ith | This does not make it in any way nonfree software. |
| 23:27 | scottj | riceandbeans: https://packages.debian.org/search?keywords=openjdk&searchon=names&suite=stable&section=main note the main at the end there |
| 23:28 | TEttinger | riceandbeans, you know the internet that you're using right now was once a DoD project? |
| 23:29 | riceandbeans | that's new, because I used debian at 3.0, and stopped at 7.4, and it was throughout then, never in main |
| 23:29 | riceandbeans | due to java's licensing |
| 23:29 | scottj | riceandbeans: we've never argued java is good because larry is a great guy, we always said it was ok because he is an ok sailor. |
| 23:31 | riceandbeans | I'm aware of arpanet |
| 23:31 | raspasov | I have a sequence that looks like this ([14227624954630003 3] [14227624954630004 4] [14227624954630005 5] [14227624954630006 6] [14227624954630007 7] [14227624954630008 8] [14227624954630009 9] [14227624954630010 10]) |
| 23:31 | justin_s3ith | riceandbeans: anyway, you seem determined to hate the jvm, and it's not really worth my energy to expend much more effort convincing you otherwise. It sounds like you will likely be happier if you don't support clojure, and let people who want to use clojure go elsewhere. |
| 23:31 | riceandbeans | it's not that simple |
| 23:31 | raspasov | (reduce (fn [result new] |
| 23:31 | raspasov | [(conj (nth result 0) (nth new 0)) |
| 23:31 | raspasov | (conj (nth result 1) (nth new 1))]) [(lazy-seq []) (lazy-seq [])] x) |
| 23:31 | riceandbeans | puppet is going to be fully moving to clojure from ruby |
| 23:31 | justin_s3ith | raspasov: use a paste site please |
| 23:31 | raspasov | anything more idiomatic than this for splitting it into two collections? |
| 23:32 | scottj | riceandbeans: it's in main in squeeze, or debian 6.0 |
| 23:32 | justin_s3ith | riceandbeans: yeah, I know some cool dudes who do clojure there |
| 23:32 | riceandbeans | the entire project is being ported to clojure |
| 23:32 | riceandbeans | so anyone using puppet will need to support clojure |
| 23:32 | justin_s3ith | riceandbeans: I assure you that the clojure they are doing at puppet is not portable away from the jvm |
| 23:33 | TEttinger | $google avian jvm |
| 23:33 | TEttinger | no lazybot still? |
| 23:33 | justin_s3ith | amalloy or Raynes need to restart it, I don't have the permissions (though I do have a login on that server) |
| 23:34 | riceandbeans | whatever happened to parrot? |
| 23:34 | riceandbeans | https://en.wikipedia.org/wiki/Comparison_of_Java_virtual_machines |
| 23:34 | justin_s3ith | riceandbeans: it's out there, and not really being used in anger from what I can gather |
| 23:35 | justin_s3ith | wait, parrot is the new perl vm |
| 23:35 | justin_s3ith | did it ever have plans to support java? |
| 23:35 | riceandbeans | I thought it did |
| 23:36 | justin_s3ith | anyway, clojure is a bytecode compiler, so unless parrot is bytecode compatible with the jvm, it won't run clojure |
| 23:36 | riceandbeans | it supports a lot of languages |
| 23:36 | justin_s3ith | OK |
| 23:36 | justin_s3ith | clojure does not generate java, it directly generates bytecode |
| 23:36 | justin_s3ith | so you need either direct clojure support (which nobody has) or jvm bytecode compatibility (in other words you need to be a jvm) |
| 23:37 | riceandbeans | jvm bytecode is java |
| 23:37 | justin_s3ith | no |
| 23:37 | justin_s3ith | java is a language |
| 23:37 | justin_s3ith | jvm bytecode is a machine language for a virtual machine |
| 23:37 | justin_s3ith | clojure generates bytecode, it does not generate java |
| 23:38 | raspasov | anything more idiomatic? thanks! :) https://gist.github.com/raspasov/499b9aa5d0b0d0b91bf8 |
| 23:40 | justin_s3ith | raspasov: you could use destructuring like so - (fn [[r0 r1] [n0 n1]] [(conj r0 n0) (conj r1 n1)]) |
| 23:40 | tomjack | [(map first x) (map second x)] ? :) |
| 23:40 | raspasov | yea that's true, I was looking for something even more than that :) |
| 23:40 | justin_s3ith | tomjack: heh |
| 23:41 | raspasov | tomjack: but that generates two sequences, doesn't it? |
| 23:41 | justin_s3ith | tomjack: the reduce has the advantage of only walking the input once |
| 23:41 | justin_s3ith | raspasov: yours generates two sequences too |
| 23:41 | tomjack | yeah, but I figure it's unlikely you care |
| 23:41 | raspasov | oh really? |
| 23:41 | tomjack | perhaps you do |
| 23:41 | raspasov | I mean |
| 23:41 | raspasov | I meant |
| 23:41 | justin_s3ith | raspasov: your result has two sequences inside it |
| 23:41 | riceandbeans | justin_s3ith: so you're telling me, if I write hello world in clojure and I wrote the same in scala, and compiled it to bytecode, the bytecode would not be identical |
| 23:41 | raspasov | walking it once, instead of two sequences - yes the result is two sequences |
| 23:41 | justin_s3ith | riceandbeans: absolutely not |
| 23:42 | raspasov | used the wrong language :) |
| 23:42 | riceandbeans | vvkvebkiuhcbtdthitebjgltrnuvdrhiunnfhkhhvtjv |
| 23:42 | riceandbeans | vvkvebkiuhcbjglklrndvdldultbrhejbjjfuuflbien |
| 23:42 | justin_s3ith | riceandbeans: both generate jvm bytecode, but they have different infrastructure for bootstrapping the runtime parts of their languages |
| 23:42 | raspasov | ok thanks guys! |
| 23:44 | justin_s3ith | riceandbeans: on the other hand it is trivial to call java code from clojure, clojure code from java, scala code from clojure, clojure code from scala etc. etc. |
| 23:48 | riceandbeans | I was under the impression that JVM languages translated the parent language code to java before compiling |
| 23:48 | justin_s3ith | riceandbeans: none of the ones that are any good |
| 23:48 | justin_s3ith | java the language sucks |
| 23:48 | justin_s3ith | the jvm byte code / vm is much better |
| 23:49 | justin_s3ith | anyway, I am turning in for the night, best of luck |
| 23:49 | tomjack | scala code from clojure, trivial? hmm |
| 23:50 | justin_s3ith | tomjack: it compiles to classes you can invoke via interop |
| 23:50 | cfleming | It's relatively trivial but very ugly |
| 23:50 | tomjack | ISTR looking only at classes and methods, it seemed nightmarish |
| 23:50 | tomjack | ah, you just have to know what to look for I guess? |
| 23:50 | justin_s3ith | cfleming: pretty is a higher standard |
| 23:50 | cfleming | Yeah, you have to know how it mangles its classes, and some understanding of how it encodes traits etc |
| 23:51 | cfleming | justin_s3ith: No doubt. |
| 23:51 | cfleming | There's a company near here using datomic with Scala clients, actually |
| 23:51 | cfleming | Although that's the other direction, of course |