#clojure logs

2015-02-05

00:11tomjackinterestingly metadata does not survive apply for vectors
00:11tomjackgenerally, for proper seqables which don't copy their metadata
00:12tomjack(fn [& args] (meta args)) is a user error I suppose
00:15amalloytomjack: well, that's because vectors are never *actually* the arglists
00:15amalloyrather, the arglist is (seq v), not v
00:15amalloyi simplified a little for Lewix
00:19tomjackI thought I understood metadata, but I was wrong
00:20amalloyi mean, metadata lives on values, and if you construct a new version of the same value by modifying it a bit, eg via conj, you get the same metadata
00:20amalloyif you construct a totally distinct object, eg via seq, you don't
00:21tomjackI understand what happens; I want to understand what it means
00:21amalloywell, i thought i was explaining that
00:22tomjack"same value" is reminiscent of "same electron"
00:22tomjackyou don't mean same as in =, right?
00:22justin_smithtomjack: same Object
00:22justin_smithnot value, but identity
00:22amalloywell, the metadata is the same as in identity
00:23amalloyi was talking about getting a new version of a value, which of course leaves you something which is not "same"
00:23julianlevistonLewix: a vector isn’t a seq, is it?
00:23tomjackI don't think you mean the same thing by "a value" as I do
00:24justin_smithtomjack: what is a value?
00:24julianlevistonjustin_smith: is it the content of something?
00:24tomjackor rather, when I say "what it means", I'm thinking in a context where, inside (let [x [1 2 3] y [1 2 3]] ...), x and y refer to the same value (regardless of any compiler tricks)
00:25justin_smithtomjack: right, that's the same value
00:25justin_smithdifferent identities
00:25tomjackbut I find that my variables actually seem to refer to a pair of a value and an identity
00:25julianlevistontomaw: do you mean memory location?
00:25justin_smithtomjack: vars have identities, you can get at it via resolve, (var x), #'x etc.
00:25tomjacks/identity/non-value/, I dunno what really
00:25justin_smithtomjack: metadata does not go with values, it goes with identities
00:26tomjackright
00:26julianlevistontomjack: this is going to get very existential. :)
00:26justin_smithjulianleviston: there's a good hickey talk, I forget which one, about values state and identity that makes all this stuff very clear, he even references Whitehead
00:27julianlevistonjustin_smith: yeah, I’ve seen it a couple times. I love it :) Whitehead rocks… if not a little self-confusing at times.
00:27julianlevistonjustin_smith: I think it was actually the first exposure I had to clojure.
00:27tomjackso when working with values, I expect that, given I am careful in my code, I can put on "metadata-blocking glasses" and see a version of my code where the identities become irrelevant for understanding the meaning of the code
00:28julianlevistontomjack: I guess that depends if your code deals with meta-data or not!
00:28tomjackit's ok if the code deals with metadata
00:28tomjackin certain ways
00:28justin_smithtomjack: sure, metadata is used as an implementation detail that you can usually ignore
00:28tomjacke.g. consider (defn identity' [x] (vary-meta x update :counter (fnil inc 0)))
00:29tomjackI can put on metadata-blocking glasses, and then (= identity identity') as far as I'm concerned
00:29justin_smithtomjack: it wouldn't work on java Objects, or primitives
00:29justin_smithwhile identity does
00:29tomjackah, yes, it's a restricted identity
00:29tomjackto IObj
00:29justin_smithright
00:30tomjackok, I guess I do understand metadata
00:38tomjacknot really though. I guess some fns should be able to get tickets which permit them to inspect certain metadata (and to use the result of the inspection in the return value, not just in the return metadata). e.g. eval needs to be able to case on :macro
00:40justin_smithtomjack: it does that by looking up the var
00:40justin_smithtomjack: eval doesn't get the var as an arg, it gets a symbol, it uses that to find the var, and uses that to find the metadata
00:41tomjackyes, but if I had metadata-blocking glasses, putting them on would break macroexpansion
00:41tomjackwell, no, though. because vars aren't values
00:43tomjackI'll just wait until after I macroexpanded to put the glasses on :)
00:51tomjack(fn constantly' [x y] (with-meta x (merge (meta x) (-> y meta meta))))
02:20sobelcan someone help me understand what the idiomatic way to solve a little programming problem is with clojure? i have a simple row-data transformation to make
02:21Empperishoot
02:22sobelnutshell: reading csv, i need to capture some header data and distribute it to body rows. target is more csv, eventually on disk
02:23Empperifirst https://github.com/clojure/data.csv
02:23sobeli got as far as that library and it seems to read ok
02:24Empperithen I'd need a bit more information about "capturing header data and distributing it to body rows"
02:24Empperiwhat do you mean with that?
02:24Empperitake the first row then copy-paste that data to rows after that?
02:24sobeldenormalizing
02:24sobelyes
02:25Empperiok, so you have something like:
02:25Empperifoo;bar
02:25Empperiblergh;blorgh
02:25Empperiand you want:
02:25Empperifoo;bar;blergh;blorgh
02:25Empperi?
02:25sobelpretty much. the rows containing the foo;bar are identified by the content of the 1st element
02:26Empperiok, wait a sec then
02:27sobelthere will be >1 blergh;blorgh (body rows)
02:27ibashBlergh
02:32Empperisobel: https://www.refheap.com/b8917f48546768a06cf6b0dcf
02:32Empperishould get you started
02:33Empperidefinetly not what you need exactly
02:34sobeli can mung my way through the code if i have a decent design target. so, the header row will come after a row with a start token. so there's a couple state transitions there.
02:37vasHi, is it possible to reload changed html without restarting my lein server?
02:41julianlevistonvas: I thought that was the default?
02:45julianlevistonvas: Assuming you have :reload true set, or whatever that option is...
02:47vasmost files definitely follow that behavior, but my html files are not being reloaded. perhaps firefox is the culprit...
03:23devllHow to get the port of REPL?
03:25ggherdovdevll: probably not the answer you expect, but: `netstat -tulpn | grep java` on my ubuntu machine
03:26ggherdov(in your shell, not in the REPL)
03:26ggherdovdon't know how to make clojure tell you that
03:30devllI know this command.
03:30devllI have many Java threads
03:31noididevll, lein repl creates a file called .nrepl-port
03:31devllnoidi: thx
03:34devllnoidi: which dir ?
03:35devllI cant find it from current dir.
03:36devllmy bad. C
03:36devllI found it.
03:37ggherdovHello. I need a function (update-or-insert map key val func default) which takes a map, a key-val pair, a function.
03:37ggherdovIf key is already in map, gives a new map where key is mapped to (func (key map) val). If key not present, gives a map where key is mapped to (func default val).
03:37ggherdovExample: values are numbers. If key present, sum w/ new value. If not, insert value (default is 0).
03:37ggherdovDoes it exist already?
03:39julianlevistonggherdov: update-in? I’m not sure
03:39ggherdovjulianleviston: uhm, that one overwrite if key's already there.
03:39ggherdovbasically is a mix of the behaviours of update-in and assoc.
03:40noidi,(merge-with + {:a 2} {:a 1, :b 2})
03:40clojurebot{:b 2, :a 3}
03:40ggherdovnoidi: very many thanks
03:44julianlevistonggherdov: haha I’m sorry I had no idea what you meant from your description. My deficiency, I’m sure.
03:44julianleviston(inc noidi)
03:44lazybot⇒ 1
03:45hyPiRionggherdov: usually you can combine update-in and fnil
03:45julianlevistonggherdov: I don’t see how that fits your “defaults” requirement, tho
03:46julianlevistonggherdov: but like I said, I don’t understand the problem, really.
03:46hyPiRion,(map #(update-in [:a] % (fnil + 10) 1) [{:a 1} {}])
03:46clojurebot#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap>
03:47hyPiRion,(map #(update-in % [:a] (fnil + 10) 1) [{:a 1} {}])
03:47clojurebot({:a 2} {:a 11})
03:47hyPiRionggherdov: key is :a, 10 is default, func is +, val is 1
03:47hyPiRionthat is your goal?
03:48julianlevistonhyPiRion: if you only have one key, you don’t need to wrap it in a vec, I don’t think.
03:49hyPiRionjulianleviston: you can use update if you're running 1.7, but it's still in alpha
03:49hyPiRion,[(update {:a []} conj 1) *clojure-version*]
03:49clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
03:50julianlevistonhyPiRion: no, update-in…
03:50hyPiRionoh dear, I need my morning coffee
03:50hyPiRionjulianleviston: that doesn't work
03:50hyPiRion,[(update {:a []} :a conj 1) *clojure-version*]
03:50clojurebot[{:a [1]} {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}]
03:51julianlevistonhyPiRion: right you are… I read the doc wrong.
03:51julianlevistonhyPiRion: SO MANY MISTAKES! Julian… lurk more!
03:54ggherdovhyPiRion: thanks for the hint about fnil. Yes that's it
03:55hyPiRionhurray!
03:55julianleviston(inc hyPiRion)
03:55lazybot⇒ 66
03:56ggherdovlol for inc-ing users :) I think ##java has something like that too
03:56ggherdov(the channel)
03:56hyPiRionyeah, many have some sort of bot
03:56ggherdovthen ...
03:56ggherdov(inc noidi)
03:56lazybot⇒ 2
03:57ggherdovwhat's right is right
04:09zactshum I need to improve my clojure style
04:10zactsI find myself using map / reduce / filter like I did regexes in Perl
04:10zactsI don't think I use them for what they are supposed to be used for
04:11zactsalthough it seems it's better to use higher order functions than a recursive equivalent
04:11zacts(loop recur) in this case
04:12zactsI need to unlearn perl for clojure, oh well. It'll happen eventually. lol
04:13hyPiRionzacts: Stuff like that happens with experience. I'd suggest not to stress it :)
04:14zactsheh, yeah
04:22kirGreetings all. Trying to understand Clojure namespace; thought I understood it, until I replaced (ns kir.funcs) with (in-ns 'kir.funcs) in a lib - resulting in an error....
04:23kir"Unable to resolve symbol: defn in this context, compiling:(kir/funcs.clj:7:1)[...]"
04:24kirI was under the impression the (in-ns) would create a namespace for the lib, just as (ns) did?
04:25kirBtw, I'm including the lib with : (use 'kir.funcs)
04:26michaelr`cursive users here?
04:26michaelr`or the cursive developer? ;)
04:27hyPiRionkir: No, in-ns makes the barebones of a namespace only
04:28hyPiRionYou would at least have to do something like (clojure.core/refer 'clojure.core) to get core functions, and probably some more if you want to be on the safe side
04:28hyPiRionMy suggestion is to just use ns :p
04:29julianlevistonmichaelr`: I’ve been using it since yesterday a little...
04:29kirhyPiRion, thanks for the tip, going to test...
04:29michaelr`julianleviston: :)
04:30cflemingmichaelr`: What's up?
04:30julianlevistonmichaelr`: can I help?
04:30jinagaranoi'm trying to set up a postgresql db for use with clojure. i'm running windows 7, installed postgresql, added the dependencies to project.clj. when i'm trying to create a table, i get an error "org.postgresql.util.PSQLException: Connection refused." hostname, port and user/password are correct. what could be the problem?
04:30julianlevistonmichaelr`: ooh even better… the main man of all things running writing :)
04:30michaelr`configure identation parameters, it's not always working
04:30michaelr`cfleming: sometimes it does.. but a lot of times it doesn't
04:31michaelr`is there already an issue open on this or I'm doing something wrong?
04:31julianlevistonjinagarano: stupid question, but is it on?
04:31julianlevistonjinagarano: that happens to me often.
04:31jinagaranohow do i turn it on? no stupid questino there :)
04:32cflemingmichaelr`: What are you doing to adjust the parameter?
04:32kirhyPiRion, that worked. Previously I had tried (refer 'clojure.core) to resolve it. I can see my error now. Thank you :)
04:32julianlevistonjinagarano: sadly I don’t know on win… on the mac, I open it. You can set it up to always run, but I haven’t done that… and I’m not sure that it’s the default, depending on your installation.
04:32michaelr`cfleming: Alt-Enter on defonce, for example and then select 2 from the dropdown menu.
04:33cflemingmichaelr`: Ok, and that doesn't work?
04:33jinagaranojulianleviston: well, i can find that out. thanks!
04:34hyPiRionkir: np :) If you want to know more about how the ns macro works, you can try (require '[clojure.walk :refer [macroexpand-all]]) and do (macroexpand-all '(ns foo)). You could also attempt to read the source, but that's not always as easy
04:34michaelr`cfleming:
04:34michaelr`https://www.refheap.com/31ab32048689327cabf9d10bb
04:34michaelr`nope, here is an example ^^
04:35hyPiRionI find macroexpanding to be helpful when I don't know what happens behind the scenes
04:35cflemingmichaelr`: That's correct for a setting of 2, if you want the next line indented, you want to set it to 1, or even better to Only Indent
04:35cflemingmichaelr`: I need to put some text on the website explaining that parameter
04:36michaelr`indeed 1 worked :)
04:36michaelr`I though it was about the number of tabs/characters to indent
04:36cflemingmichaelr`: Here's how this works - this is designed for macro forms. They generally have a number of parameters, and then a body.
04:36michaelr`oh cool, i get it
04:37michaelr`this is the number of params
04:37cflemingmichaelr`: That number is the number of elements after the head symbol that Cursive will assume are parameters
04:37cflemingmichaelr`: Right.
04:37michaelr`great
04:37michaelr`wish I knew that earlier
04:37michaelr`;)
04:37cflemingmichaelr`: The parameters get lined up, and the rest of the elements are assumed to be the body and are indented by 2
04:37kirhyPiRion, cheers, I was actually wondering how macro expansion works.
04:37michaelr`ok
04:38cflemingmichaelr`: Yeah, my doc requires a little inventiveness, sadly
04:38michaelr`btw, thanks for Cursive
04:38michaelr`Especially the wonderfull debugger
04:38michaelr`it's a life saver
04:38cflemingmichaelr`: If you set it to only indent, then everything after the head symbol will be just indented by 2 spaces - this is good for defn-like things
04:38cflemingmichaelr`: No worries, I'm glad it's working for you!
04:38clojurebotCool story bro.
04:39cflemingmichaelr`: More bugfixes in the next drop, expression eval should be more reliable
04:39michaelr`the debugger really improved in the last version
04:40cflemingmichaelr`: Yeah, I totally broke it in the previous one, and while I was fixing that I fixed a lot of other things.
04:40cflemingmichaelr`: I use the debugger all the time, I wish I'd done that a year ago, it only took two days ;)
04:40michaelr`heh
04:41michaelr`hmm
04:41cflemingmichaelr`: Now that expression eval works, it's a small step to a debug REPL when you're stopped at breakpoints
04:42michaelr`used it yesterday, it actually works :)
04:42cflemingThe eval?
04:42michaelr`yes
04:42cflemingYeah
04:42michaelr`Alt-F8
04:42cflemingI can't believe I lived without it for so long, or at least with a seriously broken version
04:44cflemingIntelliJ 14 has some really nice debugger enhancements in Java, I have to see how many of them I can make work
04:44michaelr`Is there an option somehow to set up a shortcat to eval (user/reset)?
04:44michaelr`shortcut
04:44julianlevistoncfleming: is there a good video walkthrough on cursive?
04:44cflemingmichaelr`: Unfortunately no, see https://github.com/cursiveclojure/cursive/issues/85
04:44cflemingjulianleviston: Sadly there isn't even a bad one
04:45cflemingjulianleviston: It's somewhere on my to-do list
04:46julianlevistoncfleming: delegate! :)
04:46cflemingjulianleviston: Hehe. There are a couple that help with getting it set up, but they don't go into great depth.
04:47julianlevistoncfleming: I watched an install video the other day… can’t remember where it was but apparently there was a second video but I can’t remember where it was
04:47michaelr`cfleming: good to know that other people experience the same pains and needs as I do..
04:47julianlevistoncfleming: ah yes.
04:47michaelr`cfleming: +1 mouseless jump to repl
04:47julianlevistonjony epsilon…
04:47julianlevistonhttp://vimeo.com/103808402
04:48cflemingmichaelr`: Yeah, I think I'm pushing 300 open issues these days. Whatever your heart desires is probably in there somewhere.
04:48cflemingjulianleviston: Yeah, Timothy Baldridge has one too
04:48julianlevistoncfleming: is it all self?
04:48julianlevistoncfleming: are you going to do all of this stuff yourself?
04:48cflemingjulianleviston: Well, mostly.
04:49cflemingjulianleviston: I'm working on an extension API, in the short term that will be for adding symbol resolution for 3rd party libs
04:49julianlevistoncfleming: I don’t want to be rude about jony but it’d be nice if he edited his videos a bit… and I find his audio could do with some compression
04:49cflemingjulianleviston: In the long run people will be able to add more complex functionality, but developing a good API takes time
04:50cflemingjulianleviston: Try Timothy's and see if it works better for you
04:50julianlevistoncfleming: it’s purchase?
04:50cflemingjulianleviston: There's one free and one non-free on CLJS
04:51cflemingI have 305 open issues. Fortunately I have 421 closed issues, so I'm still winning.
04:52julianlevistoncfleming: god I wish I would hurry up and finish the project I’m working on so I could start on my the pedagogical project I really want to do.
04:53kirmichaelr`, " cfleming: +1 mouseless jump to repl" - only possible, through custom keymap
04:53kiralready*
04:58michaelr`kir: please share :)
05:00julianlevistoncfleming: I really wish that the REPL was even more tightly integrated with the IDE…
05:00julianlevistoncfleming: generally, not specifically to cursive.
05:01julianlevistoncfleming: I want the forms I’m editing to be the live forms in the “REPL”.
05:01kirmichaelr`: Settings -> Keymap -> In the keymap list there is "Other" -> in that list there is "REPL" - I've set mine to alt+0
05:02kirmichaelr`, press esc when you're in the REPL to get back to your code
05:04TEttinger(inc kir)
05:04lazybot⇒ 1
05:07cflemingjulianleviston: You mean like a LightTable style instarepl?
05:12julianlevistoncfleming: Sort of. LT still has a separate process than the source. I mean that the “source” *is* the live data structures. So if you have a (def x 5) and you change that 5 to 10, it does a reload… to do this, you’d have to mod clojure quite a bit, I imagine… stuart sierra was barking up this tree a bit with his component workflow… I’d like my “source” to be actual live data within a VM… and for it to
05:12julianlevistonable to describe itself rather than the opposite 2 - step process which is REPL driven development.
05:14julianlevistoncfleming: so… editing that 5 to a 10 is changing the value in memory first… and only then serialising it to display and/or text for the source… if that makes sense. It’s really not possible at the moment, AFAIK… but we could get there… and it’d be… amazing. Because then you really could use the full power of LISP on the data structures that comprise the program, if that makes sense...
05:15cflemingjulianleviston: Sure - I'm not sure what the practical difference of that is from modifying the text and have it update though
05:16julianlevistoncfleming: when your “source” isn’t text, interesting things can happen (as I’m pretty sure you know). A lot of errors would be impossible… like creating an invalid data structure, or a syntax error...
05:17julianlevistoncfleming: You’d effectively get live linting for free.
05:18julianlevistoncfleming: and a whole raft of different kinds of editors would be pretty trivial… like the gorilla REPL… because you could simply plug functions into your editor, right? :-) it’s all just functions.
05:18julianlevistoncfleming: I think macros break things, tho… because they’re inherently tied to reading… perhaps. Anyway, it’s just an interesting idea, really :-)
05:19cflemingThe problem is that you still have to represent your program somehow, probably as something similar to the text we use now. And it's still a two step process since that doesn't get evaluated directly, it gets compiled.
05:21julianlevistoncfleming: yep. It depends how you view your source of truth. Smalltalk VMs are an interesting example… file in / file out… of pure true data structures that can’t be “broken”.
05:21julianlevistoncfleming: I think shifting as much of our “stuff” (as programmers) into data as possible is the best idea… given that that’s where flexibility lies.
05:22julianlevistoncfleming: but yeah, good points, as always.
05:25cflemingjulianleviston: I definitely think it's good to think about these things, but I struggle to see a useful path to actually making a real editing environment out of them. I haven't looked closely at Eve, I should take another look at it.
05:25julianlevistoncfleming: I guess we’ll see what chris granger’s next project eventuates as ;-)
05:25julianlevistoncfleming: oh yeah, that’s what it’s called? Last time I looked it was called aurora… does it have a way one can look at it now?
05:25julianlevistoncfleming: last time I looked (preview video) it had gone too far, IMHO…
05:26julianlevistona lot of times when people try to simplify, they go a bit too far.
05:26julianleviston“Lovely, but limited” springs to mind.
05:26cflemingI think the language is Aurora and the environment is Eve?
05:26cflemingNot sure.
05:27michaelr`kir: i mean, I have the repl tool window mapped to Alt-6 and there is
05:27michaelr` F12 but often it wouldn't go to the command prompt. another thing
05:27michaelr` is that I would often like to switch to the console in the repl in
05:27michaelr` order to examine a long exception
05:27michaelr`sorry, was disconnected
05:29cflemingmichaelr`: Yeah, the solution is basically what kir said right now. Alt-num to go to REPL, and esc to go back
05:32kircfleming: Btw, I really appreciate the multi-line-input REPL; thanks.
05:32cflemingkir: No worries, glad you're liking it. I use that a lot too.
05:34julianlevistoncfleming: this is the only thing I’ve seen of aurora: https://www.youtube.com/watch?v=L6iUm_Cqx2s
05:34cflemingjulianleviston: Yeah, me too
05:34julianlevistoncfleming: I had an almost visceral reaction to the tonal quality of his voice.
05:36cflemingjulianleviston: More than that, I just wasn't very excited by the video
05:36cflemingI guess sooner or later someone will reinvent programming, but I haven't seen anything that shouts that to me yet.
05:38julianlevistoncfleming: yeah, it just seemed like another mathematica to me… and it seemed to not be building on the past, but kind of clearing it out… which made me a bit sad… the main thing I dislike, though, is that the system can’t be modified from within itself, or applied to itself… it’s not homoiconic… not that most interfaces are, but I expect that…
05:38julianlevistoncfleming: I feel that frank (VPRI) or even seaside are more advanced.
05:39julianlevistonbut hey, what have I done latel? :-) they’re doing good work.
05:39julianlevistonlatel*
05:39julianlevistonlately* (sigh)
05:39julianlevistoncfleming: as are you! :) <3
05:40TEttingeryou've made typos lately :D
05:40julianlevistonTEttinger: boy have I! :)
05:40cflemingAbsolutely, kudos to them for trying. I'm interested to see more of what they come up with. I'd just like to feel more optimistic about it.
05:41TEttingerit's interesting how a number of questions have popped up in ##fsharp about clojuresque usage of the language (code as data and calling things by string name), which seems very difficult in such a strictly typed language
05:42julianlevistoncfleming: if they can get simple while keeping advanced capability (or some way of traversing them) then it’ll be cool… that’s (interestingly) what my primary interest is.
05:52julianlevistonIs a vec of 3 elemet vecs the best way to represent a tuple?
05:53julianlevistonAcutally nevermind. It’s small. I’ll just use that.
05:53Glenjaminit is the simplest
05:53julianlevistonGlenjamin: I really meant a collection with three elements. If it were large, I’d use a vec of records, yeah?
05:54Glenjaminlarge number of elements, or large number of items?
05:55Glenjaminactually, i don't really know the answer either way
05:55julianlevistonGlenjamin: elements… all good. Depends what the criteria are. HeHe :)
05:55Glenjamini know there's an optimised tuple implementation available if you need high perf short-tuples
05:55julianlevistonGlenjamin: thanks, I’ll keep that in the back of my mind.
06:16luxbockwhat is the etiquette for using someone elses work in your own library? I'm building a REPL util library for myself, and I'd like to use print.foo but do some changes that might not jive with the author, though I haven't asked yet
06:16luxbockI'd obviously give attribution to the author, but is there something beyond that I should do if I'm just going to rip a huge part of someone elses useful library and do some tiny tweaks?
06:18julianlevistonluxbock: you’d probably be best advised to ask him. Different folks have different ideas of what’s reasonable.
06:18julianleviston(or her)
06:18luxbockalright, I'll ask him how he'd feel about the changes I'd like to make
06:18Glenjaminif all else fails, you'll want to follow the license terms
06:19luxbockyeah, it's MIT license
06:21TEttingerMIT doesn't even require attribution IIRC
06:21TEttingeryou can't change the license on the MIT-licensed files, but that's about it
06:22luxbockyeah I know the license allows me to do what I want, but I was more curious about the etiquette :)
06:22TEttingertell him, thank him, change your fork at will?
06:22luxbockyep I'll do that, thanks
07:58justin_smithTEttinger3: rubyists giving f# a go? (regarding using code as data)
08:15NhanHIs there anyway you can format ring stacktrace with lein plugin like ultra ? (Ie when I'm running as `lein ring server-headless` and error popup, it formatted nicely)
08:15justin_smithNhanH: you could replace the wrap-stacktrace middleware
08:17NhanHdo you mind elaborate a bit? (I have no idea how lein plugin work), so basically, I need to replace the wrap-stacktrace middleware without whatever the plugin is using to format the s tacktrace, right?
08:17justin_smithit's not a lein plugin
08:17justin_smithbut yeah
08:18NhanHwhat is not a lein plugin? Middleware?
08:18justin_smithright
08:18justin_smithlein is for build time
08:18NhanHyeah I know
08:18justin_smitha lein plugin could only help with errors during dep resolution / startup
08:18justin_smithit can't help you at runtime
08:19NhanHokay thanks. So I guess the follow up question would be: is there any middleware to format ring stacktrace?
08:20justin_smithlike I said, wrap-stacktrace does that, and if you don't like its formatting, you could make your own based on what ultra does
08:20justin_smithhttps://github.com/mmcgrana/ring/blob/master/ring-devel/src/ring/middleware/stacktrace.clj
08:22justin_smithNhanH: this is what wrap-stacktrace does: http://i.imgur.com/67oFIEf.png
08:23NhanHI tried that earlier, and I think that's the default behaviour of ring even if you don't put the middleware in. But yeah, that stacktrace is still a bit annoying
08:23NhanHThanks anyway
08:24justin_smithNhanH: ok, so we have the other option, making some other handler based on wrap-stacktrace, with behavior more like ultra
08:26NhanHseems like time to read ultra source! :-)
09:46vasis there an idiomatic way to serve a favicon with compojure or ring?
09:46justin_smithvas: typically I use a middleware that special cases "favicon.ico" no matter what the leading path is
09:48vasjustin_smith: coo. thanks for your <input>
09:48vas=]
09:51vasi'm not really sure what the favicon request even looks like to write code to handle it in my barebones routing..
09:51justin_smithvas: https://www.refheap.com/96939
09:52justin_smithit's a bit convoluted (those abstractions make sense with my other custom middlewares) but it works
09:53justin_smithrefer-favicon is a middleware that can be used in the same way you use any other ring middleware
10:02justin_smithvas: just updated that paste with a simpler version at the bottom https://www.refheap.com/96939 that doesn't rely on the other defs
10:13thesaskwatchHi .. anyone knows how to disable emacs prompt asking about file save before evaluating file via cmd+c cmkd+k ?
10:13the_freyM-x customise might present an option to disable it?
10:16thesaskwatchthe_frey: clever ;)
10:19ordnungswidrigthesaskwatch: you can defun a function that calls save-buffer and cider-eval-buffer
11:05acron^hey all
11:05acron^I'm having trouble reading from a file
11:05acron^https://www.refheap.com/96945
11:05acron^I only want to read the first 5 lines
11:05acron^but I keep getting Caused by: java.io.IOException: Stream closed
11:06acron^Exception in thread "main" java.io.IOException: Stream closed
11:06acron^if I only inspect the first line, it work fine ...
11:06justin_smithacron^: map is lazy, you need to force the results you use before leaving the "with-open" context
11:06julianlevistonacron^: is LF what you think it is?
11:06ordnungswidrigacron^: I guess that line-seq is lazy. Until you try to evaluate the whole seq the reader is closed
11:06julianlevistonjustin_smith: ah… cool :)
11:07justin_smithacron^: what happens is that by the time the map tries to do its thing, you are outside the with-open block
11:07ordnungswidrigacron^: (doall lines) might help
11:07justin_smithacron^: use (doall (take 5 (map ...))) if you need to use with-open
11:07justin_smithor yeah, actually just adding a doall
11:08justin_smithacron^: also, (nth (take 5 sq) 5) will always be nil
11:08ordnungswidrigit's actually when `map` want's to do it's thing but when (nth lines 1) forces seq
11:08julianlevistonthat code could deal with some reformatting
11:08ordnungswidrigthat should read "actually not when `map`..."
11:09acron^julianleviston: i am really open to suggestion
11:09acron^i'm pretty new to clojure
11:09julianlevistonit’s not immediately obvious where the let block bindings ends.
11:09justin_smith,(nth (take 5 [1 2 3 4 5]) 5)
11:09clojurebot#<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>
11:09justin_smithoh yeah
11:09justin_smithnot even nil, it's an exception :)
11:09justin_smith,(nth (take 5 [1 2 3 4 5]) 4)
11:09clojurebot5
11:10justin_smith,(nth (take 5 [1 2 3 4 5]) 5 nil)
11:10clojurebotnil
11:10acron^sorry
11:10acron^the 5 was an error
11:10justin_smith(if you don't want the exception behavior, you can provide a default)
11:10acron^should be 4
11:10justin_smithright
11:10ordnungswidrigacron^: #(convert-line %) can be simplified to convert-line, unless that's a macro
11:10acron^ordnungswidrig: face-palm, oh yeah :)
11:11acron^sorry im still not 100% where i need to add thi9s doall
11:11julianlevistonacron^: this is what I’d write it as… https://gist.github.com/JulianLeviston/c5def8e78eeca9f1eaba
11:11acron^around the with-open
11:11acron^?
11:11justin_smithacron^: (doall (map ...))
11:11justin_smithacron^: once you leave the with-open, it's too late, the with-open is closed
11:12justin_smithso you need to force the result before the with-open exits
11:12acron^ahhh
11:12acron^that worked perfectly
11:12acron^ok
11:12acron^so
11:12justin_smithit's as if you opened the gate, said "when I ask for an apple, get one from that tree, closed the gate, and then asked for an apple
11:12justin_smithmissed a close " up there
11:13acron^nice analogy :)
11:13ordnungswidrigacron^: make sure that you "take" within the "doall" or you will force the whole file even if you process only the first n lines
11:13acron^nice analogy :)
11:13acron^oops
11:13justin_smithordnungswidrig: yeah, in the original the take is inside the map call
11:14acron^new version: https://www.refheap.com/96947
11:14acron^works a treat :)
11:14justin_smiththe first 4 should maybe be a 3? just a guess
11:15acron^you'd have thought so, wouldn't you?
11:15acron^actually the file format author decided to put 2 vars on that line, space-separated
11:15ordnungswidrign acron^: a more idiomatic version https://www.refheap.com/96946
11:15acron^and leave blank the line above
11:16acron^what's the ->> notation?
11:16ordnungswidrigacron^: a very importand short cut to avoid (nested (deep (burried (whatever (function calls)))))
11:17ordnungswidrigacron^: (->> [1 2 3 4] (map odd?)) => (map odd? [1 2 3 4 5])
11:17julianlevistonacron^: it’s the human centipede of clojure…
11:17justin_smith,(let [nums [1 2 3 4 5] [a b c] nums] c) ; acron^ - this is another trick that may help you
11:17clojurebot3
11:17acron^julianleviston: oh god, i hope not!
11:18ordnungswidrigacron^: ->> takes the first argument and inserts it as the last argument in the following expression. Then it takes the result and inserts it as the last argument to the next expression and so on.
11:18ordnungswidrigit a so called "threading macro".
11:18julianlevistonacron^: there are two variants… -> feeds the output into the first arg of the next form… and ->> feeds the output into the last arg of each form.
11:18justin_smithacron^: the threading macros (-> / ->>) are for propagating data through expressions
11:18acron^Ah ok, how does it differ to just -> cs ive seen that too
11:18acron^Aha
11:18ordnungswidrig-> inserts as the first argument, ->> as the last
11:18acron^Got it
11:18julianlevistonacron^: :) so pretty.
11:19ordnungswidrigsome-> stops as soon as there's a falsey value (typically nil)
11:19ordnungswidrigwhere handy for, e.g. (some-> x inc)
11:19julianlevistonordnungswidrig: better explain as-> as well! :-)
11:20ordnungswidrigand there are cond-> and as-> which are advanced variations
11:20justin_smith,(some-> {false :ordnungswidrig} false str)
11:20clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn>
11:20justin_smithhrmph
11:20justin_smith,(some-> {false :ordnungswidrig} (get false) str)
11:20clojurebot":ordnungswidrig"
11:21justin_smiththat never returned false though, I need coffee
11:21justin_smithlol
11:21ordnungswidrighahaha
11:21ordnungswidrig(inc coffee)
11:21lazybot⇒ 1
11:21ordnungswidrigno wonder...
11:21justin_smith(some-> {:a false} :a)
11:21justin_smith,(some-> {:a false} :a)
11:21clojurebotfalse
11:22justin_smith,(some-> {:a false} :a inc)
11:22clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number>
11:22justin_smithas expected
11:22justin_smith,(some-> {:a nil} :a inc)
11:22clojurebotnil
11:22justin_smithordnungswidrig: as we see, only nil short-circuits some->
11:22justin_smithfalse does not
11:22fortruceif I want to map a function with side effects over a seq, is there a way to do it such that I don't have to hold the entire seq in memory as it's being done?
11:22acron^justin_smith: https://www.refheap.com/96948
11:23justin_smithfortruce: dorun
11:23justin_smithfortruce: or use doseq instead of map
11:23fortrucejustin_smith: thanks, i'll check those out
11:23justin_smithacron^: yeah, destructuring is pretty cool, huh
11:23ordnungswidrigjustin_smith: oh, I did not know that. I wonder why.
11:23justin_smithordnungswidrig: some-> is specifically for nil
11:23justin_smith,(doc some)
11:23clojurebot"([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"
11:24justin_smith,(doc some->)
11:24clojurebot"([expr & forms]); When expr is not nil, threads it into the first form (via ->), and when that result is not nil, through the next etc"
11:24ordnungswidrigI can live with that ;-)
11:25julianlevistonoooh
11:25julianlevistonoh nevermind.
11:25julianlevistonlol @ self
11:25justin_smithacron^: you could also replace the binding of lines with the destructure directly, but that's a style decision
11:26julianlevistonacron^: you could also use interpose “\n” if you get bored of all those \n repetitions.
11:26justin_smithjulianleviston: it's a little trickier with a 3 item pattern though - unless there is some interpose / concat trick
11:28justin_smith,(apply concat (interpose ["\n"] [[:a :b] [:c :d] [:e :f]]))
11:28clojurebot(:a :b "\n" :c :d ...)
11:28justin_smiththat works, kind of, but a little clumsy
11:29tcrayford____so yesterday I open sourced a clojure webapp profiling tool: Clojure Miniprofiler: http://yellerapp.com/posts/2015-02-04-miniprofiler.html (in case anybody here does webapp server performance work in clojure). I'd love to hear any feedback anybody has
11:30justin_smithtcrayford____: COOL, I'll definitely check that out
11:30lunkhello, is there a more idiomatic way to do fall-back tests for resolving parameters/environment variables? http://pastebin.com/Ef2d66QY
11:30lunkapparently beanstalk says env, but means params, for their tomcat container
11:31havenwoodtcrayford____: ooh, nifty!
11:36julianlevistonjustin_smith: I love clojure… ## (apply str (map #(apply str %) (let [newlines-every-second-element (comp (partial interpose "\n") (partial partition 2))] (newlines-every-second-element ["a" "b" "c" "d"]))))
11:36lazybot⇒ "ab\ncd"
11:37julianlevistonjustin_smith: very silly of me, I know… but I like that I can build my own custom function to do whateve I like quite efficiently as if it was a first class function. Not that my version there was particularly elegant, but yeah :)
11:40acron^justin_smith: https://www.refheap.com/96948
11:40acron^oops
11:40acron^sorry
11:40acron^keep pressing up-enter
11:41julianleviston,(defn interpose-nth [n i coll] ((comp (partial interpose i) (partial partition n)) coll))
11:41clojurebot#'sandbox/interpose-nth
11:41julianleviston,(interpose-nth 2 "\n" [1 2 3 4])
11:41clojurebot((1 2) "\n" (3 4))
11:42julianlevistonnot *quite* what I was after hm.
11:42acron^Random question - how do I specify mutiple things in :require ?
11:42julianleviston(:require [om.core :as om :include-macros true] …)
11:42julianlevistonreplace the … with as many of those bracketed sections as you like...
11:42julianlevistonacron^: assuming you’re talking about the ns require?
11:43dnolencfleming: ping
11:43acron^julianleviston: yes, thanks
11:43acron^it's giving me grief
11:46acron^thanks, i was doing something weird
11:46julianlevistonjust looking at the interpose source humbles me.
11:46acron^lol
11:47julianleviston:)
11:59julianlevistonis there a thing like when-let which has a separate predicate function instead of the first binding?
11:59julianleviston(uknown-fn predicate [bindings…] (fn body)…)
12:00julianlevistonI guess I could just do what I usually do: wrap a let in a when...
12:00justin_smithjulianleviston: that would be an easy macro to write
12:00llasramjulianleviston: You want the maybe monad from algo.monads
12:00llasram(although I do think it'd be nice if `maybe`-specialized version of it were in core)
12:01julianlevistonI basically want (when-not empty? [x thing] ...)
12:02gfredericksjulianleviston: use seq
12:02julianlevistoni want when to be predicate-pluggable hehe :)
12:02gfredericks(when-let [x (seq thing)] ...)
12:02justin_smithgfredericks: or (when-let [x (not-empty thing)] ...) so that you still get the original datatype if it isn't empty
12:02julianlevistongfredericks: ooh cool :)
12:03justin_smith,(not-empty [1 2 3])
12:03llasram(am/domonad am/maybe-m [x (f), :when (pred1? x), y (g), :when (pred2? y)] [x y])
12:03clojurebot[1 2 3]
12:03julianlevistonjustin_smith: mind being bent. ;-)
12:03julianleviston,(not-empty [])
12:03clojurebotnil
12:03gfredericksjustin_smith: not-empty is a funny function
12:03justin_smithgfredericks: I am very fond of it
12:03julianleviston,(empty [:a :b :c])
12:03clojurebot[]
12:03gfredericksit smells wasteful to my prematurely-optimizing gut
12:04justin_smithgfredericks: for example, (when-let [x (seq {:a 0 :b 1}] ...) - not-empty is a clear winner here
12:04gfrederickssince it has to make a whole seq just to find out if something is empty
12:04julianlevistonjustin_smith: it *is* more sematically explanatory
12:04justin_smithgfredericks: "make a whole seq" doesn't neccessarily mean doing much work
12:04julianlevistonjustin_smith: as well
12:04julianlevistonthanks both!
12:04julianleviston(inc justin_smith)
12:04lazybot⇒ 181
12:04julianleviston(inc gfredericks)
12:04lazybot⇒ 116
12:04gfredericksjustin_smith: I know it's just an object allocation that feels silly
12:05justin_smithgfredericks: sure, but (when-let [x (seq y)] ...) doesn't improve on that much does it?
12:06gfredericksjustin_smith: oh no, I wasn't making that comparison
12:06julianlevistonI’d still prefer do have (when pred let-bindings) tho
12:06justin_smithOK, got it
12:08ontoillo1icalIs it possible for me to import testing namespaces from another project? I.e. I want to import his ns https://github.com/clojure-liberator/liberator/blob/master/test/checkers.clj, is there anyway to do that?
12:08gfredericksontoillo1ical: tests aren't normally packaged with libraries, so you couldn't do that in any normal way
12:08justin_smithjulianleviston: this does what you want (defmacro pred-let [cond bindings & body] `(when ~cond (let ~bindings ~@body)))
12:09ontoillo1icalgfredrick: thanks, I guess I'll just copy it into my own lib
12:09julianlevistonjustin_smith: I’m macro-averse…
12:09andyf_ontoillo1ical: If licenses are compatible or you get author's permission, you can copy the source
12:09justin_smithjulianleviston: the macro is already done, and let and when etc. are macros already :)
12:09julianlevistonjustin_smith: but thanks heaps… I know half the language I use is macros… :)
12:09justin_smithjulianleviston: it's a simple macro, it just works
12:10julianlevistonjustin_smith: macros also scare me from cljs… only because I’ve never built one and had it work
12:11justin_smithOK. If you want a better syntax, the answer is going to be a macro (though sometimes you can express something more elegantly in the existing syntax (using the macros that exist already))
12:11csd_,(let [[f s] (clojure.string/split "split me" #" ")] [f s])
12:11clojurebot["split" "me"]
12:11andyf_arrdem: Have you by any chance asked ClojureDocs folks if they mind if Grimoire tracks updates made to ClojureDocs in the future? Or were you planning on letting them gradually diverge?
12:12andyf_Well "planning" might not be the most precise use of language there :)
12:12csd_The clojure.string/split docstring is misleading
12:12bbloomignore the crazy transducer version... the source is just (drop 1 (interleave (repeat sep) coll)) :-)
12:12andyf_csd_: How so?
12:12csd_Optional argument limit is the maximum number of splits => ["x" "y"] is one split, not two
12:13csd_,(let [[f s] (clojure.string/split "split me" #" " 1)] [f s])
12:13clojurebot["split me" nil]
12:14llasram(doc clojure.string/split)
12:14clojurebot"([s re] [s re limit]); Splits string on a regular expression. Optional argument limit is the maximum number of splits. Not lazy. Returns vector of the splits."
12:15{blake}I take that "split" as a noun, not a verb.
12:15llasramcsd_: I think the fact that it "returns a vector of the splits" clarify that "split" here refers to one of the resulting split-off strings, no the split-point
12:15{blake}i.e., "number of splits" <> "number of times I will split this" but "number of pieces resulting".
12:15julianleviston{blake}: split is the gap between things, not the things
12:16llasramI've always found it weird in Python you specify the number of split points
12:16julianleviston{blake}: if you split wood in two, you’re splitting it once into two pieces… or… it is a single piece of wood with one split in it.
12:16arrdemandyf_: "planning" is pretty generous for me :P
12:17justin_smithit's just verb vs. noun, in clojure you clearly specify noun (how many results) in python the verb (how many times to perform the splitting action)
12:17arrdemandyf_: the plan such as it is was to at some point go through all the examples and copy edit everything rather than just mirroring the clojuredocs examples
12:17arrdemandyf_: reality is that other things were and are higher priority :c
12:18julianlevistonjustin_smith: yeah but “pieces” would be a better word. The noun split means gap between pieces
12:18andyf_arrdem: Yeah, that is a big job
12:18{blake}julianleviston: If you're dividing up loot from your heist, you each get a split. =P
12:18arrdemandyf_: it's much smaller than it sounds, but yeah it's just time with a text editor and thinking about each fn
12:19justin_smith{blake}: exactly
12:19andyf_Well, maybe I am slow at it, but there are over 600 vars in Clojure alone
12:19{blake}julianleviston: See definition "split (noun)" 2, 3b, & 5. http://www.merriam-webster.com/dictionary/split
12:19justin_smith"a piece or part separated by or as by splitting"
12:19julianleviston{blake}: it’s not the primary definition…
12:19arrdemandyf_: done with HW for the week so I'm gonna try and get all the ox stuff out of my head and crunch on Grimoire before SimpleDB takes the site down again. I'd be happy to talk to the clojuredocs folks if you think it'd be useful.
12:19{blake}That's English for ya. There is no noun that cannot be verbed! And vice-versa!
12:19justin_smith{blake}: if only we could make string/split give you an ice cream sundae containing a banana
12:20julianlevistonjustin_smith: now I’m hungry :)
12:20{blake}justin_smith: Ha! That would be...python-esque somehow.
12:20justin_smithclojure.banana could have other useful functions in it too
12:20{blake}Homonyms, man. I tell ya.
12:20andyf_I only ask because if they don't mind you periodically updating the parts if Grimoire from there to the latest, it might be nice.
12:21andyf_s/if/of/
12:22{blake}Homonyms really suck in other languages. "I already learned this means 'criminal gang', whaddayamean it's also "893"?"
12:22arrdemyeah. that would be nice... but getting a real editing workflow added would be nicer.
12:22justin_smith{blake}: that's why on the chinese internet they always call politicians "mud horse"
12:22julianleviston{blake}: grass mud horse...
12:23justin_smiththat's the one, yeah :)
12:23julianleviston{blake}: it’s a homonym for something really rude about your mother.
12:23{blake}Nothing makes me happier than a defiant populace.
12:23andyf_arrdem: Your edit examples link could go to ClojureDocs :)
12:23justin_smithhttp://chinadigitaltimes.net/space/Grass-mud_horse
12:23arrdemandyf_: rofl then I may as well just close down Grimoire
12:24justin_smith"Originally conceived as a zebra, the grass-mud horse is now an alpaca."
12:24arrdemandyf_: which isn't on the cards since I just made it into gigasquid's book :P
12:24julianleviston{blake}: irrespective, the word is ambiguously used. Which was the problem.
12:24andyf_Currently you do have info they do not, e.g. Thalia content (not a lot, but something)
12:24julianleviston{blake}: change it to piece, and it wouldn’t be.
12:25andyf_Which gigasquid book is that?
12:25arrdemLiving Clojure
12:25arrdemhttp://shop.oreilly.com/product/0636920034292.do
12:25{blake}julianleviston: I'm all for doc improvement.
12:26arrdemandyf_: thinking of which I probably owe you a lib-grimoire backed thalia version...
12:26{blake}So..."Joy of Clojure 2ed" is over $40?
12:26justin_smith{blake}: following some more links there, I found the delightful euphamism "death by hide and seek"
12:26justin_smith{blake}: worth every penny!
12:26julianleviston{blake}: yeah.
12:26arrdemsomething something datastore duplication.
12:26arrdem{blake}: totally worth
12:27julianleviston{blake}: makes me sad, too. I don’t have $40 to spend on it and I’ve wanted it for about a year.
12:27{blake}justin_smith: If that were French, I'd guess it was sexual.
12:27julianleviston{blake}: let alone 50+ which is what it is here...
12:27matziehi, noob qn:- given a map like {:a "apple" :b "banana" :c "cherry"} , how would I create a string joining the values for some of those keys with a period, eg for :a and :c I’d want the output “apple.cherry” ?
12:27justin_smith{blake}: reminds me of soviet humor
12:27bbloomtalk to your employer about starting a company library
12:28julianlevistonmatt_c: SOME of them?
12:28matziebah sorry if that got emoticon’d for you
12:28{blake}So far I haven't had much luck with Clojure books. They tend to caught up in the weeds. Although, I'm now at the point where I can appreciate some of those weeds, and am grateful the books exist.
12:28bbloomask other employees to donate their books
12:28julianlevistonmatt_c: you want “:a,:b,:c” ?
12:28justin_smith,(map (fn [[k v]] (str (name k) \. v)) {:a "apple" :b "banana" :c "cherry"})
12:28clojurebot("c.cherry" "b.banana" "a.apple")
12:28matzieI want to pick some keys from the map and construct a string from them
12:28justin_smithahh
12:28llasram,(let [m {:a "apple", :b "banana", :c "cherry"}, keys [:a :b]] (clojure.string/join "." (map m keys)))
12:28clojurebot"apple.banana"
12:28{blake}justin_smith: In Soviet Russia, the joke's on you?
12:28justin_smithoops!
12:28julianlevistonmatt_c: ah… well
12:28julianlevistonmatt_c: select-keys will get you specifc keys...
12:29julianlevistonoops
12:29justin_smith{blake}: no, I mean actual jokes from soviet russia (like the one about the man who stole stalin's pipe)
12:29julianlevistonmatzie: but you mean you want the values of particular keys…
12:29{blake}justin_smith: Oh, I only know a few of those. "In five years, every Soviet citizen will have helicopter!"
12:29justin_smithright
12:30matzie(actual context is a riemann event that goes to influxdb, triying to set :series to the value of :host and :service … but I’m climbing a whole lot of learning curves simultaneously)
12:30matzieand i don’t yet know enough clj to understand the riemann doc on this case
12:31{blake}(They're actually not much funnier in the original Russian...)
12:31justin_smith,(apply (partial clojure.string/join \.) ((juxt :a :c) {:a "apple" :b "banana" :c "cherry"}))
12:31clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: string/join>
12:32justin_smith,(clojure.string/join \. ((juxt :a :c) {:a "apple" :b "banana" :c "cherry"})
12:32clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
12:32justin_smith,(clojure.string/join \. ((juxt :a :c) {:a "apple" :b "banana" :c "cherry"}))
12:32clojurebot"apple.cherry"
12:32julianlevistonmatzie: well, you set something in a map with the assoc function...
12:32julianlevistonmatzie: ##(doc assoc)
12:32lazybot⇒ "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."
12:33matzieah… justin_smith ’s answer is making sense.
12:33julianlevistonmatzie: oh ok :)
12:33justin_smith(inc juxt)
12:33lazybot⇒ 19
12:34justin_smithmatzie: though select-keys would work better if the keys were eg. strings instead of keywords
12:35matzieso… I have a map, ‘event’, already which contains many keys, of which I want to take two (:host and :service), and create a period-separated string from those… I think I can work with this info, thanks all
12:35justin_smithnp
12:39gfrederickscould refs & stm & such be a library?
12:39gfredericksI guess they interact with agents pretty closely
12:40justin_smithgfredericks: I think refs + agents would want to be one lib
12:40justin_smithgfredericks: but atoms, apropriately, could stand on their own :)
12:44justin_smithgfredericks: also, you would probably end up with futures+agents using separate pools instead of sharing one
12:45hiredman_if the stm exposed hooks for detecting transaction commits (which I am pretty sure ztellman wants, I seem to recall discussing this in a loud bar) agents could just hook in
12:45justin_smithoh, that's interesting
12:46gfredericks~this |was| discussed in a loud bar
12:46clojurebotIn Ordnung
12:53dnolenwow the ability to break on uncaught exceptions in CursiveClojure is going to change my life
12:57bbloomdnolen: one of these days yet we'll have every obviously good tool in one damn language :-P
12:57dnolenbbloom: eh between real static analysis, real debugging support, real refactoring support I'm not going to dumb text editors for Clojure programming.
12:58dnolengoing back
12:59bbloomdnolen: understood. we've discussed this, but for onlookers: i use intellj for java most of the time and the rest of the time i do major text editing via vim, switching back and forth --- may consider doing similar for clojure soon
13:00dnolenbbloom: the Emacs simluation in IntelliJ is amazingly good, otherwise I would feel the pain more. I imagine getting the real VIM experience is a different matter.
13:00bbloomdnolen: yeah, evil is the only vim emulator that even comes close, but it just breaks muscle memory so badly
13:00bbloomuncanny valley thing going on. i'd almost rather a significantly worse emulation
13:01bbloombigger problem is that there's never a good time to switch
13:01bbloom~2 weeks lost productivity is a hard fixed cost to pay
13:01clojurebotAlles klar
13:03bbloomdnolen: the ktc crew going to come out for some composable macros at PWL tonight?
13:03TimMcclojurebot: 2 weeks lost productivity?
13:03clojurebot2 weeks lost productivity is a hard fixed cost to pay
13:03bbloomTimMc: nice.
13:03dnolenbbloom: I'm coming for sure
13:03bbloomcool
13:03dnolenbbloom: not sure about Kovas
13:04bbloomlooking forward to meeting Sam, as we've had some fun twitter interactions in the past
13:05gfredericksthe threadBound field on the Var class is interesting
13:06gfredericksI have to assume it's just a perf thing
13:06justin_smithgfredericks: isn't that about dynamic vars?
13:06gfredericksyeah
13:06gfredericksit starts out false
13:07gfredericksand the first time you use binding on a var it (for that var) gets set to true, and then it just stays true forever
13:07gfredericksafaict
13:07bbloomi wondered about that as well
13:07bbloomit seems like you could check instanceof Unbound
13:07bbloomsaving a pointer & an atomic deref
13:07gfrederickscheck that on what?
13:08gfredericksthe root being unbound doesn't say anything about whether the var has a thread-local binding
13:08TMAVIM emulation in IntelliJ is quite good -- at least compared to eclipse or netbeans counterparts; alas I have never got around to acquire more than basic knowledge of emacs
13:08bbloomgfredericks: er, yeah, you're right
13:08bbloomgfredericks: sorry, was speaking from memory (poorly)
13:09gfredericksso presumably it only helps for dynamic vars that don't ever get bound
13:09gfrederickswhich I guess could happen enough in practice?
13:09tcrayford____gfredericks: sounds like a thing one could measure haha
13:10gfrederickstcrayford____: well it's more about how dynamic vars get used in different codebases
13:10Bronsagfredericks: Var.java is kinda confusing. there's dead and duplicated code
13:10gfrederickse.g., libraries that have them for some kind of config that's rarely used
13:10tcrayford____so measure some open source ones haha
13:10gfrederickstcrayford____: well it's not just about the library itself but how people use them
13:11tcrayford____gfredericks: guess there's not really enough open source *apps* to measure that haha
13:12gfrederickstcrayford____: appending "haha" is your new verbal tick?
13:14tcrayford____haha
13:21gfredericks,(keys (get-thread-bindings))
13:21clojurebot(#<Var: --unnamed--> #'clojure.core/*ns* #'clojure.core/*read-eval* #'clojure.core/*err* #<Var: --unnamed--> ...)
13:22gfredericks^ surprised at how many unnameds there are
13:23gfredericksI just deref'd all the unnamed vars in my repl and got (nil 72 0 true nil nil 1 1 1 21982 19308 #<clojure.lang.DynamicClassLoader@f774f clojure.lang.DynamicClassLoader@f774f>)
13:23tcrayford____gfredericks: in a fresh reepl?
13:23gfredericksnot too fresh
13:24gfrederickshaha
13:24tcrayford____freshen up
13:25sentient22Can I ask a really noob question?
13:25tcrayford____sentient22: welcome. Yes!
13:25sentient22Okay so, new to clojure, been reading the documentation
13:25gfrederickslol a fresh repl stackoverflows for (get-thread-bindings) at java.util.Currency.getInstance
13:25tcrayford____(typically in irc: don't ask if you can ask a question, just ask it)
13:25sentient22Lists can't be indexed, according to the docs
13:25gfrederickstcrayford____: well you might at least have to establish the purpose of the channel
13:26justin_smithsentient22: you can use nth, but they are not associative
13:27sentient22Okay, so my question is then why does (assuming my list is '(1 2 3)) (.indexOf my-list 1) return 0?
13:27justin_smithsentient22: that's not the same sense of "indexing" that we mean regarding associative data structures
13:27gfrederickswhat docs say "can't be indexed"?
13:28sentient22http://clojure-doc.org/articles/tutorials/introduction.html
13:28sentient22and justin_smith okay that makes a little more sense
13:28Bronsa,(nth '(1 2 3) 0)
13:28clojurebot1
13:28justin_smithsentient22: "access by index" is not the same as getting the item from an index
13:28justin_smithsentient22: nth walks a list until it gets to n
13:29justin_smithsentient22: while with a vector you can directly access item n
13:29sentient22Yeah okay I see what you're saying. Cool. Thanks!
13:29sentient22Just got confused for a second because for some reason I thought .indexOf would fail
13:29sentient22But it was just my own mind playing tricks on me lol
13:29justin_smithsentient22: yeah, it's a different usage of the word index
13:30sentient22yeah. Thanks all!
13:30justin_smithsentient22: clojure tries to avoid abstracting over things that lead to big inefficiencies, treating lists as lookup arrays is one example of that
13:31justin_smith(of a thing that is made less convenient because it's inefficient)
13:31sentient22Ahh yeah okay
13:34gfredericks,clojure.lang.Var/rev
13:34clojurebot989
14:29mgaarehaving a strange issue with tools.namespace. I do (refresh) on a fresh repl, it says it's reloading all the ns's, throws an exception loading a later ns that an earlier loaded ns was not found. If I go through and manually compile all the ns's, it eventually works fine
14:32stuartsierramgaare: AOT
14:32tbaldridge~aot
14:33clojurebotaot was so ahead of its time
14:33tbaldridge~aot
14:33clojurebotaot was so ahead of its time
14:35gfrederickstbaldridge: sorry did I pollute actual useful things that the bot says?
14:35tbaldridgegfredericks: nah, I forget what the right incantation is to get the "AOT" image
14:35tbaldridge~AOT
14:35clojurebotAOT is kinda broken already
14:35tbaldridge~AOT
14:35clojurebotAOT is kinda broken already
14:36tbaldridgeit was the aliens guy
14:36tbaldridgeoh well
14:37stuartsierraHow about this http://imgur.com/ojVQfVv
14:39tbaldridgeI was thinking of this one: https://i.imgflip.com/h9gtq.jpg
14:39tbaldridgebut yeah, that works too
14:43stuartsierraI think we scared off mgaare.
14:43TimMc~aot
14:43clojurebothttp://i.qkme.me/3vb225.jpg
14:44TimMcIt's case-sensitive, I guess.
14:48hyPiRionhrm
14:49mgaarestuartsierra: sorry, someone grabbed me to look at an issue where cljsbuild was working under bash and failing under zsh..... no idea. anyway, thanks, after a lein clean things are reloading again
14:49hyPiRion,(map (comp first second) ['#(+ %) `#(+ %)])
14:49clojurebot(p1__25# p1__26__27__auto__)
14:50TimMcyup
14:51TimMcI've occasionally wondered about that.
14:51llasramauto-gensymed gensyms?
14:52hyPiRionI wonder if it matters.
14:54stuartsierraclojurebot: tools.namespace
14:54clojurebotI don't understand.
14:55TimMc~you
14:55clojurebotyou have to double-pinky-swear before you :refer :all
14:55stuartsierrahaha
14:57gfredericks~you
14:58clojurebotyou are a weirdo
14:58bbloomawesome.
14:59llasram~you
14:59clojurebotyou are the cloud
14:59llasramYES
14:59gfredericks~it
14:59clojurebotit is time for clojure history anecdotes with technomancy
15:00llasramAwww
15:00gfredericks~it
15:00clojurebotit is for clojure.pprint/cl-format :)
15:01bbloom~why
15:01clojurebotbbloom: because you can't handle the truth!
15:01bbloom:-)
15:01bbloom~what
15:01clojurebotwhat is cells
15:01bbloom~what?
15:01clojurebotwhat is not a bug
15:01gfredericksllasram: I was thinking that
15:01gfredericks~I
15:01clojurebotI don't have any opinions of my own
15:01llasram~clojurebot
15:01clojurebotclojurebot is perhaps the definition of a legacy software system
15:01bbloom~i
15:01clojureboti is disapoint
15:01bbloom~i
15:01clojureboti is disapoint
15:01bbloom~i
15:02llasramNow *that* is disapoint
15:03hyPiRion~gfredericks
15:03clojurebotgfredericks is gfredricks
15:03llasramha
15:04hyPiRionclojurebot, tautologist
15:04TimMcIs it possibly getting factoids over a network connection like it does with eval?
15:04clojurebotexcusez-moi
15:04gfredericksactually it's a misspelling
15:05gfredericksI guess to make the factoids less spelling sensitive
15:05gfredericks~gfredricks
15:05clojurebotgfredricks is a menace to bots everywhere
15:05gfredericks~gfredericks
15:05clojurebotgfredericks is a DSL for seeding clojurebot with high-concept talk ideas
15:06gfredericks~bbloom is an ornithologist
15:06clojurebotA nod, you know, is as good as a wink to a blind horse.
15:06bbloomgfredericks: fishing for a bird talk?
15:06gfredericksyep
15:06gfredericksI assume some sort of metaphor about birds living in trees
15:06llasramas long as he doesn't start birding for a fish talk
15:06bbloomgfredericks: you figure out how to get me to rant about birds and maybe i can do that for you
15:06gfredericksI'm sure you'll work it out so it makes sense
15:07TimMcmockingbirds
15:07llasramBecause I don't know what that would mean
15:07TimMcI'll tell you when you're older?
15:08llasramheh
15:09hiredman_llasram: it is doing terrible core.logic things to infer new facts
15:09TimMcSo with the right set of facts we could make it hang for absurdly long?
15:09hiredman_any set?
15:10TimMcYou're suggesting that it already hangs for absurdly long?
15:11hiredman_I dunno
15:12llasramhiredman_: ah, interesting
15:12hiredman_a never used feature is clojurebot keeps a list of infered facts for some amount of time after being asked something, and if it is given a botsnack before a timeout it stores those facts in the db so they don't need inference again
15:13llasramoh!
15:13llasramThat's cool
15:14gfrederickshiredman and his intimate secrets about clojurebot
15:14llasramclojurebot: ~it is time for clojure history anecdotes with hiredman
15:14clojurebotIn Ordnung
15:14llasramDamn it
15:15llasrammeant that to be clojurebot, but I am bad at editing text
15:15hiredman_clojurebot: origin story?
15:15clojurebothttp://clojure-log.n01se.net/date/2008-11-21.html#13:04
15:15llasramOh my
15:16llasramWay back from in the rhickey-on-IRC era
15:17llasramPretty amusing that rhickey's handle gets highlighted in red there
15:23tbaldridgellasram: kind of like a red-letter Bible
15:23TimMchiredman_: I've done ~botsmack after an inference but maybe not a ~botsnack.
15:24rhickeyThou shalt not mutate within my sight.
15:24tbaldridgerofl
15:25TimMc(let's see if that highlighting is still in effect)
15:28moquistI've read this line about 20 times and I still only understand it if the word order is wrong: "If a transaction specifies a unique identity for a temporary id, and that unique identity already exists in the database, then that temporary id will resolve to the existing entity in the system." (from http://docs.datomic.com/identity.html )
15:29moquistIt seems to me that it wants to say: "If a transaction specifies a temporary id for a unique identity attribute, and that unique identity already exists..."
15:29kirillhi all, is there some kind of generic way to turn off various annoying logs from java libraries? I'm using a clojure library that uses netty, and I keep getting messages like "[main] DEBUG i.n.util.internal.PlatformDependent0"... which I'm not interested in
15:29moquistAm I misunderstanding, or on the right track?
15:31llasramkirill: Depends on the logging libraries in play. Usually you can tweak which classes log at what level with a small Java property file
15:31amalloykirill: you basically have to figure out how java's logging works, and create an appropriate log4j.properties file (or whatever library is being used)
15:32stuartsierramoquist: "identity" in this case refers to the *value* of an attribute with db.unique/identity.
15:32stuartsierraAs in, your account number is an "identity" for you at the bank.
15:33stuartsierraAt least I think that's what it means. :)
15:48TimMcllasram: Check out the source for the IRC logs. For rhickey lines it has class="bdfl" :-P
15:51gfredericks~bdfl
15:51clojurebotExcuse me?
15:57seangroveI don't suppose there's anything like om/shared in reagent?
16:01bbloomgfredericks: i could however probably give a whole talk about record players
16:01gfredericksbbloom: I don't think there's any good reason not to
16:01bbloomi don't know anything about records / record-players, other than that i'm sick of picking up a record and having a record player attached to it ;-)
16:02bbloom(this is me bitching about OOP, if you can't tell)
16:02gfredericks~this is bbloom bitching about OOP
16:02clojurebotYou don't have to tell me twice.
16:02gfredericks~this
16:02clojurebotthis was discussed in a loud bar
16:04gfredericksbbloom: not a bad metaphor
16:04bbloomnot strictly mine: it's from GEB
16:04bbloombut it has stuck with me
16:05gfredericksoh man he couldn't'vebeentalkingabout OOP in context though
16:05sobel(inc GEB)
16:05lazybot⇒ 1
16:05bbloomi particularly enjoyed the bit about whether or not aliens could interpret a record "correctly".... even if they got it to produce sounds, would it elicit the emotion that the composer was intending? who knows.
16:13nicferrierhas anyone done any static analysis on clojure? for example security analysis?
16:16dagda1I'm trying to solve the project euler problem for selecting the nth prime number, my code works but it is not quick enough https://gist.github.com/dagda1/1f765e0fcade3193f1e0 can anyone suggest what is the bottle neck
16:17dagda1by not quick enought, I mean it times out for the bigger numbers thrown at it on the test hacker site
16:17dagda1I was thinking if I could ignore even numbers apart from 2 in the (iterate inc 2) bit
16:18dagda1I'm surprised it times out TBH, I'm not really using loop/recur
16:20jinagaranonoir.validation/rule doesn't set any errors for me. syntax is correct, arguments are passed properly, and if i evaluate them in the repl, the checks give proper return values. does anyone have an idea what the problem could be?
16:24gfredericksdagda1: you're filtering on (range 2 n) which takes a while for large n
16:25dagda1gfredericks is there an alternative that you know?
16:26gfredericksgoing up to (inc (Math/sqrt n)) is sufficient
16:27dagda1gfredericks are lazy sequences slow?
16:28hyPiRionI'd say the algorithm is more important than the underlying data structures here.
16:28gfredericksyep
16:29dagda1gfredericks: indeed
16:29hyPiRionBut if you need low constant factors and don't want to find a clever algorithm to make primes, you could always use https://github.com/hyPiRion/primes
16:29dagda1hyPiRion: I know but it is all about learning clojure
16:29gfredericksand https://github.com/gfredericks/composites
16:30hyPiRiondagda1: ah. Well, then I'd focus on the algorithms :) I've done some project euler problems in Clojure, and the data structures doesn't really matter if you're doing them "the right way"
16:31gfrederickswell you don't want to misuse the data structures at least
16:31hyPiRionOh, yeah.
16:32gfredericksgood ole (vec (concat (subvec v 0 i) [x] (subvec v i (count v)))) ;; lifehack
16:33hyPiRiongfredericks: psh, (-> (subvec v 0 i) (conj x) (into (subvec v i (count v))))
16:33TimMcGood thing we're using performant datastructures, amirite?
16:34gfrederickshuh; does that work?
16:35gfredericks,(def v (vec (range 10)))
16:35gfredericks,(def i 3)
16:35clojurebot#'sandbox/v
16:35clojurebot#'sandbox/i
16:35gfredericks,(def x "fort-ytwo")
16:35clojurebot#'sandbox/x
16:35gfredericks,(-> (subvec v 0 i) (conj x) (into (subvec v i (count v))))
16:35clojurebot[0 1 2 "fort-ytwo" 3 ...]
16:35gfrederickshrm
16:35gfredericksI remember some difficulties with subvectors and transients, I guess it just means that into doesn't use them
16:36hyPiRiongfredericks: should be fine if they're implemented correctly
16:36hyPiRionbut yeah, when you speak about it, I remember something about that as well
16:36raspasovdoes anyone know what's the memory cost of (go (loop [] (do "something") (recur)))
16:37justin_smithraspasov: nearly nothing, it compiles to about what a while true loop would
16:37dagda1gfredericks: could you explain.... going up to (inc (Math/sqrt n)) is sufficient
16:38gfredericksdagda1: any divisor above sqrt(n) has a corresponding divisor below sqrt(n)
16:38gfrederickse.g., 100 is divisible by 20, but it's also divisible by (/ 100 20) == 5
16:39justin_smithanother way to put it: it will have no pair of factors where both are greater than its square root
16:39_alejandrogfredericks: dagda1 because for any x,y > sqrt(n), x * y > n^2
16:39_alejandrodoh x * y > n
16:40raspasovjustin_smith: thanks, I have a use case where I'd have potentially a lot of those to ensure sequential operations to many locations, wondering if I should worry about GC-ing those loops when they are not in use
16:40justin_smithraspasov: I would be much more concerned about the CPU cost
16:41raspasovGC-ing the loop while ensuring that re-establishing the loop doesn't violate the sequential semantics seems tricky without going into lock land
16:42tcrayford____You care about GCing the loop - if you don't, you can cause unbounded thread growth on the JVM (iirc)
16:42raspasovjustin_smith: well I assume that having a bunch of loops parked doesn't incur any cost? most of the loops will be parked most of time
16:42justin_smithraspasov: also, gc automatically reclaims resources, but you can't actually "gc" anything. You can make a loop stop (easiest from inside the loop) but the vm decides when to reuse the memory
16:42justin_smithraspasov: parked core.async loops?
16:43moquistHm. stuartsierra seems to be gone now, but here's code I wrote to test my suggested change to the Datomic docs: https://github.com/moquist/datomic-uniqueness-ftw
16:43justin_smithraspasov: core.async makes a big difference here, because they won't actually hog a thread if parked
16:43raspasovjustin_smith: by GC-in the loop I mean "ending" the loop by having it not (recur) or be parked any more
16:43raspasovjustin_smith: yes I'm aware of that
16:43justin_smithraspasov: OK, I think "halt" is more clear here
16:43raspasovthat's why I'm using them :)
16:43justin_smithraspasov: OK, but you didn't mention core.async, that is like - the most important detail here
16:44justin_smitha parked go block isn't going to use many resources at all, no
16:44raspasovjustin_smith: well (go) assumes the non-thread version
16:44justin_smithraspasov: which is why I asked if it was parking (you can't park (thread))
16:44raspasovthere's the (thread (loop [])) version that actually blocks a real thread I think
16:44justin_smithright
16:45justin_smiththat can only block, it doesn't really park
16:45raspasovyea but this is a potentially very long lived process, and over time there could be 100s of thousands of parked loops
16:45raspasovI believe the documentation uses "park" for the "fake" threads and "block" for the real threads
16:46justin_smithfrankly I'm not sure how that would scale, but I bet some profiling would help you predict
16:46raspasovbut anyway I think we understand each other :)
16:46tcrayford____raspasov: depends on your machine too. I've seen modern machines do that many native threads ;)
16:46tbaldridgegos are attached to channels when parked, if the channel is GC'd the gos will be as well.
16:46justin_smithraspasov: yes, go glocks can park or block, threads can only block
16:46raspasovtbaldridge: oh that's good to know, thanks!
16:47tbaldridgeraspasov: go blocks are really just fancy callbacks, so they behave the same way that (take! c (fn [v] ...)) would
16:47amalloygo blocks can block?
16:47tbaldridgesure, if you do something blocking in them ;-)
16:47justin_smithamalloy: if you fuck up you can do something blocking in a go block
16:47amalloywell, i guess that's fair
16:47justin_smithit's a bad idea though
16:47tbaldridgeor if you do something stupid like, (chan 10 (map (fn [x] (Thread/sleep 10000) x)))
16:47sobelis that why <! is distinct from <!! ?
16:47sobel(parking)
16:47tbaldridgeexactly
16:48raspasovyea I always send to an agent or future or something else non-blocking if I have some IO to do, et
16:48sobelhey, i'm learning
16:48raspasovetc
16:48sobelreasoning even
16:48tbaldridgeraspasov: or instead of a future, just use (thread ...) that way you get backpressure
16:48tbaldridge*instead of a agent
16:48_alejandroraspasov: https://tbaldridge.pivotshare.com/media/core.async-episode-7-gc'd-go-blocks/9394/feature was useful for me to understand how core.async and gc interact
16:48sobelsmall victories. hoping to deploy the first clojure in a client env. for my company next week, too. :)
16:48raspasovtbaldrige: yes, I do use that as well, thanks!
16:49raspasovtbaldridge*
16:52raspasov_alejandro: thanks I'll check that out!
16:54cflemingdnolen: pong
16:55dnolencfleming: figured out, being able to drop into the debugger on any exception in IntelliJ is sick
16:55dnolencfleming: gonna save me hours
16:55cflemingdnolen: Yeah, that's a life-saver. I need to document the debugger now that it works properly.
16:56dnolencfleming: it's seriously amazing
16:56cflemingdnolen: Expression evaluation now works too.
16:56raspasovdnolen: do you run your project directly from IntelliJ or connect remotely to a REPL in a terminal?
16:56dnolenraspasov: locally
16:56cflemingdnolen: I'm going to propose a talk for Clojure/West on the debugger I think.
16:56dnolencfleming: my Clojure debugging workflow is finally almost as good as ClojureScript, lol
16:56raspasovdnolen: yea I was trying to make that work the other day but some leiningen plugin was causing me trouble
16:57cflemingdnolen: Haha
16:57raspasovotherwise can't wait to get all the IntelliJ/YourKit local goodness :)
16:57amalloycfleming: i would install intellij just for a debugger
16:57cflemingdnolen: Since eval now works, you can now also put conditions on breakpoints too
16:58cflemingamalloy: Now's your chance! Some bugfixes in the next drop too.
16:58raspasovcfleming: yes do that, I've been using Cursive for months and I think I only managed to start it once by accident :)
16:58cflemingSome Java-specific (but mostly relevant) info here: https://confluence.jetbrains.com/display/IntelliJIDEA/Debugger
16:59sobelwhat's the status of Cursive? do you have to own IntelliJ to use Cursive or what?
16:59cflemingsobel: No, it works with the free community edition.
16:59raspasovIntelliJ community edition is great & free
16:59sobelcool
17:00amalloymy main objection to intellij is that it doesn't start with an E like every other great editor/ide
17:00dnolensobel: the intention however is the Cursive will cost money in the future, but at this point I'm all "take my money" already :)
17:00raspasovamalloy: that's a pretty big price to pay :)
17:00amalloyemacs, eclipse, and of course ed
17:01cflemingYeah, since evim changed its name, I'm bugging JetBrains to do the same.
17:01raspasovwhat about Notepad, I heard all the legit hackers only use Notepad
17:02cflemingsobel: The idea is that there'll be a standalone version of Cursive, and a plugin to IntelliJ for those using Ultimate Edition. The same licence will work for both, so you'll be able to switch.
17:02justin_smithcfleming: ex ;)
17:02hiredman_back when I was doing euler problems in clojure I did them mostly in notepad++ with a clojure repl running in a cmd.exe window
17:02hiredman_worked great
17:02raspasovfor clarification I'm talking about the most basic Notepad that comes with Windows since prob 95 lol
17:02sobeldnolen: that was my exp. with IntelliJ: take my money!
17:03dnolensobel: well cfleming is continuing in that great tradition then
17:03sobelhaving LT and SublimeText both with working REPLs really cuts my urgency, though.
17:03hiredman_raspasov: sure, the biggest improvement of notepad++ over notepad in this case is notepad++ will hilight matching parans
17:04sobelbut i have to think about more than myself, i'm hoping to start a whisper campaign for clojure to replace all our stupid groovy code here
17:04sobeland maybe some of the core java
17:04raspasovhiredman_: haha yea, I can't imagine not having color coding lol
17:04amalloyhiredman_: i'd have guessed the biggest improvement is it doesn't completely fail at handling unix line endings
17:04hiredman_the great thing about having a lot of practice copying and pasting code between an editor and a repl is it is a workflow that works *everywhere*
17:05hiredman_I can do things the same if the repl is in an ssh session in to dev or qa servers vs locally
17:05expez:db/id #db/id[:db.part/db] <- what does this literal notation mean in datomic schemas? Is this simply how you tell datomic to fabricate an id for you?
17:05sobelhiredman_: that's where i'm coming from, and it's a great advantage until i don't need it and then it becomes a costly capability to maintain
17:05amalloyi've tried turning on paren-highlighting in emacs, and couldn't really get the hang of it. it feels like a distraction, and not really needed when you have paredit commands like paredit-backward-up or whatever
17:08sobelindenting/coloring in ST3 seem to be ok
17:09moquistexpez: Yes. See the docs for d/tempid, also.
17:16justin_smithtbaldridge: above, when you recommended using (thread) for things that might block, do you mean putting the whole loop in (thread) or just the blocking action?
17:16tbaldridgethe whole loop
17:16justin_smithahh, OK
17:17tbaldridgeor at least move the the blocking bits to a different thread via a channel
17:17justin_smithtbaldridge: right, and they would be in their own loop in a (thread) block
17:24sobelhas anyone (present) deployed with nginx-clojure? the nginx's cosocket support seems like it would be a pretty good boost.
17:27justin_smithsobel: my impression was that the boost nginx-clojure offers doesn't apply to the main bottlenecks you'd actually see in a clojure app. That said I haven't tested it to confirm.
17:31sobeljustin_smith: i try to plan ahead to take advantage of the deployment environment for flexibility and performance, so i am looking to nginx for simple vertical scaling
17:32sobelneed to borrow a prod environment to beat it up sometime
17:32justin_smithsobel: how would the nginx plugin make deployment / scaling easier?
17:32justin_smithsobel: you can get a digitalocean server for like $10 a month
17:34dagda1gfredericks: thanks
17:34mgaaresobel: have you seen this? https://github.com/ptaoussanis/clojure-web-server-benchmarks
17:34sobeljustin_smith: the obvious/minimum needs are serving static content and proxying dynamic content reqs to your app. my experience is apache2 (to say nothing of nginx) beats java for that kind of service
17:35justin_smithsobel: sure, for security if nothing else I put nginx in front of my clojure app
17:35mgaaresobel: probably the most common way to do clojure web deployment is to have nginx as a reverse proxy in front of a clojure app
17:35justin_smithsobel: what I don't get is the rationale for putting the jvm inside the nginx process
17:35mgaareand the clojure web app runs using an embedded web server
17:35justin_smithexactly
17:36sobelinteresting. i had not seen that graph since the may 2014 data.
17:38sobeli have been pretty used to deploying tomcat with mod_jk or just http proxying, but i was looking at OpenRESTy as an app platform when i saw nginx-clojure and started thinking clojure would be a brilliant member of that platform
17:39sobelso the interest is at least partly experimental. glad to see other servers reaching parity (and then some) with nginx-clojure, rather than leaving it in the dust :)
17:39dahyeah, http reverse proxy has to be the most simple to configure and operate
17:40dahit's handy to be able to hit the application server directly locally, too
17:40mgaaresobel: also, have you seen immutant?
17:40dahinstead of it being embedded or speaking some binary protocol
17:40mgaare(gotta give the shout-out there, those guys are great)
17:40sobelmgaare: no, but it's on my radar now
17:41mgaaresobel: what's particularly nice about the new version of immutant is that you can deploy an app that uses the immutant libraries either standalone or inside a wildfly (nee jboss) container
17:42sobelhaven't heard that name (jboss) in a while
17:42justin_smithsobel: it's the container for the top performer on that benchmark :)
17:43sobeljustin_smith: good enough for me!
17:47jcrossley3mgaare: thanks :)
17:48jcrossley3sobel: find us in #immutant if you get stuck
17:48sobelthanks!
17:49jcrossley3sobel: justin_smith: technically, that benchmark was run with immutant *out* of container, no wildfly involved.
17:49justin_smithjcrossley3: oh, OK
17:50justin_smithjcrossley3: shows how much I know :)
17:50sobelis it faster with wildfly?
17:50jcrossley3sobel: i wouldn't expect much difference at all, tbh. undertow is doing all the work either in-or-out of wildfly
17:50sobelk
17:51sobeli really thought SQL would be the last data-drive language i'd ever need
17:52tehgeekmeisterhow do i coerce a url to a string representing just the contents of the url?
17:52tcrayford____tehgeekmeister: what url type do you have, and what do you mean by "contents"
17:52tehgeekmeisterhave a file url
17:52amalloyalso by "coerce"
17:52sobel.toString?
17:53tcrayford____the path, the protocol? the host?
17:53tehgeekmeisterwant just the portion after the file: bit
17:53tcrayford____tehgeekmeister: what url class is it
17:53tcrayford____(class url)
17:53tehgeekmeisteron it
17:53tcrayford____(probably .getPath for a java.net.URL)
17:53tehgeekmeisteryep, that's the kind it is
17:54tehgeekmeisterwill try now
17:54tcrayford____(no idea if that actually works though, just scanned through the javadoc)
17:54amalloy,(let [s "file:///home/akm/whatever.txt", u (java.net.URI. s)] (.getSchemeSpecificPart u))
17:54clojurebot"///home/akm/whatever.txt"
17:54tehgeekmeisterit seems to have worked
17:56amalloytehgeekmeister: just about anything will work fine for a file: url; the question is what you want it to do on other sorts of uris
17:56amalloyeg, for http://google.com?q=wikipedia
17:56tehgeekmeisterthis is always going to be a file url in this case
17:56tehgeekmeisteri'm really just trying to get the path to a resource in my leiningen project
17:56tehgeekmeistera shell script i want to bundle and execute
17:57tehgeekmeister(by bundle i mean bundle with the app)
17:57amalloywhy do you need its path?
17:57tehgeekmeisterfor shelling out to it
17:57tehgeekmeisterconch takes paths,
17:57tehgeekmeisternot files
17:57amalloyif you bundle it with the app, it won't be in a file at all, but in your jar
17:58tehgeekmeistercrap
17:58tehgeekmeisteri seriously misunderstood something, then
17:58tehgeekmeisteri found this code on the net, and have been building off of it
17:58tcrayford____you could always copy it out of the jar and throw it in /tmp
17:58tcrayford____#notagoodideathough
17:58justin_smithtehgeekmeister: you can slurp the file and provide that to /bin/sh via conch maybe?
17:58tehgeekmeister(-> (Thread/currentThread) .getContextClassLoader (.getResource path))
17:59tehgeekmeisterand using that to get files of things in the resource directory
17:59justin_smithtehgeekmeister: how did the files get out of the jar?
17:59amalloytehgeekmeister: that's fine if you actually have files. but if you're distributing this program as a runnable jar
17:59amalloyinstead of as like a "please clone the git repo and run from that"
17:59tehgeekmeisteri can distribute it however i want
18:00tehgeekmeistercould be made jar-friendly later, if need be
18:00tehgeekmeisterfor now, i can just use it as a repo
18:00tehgeekmeistergood to know it is not yet jar friendly, though
18:03bashedCan anyone point me to a good intro on how clojure or any other immutability-centric language handles performance issues? Intuitively, it would seem that in-place transformation of a data structure would be more performant than making a copy of the data structure for each action.
18:04justin_smithbashed: full copies are not needed if you can't mutate :)
18:04amalloybashed: it is, but we don't actually copy the whole data structure
18:04justin_smithbashed: basic idea, you have a tree which shares most of its structure
18:05sobelbashed: the nutshell explanation for me is that immutability takes a lot of complexity out of concurrency, which helps performance. also, as mentioned, the data structures support cheating our way around full copies
18:05bashedOh, so is there a case when the immutability really affects perforamnce?
18:06amalloybashed: i mean, every operation is slightly slower than the equivalent mutate-in-place operation
18:06justin_smithbashed: sure, it affects cache behavior because we have more heap fragmentation
18:06sobelsure. you won't have to lock a clojure data structure yourself.
18:06amalloybut it's not a lot slower, and you get a lot of benefits out of it, like keeping old versions, not needing to lock...
18:06justin_smithbashed: but most apps don't need to optimize to that level (and we have java arrays if you hit that point)
18:08turbofailoh boy. a badly formatted sha1sum file for a maven artifact
18:09hyPiRionturbofail: like https://repo1.maven.org/maven2/org/apache/spark/spark-core_2.10/1.2.0/spark-core_2.10-1.2.0.pom.md5
18:09hyPiRion (?)
18:10turbofailyep, that's the one
18:14turbofailah, after following the chain of bug reports i arrive at some stuff you're involved in
18:19justin_smithturbofail: the hyPiRion is calling from inside the thread
18:19sobelhaha
18:21hyPiRionturbofail: I should've given you the tip about `:checksum :warn` as a temporary fix
18:21turbofailthen who was lein?!?
18:22tcrayford____hyPiRion: any idea if there's a faster way to iterate through PersistentTreeMap than reduce-kv (e.g. without allocating a function)
18:23tcrayford____loop/recur are (with first/rest calls), surprisingly slower
18:23tcrayford____wait, not treemap, persistentarraymap
18:24turbofailhyPiRion: yeah. unfortunately my stuff is still broken even after succesfully fetching the dependency, but that's an unrelated issue
18:24amalloyit's not at all surprising that loop/recur is slower than reduce-kv
18:24amalloyallocating a function to give to reduce-kv is going to be your fastest option
18:24hyPiRionturbofail: gurr. At least one step closer to a solution
18:25turbofailyeah. it looks like spark changed the signature of some of their constructors
18:49weidoes there exist an rpc library (similar to shoreleave-remote) that runs asynchronously over sente?
18:56dweaveI don’t really understand clojure’s (hickey’s) take on FRP. Basically my understanding is that “we don’t need it because clojure has point in time identities (datastructures)”. But isn’t FRP useful for more than just modeling time? isn’t it about composability?
18:57dweavethese seem to be orhthoginal concepts, but the general attitude is that frp solves a problem clojure doesn’t have.. Or am i missing something
18:59justin_smithdweave: I think there are a few things in clojure that approach the general territory of FRP. core.async, prismatic/plumbing, ztellman/manifold
18:59justin_smiththough none of those are exactly FRP of course
19:01justin_smithdweave: in fact, now that I think of it, the one thing that I think really could be FRP is the audio / control data flow in kunstmusik/pink which has explicit stepped time (because the audio signal processing algorithms it implements all need to be strict about time)
19:01dweavehmm
19:02justin_smithbut that project is not very functional, as clojure code goes (because it needs low latency)
19:02justin_smithmaybe I should say "not very pure"
19:02dweaveI guess why is this not something that’s more widespread in clojure tho.. For instance clojurescript Om has no good corollary. I find it a great paradigm in gui programming
19:03aperiodicthere's also a more-or-less port of ELM using core.async: https://github.com/jamesmacaulay/zelkova
19:03justin_smithdweave: well clearly cljs/om use core.async for the pipelining of events / calculations that frp would have
19:03justin_smithdweave: but it doesn't have the strict stepping of time that would make it frp
19:03dweaveyeh
19:04dweavei think the difference with om is that ReactJS solves some of that problem
19:05justin_smithpink is pull based frp iirc
19:05dweaveyou know longer have to explicitly connect events to UI updates
19:05justin_smith(but I would not recommend trying to use pink for web dev at all... it's very specialized for audio synthesis)
19:06justin_smithdweave: is the strict time sync actually something you need? because otherwise core.async can surely do the rest
19:07dweavei think it is something i need, but let me give u an example and tell me if it qualifies as strict time sync
19:08dweavewell my examples a little complicated. so i’ll simplify. Say I have a button and I only want some action to take place if I click it twice within a set number of seconds.
19:08dweavethat’s a problem FRP handles elegantly
19:08dweaveis that wat u mean by strict time
19:09justin_smithdweave: core.async does this nicely if you define debounce (which I swear should totally be built in by now)
19:09dweavethe problem I’ve found with core.async is it places emphasis on using transducers
19:09dweavewhich u have to bake in when u create the channel
19:09justin_smithdweave: no, what I meant was that in frp there is a global model of time (often with a sampling rate and strict propagation semantics) and core.async is a bit looser about this stuff
19:09dweavethat limits composabliity “down stream” no?
19:09justin_smithdweave: how would using a transducer limit composability
19:10dweavesay i have a channel already
19:10dweavei can’t “add” a transducer to it
19:10justin_smithdweave: a transducer is compatible with an frp stream processor
19:10dweavewhat is frp stream processor in this context
19:11justin_smithdweave: some element that processes your data between a source and sink
19:11justin_smithin the abstract sense, anything with both inputs and outputs
19:11dweavei see
19:12justin_smithdweave: being able to recompute the graph at runtime can be a limitation in cljs (no eval / no compiler in the runtime) but not a limitation of core.async itself
19:12justin_smithbut recomputing graphs should be a rare event anyway if you care about perf at all
19:12dweaveif I have a channel i guess i’m wondering how to apply a map function to it
19:13justin_smithand in practice you can make a graph that is flexible enough to represent the various kinds of processing you need
19:13dweavesay it’s being consumed by another component
19:13justin_smithdweave: the map function can be provided as an argument to the channel
19:13dweavebut map is deprecated
19:13dweavein favor of transducers
19:13justin_smithno, we just use the transducing map now
19:13justin_smithit's still map
19:13dweaveoh
19:13dweavewhat’s that look like?
19:14dweave(map ch fn)
19:14dweave?
19:14justin_smith(chan buffering (map f))
19:14dweaveand that produces a new channel?
19:14justin_smithright
19:15justin_smithyou can send things to that channel in order to have them processed
19:15dweavebut what if I already have a channel is what i’m saying
19:15justin_smithdweave: then feed that channel into the mapping one
19:15dweavejust using pipe?
19:16dweave(pipe existing-chan (chan buffering (map f)))
19:16justin_smiththere is also map (as opposed to the depricated map<)
19:16dweaveand that does something like i just did ^
19:16dweave?
19:16justin_smithhttps://clojure.github.io/core.async/#clojure.core.async/map
19:17dweaveah yes thank u
19:18justin_smithit's too bad core.async isn't as straightforward to demo on this channel as clojure.core is
19:18justin_smithit would be cool to have a "show and tell core.async" env for doing demos and establishing what works
19:18dweaveyeah
19:19dweavecould that be a lazybot plugin
19:19justin_smithyeah, the security would be tricky - there's good reason to restrict threaded / async stuff
19:19justin_smithbut there's probably a way to do it...
19:19dweavetrue
19:25kiwitobesIs there any way to use Swing (or any other window library) if I'm connected to a remote REPL?
19:26kiwitobesTrying to open windows complains that the environment is headless (which makes sense) but I can't tell if there's a way to run this part locally
19:26justin_smithkiwitobes: if the remote repl was started with the X server display set, the display is running, and it has permissions to access that display (on *nix)
19:26justin_smithkiwitobes: you would need to do X11 forwarding, and have an X server running
19:26justin_smithor if you use another windowing system - well good luck!
19:26kiwitobesjustin_smith: Ah, ok, thanks!
19:27kiwitobesYes, I'm using X11
19:27justin_smithkiwitobes: you also need a java jre that has all the display stuff (not a headless jre)
19:27justin_smithkiwitobes: ssh has an option to do compressed ssh session forwarding
19:27justin_smithbut there is some config needed, and X over a socket is notoriously hard to use
19:27justin_smithas in laggy, it's a fairly noisy protocol
19:28kiwitobesRight, I'm thinking I'll have to have a local repl somehow talking to the remote one
19:28justin_smithkiwitobes: that would give a much better user experience for sure - you could use some protocol to coordinate between the two processes
19:32kiwitobesI looked into using Gorilla REPL, but it doesn't connect to remote REPLs, it has to run its own
19:51arrdemwhat do people like for working with SQL?
19:52justin_smithmore and more I think sql is the right dsl for doing sql in
19:52arrdemso you'd go with yesql
19:52justin_smithyeah
19:52arrdemhum...
19:52justin_smithhaven't used it in anger yet though
19:53justin_smithjust base line frustrations with various attempts to abstract over it
19:53arrdemfair. I used ibdknox's simpledb (which is an unbounded in memory map) in Grimoire and it's really just a memory leak that I need to replace with a real datastore.
19:53arrdemso looking to see what my options are.
19:54justin_smitharrdem: so by "sql" you mean "persistent data store"
19:54justin_smith(though many of the good options are sql of course)
19:54arrdemby SQL I mean "SQL is something I need to learn anyway and the only set of datastores I have confidence in finding working drivers for"
19:54justin_smith:)
19:54vasHi. I'm trying to use compojure and a simple HTML form to write to a database. any hints on how to make my submit button do an action that is caught by my router clj? (=
19:54arrdemwith all due respect to cbp for his awesome work on bitemyapp/revise it is out of date.
19:55arrdemotherwise I'd just use rethinkdb again :P
19:55tbaldridgefor grimoire, I'd be tempted to use some sort of document db
19:55tbaldridgelike couchdb
19:56justin_smithvas: create a POST route, and point the form at it, and use wrap-params and friends (ring middleware) to turn the request data into a map of data
19:56arrdemyeah... since I'm finally caving to using a "real DB" anyway for analytics I may need to rethink the filesystem "datastore" I'm using for the actual documentation data.
19:56justin_smithvas: also, in practice, minimize your points of failure - test the route using CURL, then once you like those results, use the request form on a page etc.
19:57arrdemthe datastore in question is just for storing analytics (for now..)
19:57justin_smithvas: nothing more maddening than "everything is broken and I don't know if I fixed either side yet" when you don't have the form or the backend working yet
19:58vasjustin_smith: ah, that is a great idea. curl ftw. i just read about cemerick/friends today, checking it out now. also, madness is not always a bad thing *sips tea at tea party* thanks for the data|code.
20:03arrdemtbaldridge: have you used clutch or another couchdb driver?
20:03tbaldridgeI did a long time ago, but the api is so simple, you can almost use slurp + data.json if you had to
20:04arrdemgotchga
20:09cflemingSo my understanding is that destructuring cannot be used in Clojure deftype/defrecord/reify method implementations, but can in ClojureScript - is that right?
20:10arrdemyes IIRC
20:10tbaldridgereally?
20:10arrdemtbaldridge: I've never seen it done in CLJ at least
20:10tbaldridge,(reify clojure.lang.IDeref (deref [[x y]]))
20:10clojurebot#<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: sandbox$eval25$reify__27>
20:10tbaldridgeinteresting....
20:11Bronsayeah deftypes & co in cljs expand into extend-type expressions
20:11cflemingMakes sense, since in ClojureScript I guess it desugars down into fns set to JS properties in the end
20:11Bronsacfleming: correct
20:11tbaldridgesomeone should patch clojure...
20:12cflemingBronsa: Ok - so extend-type allows destructuring? Is that true in Clojure too?
20:12amalloytbaldridge: you can destructure just fine in deftype and friends
20:12amalloyyou just can't use &args
20:12amalloywhich people sometimes conflate
20:12cflemingamalloy: Are you sure about that?
20:12Bronsaamalloy: I don't think you are right
20:13amalloyi just did it in a reify
20:13amalloy(defprotocol Foo (f [this x])) (f (reify Foo (f [this [a b]] (+ a b))) [1 2]) ; 3
20:13Bronsaoh well, TIL
20:14amalloysame in a deftype
20:14Bronsa(inc amalloy)
20:14lazybot⇒ 221
20:15Bronsahttps://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L63-L65 relevant code in core_deftype for those interested
20:17cfleming(inc amalloy)
20:17lazybot⇒ 222
20:17Bronsatbaldridge: looks like the exception of your example comes from trying to print the reify
20:17cflemingAnd that's independent of whether it's implementing an interface or a protocol, I guess
20:19cflemingSo I guess this also means that extend-type and extend-protocol also allow destructuring.
20:19Bronsano doubt about that
20:20cflemingOk, now I'm confused - the examples for extend-type also show it allowing rest params?
20:21cflemingActually, of course, since that ends up as an fn too
20:22Bronsacfleming: http://sprunge.us/TcQT
20:22Bronsaweird, but valid usage
20:22vasin a very simple attempt to get a POST route working in my router clj i have something like ,(POST "/ptest" [val] (str "the val was : " val)) ... but I keep getting a 403 ferrbidden when using curl -X POST
20:23cflemingHuh
20:23cflemingBronsa: Like you say, TIL
20:23cflemingBronsa: I'm starting to think that the grammars I'm developing for Cursive will be pretty useful, this stuff is hard to figure out from doc + examples
20:25Bronsacfleming: a weird thing about that example is, the accepted arities to f are still determined by the declared arities in the defprotocol, even though there's a variadic impl
20:25Bronsae.g. you cannot invoke (f) or (f 1 2 3)
20:26Bronsabut I've never seen varargs used in extend-protocol
20:26cflemingI guess that makes sense, since the f you invoke is created by the protocol, which looks the implementing f up, right?
20:26Bronsayeah
20:27justin_smithvas: maybe try turning off any auth et. until you have the basic functionality
20:29justin_smithvas: it can help to add sn outermodt middleware that dumps info before the rest of the code runs
20:29justin_smith*outermost
20:32vasjustin_smith: it's pretty much as barebones as it can be. that is a good idea... it is bizarre because all the GET routines work fine..
20:32justin_smitheasy to write your own printing middleware, but eg. ring.middleware.logger is an option as well
20:33vasjustin_smith: thanks for mentioning curl, that is actually life-saving in this circumstance
20:33amalloyvas: what happens if you send a GET request for a route that your app doesn't handle at all, like curl http://localhost/dsaffas
20:33justin_smithperhaps something like ring-sntiforgery id on by default?
20:34justin_smith*antiforgery
20:34vasjustin_smith: the GETs have a catchall, but the POST returns <h1>invalid anti forgery token</h1> ...
20:35amalloysounds like justin_smith wins the prize
20:35vas:)
20:36rakkarexcuse guys, but do you know where I can get a good clojure .pdf file tutorial? I can see a lot about it in different sites.
20:36rakkarjust free tuto
20:37amalloyi don't understand what you want, rakkar. a tutorial on using pdfs in clojure? a tutorial on clojure, delivered as a pdf...?
20:37rakkarto read offline
20:37rakkarin my tablet
20:37rakkarif I got in my needs
20:37rakkarwill check some good book before
20:37rakkarI have already tried somethings on this language, very impresive.
20:38vasjustin_smith: so, in short, i need to do sessions in order to be able to POST something? (pardon my nubility)
20:38arrdemO'reily will happily sell you a PDF copy of any of the Clojure books...
20:38rakkara lot of books there
20:38amalloy*chuckle* nubility is an actual word, vas, which means something different from "newness"
20:39vasamalloy: rofl i just looked it up. haha
20:39rakkarmany books, what could be the best?
20:39arrdem~books
20:39arrdem,1
20:39clojureboteval service is offline
20:39rakkarlike to beginners, or to work with oracle databases
20:40rakkaror concurrency
20:40cflemingWhile I'm at it, is it there any restriction on the placement of :as and rest params in parameter lists and destructuring?
20:40cflemingBy convention they're always last, but is that required?
20:41cfleming,(fn [a & b c] (+ a b c))
20:41clojurebot#<CompilerException java.lang.RuntimeException: Unexpected parameter, compiling:(NO_SOURCE_PATH:0:0)>
20:41cfleming,(fn [a b & c] (+ a b c))
20:41clojurebot#<sandbox$eval49$fn__50 sandbox$eval49$fn__50@32529bfc>
20:41cfleming,(fn [[a b & c]] (+ a b c))
20:41clojurebot#<sandbox$eval75$fn__77 sandbox$eval75$fn__77@6f35ec84>
20:41cfleming,(fn [[a & b c]] (+ a b c))
20:41clojurebot#<CompilerException java.lang.Exception: Unsupported binding form, only :as can follow & parameter, compiling:(NO_SOURCE_FILE:0:0)>
20:42cflemingWow, that's a helpful error messge
20:42cflemingmessage
20:42cfleming,(fn [[a b & c :as d]] (+ a b c))
20:42clojurebot#<sandbox$eval129$fn__131 sandbox$eval129$fn__131@65d0c5d2>
20:42cfleming,(fn [[a b :as c & d]] (+ a b c))
20:42clojurebot#<sandbox$eval157$fn__159 sandbox$eval157$fn__159@56cbdfca>
20:42cfleming,(fn [[a :as b c & d]] (+ a b c))
20:42clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: c in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:43cflemingInteresting
20:44cfleming,(fn [[:or {b 10} a :as b & c]] (+ a b c))
20:44clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: c in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:44Bronsacfleming: :as and :or go after fixed & varargs
20:45cflemingBronsa: (fn [[a b :as c & d]] (+ a b c)) worked, or at least compiled - whether the fn does the right thing is another question
20:46Bronsacfleming: & d is just ignored there
20:46Bronsa,(fn [[a b :as c & d]] d)
20:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: d in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:46cfleming,(fn [[a b :as c & d]] (+ a b c d))
20:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: d in this context, compiling:(NO_SOURCE_PATH:0:0)>
20:46cflemingI see
20:46cflemingNice, thanks
20:46cfleming(inc Bronsa)
20:46lazybot⇒ 91
20:47amalloywhoa what, it's ignored, not an error?
20:47cflemingLooks like it
20:47cflemingThis is why we should be using grammars to parse our forms
20:48Bronsacfleming: no why, c.c/destructure, c.c/for and c.c/doseq are so nice to read :P
20:48cflemingThis, and many other reasons
20:48amalloywell. it's a bit tricky, because you either have to do what's currently done, and have the reader just accept lists and vectors and so on
20:48amalloyor else you have to adjust the grammar every time you write a macro
20:48justin_smithvas: was walking to the clojerks meetup. it will suffice to provide the token ring generates when serving the page with the form, or turn off the middleware
20:49cflemingamalloy: I define grammars for each individual form
20:49amalloycfleming: and user-supplied macros?
20:49cflemingamalloy: They'll be provided by an extension api
20:49justin_smithvas: actually the session may be used to track token validity...
20:49cflemingWords can't express how much better doing that made my life
20:49amalloyhuh? it sounds like you're saying i have to write an intellij extension to write a clojure macro, but that can't be what you mean
20:50cflemingNot quite. You have to write a Cursive extension if you want support in Cursive for your macro.
20:50amalloywhere support in cursive means...
20:51cflemingBut "write an extension" makes it sound like more work than it is - it's pretty simple
20:51cflemingHaving your symbol resolution work, basically.
20:51cflemingOtherwise there's no way for Cursive to see inside macros to see which symbols they define.
20:51vasjustin_smith: i've always wanted to visit oregon... thanks for your help. i will investigate how to turn it off for now... although eventually CSRF protection will be +
20:53cflemingamalloy: But the extension mechanism is only required in Cursive since I need to support all macros. For a normal lib that needs to parse its own macros, it can be totally self-contained.
20:53justin_smithvas: the rradme looks quite straightforward https://github.com/ring-clojure/ring-anti-forgery
20:54cflemingamalloy: With macros it's even easier than what I do in Cursive, since you know what the form should look like, and you have &form to parse, so your first step can always be (let [parsed (p/parse &form my-grammar))
20:55cflemingThe parser combinators for a PEG parser are about a page of code, and took an afternoon to write.
20:55amalloywell, my perspective on this is that it sounds absurdly over-formal but i could believe i might be wrong
20:56cflemingAgain, it sounds more formal than it feels when you're using it.
21:01arrdemI will be.. should be fun =D
21:02turbofailyeah. it's just a significant amount of money is all
21:02turbofailideally i would have gone last year when it was in SF
21:03turbofailthen i could have at least avoided the hotel and plane ticket
21:07cflemingamalloy_: Here's an example: https://www.refheap.com/96978 is the grammar for deftype. I can then parse it like this: https://www.refheap.com/96980
21:09turbofaili still have nightmares about the c.c/for implementation
21:09cflemingamalloy_: (slightly edited to remove some Cursive-specific stuff, but that's the idea)
21:10cflemingturbofail: https://www.refheap.com/96981 :-)
21:10arrdem(inc cfleming)
21:10lazybot⇒ 10
21:10turbofailthough i guess the nasty part of `for''s implementation isn't really the parsing of it, just the things it does to handle chunked seqs and things
21:11cflemingturbofail: Sure, although the parsing is also pretty hairy. Check out ns too for a bundle of laughs.
21:12cflemingThe other nice thing about this method is that with some small extensions you can get really nice error messages like "Expecting symbol but found vector when parsing let binding vector" rather than "Clojure compiler couldn't convert ISeq to char fuckyou"
21:13arrdemIt's A Feature™
21:14cflemingAnd you don't get weird corners like rest params being ignored if they come after :as and :or clauses just because.
21:14cflemingAnyway, I'll shut up now. tldr - this is fantastic, everyone should do it.
21:16arrdemI'll be looking out for CIDER support :P
21:20arrdemone so motivated could probably package this up as polite-core-macros or something and just alter! all the clojure.core/* macros to add nice arg parser wrappers...
21:22cflemingThat's sort of similar to what dynalint does, I guess, although that's more dynamic checks more along the lines of :pre and :post I think
21:26stevenleegquick question
21:26stevenleeghow can I get access to pow and sqrt?
21:26arrdemhalf considered answer
21:27stevenleeghttp://clojure.github.io/clojure-contrib/math-api.html is deprecated apparently?
21:27arrdem&(Math/sqrt 4)
21:27lazybot⇒ 2.0
21:27stevenleegarrdem: hurrr, got it
21:27stevenleegthanks
21:27stevenleeghaha
21:27arrdemstevenleeg: it's interop to java.lang.Math. I don't like it and think we should have real math fns but we don't.
21:28arrdemgood numerics are hard.
21:28arrdembad numerics are easy.
21:28stevenleegarrdem: what is http://clojure.github.io/algo.generic/clojure.algo.generic.math-functions-api.html
21:28stevenleegI saw that and it looks like real math fns in clj
21:29stevenleegbut I couldn't do (use clojure.algo.generic.math-functions)
21:29arrdemstevenleeg: algo.generic is a solid math fn suite implimented as multimethods, which are fine for light/medium weight use but are too slow to be called "high performance".
21:29arrdem$google arrdem meajure
21:29lazybot[arrdem/meajure · GitHub] https://github.com/arrdem/meajure
21:30arrdem^ project of mine extending algo.generic to do math on numbers with units.
21:34sdegutisHas there been any work done to separate the ClojureScript compiler from the JVM?
21:38gfrederickssdegutis: I'm not sure what this means: https://twitter.com/swannodette/status/559013608232062977
21:40cflemingsdegutis:https://github.com/clojure/clojurescript/wiki/Bootstrapping-the-Compiler
21:40sdegutisIs help welcome?
22:33julianleviston,"Just checking quotes - disregard"
22:33clojurebot"Just checking quotes - disregard"
22:33julianlevistonyay
22:44gfredericksjulianleviston: clojurebot does PMs
22:45julianlevistongfredericks: ah ok… I can't even remember how to do PMs… it's been about 15 years since I used one. lol
22:45julianlevistongfredericks: /msg ?
22:45julianlevistonyep. sweet! haha go memory, go!
22:45gfredericksI always start with /query to minimize the chance of accidentally saying something publicly
22:46gfredericksI don't want anybody to know the things I say to clojurebot in private
22:46julianlevistongfredericks: lol… there's some poetry in there somewhere ;-)