#clojure logs

2015-02-03

01:11Mr0rris0:D
01:17vasHi, i'm using CIDER to play with compojure and enlive. Compojure is in my :dependencies but is not "on the classpath" within cider.. any ideas as to why? (works in external shell)
01:25tomjackdid you kill and start a new CIDER JVM after adding to :dependencies?
01:25tomjackif so, how are you starting CIDER? cider-jack-in? from a buffer visiting a file? which file?
01:26tomjack(it should be a .clj file inside the project in question)
01:27vastomjack: you are a genius
01:27clojurebotHuh?
01:28vastomjack: i was not starting it from a .clj in the project... that was an awesomely simple fix haha. thanks
01:29tomjackC-h f cider-jack-in
01:32tomjack(the cryptic doc there means you can do `C-u C-c M-j` (when it's bound) or `C-u M-x cider-jack-in` to get it to ask you what project you want)
01:38vastomjack: those are very useful. thank you. how does one "bind" something like `C-c M-j to cider-jack-in?
01:48tomjackit's bound in cider itself I think
01:48tomjackyou just have to be in _some_ .clj file already
01:48tomjack(otherwise cider bindings aren't in effect)
01:49tomjackmaybe (global-set-key (kbd "C-c j") 'cider-jack-in)
01:49tomjack(in ~/.emacs.d/init.el in case that is not clear)
01:50justin_smithalso C-c <char> for any single symbol on the keyboard is reserved by emacs for user specific stuff
01:51tomjack..unofficially :(
01:51justin_smithsure, but only shitty elisp modes steal those keys, so if you override their bindings, it's their own fault :)
01:51tomjackI thought org-mode did?
01:52justin_smithOK, shitty or grandfathered in non-shitty :)
01:53justin_smithtomjack: I just checked in an org mode buffer
01:53tomjackmaybe it only takes minor-mode-reserved bindings, which I just learned about
01:53justin_smithlooks like they use some C-c char, but not a-zA-Z
01:54tomjackhttps://lists.gnu.org/archive/html/emacs-orgmode/2014-01/msg01141.html
01:54tomjack:)
01:55tomjackI think I agree with Bastien, org-mode is not a major mode, it's a monster mode
01:55justin_smithhaha
01:56vasdoes anybody know how to play with enlive snippets?
01:57justin_smithtomjack: "Don't define C-c letter as a key in Lisp programs. Sequences consisting of C-c and a letter (either upper or lower case) are reserved for users; they are the only sequences reserved for users, so do not block them." https://www.gnu.org/software/emacs/manual/html_node/elisp/Key-Binding-Conventions.html
01:57justin_smithtomjack: so that gives us 52 decent C-c bindings that modes can't steal (major or minor)
01:58tomjackyes, I never really realized how valuable that is, until I just had flashbacks of trying to decide on a binding
02:02ddellacostavas: what are you trying to do in particular w/Enlive?
02:08vasddellacosta: so i've got deftemplate down, i'm trying to understand how i can grab a chunk of my html page and, defining it as a snippet, duplicate the chunk
02:09ddellacostavas: I'm not sure about defining a snippet dynamically, assuming I'm understanding you right
02:09ddellacostavas: but have you checked out clone-for? https://github.com/cgrand/enlive/wiki/Table-and-Layout-Tutorial,-Part-4:-Duplicating-Elements-and-Nested-Transformations
02:09ddellacostavas: sounds like it may do what you need, if you are trying to repeat something
02:09ddellacostavas: tell me if I'm way off-base here
02:14vasddellacosta: very helpful actually.
02:14ddellacostavas: great!
02:25julianlevistonNot to start a war of editors, but am I missing much using SublimeText and not something lovelier?
02:26julianlevistonI’ve attempted to look at paredit for SublimeText a couple of times, but it just didn’t work out well for me. Am I better off using vim or emacs or something?
02:26rhg135Not at all
02:26julianlevistonIt’s often struck me that editing text is stupid.
02:26julianlevistonAnd editing forms would be much more sensible… which is what paredit is for, right?
02:26rhg135It is for programming
02:27tomjackjulianleviston: I was going to say "yes, paredit" before you mentioned it.. but I drank the kool-aid
02:29tomjackI think every language I use that is not Clojure is regularly noticeably irksome for lack of good structural editing
02:30julianlevistonI was watching timothy baldride’s tutorial before… and it looked like he knew what he was doing...
02:30julianlevistonand he was using paredit.
02:30tomjackof course, I still use them..
02:30julianlevistontomjack: oh no doubt. I wouldn’t even consider talking about this unless it was a lisp
02:30julianlevistontomjack: course.
02:31tomjackso I guess my answer is, yes, you are missing something, but no, you are not necessarily better off :)
02:31julianlevistontomjack: which editor to use tho?
02:31julianlevistona nice one with a buffer and whatnot...
02:32tomjackdunno, "not necessarily" here indicates my ignorance with regard to you (which is much greater than my ignorance with regard to myself, which itself is quite large)
02:32tomjackgood luck :)
02:33julianlevistonwhat do you use? :) vim?
02:36justin_smithI use emacs with vi key bindings
02:36justin_smithbest of both worlds
02:38julianlevistonah ok.
02:38julianlevistonwhat is tim using here? https://tbaldridge.pivotshare.com/media/core.async-episode-1-pipelines/9025/feature
02:39justin_smithno preview :(
02:39julianlevistonefpm… huh?
02:39julianlevistonI don’t understand...
02:39justin_smithI can't watch it without paying
02:40julianlevistonyeah you can. the first one.
02:40justin_smithand I don't feel like paying money to see what editor he is using :)
02:40justin_smithI watched one of his before
02:41julianlevistonyou don’t heav to pay for the first
02:41justin_smithit's not my first
02:41justin_smithlike I said
02:42justin_smithit sits there, not paying, with a donate button lit up
02:42julianlevistonweird. not for me.
02:42justin_smithhow many of his videos have you watched?
02:42hellofunkjulianleviston: i think tbaldridge uses Cursive in some of his videos
03:08julianlevistonjustin_smith: just the free one.
03:08julianlevistonjustin_smith: core async pipelines.
03:08julianlevistonhellofunk: thanks.
03:09julianlevistonhellofunk: I find editors a necessary pain.
03:09julianlevistonhaha I sound so whiney :)
03:18hellofunkjulianleviston: the editor situation for Clojure is a bit of an uphill climb, there is a learning curve regardless of the editor you choose. If I had to do it all over again, and had it been available when I started out, I'd have used Cursive, no doubt. But it's hard to break all the habits I've learned using emacs in my workflow.
03:25julianlevistonhellofunk: I don’t mind learning things. For example, 6 months ago I decided to use Colemac in addition to Qwerty…. and that’s what I’m typing on now.
03:25julianlevistonI’ll take a look at cursive, thanks.
03:26julianlevistonIntellij?
03:26julianlevistonIs it not slow and clunky bloatware?
03:26julianlevistonI guess not.
03:29julianlevistonI’m probably just wary because of eclipse.
03:32ianhedoesit,(dotimes [n (count ["a1" "b2" "c3"])] (str "&ids=" (get ["a1" "b2" "c3"] n)))
03:32clojurebotnil
03:32ianhedoesitI think I know why that doesn't give me what I want, but I don't know how to do it correctly.
03:33julianlevistonianhedoesit: I think you just want join, don’t you?
03:34julianlevistonianhedoesit: what are you trying to end up with?
03:34julianleviston“&ids=[a1]&ids=[b1]&ids=[c1]” ?
03:34ianhedoesityes.
03:34julianlevistonok one sec
03:35hellofunkjulianleviston: definitely don't make the mistake of confusing IntelliJ and Eclipse. they are quite different. I can run Cursive fine on a nearly 4-year Macbook Pro, and I don't generally hear complaints about it being slow.
03:35hellofunkjulianleviston: worth watching Colin Fleming's Clojure conj presentation about Cursive on ClojureTV youtube channel
03:36julianlevistonI think this should do it,
03:36julianleviston(let [ids ["a1" "b2" "c3"]]
03:36julianleviston (join "&" (map #(str "&ids=[" % "]") ids)))
03:36ianhedoesithellofunk: I just watched (most) of that today.
03:36julianlevistonoops.
03:36julianlevistonremove the & inside the first quote…
03:37julianleviston(let [ids ["a1" "b2" "c3"]] (clojure.string/join "&" (map #(str "ids=[" % "]") ids)))
03:37ianhedoesitthat should've been more obvious to me. :) I should probably sleep. thanks
03:38julianlevistonianhedoesit: no wukkaz.
03:38julianlevistonhellofunk: I just started watching jonyelipson’s… but ok.
03:38julianlevistonepsilon
03:38julianlevistonhttp://vimeo.com/103808402
03:39ianhedoesit(inc julianleviston)
03:39lazybot⇒ 3
03:53ianhedoesit(identity ianhedoesit)
03:53lazybotianhedoesit has karma 1.
03:53ianhedoesit(karma ianhedoesit)
04:02daniel`(identity daniel`)
04:02lazybotdaniel` has karma 0.
04:03ianhedoesit:(
04:04daniel`i know
04:05hyPiRion(inc daniel`) ; fixed?
04:05lazybot⇒ 1
04:07julianlevistoncfleming: nice talk!
04:08julianlevistoncfleming: interesting, because I’ve been ranting about structural editing for a long while… and I’ve been applying these same ideas in the project I’ve been devving for the last year or so… which is a structural editor for content… (ie websites).
04:08daniel`hyPiRion: :D ty
04:09daniel`(inc hyPiRion)
04:09lazybot⇒ 65
04:09michaelr`hey
04:11julianlevistonhey
04:25cflemingjulianleviston: Thanks, glad you liked it!
04:27julianlevistoncfleming: it’s a really good further step into having languages and projects that are self-describing, learnable, and intelligently structured rather than “dumb text”.
04:28tomjackhmm, in gorilla repl, are we actually supposed to type code into the browser? ;[
04:28julianlevistoncfleming: I really hate how I generally can’t apply the language to the source. “Homoiconicity what?”
04:28cflemingjulianleviston: Right - I actually think text is a fine serialisation mechanism, having tried it I'm not a fan of graphical editors.
04:28tomjackah
04:28tomjacknevermind. whew.
04:28cflemingjulianleviston: I think tools should understand it though
04:29julianlevistoncfleming: yeah, definitely… cf previous work on transite.
04:29julianlevistontransit*
04:29tomjack"Should you prefer more of an antique editing experience"
04:29cflemingtomjack: I didn
04:29cflemingoops
04:29cflemingtomjack: I didn't write that, but I did have a little chuckle when I read it
04:32tomjackah, so we are supposed to paste from emacs into gorilla I guess
04:34cflemingtomjack: It seems like it would be nice to be able to treat gorilla as a remote REPL and connect to it from some other editor
04:34cflemingtomjack: Although I haven't used it so I'm not sure if that makes sense
04:34julianlevistoncfleming: what do you use as a REPL?
04:34julianlevistoncfleming: or don’t you really do REPL dev?
04:35cflemingjulianleviston: Cursive
04:35julianlevistonoh it has a REPL in it? Sorry I missed that.
04:35tomjackthe problem is all the other stuff
04:35tomjackand your interface to a document shouldn't be a cider repl
04:36cflemingjulianleviston: Yeah, I should have made that clearer in the talk - I'm not anti-REPL, I just don't think it should be used for providing basic editor functionality
04:36cflemingjulianleviston: The Cursive REPL is pretty full-featured these days
04:36julianlevistoncfleming: <3
04:36tomjackcopying into gorilla seems worth it, though
04:37julianlevistontomjack: howcomes? tell me about gorilla?
04:37Glenjaminthere's various things you can get which will send text to another app
04:38tomjackjulianleviston: well, latex, for one thing, that's very nice
04:38tomjackplus.. everything else :)
04:38julianlevistontomjack: i’ve never heard of gorilla before now.
04:38julianlevistontomjack: I’ll go take a look.
04:38tomjackI mean, if I want to share code as pedagogy, that's what I'm gonna do
04:38tomjackhttp://gorilla-repl.org/
04:39tomjackhttp://viewer.gorilla-repl.org/view.html?source=github&amp;user=&lt;&gt;&amp;repo=&lt;&gt;&amp;path=&lt;&gt;
04:39tomjackpretty nuts
04:40cflemingdoes that take a worksheet from github?
04:40cflemingAny suggestions for one to try out?
04:43julianlevistonOh ok so it’s sort of like mathematica for code, similarly to that other project that was built on Om whose name eludes me right now...
04:43julianlevistonmathematica for clojure*
04:44tomjackI'd say more "wolfram for code"?
04:44julianlevistonSo dumb question (cursive) but… how do I open my existing git project. lol...
04:44tomjacker, "wolfram for clojure"?
04:44julianlevistontomjack: same same, really… right...
04:45tomjackhttp://viewer.gorilla-repl.org/view.html?source=github&amp;user=JonyEpsilon&amp;repo=sr-basics&amp;path=ws/introduction.clj
04:46tomjack(first one I found via depth-first search on the owner of the gorilla repo)
04:46cflemingjulianleviston: Lein project?
04:46julianlevistoncfleming: actually it’s a rails project that has a lein project inside it…
04:47cflemingjulianleviston: ok, I guess you're not using IntelliJ Ultimate?
04:47tomjackpretty cool that clojure code can return latex too
04:47julianlevistoncfleming: no… I just started.
04:47cflemingjulianleviston: Ok, you won't get any Ruby support in that case.
04:47julianlevistoncfleming: that’s ok. I’m fine with no ruby support :)
04:47julianlevistoncfleming: just keen for the clojurescript support
04:49tomjackI guess: render/Renderable (render [self] {:type :latex :content "\\frac{1}{2}" :value 1/2})
04:49cflemingjulianleviston: So I'm actually not sure what the best way to do that is. I think you'd be best creating the project from scratch, since if you import your lein project it won't know anything about the rest of it
04:49cflemingjulianleviston: So, File->New project, tell IntelliJ where it is
04:50julianlevistoncfleming: I’ll give it a shot
04:50julianlevistonusing open
04:50cflemingjulianleviston: You'll be able to use open to just open the Clojure part if that's all you need
04:50cflemingjulianleviston: Just use open, and point it to either the project.clj or the enclosing dir
04:53julianlevistonCMD-SHIFT-N… guh.
04:55julianlevistonAh. I wish the find was softer (ie treated all punctuation as whitespace in search terms AND target files)
04:56julianlevistonArgh why does option-shift-right arrow (word select kbd) include the whitespace after it?
04:57julianlevistonhow do I move between objects? it seems to be “move around between text” as the standard way of navigation.
04:57julianleviston(ie char-by-char)
04:57Glenjaminthat was the issue i found when using cursive - intellij didn't quite seem to have the "usual shortcuts" i expected
04:58julianlevistonGlenjamin: yeah well I’ll put up with that.
04:58Glenjaminyeah, i didn't have time to get used to it at that point :(
04:58julianlevistonbut selecting space after is a pain in the butt.
04:58julianlevistonit all feels very java-y to me.
04:59julianlevistontime to learn
04:59SagiCZintellij is java ide after all
04:59julianlevistonSagiCZ: yes, but clojure is built on java and it doesn’t feel like java at all, even though it is.
04:59cflemingjulianleviston: Check https://cursiveclojure.com/userguide/keybindings.html for how to set up keybindings, or if you'd rather do it by hand go to settings->keymap
05:00julianlevistoncfleming: sorry I shouldn’t have said anything. I’m aware there are keybindings.
05:00julianlevistoncfleming: thanks! :)
05:00julianlevistonIs there a good tutorial on keyboard navigation? because it’s not following anything I’m used to on MacOS
05:01cflemingjulianleviston: Which keymap do you have selected?
05:01SagiCZjulianleviston: there is plenty of thing to configure in intellij.. for example if you should be able to move cursor on blank line by clicking or not
05:01cflemingjulianleviston: Settings->Keymap
05:01julianlevistoncfleming: whatever is standard. I’ll check.
05:01cflemingjulianleviston: Make sure it's Mac OS X 10.5+
05:02julianlevistoncfleming: erm… I don’t have settings. I have preferences…? but where are keymaps?
05:02cflemingjulianleviston: Right, File->Preferences
05:02julianlevistonErm, no.
05:02cflemingjulianleviston: Appearance & Behaviour -> Keymap
05:02cflemingjulianleviston: You're on a Mac?
05:03julianlevistoncfleming: all good. Yeah, it’s under the app menu, prefences.
05:03julianlevistongot it
05:03cflemingjulianleviston: Sorry, IntelliJ IDEA -> Preferences
05:03julianlevistonkeymap was os x
05:03julianlevistonswitched to 10.5+
05:04julianlevistonlovely
05:05cflemingjulianleviston: Nice. That one follows Mac standards much better.
05:05julianlevistonyeah and now I can use option up arrow to select levels of objects… huzzah :)
05:06julianlevistoncannot wait until I’ve learned this. It’s the editor I’ve always wanted… for YEARS.
05:06SagiCZjulianleviston: have you been living under a rock?
05:07julianlevistonSagiCZ: um no.
05:07julianlevistonSagiCZ: but syntax editing editors and IDEs traditionally suck. Hard.
05:07SagiCZintellij doesnt
05:07julianlevistonSagiCZ: maybe I just have different requirements than most people.
05:08julianlevistonSagiCZ: c’mon how many editors let you efficiently navigate around the actual objects of your program?
05:08julianlevistonSagiCZ: as averse to the text.
05:08SagiCZjulianleviston: i dont understand what you mean by that
05:08cflemingjulianleviston: Well, IntelliJ does for Java - the navigation is pretty amazing
05:09julianlevistonSagiCZ: cfleming can you explain it to him?
05:09julianlevistonSagiCZ: the semantic elements… as averse to the textual elements.
05:09SagiCZwell intellij can do that.. for years.. so whats the issue here?
05:10julianlevistonSagiCZ: we’ll see, I guess :)
05:10julianlevistonSagiCZ: maybe I’m assuming too much.
05:13SagiCZalso there is thousands of plugins..
05:13julianlevistoncfleming: it doesn’t like om too much. Guess that’s because of the macros in it...
05:14cflemingjulianleviston: Yeah, I'm actually working on om and om-tools support for the next release
05:14julianlevistoncfleming: sweet.
05:14cflemingjulianleviston: Out in a couple of days hopefully
05:20julianlevistoncfleming: and therefore also clojurescript? Seems to be having some issue with (.. event -target -checked)
05:21cflemingjulianleviston: ClojureScript is generally supported, although interop is difficult. There's an open issue for the .. form
05:21julianlevistoncfleming: it’s a bit sad that macros force you to kind of… build extra bits for it.
05:21cflemingjulianleviston: That one is just a bug/oversight. In general interop is hard though because in many cases symbol resolution is impossible
05:21julianlevistoncfleming: yeah...
05:21Glenjaminyou can use -> instead of .. there
05:27julianlevistoncfleming: ok so I read the “getting around” page on doc… how do I navigate left or right at the current hierarchical level under the cursor (so if I’m at the beginning of a defn, I’d like left-this to nav to the end of the last one)
05:29julianlevistoncfleming: ah ok I think I found it. I turned on other setting bindings cursive binding set and I can use paredit...
05:29cflemingjulianleviston: Does Navigate->Structural Movement->Move Forward do what you want?
05:30cflemingjulianleviston: Ok cool
05:30julianlevistoncfleming: one sec
05:30julianlevistoncfleming: actually they’re for editing, not nav. I’ll check what you said.
05:30cflemingjulianleviston: If you've applied the Cursive bindings it should have set one up for that
05:31SagiCZ.
05:31julianlevistoncfleming: yes, structural movment -> Move Forward is it… ok I’ll check it out :) maybe the website could deal with this being on there, too :)
05:31julianlevistoncfleming: sorry for so much noise. I’m just excited :)
05:32cflemingjulianleviston: I'm pretty sure it's there - https://cursiveclojure.com/userguide/paredit.html, under Getting around
05:32cflemingjulianleviston: Hehe, no worries
05:32SagiCZ.
05:32cflemingjulianleviston: Make sure you check out https://cursiveclojure.com/userguide/navigation.html too
05:34ianhedoesitif I have a common string such as a REST endpoint, `ep.example.com`, and I have multiple files which use that as a root but add onto it like `/account/get-field` and `/settings/update`, is there a better way to compose that per file other than `(str core/endpoint "/settings/update?inputs=values")`
05:37ianhedoesitI know it doesn't really save much time, I was just curious. for example, instead of just defining it in each file (i.e. `(def endpoint "ep.example.com/account")` in one file and `(def endpoint "ep.example.com/settings")` in another), including the one root endpoint from a file and changing it per file/ns
05:40julianlevistonianhedoesit: What would you like? You can always define a function which prepends some string to some args… (defn heythere [& args] (apply str "yeah yeah" args))
05:41julianleviston(heythere "woo") ; -> "yeah yeahwoo"
05:42ianhedoesityeah, I figured. I'm not sure what I'd like. :) I was just not liking having multiple vars with the same name in different files with different meanings.
05:42julianlevistonianhedoesit: well if you don’t know what you’d like, then it doesn’t matter much what you write :-) <3
05:49ianhedoesitI'd like to not have to define the same variable in multiple files when it's slightly different, but I suppose just having one function like you said that I can easily compose stuff with would be fine.
05:51julianlevistonianhedoesit: I don’t understand why you have to define the same variable in multiple files… def it in one, then use require in the others.
05:52julianlevistoncfleming: I can’t seem to get paredit turned on for some reason. Following https://cursiveclojure.com/userguide/keybindings.html it keeps not applying. Dunno if I should tell you this here or not!
05:53julianlevistoncfleming: lots of conflicts apparently.
05:53cflemingjulianleviston: I think this is just a case of confusing UI - if you go to your Keymaps panel, and check your actions there (search for slurp, for example) - does it have a binding applied?
05:53ianhedoesitjulianleviston: I don't literally define the same thing multiple times in multiple files, I just have part of the same thing in multiple files (the root of the endpoint)
05:54julianlevistonianhedoesit: sorry I’m really not sure what you’re not able to do, then…?
05:54ianhedoesitbut what you suggested is fine.
05:55julianlevistoncfleming: no it doesn't.
05:55cflemingjulianleviston: Have you copied the Mac OS X 10.5+ keymap to your own (mutable) one?
05:55julianlevistoncfleming: yep
05:56julianlevistoncfleming: then when I go into other settings -> clojure -> keybindings and choose Cursive, it has a lot of conflicts… when I apply, that “goes away”, but the bindings haven’t been applied.
05:56cflemingjulianleviston: Hmm - when you go to the Keybindings panel and select, say, Cursive from the dropdown, what do you see? Are any actions selected?
05:57cflemingjulianleviston: I see. Could you try closing the settings panel and re-opening it? Someone else reported something similar today, and I'm not sure if this has changed in v14 or something.
05:57julianlevistoncfleming: lots… but there are many conflicts
05:58julianlevistoncfleming: sure. this will be my 5th time.
05:58cflemingjulianleviston: It seems to work for most people though, not sure why it's problematic for some people.
05:58cflemingjulianleviston: Don't worry about the conflicts
05:58cflemingjulianleviston: The Cursive action will be used in Clojure contexts, and the default one otherwise
05:59julianlevistoncfleming: oh… it’s working now. I have no idea what I did differently.
05:59julianlevistoncfleming: god I feel like such a noob. apologies.
06:00cflemingjulianleviston: Nah, don't, I hate this panel - it's the worst UI. Unfortunately I can't do much else since I can't customise the Keymap one.
06:00cflemingjulianleviston: I still need to make it clearer what's going on. To make it worse, what I think you were seeing there is that IntelliJ keeps a mutated copy of the settings around, but doesn't show that copy in other panels (e.g. Keymap) until you close the window.
06:01cflemingjulianleviston: Or something - there's definitely a problem in there somewhere, I can't work it out. Unfortunately this is the first thing everyone does when they try Cursive, so I have to fix it.
06:02julianlevistoncfleming: haha :) hehe… no worries.
06:02julianlevistoncfleming: thanks so much for your help. Embrace the fail, probably! :) (ie explicit instructions on how it stuffs up)
06:03cflemingjulianleviston: Yeah, it'll have to be something like that unless I can fix it.
06:04julianlevistoncfleming: God it’s still clunky as hell (not your fault… just what I should be able to do versus reality).
06:07julianlevistoncfleming: For example, I’m two levels deep into a function… then I do “nav right” twice, and instead of going to the relative spot within the next section, it bumps me up to a higher level (level 0) and I’m now navving there. GUH. Fail.
06:07julianlevistoncfleming: paredit is stupid.
06:07cflemingjulianleviston: You'd like it to jump across at the same depth?
06:08julianlevistoncfleming: yep.
06:09julianlevistonThe equivalence in prose would be… if I’m navving at word level, then I cross a sentence-bounds (ie full stop) all of a sudden I start jumping sentences and screaming running around while my house burns down ;-)
06:09cflemingjulianleviston: What would you want here: (((foo|)) bar ((baz)))
06:09julianlevistonsematic structure isn’t being respected.
06:10cflemingjulianleviston: Jump to bar or baz?
06:10julianlevistoncfleming: well, I’m navving symbols at that point, right? so… foo| -> bar| -> baz|
06:10cflemingjulianleviston: But that doesn't respect your depth
06:11julianlevistoncfleming: that’s true.
06:11julianlevistoncfleming: but it does respect my semantic depth, I think… no?
06:11Glenjaminit's like when youre pressing "down" on a long line
06:11Glenjaminand there's a short line
06:11julianlevistonexactly.
06:12julianlevistonthink like a person, not a machine.
06:12julianleviston(that wasn’t aimed at anyone btw)
06:12Glenjaminthat implies some level of mind-reading
06:12julianlevistonGlenjamin: no.
06:12cflemingjulianleviston: Ok, so it would have to remember the depth you're at and try to maintain it. Horribly stateful.
06:12cflemingGlenjamin: Right
06:12julianlevistonGlenjamin: it implies a good deal of syntactic analysis
06:13Glenjaminyou need to know what i "meant" when i pressed "nav-right"
06:13cflemingjulianleviston: Might be able to do it though, I'll think about it.
06:13julianlevistonGlenjamin: what you mean is always bound to where you came from.
06:13julianlevistoncfleming: it was actually what I thought you’d already done.
06:14cflemingjulianleviston: But you came from somewhere else before that - it does require some mind reading to know from when you mean.
06:14cflemingjulianleviston: I don't think it's as simple as the line length case
06:14Glenjaminwhich actions continue the stateful movement, and which reset it?
06:14julianlevistoncfleming: actually the opposite. It’s more simple than the line lenght case. Line lenght is hard.
06:14julianlevistonlength.
06:15cflemingGlenjamin: Exactly
06:16julianlevistoncfleming: well, if I’m moving by character, then the next character. If I’m moving by symbol, then the next symbol, if I’m moving by sentence, then that, if by para, then that, if by function, then that, etc.
06:17julianlevistonIt would only require three levels of functions, I think… one is “move to the next at this syntactic level”, and the other is “move to the next and jump syntactic level up”, and the third is “move right, syntactic down”
06:17julianlevistonso it’d need current state… (what syntactic level you’re at)… and six “keys”
06:18cflemingjulianleviston: I don't think that's what most people want when using paredit, but maybe they're just used to something crappy.
06:18julianlevistoncfleming: you’re right.
06:18cflemingI'm still not sure what you mean by syntactic level
06:18julianlevistoncfleming: apologies for confusing this with paredit.
06:18cflemingDo you mean depth in the tree?
06:18julianlevistoncfleming: not quite really.
06:18cflemingOr do you mean char/symbol/form
06:19julianlevistoncfleming: I’m not completely sure but possibly depth in the tree...
06:20julianlevistoncfleming: For example… I want to work on a particular function. I open a file containing it, then quickly move at function level between them until I find it, then I go into that function… now I go in go in go in, then work on a particular section of the function… perhaps within a let block… I nav around inside that let block, doing my work… refactoring forms, shifting things, etc. (and so on).
06:21julianlevistoncfleming: this excited me so much because it’s possible to build meta patterns of editing on top of it. For example, you’ve done extract chunk to let block binding var, I noticed.
06:22cflemingjulianleviston: If you're talking depth in the tree, paredit already provides move forward in, move forward out, and so on
06:22julianlevistoncfleming: it does. But the left and right don’t work properly.
06:22cflemingjulianleviston: Right, but you need a lot more semantic knowledge to do that right than just tree depth
06:23cflemingjulianleviston: "that" being extract let bindings
06:23julianlevistoncfleming: Do you?
06:23julianlevistoncfleming: ah.
06:23cflemingjulianleviston: Sorry, unsynchronised writes to a single data store
06:23julianlevistoncfleming: lol no worries :)
06:25julianlevistoncfleming: I guess what I’m after is for the things we actually do to be made easier than the things we don’t do much. For example, when I’ve selected a function to work on, I very rarely need to change the arguments immediately, yet I *always* have to nav through the argument list to get to the body. W… T…. F…
06:25julianlevistoncfleming: it’s not probably worth worrying about.
06:27cflemingjulianleviston: That's definitely a worthy goal.
06:27cflemingjulianleviston: It has to be unambiguous how it works, though.
06:27cflemingjulianleviston: Anyway, I'll think about it.
06:32julianlevistoncfleming: I think it’s probably mostly there. It’s a bit tricky, though… in that ()| () -> () |() which makes it feel like two presses between each thing, so that actually each thing is not just one thing, so it doesn’t give you the feeling of navigating between single items… it gives you the feeling of navigating between things and the spaces between them. “Beginning of form 1 -> beginning of form 2 ->
06:32julianlevistonbeginning of form 3” is uniform, but “beginning of form 1 -> end of form 1 -> beginning of form 2” feels… wrong, somehow.
06:32R0B_ROD$seen godd2
06:32lazybotgodd2 was last seen quittingPing timeout: 246 seconds 1 day and 14 hours ago.
06:33julianlevistoncfleming: anyways. :) let me know if you want me to muddy the water further.
06:34julianlevistoncfleming: and I love your work so far!
06:44cflemingjulianleviston: Thanks! And thanks for the feedback too, it's interesting. I think I'll try implementing the move-at-same-depth thing and see how it works.
07:43CookedGr1phonHey all, I have a genclassed namespace, which gets created with an onCreate lifecycle method
07:43CookedGr1phonI would like to use something from another namespace throughout the file so currently havea require :refer
07:43CookedGr1phonhowever, I would very much like to require the namespace as part of the onCreate
07:44CookedGr1phonso that I can do some actions immediately before loading the namespace
07:44CookedGr1phonbut still keep the convenience of the referred naming in this file
07:58pyrtsaIs no one else worried that clojure.core/dedupe is going to miss a reasonable number of use cases because it doesn't take a "by key" function argument?
07:59pyrtsaI.e. I would've defined it as (dedupe f xs) -- remove consecutive duplicates of (map f xs); (dedupe f) -- transducer version.
08:00pyrtsaIt would be dead simple to just say (dedupe identity xs) when the current behaviour is needed.
08:01julianlevistonpyrtsa: can’t why can’t you just comp it with map?
08:01julianlevistonpyrtsa: sorry if that’s a stupid q.
08:01hyPiRionwhy not just call it dedupe-by ?
08:01pyrtsahyPiRion: Sure, could do that as well, but don't you think it's better to just do it in clojure.core?
08:01hyPiRionso you can do stuff like (dedupe-by :index = xs)
08:02hyPiRionMaybe.
08:03pyrtsaI'd still go with a signature like (dedupe[-by] f xs)
08:03Glenjamini wonder how many functions like that can be defined efficiently only in terms of clojure.core
08:03pyrtsaI honestly don't think dedupe without a key is good library design.
08:03Glenjaminthat would simplify massively me "one-function dependency manager"
08:04Glenjamins/me/my/
08:04Glenjamincertainly the -by variant is more widely applicable
08:04julianlevistonpyrtsa: it’s not a library, tho… add it to contrib?
08:05pyrtsajulianleviston: My point is, 1.7 is still alpha. This thing could be changed for the better.
08:05Glenjaminis dedupe new in 1.7?
08:05pyrtsaYes.
08:05pyrtsahyPiRion: Your use case would be simply (dedupe :index xs).
08:06hyPiRionpyrtsa: Sure, but what if I want to check on something else?
08:06hellofunka simple compojure route like (GET "/some/dir/file.html" ...) returns an error 401 when accessing site.com/some/dir/file.html#whatever and I can't figure out why... is the hash something that requires explicit mention in the compojure route also?
08:06hyPiRionsay (dedupe-by :key identity xs)
08:06hyPiRionerr
08:06hyPiRion(dedupe-by :key identical? xs)
08:06julianlevistonhellofunk: does it work without the location? (ie the hash)
08:07Glenjaminthe hash shouldn't be sent to the server at all
08:07pyrtsahyPiRion: Ah, *that*.
08:07hellofunkjulianleviston: good catch, it has nothing to do with the hash, same error.
08:07Glenjaminlooks like dedupe got added as part of rich's "transducers wip" - no separate discussion on jira afaict
08:08Glenjaminit could probably be overloaded to support index-fn and comparison-fn
08:08pyrtsahyPiRion: Actually, It could be (dedupe-by keyfn comp coll)
08:09pyrtsaLike the longer signature of sort-by.
08:09hyPiRionyeah
08:10pyrtsaCool. That'd work. But because of the partial application nature of transducers, I'd not
08:10pyrtsa...have (dedupe-by keyfn coll) defined at all.
08:11hyPiRionright. Hrm.
08:11pyrtsahyPiRion: Though... sort-by asks for a Comparator.
08:11hyPiRionan optional comparator, mind you
08:11julianlevistonI still don’t understand why you can’t compose them together… as in.. dedupe transducer composed with map… no?
08:11julianlevistonI’m missing something aren’t I?
08:12pyrtsajulianleviston: You often want to keep the original and compare by some aspect of it.
08:12julianlevistonyeah… but still
08:13julianlevistoneven so… i still don’t get it
08:13pyrtsajulianleviston: Say I'm walking a Datomic history index, only keeping the latest added/retracted boolean of the datom. If I (map :added datoms), all I've got is a sequence of booleans.
08:13pyrtsaSorry, actually the booleans is what I miss.
08:14hyPiRionpyrtsa: perhaps ask puredanger about this. Sounds reasonable to ask about it
08:14pyrtsaSo a datom being a map of keys [:e :a :v :tx :added], I'd dedupe by (juxt :e :a :v). If instead, I mapped (map (juxt :e :a :v) datoms), I'd lose the :tx and :added.
08:15pyrtsahyPiRion: Cool.
08:15Glenjamindoesnt dedupe only do consecutive?
08:16pyrtsaGlenjamin: Yeah. And any sorted sequence is terrific for that!
08:16pyrtsa...Like Datomic indices.
08:16Glenjaminoh right, sorted by eav
08:16pyrtsaYep!
08:16pyrtsa...and :tx, descending.
08:18pyrtsahyPiRion: Thinking of the most generic use case, actually (dedupe pred coll) where pred takes 2 arguments, would work. Then the ordinary use case would be (dedupe = coll).
08:20hyPiRionpyrtsa: Would be a bit ugly to get the result you wanted though
08:21pyrtsaAgreed.
08:23hyPiRion,(defn asidef [f nxt] (fn [& xs] (apply nxt (map f xs))))
08:23clojurebot#'sandbox/asidef
08:23hyPiRion,((->> = (asidef :key) (asidef :key)) {:key {:key 1}} {:key {:key 1}})
08:23clojurebottrue
08:33sveriHi, is anyone here using environ? I am having trouble to get profiles.clj to work. It does work some sort of, but somehow does not recognize I am in dev mode anymore. There also seem to be problems with cljx regarding environ. Anyone experienced this or using a different approach?
08:35jballancsveri: we've switched over to Nomad
08:35jballancnot quite as convenient as environ, but seems to be a bit more robust
08:36clgvsveri: if you can't trace it in the lib maybe that lib is too complex.
08:37sverijballanc: this is the third time I don't get it running, I guess I give nomad a try too
09:01clgvWith profiles.clj I should be able to replace all repositories by my own private proxy repository, correct?
09:02jballancin theory
09:02engblomWhile I am more productive in Clojure than in Haskell, Clojure seem to be much more difficult to teach to other than Haskell. It is easier to pick out a subset to teach when it comes to Haskell.
09:02clgvjballanc: did you experience differently in practice?
09:03engblomHas anyone been teaching Clojure here?
09:04tbaldridgeI have a friend who has picked up Clojure after only about a year in Python/Java (no programming experience at all before that).
09:05tbaldridgeHe's pretty much taken Clojure for the Brave and True and ran with it, no major issues yet
09:05clrndengblom, I have taught haskell and it can be quite difficult sometimes
09:05the_freythat's a great way to get up to practical usefulness
09:05the_freyCFTBAT that is
09:06tbaldridgethe_frey: yeah, and the early videos by Rich provide a nice basis to the whole thing.
09:07tbaldridgeSo I'm about to spout something that could be considered slightly offensive and/or controversial:
09:07TEttingergasp
09:07tbaldridgeengblom: my theory is that Haskell might be easier to start teaching to people since there are so many small details that can be covered before actually getting to the useful stuff.
09:08tbaldridgeYou have to have discussions about types, IO monads and the like before even getting to a Hello World!. In clojure you just plop a println anywhere, and can use slurp on a whim.
09:09TEttingertbaldridge: so there's more that you can use with minimal necessary knowledge, so that's a broad base to cover
09:09tbaldridgeSo while it seems like they are learning a good foundation of what is needed to program Haskell, I'd question how useful this basic Haskell knowledge is.
09:09clgvengblom: you can start teaching Clojure similarly as you would teach Common Lisp. Start from functions definition over Control flow constructs to sequence ops (map, reduce ...)
09:09Glenjaminso you reckon people struggle because they get to the "i can do stuff, what should i build?" step sooner?
09:09tbaldridgeGlenjamin: exactly.
09:10TEttingerI agree, definitely
09:10Glenjaminthe idea has a certain smug appeal :)
09:10clrndand SICP, it get's you to nothing to "write your own lazy eval champ!" in a few weeks
09:10tbaldridgeand they quickly hit really hard problems (concurrency, web interop, talking to a DB, etc), and those take time to figure out.
09:10clrndfrom*
09:12CookedGr1phonCan anyone think of a neat way to do a scoped require in clojure? What I want is when the block of code gets hit, it requires a namespace, loads if required, and then refers some functions but only within the scope of that one statement
09:13tbaldridge(require .... :as ~(gensym "ns_name"))
09:13GlenjaminCookedGr1phon: why?
09:13tbaldridge^^ don't do that ;-)
09:13CookedGr1phonI'm trying to narrow down and coordinate when namespaces get loaded in order to get my startup as slick as possible, and namespaces are too granular
09:14CookedGr1phonwaiting for everything to load (simply running through the namespace dependency tree) takes ~6 seconds, but I can get something on the screen and reacting in under 200ms if I only load what I need at the very start, and then load the rest in the background
09:15CookedGr1phonI can obviously make smaller namespaces, but then my code is horrible to follow
09:15CookedGr1phonso yeah, trying to find a way to get finer control over this
09:16borkdude_does anyone have an example of Riemann instrumentation of a compojure app
09:18clgvCookedGr1phon: so you app has to be able to do meaningful stuff while the other parts are still loading?
09:18CookedGr1phonclgv: yeah on other threads
09:18clgvCookedGr1phon: require from multiple threads? have fun with that ;)
09:19CookedGr1phonheh, ideally I won't be requiring from multiple threads
09:19CookedGr1phonthe code loading all happens in one thread, just in a strict order
09:19CookedGr1phonand then when the code is loaded, I let it go off and start doing useful work
09:29julianlevistonjog my memory… find first in coll satisfying pred? not some, but … ?
09:30julianlevistonjust first filter?
09:30Glenjaminyeah
09:30stuartsierraor (some (fn [x] (when (pred x) x)) coll)
09:31julianlevistonoh nevermind, http://stackoverflow.com/questions/10192602/return-first-item-in-a-map-list-sequence-that-satisfies-a-function-returning-tru says (some #(if (= % 1) %) '(3 4 1)) which works well...
09:31julianlevistonstuartsierra: exactly! cool thanks.. Hey hi by the way. I loved your book!
09:31julianlevistonoh no I got confused… I mean I loved component.
09:32stuartsierrajulianleviston: thanks :)
09:32julianlevistonstuartsierra: plus I really liked your last talk on it.
09:32julianleviston(inc stuartsierra)
09:38clgvlazybot seems to be on vacation
09:39Glenjamin(dec lazybot)
09:45clgv(lazybot) ; where is the irc metabot restarting lazybot? ;)
09:45clgv(send-off raynes restart lazybot)
09:47bonsai_hkquick show of hands: who is NOT into web programming
09:48clgvbonsai_hk: mostly algorithm dev
09:48julianlevistonbonsai_hk: do you mean not only?
09:48julianlevistonbonsai_hk: or not at all?
09:48bonsai_hkjulianleviston: let's say your current focus for some definition of focus
09:49bonsai_hkclgv: like algorithmic trading?
09:49tbaldridgeprobably about 90% of my work is backend DB stuff, eventually it has a web API, but don't touch that much
09:49clgvbonsai_hk: no
09:49clgvbonsai_hk: http://blog.cognitect.com/blog/2014/10/24/analysis-of-the-state-of-clojure-and-clojurescript-survey-2014
09:49clgvbonsai_hk: scroll down to "which domains ..."
09:51bonsai_hkclgv: I've seen the survey thanks but no IRC handles there to chat to :-)
09:52bonsai_hktbaldridge: well is it the request - db lookup - response kind of backend? it would be web ish
10:27luxbock,(let [ret (transient [])] (clojure.walk/prewalk (fn [x] (conj! ret x) x) '(let [x 123] (+ x 456))) (persistent! ret)
10:28clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
10:28luxbockhmm
10:29luxbockis there a better way to do this? I'd like to get a vector/list of the expressions in the traversal order
10:29justin_smith&(let [ret (transient [])] (clojure.walk/prewalk (fn [x] (conj! ret x) x) '(let [x 123] (+ x 456))) (persistent! ret))
10:29justin_smith,(let [ret (transient [])] (clojure.walk/prewalk (fn [x] (conj! ret x) x) '(let [x 123] (+ x 456))) (persistent! ret))
10:29clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.walk, compiling:(NO_SOURCE_PATH:0:0)>
10:29justin_smith,(require 'clojure.walk)
10:29clojurebotnil
10:29justin_smith,(let [ret (transient [])] (clojure.walk/prewalk (fn [x] (conj! ret x) x) '(let [x 123] (+ x 456))) (persistent! ret))
10:29clojurebot[(let [x 123] (+ x 456)) let [x 123] x 123 ...]
10:29clgvluxbock: you are using transients wrongly anyway
10:30luxbockyeah?
10:30clgvyou'd need to put the vector in an atom
10:30hyPiRion(inc clgv)
10:30luxbockah right
10:30justin_smithluxbock: you need to use the return value of conj!
10:30luxbockfirst time using them
10:30clgvyes. for hashmaps this would certainly fail for larger input (> 16 elements?)
10:30justin_smithluxbock: or, even worse, *sometimes* your code doesn't work if you fail to use the return value
10:30hyPiRionclgv: 8
10:30luxbockI was wondering if there was a way to do this without the transient
10:30luxbockor atoms
10:31clgvhyPiRion: ah 8 key+val pairs?
10:31justin_smithluxbock: sure, write your own walker, and carry two accumulators
10:31hyPiRionyus
10:31hyPiRion,(let [t (transient {})] (dotimes [i 10] (assoc! t i i)) (count t))
10:31clojurebot8
10:31clgvluxbock: not with clojure.walk
10:32luxbockalright, I think this looks a bit ugly but it's so much easier than writing my own walker that I'll just use an atom
10:32clgvluxbock: but you can write your own preorder traversal with apropriate value passing
10:32clgvit'll be just a recursive function after all
10:33luxbockright
10:38darrenhis there an idiomatic way to coerce something that may be a list of strings or a single string into a list? eg. (foo "bob") --> ["bob"], (foo ["bob" "fred"]) --> ["bob" "fred"]
10:38llasramdarrenh: no, and in my experience wanting to do that is an anti-pattern
10:39darrenhThis is to handle what ring does with multi-valued params
10:39llasramAh
10:39darrenhI'd rather ring always returned a list
10:39justin_smithdarrenh: one option would be a multimethod with implementations for string and list
10:39llasramOk, yeah. So in this case you know ring will always yield a string or a vector, so you can just check that
10:40justin_smithmultimethod may be overingeneered if you only get two types though
10:40llasram(checking generically for "any sort of sequential collection" is bizarrely more difficult)
10:40justin_smith,(sequential? "hello")
10:40clojurebotfalse
10:41darrenhah yes, I was thinking (flatten (merge [] "x"))
10:41justin_smith,(map sequential? ["hello" () []])
10:41clojurebot(false true true)
10:41justin_smith,(merge [] "x")
10:41clojurebot["x"]
10:41llasram,(sequential? (java.util.ArrayList.))
10:41clojurebotfalse
10:41darrenh,(flatten (merge [] ["a" "b"]))
10:41clojurebot("a" "b")
10:41justin_smithllasram: good point
10:42justin_smithdarrenh: I have actually never seen merge used with [], why not into?
10:42darrenh,(merge [] [:a :b])
10:42clojurebot[[:a :b]]
10:42TimMcwait what
10:42darrenh,(flatten (into [] "x"))
10:42clojurebot(\x)
10:42darrenhyeah, that didnt work :)
10:43justin_smithflatten is terrible
10:43hyPiRionsure, merge just does that strange conj thingy
10:43TimMc~flatten
10:43clojurebotflatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.
10:43hyPiRion,(conj {:a :b} {:c :d :e :f})
10:43clojurebot{:c :d, :e :f, :a :b}
10:43Glenjaminproposal to remove flatten from core
10:43justin_smithhyPiRion: oh, of course, merge is just calling conj
10:43justin_smith,(flatten {:a 0 :b 1})
10:43clojurebot()
10:43justin_smith,(flatten "hello")
10:43clojurebot()
10:45clgvdarrenh: Most of the time you want (apply concat coll) instead of (flatten coll)
10:46clgvdarrenh: It doesn't take too long until an implementation using `flatten`, will suprise you with unexpected output
10:46justin_smithclgv: well, his given usecase is that he might get {:key "val"} or {:key ["val1" "val2"]} from the ring api
10:46hyPiRionjust wrap it in a list if you really need it
10:46justin_smithbut a simple if is better than a flatten there (checking for vector?)
10:46justin_smithhyPiRion: well, the problem is that the API sometimes gives him a coll of strings, sometimes a string
10:47darrenhclearly the correct solution is to fix the ring api to be consistent at the expense of convenience ;)
10:47justin_smithdarrenh: sometimes a coll sometimes a string is not convenience
10:47justin_smithnot when you need to write code that uses the result
10:48clgvah in that case.... darrenh: I usually have a utility function similar to (defn ->sequential [x] (if (sequential? x) x [x]))
10:48darrenhmost query strings do not have multi-valued params, so returning a string most of the time is convenient.. most of the time
10:49darrenhclgv: thanks
10:51darrenha lot of web frameworks have this 'surprising array when you expected a strign' issue
10:51clgvdarrenh: often used in macro implementations that support lists and single values
10:51clgvdarrenh: ha! try json rendering in "GNU R" - it maximises those kind of surprises...
10:52justin_smithdarrenh: which leads to a conundrum if you want "principle of least surprise" - is the most surprising thing to offer a string sometimes, an array others, or to not provide that surpise like the others do?
10:53darrenhI'd go for consistency - it would confuse a new developer briefly, then they would learn the valuable lesson that query params can repeat, saving themselves much future pain
10:54justin_smithyou mean consistency with everyone else, not consistency within the API
10:54darrenhconsistency within the api: all query values are lists
10:54justin_smithahh
10:54justin_smith:)
10:54Glenjamina different access pattern for string vs seq is the only option that's unambiguous and still simple imo
10:55kodumuloOn http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ it says that thread parking breaks the 1thread = 1 job "knot". When you park a thread does that mean that thread can do other work without spawning a new thread?
10:55justin_smithkodumulo: parking means your task no longer holds the thread
10:56justin_smithand the thread can go do other things
10:56justin_smithwhen your data is ready, some other thread will pick up the process where it left off
10:56kodumuloAh so its not like the job *lives* in the thread. The job is independent and *uses* the thread when needed
10:57justin_smithkodumulo: right, or you could say the threads pick up jobs as they are ready to do work, and drops them as they park
10:57julianlevistonkudumulo - core async threadparking uses a threadpool
10:59kodumuloThats a brilliant concept. It kinda reminds me of a ruby fiber
10:59justin_smithkodumulo: the general concept is called "green threads"
10:59kodumuloah
11:00justin_smithbut in clojure it's a little different, because there are also multiple real threads
11:00kodumuloI thought green threads were just threads that didn't get their own cpu, like in ruby
11:00julianlevistonjustin_smith: unless you’re in cljs. ;)
11:00ToxicFrogjustin_smith: "greenthreads" are specifically things that look like threads to code running in the interpreter but are all hosted in the same OS thread, unrelated to thread pools
11:00Glenjamini also see it called 1:N threading
11:00justin_smithToxicFrog: ahh, sorry
11:00julianlevistonkodumulo: you probably don’t want to think about ruby threads. It’s a friggin nightmare.
11:01kodumulojulianleviston: one of the reasons I use clojure now in the first place ;)
11:01GlenjaminFibers are the same/a similar system to this
11:01kodumuloand dependencies, rubygems is a nightmare as well
11:01julianlevistonkodumulo: likewise ;-) the GIL … guh!
11:01justin_smithToxicFrog: regardless, the same implementation issues that come up with green threads also come up with core.async style threads - you need your own threading logic in the vm
11:01julianlevistonkodumulo: yeah, a whole bunch of things…
11:02julianlevistonkodumulo: OOP is really just not very good for DRY.
11:03justin_smithToxicFrog: is there a general term for this kind of mix of multiple real threads, with green-thread style pseudo-threading?
11:04julianlevistonjustin_smith: timesharing?
11:04Glenjaminah, M:N model, that's what i was thinking of
11:04justin_smithaha!
11:05justin_smithGlenjamin: yeah, just found this as you said that http://en.wikipedia.org/wiki/Thread_%28computing%29#M:N_.28Hybrid_threading.29
11:08mulleris mapcat map followed by cat?
11:08Glenjaminconcat, yes
11:08justin_smith$source mapcat
11:08TimMcThere is no cat.
11:08mulleryeah concat
11:08Glenjaminthere is now!
11:08slipsetwhile on the topic of core.async
11:08llasram(doc cat)
11:09clojurebot"([rf]); A transducer which concatenates the contents of each input, which must be a collection, into the reduction."
11:09justin_smithTimMc: I thought there was a cat transducer
11:09TimMcOy, transducers.
11:09slipsetthe fact that the go-macro is implemented as a state-machine
11:09justin_smith(source mapcat)
11:09Glenjaminthat docstring should really say "EAGER" on it massive letters
11:09slipsetis that inherent to CSP, or does the idea stem from som other place?
11:10TimMc𝑬𝑨𝑮𝑬𝑹
11:10justin_smithslipset: I think CSP was first articulated in terms of state machines, it was a CS thing after all
11:10muller,(mapcat reverse [[3 2 1 0] [6 5 4] [9 8 7]])
11:10slipsetjustin_smith:hmm, I started reading the CSP book by Hoare, but sort of fell off before the state machine was mentioned.
11:10clojurebot(0 1 2 3 4 ...)
11:10muller,(concat (map reverse [[3 2 1 0] [6 5 4] [9 8 7]]))
11:10clojurebot((0 1 2 3) (4 5 6) (7 8 9))
11:11justin_smithslipset: double checking that now
11:11mullernot the same?
11:11justin_smithmuller: apply concat
11:11mullerwhat
11:11slipsetI guess CSP mentions processes as state-machines, which makes sense.
11:11justin_smith,(apply concat (map reverse [3 2 1 0] [6 5 4] 9 8 7]]))
11:11clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
11:11justin_smith,(apply concat (map reverse [3 2 1 0] [6 5 4] [9 8 7]]))
11:11clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
11:12justin_smith,(apply concat (map reverse [[3 2 1 0] [6 5 4] [9 8 7]]))
11:12clojurebot(0 1 2 3 4 ...)
11:12mullerwhy do we need apply i don't get it
11:12julianlevistonwhen the input is a collection instead of direct arguments
11:12justin_smithmuller: map can only return one collection
11:12Glenjamin(doc concat)
11:12clojurebot"([] [x] [x y] [x y & zs]); Returns a lazy seq representing the concatenation of the elements in the supplied colls."
11:12slipsetbut the whole thing, which is nicely explained here http://hueypetersen.com/posts/2013/08/02/the-state-machines-of-core-async/
11:12justin_smithmuller: concat needs multiple args
11:12TimMcmuller: I hand you [1 2 3 4 5]. Add them.
11:13TimMc(reduce is cheating :-P)
11:13slipsetshows how the, I guess green thread like thingy in the go-macro is implemented as a state-machine
11:13muller,(apply + [1 2 3 4 5])
11:13clojurebot15
11:13mullerok :P
11:13Glenjamin,((constantly 15) [1 2 3 4 5])
11:13clojurebot15
11:14mullerI misunderstood what concat does
11:14justin_smithGlenjamin: :P
11:14Glenjaminneeds more than one testcase
11:15justin_smithslipset: I just double checked, by page 12 it is definitely talking about state machines http://www.usingcsp.com/cspbook.pdf
11:15clgvtest.check ;)
11:16slipsetjustin_smith: yes, but that's sortof the vending machines state-machine
11:16slipsetand that makes sense
11:17slipsetbut as I (akwardly) tried to formulate, my question is around how the go-macro is implemented
11:17slipsetand the usage of a state-machine to "flatten" the callback hell.
11:17justin_smithslipset: I think I missed your followup while skimming the csp doc
11:18kodumuloin cider can you reload project dependencies from repl or do do you need to quit and start new session?
11:18kodumulodo you*
11:18justin_smithkodumulo: you can redefine functions or reload namespaces, but to change a dep version you need to restart the vm
11:18kodumulojustin_smith: thanks
11:19kodumuloeverytime i cider-jack-in i feel like neo
11:24mulleris there a difference between (1 2 3) and [1 2 3]?
11:24clgvmuller: list vs vector
11:24mullerok
11:25ToxicFrogmuller: [1 2 3] is a vector literal. (1 2 3) tries to call 1 with arguments 2 and 3 and evalutes to the result. '(1 2 3) is a list.
11:25slipsetjustin_smith:seems like c# await is implemented as a state-machine as well
11:25slipsethttps://www.simple-talk.com/dotnet/.net-tools/c-async-what-is-it,-and-how-does-it-work/
11:25justin_smithslipset: yeah, a lot of things have state machines at the bottom, they are a very well understood abstraction
11:25ToxicFrog,(map type [[1 2 3] '(1 2 3)])
11:25clojurebot(clojure.lang.PersistentVector clojure.lang.PersistentList)
11:26ToxicFrog,(type (1 2 3))
11:26clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
11:26mulleryeah I meant '(1 2 3)
11:26TimMcjustin_smith: "I don't even see the parens anymore; all I see now is juxt, dosync, let."
11:26julianlevistonmuller: yeah, vectors and lists are different.
11:26justin_smithmuller: most things that work with '(1 2 3) work with [1 2 3] also - usually what matters in clojure are the interfaces more than the concrete types
11:26justin_smithTimMc: heh
11:27zerokarmaleftwhoever said that is going to betray everyone for a steak
11:27TimMcErr... I guess I meant that for kodumulo.
11:27justin_smithTimMc: I was about to say that
11:27julianlevistonmuller: vectors are fast to add to the end of, and to look up. Lists aren’t particularly.
11:28kodumuloTimMc: lol
11:28justin_smithTimMc: that's definitely true though, the parens disappear
11:28mullerlist is a singly linked list, and vector stores elements in sequence in the memory, like an array in C?
11:28kodumuloI (->) all the things so they do actually disappear ;)
11:28Glenjaminsomeone once pointed out i had 14 parens on the end of a line
11:28julianlevistonmuller: can I recommend you read clojure in small pieces?
11:28Glenjamini hadn't noticed
11:29justin_smithmuller: vector is more like a tree of arrays - it's complicated
11:29justin_smithmuller: hyPiRion has a good series of blog posts about vector implementation if you really want to know the whole deal
11:29mullerokay
11:29julianlevistonmuller: or, watch rich hickey’s talks on the persistent data structures.
11:29Glenjaminit's safe to say it acts much like an array, but is persistent
11:29justin_smithmuller: http://hypirion.com/musings/understanding-persistent-vector-pt-1
11:29julianlevistonmuller: http://daly.axiom-developer.org/clojure.pdf
11:30mullerthanks
11:30borkdudeI'm trying a query in the Riemann dashboard but I keep getting a parse error. My query is simply: '(service = "metri")'
11:31julianlevistonmuller: https://www.youtube.com/watch?v=ketJlzX-254
11:31Glenjaminborkdude: i think there's a riemann irc channel
11:31borkdudeI get invalid term \"metri\"
11:31borkdudeGlenjamin thanks
11:32muhukHow come this isn't infinite recursion? https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L1478
11:32julianlevistonmuller: coz it’s a call to the runtime.
11:33hyPiRionmuller: the most important part to know for a person new to Clojure is that a vector acts like an immutable arraylist, yet is superfast for the operations you usually do on arrays/arraylists
11:33julianlevistonmuhuk: sorry… coz it’s a call to the runtime.
11:33muhukjustin_smith: isn't (keys map) (the 2nd) evaluated first?
11:34julianlevistonmuhuk: the java interop character calls the keys method on the runtime.
11:34julianlevistonmuhuk: that’s my understanding, anyway.
11:34Glenjamini always find (. obj (method arg)) really weird
11:35muhukjulianleviston: what I see is it's calling the result of (keys map) on RT
11:35Glenjaminespecially when (. obj method arg) does the same thing
11:35julianlevistonmuhuk: nah...
11:35muhukI see
11:35hyPiRionmuhuk: Think of it as (clojure.lang.RT/keys map)
11:35julianlevistonmuhuk: (. clojure.lang.RT (keys map)) means “send the keys message to RT with the arg map”
11:35ToxicFrog...wow, that's a really unclear way of writing it.
11:35muhukgot it, thanks
11:36julianlevistonToxicFrog: and yet, it’s much easier than native java when you get used to it.
11:36Glenjamin,[(. "a" (equals "a") (. "a" equals "a")]
11:36clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
11:36julianlevistonthe . interop operator behaves more similarly to the threading macros really.
11:36Glenjaminoh, missed a paren
11:36Glenjamin,[(. "a" (equals "a")) (. "a" equals "a")]
11:36clojurebot[true true]
11:37Glenjamini find it very odd that those two do the same thing
11:37TimMcIt only becomes important when you have a nullary method.
11:37TimMcand I guess a field with the same name :-P
11:37Glenjaminoh, the former is always a fn, but the latter can be a field?
11:37ToxicFrogjulianleviston: no, I mean, it's much more unclear than either (. RT keys map) or (RT/keys map)
11:38ToxicFrogAnd AFAIK has the same semantiocs
11:38julianlevistonToxicFrog: k.
11:38hyPiRionlet's try it out
11:38hyPiRion,(clojure.lang.RT/keys {:a 1 :b 2})
11:38clojurebot(:b :a)
11:39TimMcGlenjamin: As I understand it, yes. As long as there are no args.
11:39justin_smith,(Math/PI) ; more interop "fun"
11:39clojurebot3.141592653589793
11:39TimMc(.foo obj) could be a field access or method call.
11:39ToxicFroghyPiRion: there we go then.
11:39TimMcjustin_smith: :-(
11:39Glenjamin,(. (first {:a 1}) key)
11:39clojurebot:a
11:39Glenjaminerm, that's not what i meant to do
11:39Glenjaminbut it worked :s
11:40Glenjaminto the local repl!
11:40ToxicFrog(. obj method (a b c ...)) I could see, maybe, but (. obj (method a b c ...)) just rubs me the wrong way.
11:40hyPiRionjustin_smith: whut
11:40hyPiRion,Math/PI
11:40clojurebot3.141592653589793
11:40hyPiRionok, that's a tad weird
11:41Glenjamin,[(. (first {:a 1}) getKey) (. (first {:a 1}) (getKey))]
11:41clojurebot[:a :a]
11:41clgv,(read-string "(Math/PI)")
11:41clojurebot(Math/PI)
11:41clgv,(macroexpand-1 (read-string "(Math/PI)"))
11:41clojurebot(. Math PI)
11:42clgv,(macroexpand-1 (read-string "Math/PI"))
11:42clojurebotMath/PI
11:43Bronsaclgv: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6893-L6900
11:46clgvBronsa: alright.
11:48justin_smithhyPiRion: I think it is backward compatibility or something?
11:51stuartsierrayes, there were several variant syntaxes for the . special form before the .method and Foo/static syntax were introduced.
11:52stuartsierraAnd (.field object) still works on Clojure JVM despite the addition of (.-field object)
11:56clgvI always thought (.-field object) is CLJS only...
12:10justin_smithclgv: well, java classes are much less likely to have fields you use directly (as opposed to an accessor method)
12:12clgvjustin_smith: what is that referring to?
12:13hyPiRionTimMc: how's that Swearjure transpiler going, btw?
12:13julianlevistonclgv: interop
12:14clgvjulianleviston: that is surprising
12:16TimMchyPiRion: On hold since forever. Function-calling is actually tricky -- you have to know whether it's a call like (:foo {}) or a call to a swearjure-transpiled fn.
12:17Glenjaminconvert to AST in between?
12:17TimMcand sometimes the latter is derived from an expression like (if x fn1 fn2).
12:18TimMcGlenjamin: I may just say that you can never call a swearjure-transpiled fn, but have to use a form like (fncall f a0 a1 a2)
12:18Glenjaminthat seems simple enough
12:19TimMcTHat was the only technical stumbling block I ran into. The main problem is that I have better things to do. :-P
12:19clgvTimMc: damn that's a pity. so swearjure is never going to see broad application in industry ...
12:19Glenjaminin other news, i got turned down for a remote UK clojure job today in favour of someone younger and cheaper >.<
12:19TimMcclgv: Pull requests welcome!
12:19clgvTimMc: :P
12:19zerokarmaleftTimMc: what would a swearjure conference be called?
12:20clgvzerokarmaleft: pub brawl?
12:20TimMczerokarmaleft: Something unprintable, I'm sure.
12:20justin_smithour local clojure meetup is clojerks, so I imagine swearjerks would work nicely for swearjure
12:20TimMc#<conj>
12:21justin_smithoh wait, what's swearjure for conj?
12:21hyPiRionTimMc: asking because http://hypirion.com/musings/swearjure-is-turing-complete
12:21hyPiRionjustin_smith: it's just `[~@xs ~x]
12:21zerokarmalefthah, perfect
12:22justin_smithso, it's "the swearjure `[~@xs ~x]" of course
12:22justin_smiththe unpronouncability is a feature
12:22hyPiRionheh
12:22hyPiRionThe conj function is something like
12:23TimMchyPiRion: Oh fuck, replacing the binding form! Brilliant!
12:23justin_smith"the swearjure syntax-quote vec-literal unquote deref xs unquote x endvec"
12:23hyPiRionjustin_smith: #([`[~@% ~(`[~@%&](+))]](+)) I think
12:24justin_smithoh wow
12:24julianlevistonGlenjamin: how old are you? If I’m allowed to ask
12:24Glenjamin27 :)
12:24justin_smithI won't try to spell out the pronunciation of that
12:24julianlevistonGlenjamin: waaaaaa? that’s just weird.
12:24hyPiRionTimMc: yeah, it's awesome. You can actually make sensible programs with Swearjure now :D
12:24Glenjaminwell, the other guy was probably a fresh grad without 5 years of building software experience, hence cheaper
12:25julianlevistonGlenjamin: oh well, I guess they’ll pay. LOL.
12:25julianlevistonGlenjamin: Even 5 years is not very much.
12:26Glenjamindepends where & what you worked on :)
12:26julianlevistonGlenjamin: I’m not convinced of that.
12:26Glenjaminwell, not every 5 years of experience is the same
12:26julianlevistonGlenjamin: but yes, the only thing you can really say about age is that it provides opportunity...
12:27julianlevistonGlenjamin: no guarantees the person is going to have used it wisely or not.
12:27Glenjaminit's possible to have less overall experience after 20 than it is after 5, but obvisouly the theoretical maximum after 20 years is higher
12:27TimMchyPiRion: So we can do the ski calculus now?
12:27hyPiRionTimMc: yes
12:27julianlevistonGlenjamin: of course, this disregards all the things that actually matter, too. ;-)
12:27TimMcoop, just go to that part of the blog post
12:27Glenjaminanyway, the guy was probably demonstrably cheaper, and that was due to lack of experience - either in software or negotiation
12:27TimMc*got
12:28julianlevistonGlenjamin: yeah, like I say, though, they’ll pay ;-)
12:29julianlevistonGlenjamin: I wonder how old he is? Less than 5 years in a lisp is like… do they actually understand stuff? lol. Like… I think it took the last junior I taught about 4 years to start understangin map and don’t even talk about reduce.
12:30clgvhyPiRion: isnt the usage of x,y,z cheating? ;)
12:30julianlevistonGlenjamin: I mean understanding when to use it and whatnot. <shrug> ah well...
12:35TimMcclgv: It's equivalent to $,+,-
12:35TimMcWell, no... ++, --, +-
12:36clgvTimMc: ok ;)
12:38clgvTimMc: hyPiRion: since floats in our cpus are finite you should be able to emulate them as well, right?
12:39clgvah well, only if / would return doubles instead of ratios... damn
12:57mikerodWhy would I be getting issues related to lein-cljsbuild when I do not have it configured as part of my leiningen project?
12:57mikerod"WARNING: no :cljsbuild entry found in project definition." these sorts of issues
12:57mikerodand then subsequently, I get failures for the more recent version of cljs now requiring Java 7 I guess
12:57mullerjulianleviston what.. map is easy.. reduce, granted, is a bit harder to grasp for newbies
12:57mikerodI don't need cljs for my particular workflow right now. It just started failing within the last day or so when I haven't added a dependency of any sort.
12:58mikerod"You're using [lein-cljsbuild "1.0.4"], which is known to work well with ClojureScript 0.0-2197 - *." I do not even see a lein-cljsbuild in my `lein deps :tree` or `lein deps :plugin-tree`
12:58mikerodSo I'm wondering if something is implicitly going on with leiningen now.
13:15vashello, is somnium the preferred way to connect to mongodb with clojure ^.^ ?
13:16{blake}vas: I use monger.
13:16agarmanI use the java driver directly
13:16vas{blake}: thanks thanks.
13:17{blake}vas: No problem.
13:18agarmanbeen awhile since I was in there, but also using monger
13:20{blake}If I were doing it again now, I might use JDBC directly! Not that there's anything wrong with Monger, just not sure what I got from using it.
13:21agarmanmonger mostly converts mongo data structures <-> clojure data structures
13:22agarmanand doesn't make a new DSL to hide mongos...
13:22{blake}Well, I notice using JDBC directly (for mssql) it returns thing as a map. 'bout all I need.
13:22{blake}Yeah, I'm...iffy...on the DSL thing.
13:23{blake}I used to be pro-DSL until I started using Ruby hardcore. =P
13:26vasagarman: so you prefer to use the driver directly currently? how would I go about that?
13:31agarman@vas monger was fine...it turns Mongo's command language into a DSL written in Clojure functions and converts stuff into and out of Mongo for you.
13:32agarman@vas I'd probably start with the Java driver today. I'm not big for including a lot of little, simple libraries in my projects.
13:34agarman@vas though Monger only adds transitively adds two deps, which isn't so bad
13:35vasagarman: yeah, simplicity is :key. maybe i will start with monger then until i get the hang of things. thank you for your words
13:57vasdoes anyone use any templating for CSS, such as jade or haml?
14:04{blake}vas: Under Ruby, I have. In Clojure, I've just used Hiccup.
14:04{blake}Althought that's not CSS, so never mind. =P
14:05vas{blake}: selectors and stuff, yeah. i don't mind playing css-ninja with the actual files, but i do kinda miss the elegance of jade, for example.
14:06{blake}This might be instructive: http://blog.getprismatic.com/bringing-functional-to-the-frontend-clojure-clojurescript-for-the-web/
14:13vas{blake}: you're the best. that link appears to be just what i needs.
14:13{blake}vas: Terrific!
14:25vasgeneral question: i am returning a list '({:tag :div, :attrs {:id thangID}}) ... i want to evaluate thangID before returning the list, but using the ~ operator just returns (clojure.core/unquote thangID) instead of evaluating... any suggestions?
14:27mullerwhy do I get a list in here?
14:27{blake}vas: Wouldn't that be... (thangID)?
14:27muller,(map reverse [[1 2 3] [4 5 6]]
14:27{blake}What do you mean by "evaluate"?
14:27clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
14:27mullerno
14:27muller,(mapcat reverse [[1 2 3] [4 5 6]])
14:27clojurebot(3 2 1 6 5 ...)
14:27mullerwhy a list and not a vector?
14:28muller,(map reverse [[1 2 3] [4 5 6]])
14:28clojurebot((3 2 1) (6 5 4))
14:28{blake}muller: It's my understanding that, generally, functions use the structure that works best for their operations.
14:28{blake}So changing from one type to another is pretty usual.
14:29mullerbut isn't that what this code is doing? it changes the type from vector of vectors to list of lists
14:29mulleroh sorry, I've read that as unusual
14:29mullerreverse seems to be the culprit
14:30muller,(reverse [1 2 3])
14:30clojurebot(3 2 1)
14:30{blake}muller: Map is building a list by concatenating items, I think. Which is easiest done in a list.
14:30{blake},(map inc [1 2 3])
14:30clojurebot(2 3 4)
14:30mulleroh map always returns a list
14:30{blake},(mapv reverse [[1 2 3][4 5 6]])
14:30hyPiRionmap is lazy, which is why you get back a seq
14:30clojurebot[(3 2 1) (6 5 4)]
14:30ianhedoesit,(rseq [[1 2 3] [4 5 6]])
14:30clojurebot([4 5 6] [1 2 3])
14:30hyPiRionAlso, if you know your input is always going to be a vector, use rseq
14:31ianhedoesithey, I just did that! :)
14:31hyPiRionianhedoesit: yeah, you beat me to it :)
14:32mullerthat's doesn't do the same thing
14:32aperiodi1vas: your immediate problem is that ~ only works inside of `, not '. but why not just do (list {:tag :div, ...}) if you really want a list
14:33mullerit is reversing outter vector, i am reversing inner vectors
14:33ianhedoesit,(into [] (mapcat reverse [[1 2 3] [4 5 6]]))
14:33clojurebot[3 2 1 6 5 ...]
14:36muller,(into [] (map #(into [] (reverse %)) [[1 2 3] [4 5 6]]))
14:36clojurebot[[3 2 1] [6 5 4]]
14:36mulleranything better?
14:36mulleris there a map/reverse equivalent that keeps the original data structure
14:37vasaperiodic: thanks. (list) is much easier to play with.
14:37jackhillmuller: I don't know, but I'm curious about why you want to keep the original structure.
14:39{blake}muller: Are there many things at all in Clojure that preserve data structures, I wonder.
14:39{blake}I mean, to preserve it, you sort of have to know what it is, don't you?
14:40mullerjackhill I am just learning now. but in real code I would want to keep it a vector, because, pressumably, I picked vector over a list or sequence it for a reaswon, rather than randomly
14:41jackhillmuller: ah. I wonder if I need to start doing that.
14:41vasaperiodic: excellent. got to the bottom of my issue with your insightful catalyst. gracia
14:42muller{blake} yes
14:42aperiodicvas: glad it helped! quoting is tricky and generally unnecessary outside of writing macros, which is very rarely called for
14:43{blake}muller: Well, having to know about the structure places a lot of limitations on how general you can make your code. If it's important to you, you could make code that did so, at least for your specific cases.
14:43mullerso say I wanted to implement a map equivalent that kept the original data structure. how would I go about it? would I have to hardcode the types in the function, or can i somehow have each function per type
14:43mullers/each/one
14:43{blake}muller:
14:43ianhedoesitmuller: I think you should really think about why you think you need to do that.
14:44{blake}muller: I'm a relative noob myself, and I used to worry about the same thing. Having actually coded in Clojure for a while, it hasn't really been an issue.
14:45{blake}If I need a specific type, I'll use an "into {}" or "into []" or whatever on the return value of whatever's changing my type.
14:45mullerianhedoesit because I picked certain data structure (be it a vector, list or something else) because of the properties it has. and I want to keep it that type
14:45ianhedoesitI understand the difference between a list and a vector in terms of performance, but Clojure will typically decide what's best for you anyway, as far as I understand it.
14:46{blake}When you get down to it, it's a sort of premature optimization.
14:46mullerianhedoesit but it doesn't do that, it always returns sequence. even when it is not the best type
14:46ianhedoesithow do you know
14:47ianhedoesitI mean how do you know that is not ideal?
14:47mulleri was told that in here a couple of minutes ago
14:47mullerblake I don' think it is premature optimizatio to pick (and stick to) appropriate data structure
14:47{blake}muller: I think map returns sequence precisely because it's the best option.
14:48mullerwhy is it the best option?
14:48ianhedoesitfor one it's a lazy seq, so that's obviously better than realizing any data structure every time.
14:49{blake}muller: That is a big question. But you're going in to this with assumptions you've carried over, presumably from other languages.
14:49{blake}And again, I did the same thing. I finally just gave up those notions and found the issue more-or-less vanished.
14:50mullerif i am processing the list once what advanage do i get from laziness?
14:51mullerian I am not. I just want to write clear code. (into [] (map #(into [] (reverse %)) [[1 2 3] [4 5 6]])) could be clearer
14:52mullerso my question still remains, what would be clojure's way of writing a map like that, that doesn't return sequence but whatever datastructure caller passed
14:52raspasovmuller: what are you trying to do?
14:52raspasovmake this nicer? (into [] (map #(into [] (reverse %)) [[1 2 3] [4 5 6]]))
14:53mullerraspasov I want a map equivalent that doesn't return a sequence but whatever type it was passed
14:53mullerhow would I write it?
14:53tbaldridgetransducers can do that
14:53mullerok googling
14:54tbaldridge(one sec while I construct an example)
14:54{blake}tbaldridge: Ooh, cool.
14:55bucketh3adto relevant parties, why not: (vec (map (comp vec reverse) [[1 2 3] [4 5 6]])) ?
14:55raspasovmuller: when you say whatever type - is that limited to maps, vectors, sets, LazySeqs, etc usual suspects in Clojure?
14:56ianhedoesit,(mapv (comp vec reverse) [[1 2 3] [4 5 6]])
14:56clojurebot[[3 2 1] [6 5 4]]
14:56bucketh3adMmm. even purdier.
14:56ianhedoesit:)
14:56mullerraspasov that would be enough. but im curious if we could make it extensible too, so that you could extend it for other data structures
14:57tbaldridgeyeah, what ianhedoesit said, that's pretty clean
14:57raspasovdo look into transducers like tbaldridge says, it can make the transformation in one step I believe, without generating intermediary lazy seqs
14:57justin_smithbucketh3ad: one better: (mapv (comp vec rseq) [[1 2 3] [4 5 6]])
14:57justin_smithrseq is faster if you know the arg is a vec
14:58tbaldridgeyou can also make into generic via empty: ,(let [coll [1 2 3]] (into (empty coll) (map inc coll)))
14:58{blake}muller: Sure. Though obviously your new routines have to have someway to construct the final output of previously unknown types.
14:58mullerthat is much cleaner yeah
14:58ianhedoesitI recommended rseq earlier and I already forgot.
14:58justin_smithhaha
14:59muller{blake} why? they have a function that transforms the elements. and you write a new function per type that represents a data structure
14:59{blake}ianhedoesit: I didn't! I'd never heard of rseq before you mentioned it. So, thanks!
15:00{blake}muller: Right, that's what I mean: You need a new function per type. Look, you either transform it yourself after, or you have your routine make that transformation for you, right?
15:00mulleryeah
15:01{blake}muller: If you want to preserve structures all-the-way-down, you'd pretty much have to rewrite Clojure's basic elements to do so.
15:01{blake}At least I think so. Y'all can correct me if I'm wrong.
15:02mullerI don't know what you mean by Clojure's basic elements
15:02tbaldridgethat's pretty much what transducers allow you to do, write algorithms without worrying about input or output types
15:02justin_smith(inc tbaldridge)
15:02raspasovhere is the transducer version (defn transform-into-self [xf coll] (into (empty coll) xf coll))
15:02raspasovand use it (transform-into-self (map inc) [1 2 3])
15:02tbaldridge,(into [] (map inc) [1 2 3]) ;; no seqs were created by this code
15:02clojurebot[2 3 4]
15:03mullerI would like to write this myself for practice and learning. can I write a map that dispatches on the type of the second argument (type that we are mapping over)
15:03vasthanks everyone for being kind and awesome. have a good breakfast/lunch/dinner when you do! (=
15:04justin_smithmuller: you could. It will be easier if you use transducers. I think people use the name fmap for this function sometimes?
15:04raspasovmuller: just a note, most likely you need 1.7 alphas to have transducers
15:04raspasovout of the box
15:04mullerdo I have to hardcore the types in one function definition, or can I separate definitions, one per type
15:04mullerhardcode :)
15:04justin_smithoh yeah, 1.7 is not out of alpha yet, and you need 1.7 for transducing
15:04{blake}tbaldridge: Wait, what? How is that possible?
15:05{blake}tbaldridge: Doesn't (map inc) make a sequence? What sorcery is this?!
15:05justin_smithmuller: third option is create the right type using one function, regardless of the type of the input
15:05arrdem{blake}: transducer magic
15:05justin_smithmuller: without hardcoding types
15:06{blake}arrdem: My God, it's like a thermos! It keeps the hot hot, and the cool cool! But how does it know?!
15:06justin_smiththe asterix on "regardless of the type of the input" being the type would need to work with the protocols underlying empty / into
15:06tbaldridge{blake}: no, (map inc) creates a transducer, so it looks something like this (once it all executes), (.reduce [1 2 3] (comp conj (map inc)) [])
15:07{blake}tbaldridge: Ahhhhh. That's kind of awesome. So this is in 1.7, though, right? Us <=1.6 types are still making seqs and whatnot.
15:08tbaldridgeyes sadly, but 1.7 is pretty stable ;-)
15:09{blake}tbaldridge: Well, thank you for that example. I'd sort of grasped that transducers worked that way, but that's a simple and clear demonstration of their power.
15:10mullerso I would use defmulti and defmethod for this? to write a function that dispatches on the type of some argument
15:10raspasov{blake}: the even cooler part is that you can "attach" transducer transforms to channels :)
15:10tbaldridgemuller: since you're only using a single dispatch, protocols are probably what you want
15:11{blake}raspasov: I...can't even.
15:11mullertbaldridge ok cool
15:11tbaldridge{blake}: right, tansducers decomplect (*ducks*) the three things in a normal lazy seq transform: a) iterating the source, b) the transformation, c) the output type. Each one of those can be tweeked with transducers
15:12raspasovif you (def x (chan 1 (map inc)))
15:12raspasov, (>!! x 1)
15:12clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: >!! in this context, compiling:(NO_SOURCE_PATH:0:0)>
15:12raspasovyou get (<!! x)
15:12raspasov2
15:12{blake}tbaldridge: And we get that for free? Backwardly compatible, no performance hit...
15:13{blake}raspasov: Dude.
15:13raspasovbut then you have to make sure everything that gets through the channel is a number, otherwise there will be exception (you can supple an optional exception handler)
15:13raspasovsupply*
15:13tbaldridgethe performance is actually better (due to less memory allocation), but at the cost of having to rewrite your code a bit. Notice how we're doing (map inc) not (map inc coll)
15:14TimMcIt only costs one arity. :-P
15:14michaelr`hi
15:14noonianbut the old version of map is still there so you can do it incrementally
15:14noonianold arity I should say
15:14{blake}raspasov: I would imagine. But still cool.
15:15ianhedoesitraspasov: why do you need to map inc and not just inc?
15:15tbaldridgeTimMc: the first arity is free :-P
15:15justin_smithhaha
15:15ianhedoesit(I don't know anything about channels or anything)
15:16mullernoonian how do you pick between old and new version of map?
15:16raspasovianhedoesit: everyone asks that :) it's like you're "mapping" over what passes through the channel, and because inc (I guess) does not have transducer arity? tbaldridge is that right?
15:16michaelr`my application will be in clojurescript with the server side API handled by compojure delegating to liberator, now i've used secretary for routing in clojurescript before. i wonder whether there is any upside to using bidi instead and whether there is any real use case to push it between compojure and liberator as well?
15:16justin_smithianhedoesit: inc works on numbers, he wants inc to be applied to every number that comes from some source of data
15:16noonianmuller: if you're using 1.7 you will have the new version, otherwise you have the old version
15:16noonian,(map inc)
15:16clojurebot#<core$map$fn__4507 clojure.core$map$fn__4507@7b908768>
15:16mullerhmm
15:16noonianguess clojurebot is using 1.7 lol
15:17tbaldridgeianhedoesit: right, what channels need are transducer functions which deal with streams of values. So you can also do stuff like this with channels
15:17mullerif i got it right (map inc) calls a different function than (map inc x)?
15:17tbaldridge(def a (chan (comp (partition-all 2) (map inc))))
15:17ianhedoesitthat's what I figured, I just thought maybe channels could just take any function
15:17tbaldridgeThat'll increment numbers, and then partition them,
15:17ianhedoesitI don't know how data is passed around with channels or anything about them
15:17{blake}muller: Sorta. Multiple arities are described in the same function declaration.
15:17raspasovmuller: yes, different arity of the same fn
15:17ianhedoesit,(map inc 1)
15:17clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
15:17mullerok it executes different code
15:18mullercool
15:18noonianmuller: (map inc) returns a 'transducer' which you can then apply to a collection using the new transduce or sequence functions (sequence isn't actually new). (map inc [1 2 3]) actually applies the function and returns a new collection immediatly
15:18ianhedoesit,((map inc) 1)
15:18clojurebot#<core$map$fn__4507$fn__4508 clojure.core$map$fn__4507$fn__4508@7ebb051c>
15:18ianhedoesitoh okay
15:18justin_smithianhedoesit: by taking a transducer to apply to the channel, instead of a function to map across the channel, there is the added flexibility that the transducer could be a reduction (ie. summing all numbers to come in on the channel)
15:19ianhedoesit,(((map inc) 1) 1)
15:19clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
15:19tbaldridge,(((map inc) conj) [] 1)
15:19clojurebot[2]
15:19ianhedoesitjustin_smith: okay, neat.
15:19tbaldridgeianhedoesit: thats what you want ^^
15:19mullernoonian (map inc [1 2 3]) returns a sequence, like now, yes?
15:19ianhedoesittbaldridge: lol thanks, yeah
15:19mullerlike before rather
15:19noonianmuller: yes, the semantics for the other arities of map are the same as always
15:20noonian,(map inc [1 2 3])
15:20clojurebot(2 3 4)
15:20noonian,(sequence (map inc) [1 2 3])
15:20clojurebot(2 3 4)
15:20noonian(sequence (comp (map inc) (map (partial * 10)) [1 2 3])
15:20noonian,(sequence (comp (map inc) (map (partial * 10)) [1 2 3])
15:20clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:20noonian,(sequence (comp (map inc) (map (partial * 10))) [1 2 3])
15:20clojurebot(20 30 40)
15:21ianhedoesit"magic"
15:21mullerjust wondering if I understand sequences. if we assign the result of (map inc collection) to a variable nothing is computer? until we start pulling values the from resulting seqeuence
15:22mullercomputed
15:22ianhedoesitnothing is computer
15:22justin_smithmuller: yes, map is lazy
15:22{blake}impossible is nothing
15:22justin_smithmuller: not all sequences are lazy, but lazy-seq (which map creates) is
15:23ianhedoesitis there any timeline or ETA for a "stable" Clojure 1.7?
15:23mullercan I skip some values in a lazy-seq
15:23muller(and skip computing those values)
15:23justin_smithmuller: no, they must be realized in order
15:24muller,(def x (map print [1 2 3]))
15:24clojurebot#'sandbox/x
15:24muller,x
15:24clojurebot(123nil nil nil)
15:24justin_smith,x
15:24clojurebot(nil nil nil)
15:25TimMcjustin_smith: Map is *sort of* lazy.
15:26mullerwhy sort of
15:26l3dxafter connecting cider to a repl (or using jack-in) the repl buffer doesn't show up. any suggestions?
15:26TimMc,(def ch (map println (range)))
15:26clojurebot#'sandbox/ch
15:26TimMc,(def ch (first (map println (range))))
15:26clojurebot0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n#'sandbox/ch
15:26mullerwhy does it compute all values?
15:27TimMcChunked sequences.
15:27TimMc"Lazy" means "it probably won't do any computation, and it definitely won't do all of it, but it might do something in the middle."
15:28TimMc(range) emits a sequence that is realized in chunks of 32 at a time; map respects that and computes each of those chunks as a unit.
15:28mulleroh
15:28TimMcIf you're doing side-effecty stuff in there, you might get surprised.
15:28mullerdoes (range) retur n lazy-seq or something else
15:29TimMc&(class (range))
15:29TimMc,(class (range))
15:29clojurebotclojure.lang.LazySeq
15:30{blake},(type (range))
15:30clojurebotclojure.lang.LazySeq
15:30{blake}huh
15:30TimMc,(class (seq (range)))
15:30clojurebotclojure.lang.ChunkedCons
15:32justin_smithTimMc: but the specific answer for "will map do anything if I don't use the result" is the same - or is there some datatype that messes with that too?
15:32mullerintermediate sequence won't be created in here right? (map f (map g (range))))
15:33justin_smithmuller: it will, and that is part of why we have transducers now
15:33justin_smithmuller: because (comp (map g) (map f)) doesn't create the extra seq that your version does
15:35TimMcjustin_smith: Mmmm... I could make one, I think.
15:36amalloymuller: it will be created, but not realized all at once
15:36justin_smithTimMc: I'd be interested to see that (and even more interested to see a sane reason that one would be needed :))
15:37TimMcjustin_smith: I don't think I can make something that will involve calling f in (map f c), but if realizing c involves side-effects, then I can make those happen.
15:38TimMcMmm, no, not even that I think.
15:44csd_Have any of you experienced a bug in Cider where it seems to temporarily loose the ability to create an nrepl session?
15:44amalloyTimMc: yeah, i think that's impossible. map just returns (lazy-seq ...) before it does any work, so nothing will happen until you seq the result
15:44csd_lose*
15:47csd_it would appear that the solution is to do cider-jack-in a second time, while the buffer for the first attempt is still open
15:47amalloy,(read-string "#;")
15:47clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
15:48justin_smithcsd_: weird
15:48amalloyi was surprised this returned EOF rather than "no dispatch macro for ;"
15:49Bronsaamalloy: tagged literals can have spaces between # and the tag
15:49Bronsa,(read-string "#;\nfoo[]")
15:49clojurebot#<RuntimeException java.lang.RuntimeException: No reader function for tag foo>
15:50justin_smith,(read-string "#;\n_invalid []")
15:50clojurebot#<RuntimeException java.lang.RuntimeException: No reader function for tag _invalid>
15:50justin_smitherr
15:50justin_smith,(read-string "#;\n_ invalid []")
15:50clojurebot#<RuntimeException java.lang.RuntimeException: No reader function for tag _>
15:50justin_smithoh, #_ is different I guess
15:50amalloyBronsa: it's just, i would have expected the ; to be an invalid part of a dispatch macro, not a comment in the middle of one
15:50justin_smithit just looks like a tagged reader
15:51Bronsaamalloy: it's not going to intepret it as a dispatch macro anymore. it's in tagged-reader mode :P
15:51Bronsaamalloy: there's no invalid dispatch character error anymore
15:52amalloyBronsa: the error message is still there, in a not-unreachable code path
15:52Bronsaright
15:52Bronsano wait, not-unreachable?
15:53amalloywell, it's not unreachable as far as the compiler is concerned - there are if/else branches that lead there. i can't tell for sure whether they are "actually" unreachable
15:54Bronsaamalloy: I'm pretty sure there's no way to get that exception anymore
15:55amalloyhmmm
15:55amalloychallenge accepted
15:55gfredericksleiningen user-profile protip: seldom-used plugins can be "hidden" from the leiningen startup & classpath by shoving them in a dedicated profile and adding an alias for that plugin's command that expands to with-profile
15:57amalloyBronsa: https://www.refheap.com/41aa882e49e562b2d00f0ed84
15:58amalloynow that you know it's possible, care to guess how, or shall i spoil it?
15:58zactshi which doc explains examples of how to create subdirectories to my project structure within a clojure app?
15:58zactsapp -> subdirectory within my lein repo
15:58Bronsaamalloy: does it involve using a custom tagged reader?
15:58amalloyyes
15:58Bronsathat's cheating :P
15:59amalloyhey, you said it was unreachable
15:59Bronsafair enough
15:59zactshum.. Java.io.File. ?
15:59amalloyanyway, the custom reader is just (constantly nil)
15:59zactsis this the proper way to do this?
15:59amalloyif you invoke that reader you get the old no-dispatch-macro error
15:59Bronsaamalloy: ah yeah, there is actually a ticket in jira for that
16:00crash_epDo any of Clojure's iterating procedures result in a stack overflow if actually allowed to iterate over an infinite sequence? E.g., `doseq`?
16:00tbaldridgecrash_ep: no
16:01crash_eptbaldridge thanks
16:02{blake}zacts: What are you trying to accomplish?
16:02amalloytbaldridge: you can produce sequences that will cause stackoverflows when you iterate over them, which may be what crash_ep is worried about
16:03tbaldridgehey, I didn't say it was unreachable ;-)
16:04crash_epamalloy what are you talking about?
16:05zacts{blake}: just save config files, but I figured it out
16:05{blake}zacts: Congrats. =)
16:05amalloyi mean, if you produce a sequence like uh...(nth (iterate #(map inc %) (range 5)) 10000)
16:05zactsthanx {blake}
16:06amalloythat's a perfectly fine result in theory (and if you change 10000 to 100 it works fine), but in practice trying to consume it causes a stack overflow
16:06amalloybut this is related to the sequences you produce, not how you iterate over them
16:10crash_epamalloy: why is that? Doesn't `iterate` create a lazy sequence?
16:12amalloyhttp://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow
16:13amalloyis the same sort of problem as what i'm describing here
16:13fortruceis there a way to force a rational to be represented as a decimal in the repl?
16:14justin_smithfortruce: (double (/ 2 3))
16:14justin_smith,(double (/ 2 3))
16:14fortrucejustin_smith: thanks
16:14clojurebot0.6666666666666667
16:15ianhedoesit,(float (/ 2 3))
16:15clojurebot0.6666667
16:15justin_smithfortruce: that's actually doing a type conversion, but it's probably the simplest thing
16:16fortrucejustin_smith: yea, i just need it for a quick calculator
16:16ianhedoesit,(/ 2.0 3)
16:16clojurebot0.6666666666666666
16:16crash_epamalloy thanks for the link
16:16fortruceianhedoesit: thats cool :)
16:16justin_smithyeah, you could always potentially pollute the calculation too
16:17ianhedoesit,(/ 2. 3)
16:17clojurebot0.6666666666666666
16:17TimMc,(nth (iterate #(map inc %) (range 5)) 10000)
16:17clojurebot#<StackOverflowError java.lang.StackOverflowError>
16:17TimMcTake that, bot!
16:19justin_smithTimMc: for some reason I thought lazy-seqs would handle that better
16:19crash_epTimMc you animal
16:22tbaldridgehyPiRion: read your blog post earlier today, +1
16:23hyPiRiontbaldridge: the performance one or the swearjure one? :p
16:23tbaldridgehyPiRion: both, but I was thinking about swearjure
16:23hyPiRionhaha, thanks
16:24tbaldridgehyPiRion: the performance one was good as well, it mentioned many concerns I've had about vectors, but never took the time to investigate
16:32hyPiRionYeah – fortunately I don't think very many people hit perf issues related to the vector impl
16:33hyPiRionExcept for ztellman, who seems to have perf issues with about everything :p
16:34gfredericksthe one constant factor in all of ztellman's perf issues is ztellman
16:40{blake},(map (fn[i](inc i)) [1 2 3])
16:40clojurebot(2 3 4)
16:41{blake}(let [afn (fn[i] inc i) (map afn [1 2 3]))
16:41{blake},(let [afn (fn[i] inc i) (map afn [1 2 3]))
16:41clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
16:42{blake},(let [afn (fn[i] inc i)] (map afn [1 2 3]))
16:42clojurebot(1 2 3)
16:42{blake},(let [afn (fn[i] (inc i))] (map afn [1 2 3]))
16:42clojurebot(2 3 4)
16:42TimMcgfredericks: O(ztellman)
16:44amalloywhat in the world is http://octopushub.org/clojure/2015/01/26/hellofunk-did-you-notice-stackoverflowcom-questions-28131135-howtoimplementzipwithfoldlinaneagerlanguage.html about, does anyone know? it seems to be a bizarre collection of things said to me about clojure
16:45gfredericksamalloy: this is the future of content
16:45gfredericksjump on the bandwagon or you'll be left by the train with no elephants in your pockets
16:46amalloygfredericks: you're making the problem worse now. i can just see tomorrow's headline: "amalloy: this is the future of content"
16:46gfredericksyou mean making the problem better
16:46hyPiRionhaha
16:53TimMcHmm, I can't see any obvious way to perform an injection attack on that site.
16:54TimMcIt probably won't even pick on you again any time soon, so you'd have to predict the next search...
16:56TimMcHah, the last "related question" is from me.
16:56aaelonyI know I'm behind the times and this is a silly question, but I'm following a simple Transducers example using filter (http://ianrumford.github.io/blog/2014/08/08/Some-trivial-examples-of-using-Clojure-Transducers/), and the repl is telling me that I have the "Wrong number of args (1) passed to: core/filter". I imagine I need to require a particular version of Clojure and possible use/require something but haven't googled for it correctly yet
16:56aaelony. What might I need to get this to work?
16:57tbaldridgeaaelony: switch to the latest clojure alpha
16:57amalloyTimMc: i think they record everything anyone says, and synthesize pages based on all the subjects somewhere
16:57tbaldridge, *clojure-version*
16:57TimMcThe pages aren't dynamic, I think...
16:57clojurebot{:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}
16:58amalloywell actually, that's interesting. "site:octopushub.org justin_smith" returns a bunch of results, but "site:octopushub.org timmc" gets none at all
16:59aaelonytbaldridge: Thanks, Tim. My google-fu is terrible though and I'm not finding the right artifact etc for the project.clj
16:59tbaldridgeaaelony: http://search.maven.org/#artifactdetails%7Corg.clojure%7Cclojure%7C1.7.0-alpha5%7Cjar
17:00tbaldridgeany 1.7 alpha should work, but alpha5 is the latest
17:00aaelonytbaldridge: perfect. thank you.
17:00TimMcfuzz `fuzz`` <s<b>cript>document.location = "http://zombo.com&quot;;&lt;/s&lt;b&gt;script&gt; !#@*)&%@)@@$">"@$:
17:00TimMc*shrug*
17:00aaelony:)
17:02TimMcamalloy: You could try emailing david.mazvovsky@gmail.com to ask what up.
17:03justin_smithamalloy: wat? Is this some new version of blogspam?
17:04amalloyi don't know, man. it's weird
17:04amalloyTimMc: whence that address?
17:04justin_smithsomeone scraping bytes off the wire?
17:04TimMcamalloy: whois
17:05TimMcjustin_smith: The content scraper is... IN the room!
17:05justin_smithhaha
17:05justin_smithmaybe it's the side job of that spanish speaking bot
17:05amalloyjustin_smith: i'm inclined to think they're scraping one of the log sites or something
17:05tbaldridgeperhaps it's someone's job
17:05justin_smithahh, yeah, that makes more sense
17:05amalloybecause someone with an irc bot would be less confused about who wrote what
17:06TimMcThey have IRC logs from several channels.
17:06amalloylike, all the messages "mentioned by justin_smith" are actually messages *to* justin_smith, like "justin_smith: thanks"
17:07TimMcI wonder if I could file a DMCA request against them.
17:07TimMc...no, they're in Israel, aren't they.
17:07justin_smithTimMc™
17:07justin_smithhaha
17:08amalloyTimMc: well, you could ask google to hide their links. that's how the DMCA works against non-US stuff, right?
17:08justin_smithI mean your nick already has the ™
17:08TimMcyup
17:09TimMcMmm... their website is hosted in EC2, in the US.
17:09TimMcI wonder how that works.
17:10tbaldridgeTimMc: well we are talking about DCMA, isn't the domain of that basically "we'll sue anyone who doesn't abide by our laws, YAH! 'murica!"
17:10weavejesterHas anyone come across an "unsupported binding form" error in the latest Clojurescript versions?
17:11weavejesterOr has anyone actually successfully used the latest Clojurescript without it excepting?
17:11weavejesterI assume it must work for someone :)
17:11michaelr`weavejester: are you on 55 or 60?
17:11weavejestermichaelr`: 60
17:12michaelr`60 works for me
17:12weavejesterHm...
17:12weavejesterIt would be nice if I had some way of figuring out where this error is coming from
17:13michaelr`maybe one of the middleware
17:13michaelr`try maybe lein-ancient to upgrade deps
17:13weavejestermichaelr`: Are you using cljsbuild 1.0.4?
17:14weavejestermichaelr`: This is a pretty simple project. It just relies on Clojure, Clojurescript and tools.macro.
17:15weavejesterOh wait, I think I've figured it out.
17:16weavejesterThe project was still pulling in Clojure 1.5.1
17:16weavejesterHm... okay, it's still failing.
17:16michaelr`1.0.4
17:17michaelr`lein clean (?!)
17:18weavejesterYeah, I think it picked up something weird
17:20weavejesterAhah, that's done it. Looks like the problem is that 2760 only works with Clojure 1.6.0 or greater
17:20weavejestermichaelr`: Thanks for your help
17:32{blake}I'm mapping over a routine that returns a map, so I get a sequence of maps as a result. Because I want just a single map, I'm then doing an apply merge.
17:32{blake}(apply merge (map function stuff))
17:32{blake}I feel like I'm doing too much here.
17:32justin_smith{blake}: wait, how do you get a sequence of maps out of a map?
17:32justin_smithyour function turns a k/v pair into a map?
17:33amalloyjustin_smith: {blake} means "i'm mapping (a function that returns a map) over some sequence"
17:33{blake}Well, my function takes parameters for an SQL query and returns a map of the values.
17:33{blake}amalloy, justin_smith: Yes, sorry if that wasn't clear.
17:33justin_smithaha
17:34amalloy{blake}: (apply merge (map ...)) seems fine
17:34justin_smith{blake}: you may want to use reduce / into, but merge over map seems decent enough
17:34{blake}amalloy: OK. I was thinking I could reduce it into a {}, too, but not sure it's better.
17:35{blake}justin_smith: Hah. OK. Thanks, guys.
17:35justin_smith{blake}: no need for {} even (reduce (fn [acc m] (into acc (f m))) mps)
17:35justin_smithor wait, that would skip the f on the first of mps, so use {} as your explicit initial val
17:36justin_smithbut it comes out pretty much the same
17:36{blake}Let me try reduce, while I have the time.
17:37amalloyi don't really love that reduce. it's just manually inlining the map call, doing transducers by hand
17:37tbaldridge{blake}: in short, upgrade to 1.7
17:38amalloy(into acc (map f) mps) is the same thing i think, with transducers?
17:38tbaldridgeyep, pretty much
17:38{blake}justin_smith: It doesn't help readability, to my eyes. But I tried. =P
17:45TimMcclojurebot: {blake} |means| "i'm mapping (a function that returns a map) over some sequence"
17:45clojurebotIn Ordnung
17:46{blake}Was ist das?
17:50TimMcJust teaching clojurebot some crap.
17:52ianhedoesitclojurebot: what does {blake} mean
17:52clojurebotExcuse me?
17:52ianhedoesit;-;
17:52{blake}heh
17:52{blake}This could be useful.
17:57TimMcclojurebot: {blake}?
17:57clojurebot{blake} means "i'm mapping (a function that returns a map) over some sequence"
17:58{blake}clojurebot words?
17:58{blake}clojurebot: words?
17:58clojurebotThese words are razors to my wounded heart
17:59ianhedoesitclojurebot: TimMc?
17:59clojurebotTimMc is a jerk
17:59{blake}heh
17:59ianhedoesitwhoa there
18:00{blake}When I use a word, it means just what I choose it to meanneither more nor less.
18:00TimMc~TimMc
18:00clojurebotTimMc is a jerk
18:00TimMcheh, maybe that's all it knows about me
18:01ianhedoesit~ianhedoesit
18:01clojurebotExcuse me?
18:01ianhedoesitclojurebot: ianhedoesit |means| "what a great guy - from clojurebot with love."
18:01clojurebotIk begrijp
18:02ianhedoesit~ianhedoesit
18:02clojurebotianhedoesit means "what a great guy - from clojurebot with love."
18:03ianhedoesitTimMc: clojurebot is just a clojure wrapper for PircBot by jibble.org right?
18:11TimMcDunno, check source.
18:12TimMcianhedoesit: I used "means" because of a comment amalloy made that made it sound like he was defining "{blake}", but you can use anything.
18:12atratuscan anyone explain how make-array results in nesting? https://github.com/clojure/clojure/blob/clojure-1.6.0/src/clj/clojure/core.clj#L3680
18:13atratusdoes that line mean its relying on Java to do the work and not clojure?
18:14TimMcyeah
18:14TimMc...I don't understand why it's so hard to find the javadocs online
18:16TimMcWell, I guess the answer is "Oracle doesn't understand internets".
18:16TimMcatratus: It's a call to java.lang.reflect.Array/newInstance
18:18atratusTimMc: ok thankyou, yeah that stuff is awful
18:18sardinha_bibameaning of falsey and truthy please? I am new to programming and not a native english speaker, so I'm having some difficulty understand it and online translations didn't help.
18:19TimMcsardinha_biba: true and false are actual booleans; many languages use broader notions of true-like values and false-like values.
18:20TimMcSo in Clojure, nil and false are treated as false-like (falsey) and everything else are true-like (truthy)
18:21TimMcForms like (if x ...) coerce x into an actual boolean value (true or false).
18:22sardinha_bibaTimMc: Thank you. makes more sense now. Thought that falsey was somewhat different than false
18:45{blake}If I have a multi-user app that connects to mongoDB, can anyone think of a reason why I shouldn't just use the same connection for all calls into it? As opposed to trying for a connection per user/session/whatever?
18:55amalloy{blake}: don't make a connection per user
18:55amalloyunless you're letting users build their own queries or something and you need them to have different permission levels i guess
18:56{blake}amalloy: Nah, nothing that sophisticated. It's really just a substitute file system, if we're being honest.
18:57{blake}I think I just need a way to check if the connection is still good.
19:27ianhedoesitwhat are you using for establishing the connections?
19:27tcrayford____{blake}: I'd establish the connection at once, then pass it through everything. Typically your client should handle connection errors/reconnection/etc
19:28tcrayford____(though I have *no* idea how good mongo's jvm drivers are, I try really hard to never use or think about mongo)
19:28tcrayford____{blake}: one common pattern (if you're using ring) is to `assoc` it onto the request in a middleware
19:29{blake}tcrayford____: So you'd have it so that every session had its own connection?
19:29tcrayford____{blake}: no, one connection, but shared
19:29tcrayford____just it *looks* like every session has it's own connection
19:30tcrayford____means that testing gets easier - you don't have a global connection anywhere, it just comes in with the request
19:30{blake}tcrayford____: OK, so what's the benefit of passing around...oh, I see. =P
19:30tcrayford____:)
19:31tcrayford____also like, means that you don't have jvm bootup dependent on connections happening, which *can* mess you up in production etc
19:31Glenjamintcrayford____: ah good, it's not just me doing that (assoc resources into req)
19:31tcrayford____Glenjamin: pretty sure that's a standard pattern at this point
19:31Glenjaminwhy do you always have so many underscores?
19:31tcrayford____trying to win an award
19:31Glenjamini've seen a few examples that have their routes close over "components"
19:32{blake}Well, my guy wrote some code that just blithely opens a connection for every request. Which is cool. Until you have a few zillion connections.
19:32killfillnewbie question: (def a (atom {:hi "there" :list [1 2 3 4]})) <-- how could i delete one element of that :list?
19:32justin_smithkillfill: does that vector have to remain a vector?
19:33killfilljustin_smith: i think so. yes.
19:33tcrayford____{blake}: I once had code in production that uh, spawned a thread for every incoming request, and left it there (because of a bug)
19:33tcrayford____stuff goes south north of like 200k threads on linux apparently
19:33{blake}tcrayford____: That takes a man's OS to handle...a manly man's OS.
19:33tcrayford____(on that hardware anyway)
19:34{blake}tcrayford____, Glenjamin: I'm curious about the passing around resources, though: What I get back from connect-db looks like "#<DBApiLayer mydbname>".
19:34tcrayford____{blake}: also note that pattern (new connection per request) will *really* mess you up in postgres and some other databases - they spawn a new process per client connection
19:35justin_smith,(swap! (atom {:hi "there" :list [1 2 3 4]}) update-in [:list] ((fn [n] (fn [v] (vec (concat (take n v) (drop (inc n) v))))) 2)) ; killfill
19:35clojurebot{:list [1 2 4], :hi "there"}
19:35justin_smithkillfill: it's a little awkward with the drop-nth as an anonymous function, but that's easy to fix in a real namespace
19:35{blake}tcrayford____: Well, I think it's caused us some issues on Mongo, as well. =P
19:35killfillwops
19:35justin_smithkillfill: also, labeling a vector as :list is kind of weird
19:36killfilli could probably have figure that out in 1 year.. :P
19:36tcrayford____{blake}: /me resists making disparaging remarks about mongo
19:36justin_smithkillfill: it's more straightforward if it isn't a one-liner
19:37killfilljustin_smith: if having a list instead of a vector, would it make it simplier? or we would just take thouse 'vec' out
19:37justin_smithkillfill: general idea is that swap! mutates the state of an atom, and returns the new state, update-in takes a sequence of keys and runs a function on the value found at the end
19:37justin_smithkillfill: having a list would just take out the vec call
19:38{blake}tcrayford____: Swing away. I've got no emotional attachments.
19:38killfilljustin_smith: thanks!
19:38{blake}But I'm still not seeing how I'd pass that connection through an HTTP request.
19:38justin_smithkillfill: simpler example of update-in:
19:38justin_smith,(swap! (atom {:a {:b 0}}) update-in [:a :b] inc)
19:38clojurebot{:a {:b 1}}
19:39dbronicoI'm using Clojure for a simple script, and when I run it from the REPL, all is well. When I run it with lein-exec, it prints my debug messages but terminates before the call to 'map' is done. Can anyone help me sort this out?
19:39justin_smithkillfill: what I do in the first example is only different in a couple of small details
19:39{blake}dbronico: Paste it to refheap!
19:39justin_smithdbronico: map is lazy
19:39justin_smithdbronico: map does nothing, unless you consume the value
19:39justin_smithdbronico: in the repl, the printing step consumes the value
19:40dbronicoAha, so a doall should fix it up, I'm thinking?
19:40justin_smithdbronico: use dorun, unless you need to use the return value somewhere
19:40{blake}dbronico: Well, it'll reveal the error in the REPL, anyway.
19:40justin_smith{blake}: ?
19:40amalloydbronico: http://stackoverflow.com/questions/28183226/how-main-works-on-clojure/28185462#28185462
19:41amalloywhich is saying the same thing as justin_smith but with more words
19:41justin_smith{blake}: the repl hides the error because printing forces the lazy seq to be realized
19:41bonsai_hkdbronico: if you're "doing things" using map, i.e. a glorified for-loop, then rather use doseq instead
19:41{blake}justin_smith: Right...so if he does a -- okay, right, got it backwards.
19:41justin_smithheh
19:41dbronicojustin_smith: OK, that seemed to be the ticket.
19:42justin_smithdbronico: very common mistake, I made it more times than I care to admit
19:42justin_smith~map
19:42clojurebotmap is *LAZY*
19:42justin_smithhaha
19:42dbronico{blake}, amalloy: Thanks for the attempt. You guys are like sharks in here! =]
19:42dbronicobonsai_hk: I will definitely check that out.
19:43justin_smithdbronico: it's a cutthroat battle for imaginary internet points
19:43justin_smith$karma amalloy
19:43justin_smithhe's ahead
19:43justin_smith:P but lazybot is slacking
19:43amalloyis lazybot dead again? i restarted him last night i think
19:43{blake}It's #Clojure, where the games are made up and the points don't matter.
19:43tcrayford____{blake}: sent you a pm, unsure if you saw it
19:44justin_smithamalloy: is lazybot dying or just in a weird disconnect / netsplit state or something?
19:44amalloydisconnected
19:44amalloybut doesn't recover
19:44amalloy&1
19:45lazybot⇒ 1
19:45justin_smithamalloy: so theoretically the fix would be detecting disconnection (which eg. my client seems to do fine) and handling that event
19:45amalloyi think it tries to do that but is broken somehow
19:45justin_smithby my client I mean my regular irc client, not some irc lib I am sitting on
19:45amalloyright
19:46justin_smithamalloy: I am not at all surprised that the API update broke that hook / trigger (if that's even how it works)
19:46amalloyjustin_smith: it was broken before you touched it, in exactly the same way afaict
19:50amalloythe gradual reputation gain i get from old SO answers is a fun reminder of the weird questions people ask sometimes: http://stackoverflow.com/q/8531793/625403 is someone asking how to create a future that doesn't actually start right away
19:52justin_smitha slight distinction, completing in the future vs. starting in the future
19:53justin_smithsee also, people expecting agents to abstract fixed actions over parameters that come in from the client, rather than a stored state modified by an action provided by the client
19:55amalloyjustin_smith: of course, in one sense it actually is a fixed action: the function #(apply % current-state %&)
19:56amalloynot that this is a terribly useful sense
19:56justin_smithwell, the naive expectation is that they would somehow be able to define that action of course
19:57amalloyright. i want a log-to-file agent, and i want to send it lines to log
19:57justin_smithmaybe we can make a ticket on JIRA requesting that agent and go switch names from now on
19:57justin_smiththen people would be less confused
19:58justin_smith(not really)
19:58amalloyjustin_smith: that'll be the first change made after https://github.com/clojure/clojure/pull/6
19:59justin_smithhaha
20:05justin_smithso, in this CMU text, I see the following "Reactive agents simply retrieve pre-set behaviors similar to reflexes without maintaining any internal state." http://www.cs.cmu.edu/afs/cs/usr/pstone/public/papers/97MAS-survey/node14.html ; while in the docs for agent I see "Clojure's Agents are reactive, not autonomous - there is no imperative message loop and no blocking receive." http://clojure.org/agents
20:05justin_smiththis is two different meanings for "reactive agent" right?
20:05amalloyprobably. reactive is practically just an adjective meaning "friggin awesome"
20:06justin_smithheh
20:06justin_smith"functional friggin awesome programming"
20:06justin_smithit works!
20:06amalloyalso, there is a kinda funny github bug involving issue references that i just noticed
20:06justin_smithamalloy: yeah, that issue ref was weird
20:06justin_smithon issue 6
20:06amalloyjustin_smith: it's not just issue 6!
20:06justin_smitherr.. pull 6
20:06justin_smithoh?
20:07amalloy*all* the low-numbered issues in the clojure repo are "mentioned" by that other one
20:07amalloyup to #29
20:07amalloybecause that other one includes a paste of some console output
20:07amalloywhich contains lines looking like: "native: #25 pc 00008cf0"
20:08justin_smithah, and I bet some crazy regex grabs those
20:08justin_smiths/crazy/dunderheaded/
20:08hiredman_it turns out github is just a pile of heuristics that fail at the edges like everything else
20:08amalloybut...unicorns?
20:09hiredman_unicorns, scrum, and agile best practices, etc
20:17xemdetiaI once saw a project manager increase efficiency by twelve unicorns once
20:34tehgeekmeisterhow do you set pprint to be less eager about adding newlines between keys (with no dedent) and complex values?
20:34tehgeekmeisteris there any way?
20:44justin_smithtehgeekmeister: http://clojuredocs.org/clojure.pprint there are some variables that help control how pprint behaves
20:44tehgeekmeister@justin_smith yeah, i looked at those
20:44tehgeekmeisterset the print-miser-width to like 10k and it still didn't do what i was after
20:45justin_smithtehgeekmeister: how about *print-right-margin*
20:48tehgeekmeister@justin_smith trying it now
20:49tehgeekmeisternope, set it to 10k-ish too
20:51tehgeekmeistermaybe I'm doing it wrong, i did: (def ^:dynamic *print-right-margin* 1000000)
20:51tehgeekmeister(10k-ish apparently means a million.)
20:51tehgeekmeister@justin_smith see above
20:51justin_smithtehgeekmeister: that's not how it works
20:52justin_smithtehgeekmeister: https://www.refheap.com/96881
20:52tehgeekmeisterchecking now, thanks for the help
20:52justin_smithnotice I got pprint to put 100 numbers one one line
20:53justin_smith*on one
20:53justin_smithtehgeekmeister: the docs indicate that there is a variable called *print-right-margin* in clojure.pprint which controls that behavior
20:54tehgeekmeisteryeah, so this isn't exactly what we're after fixing, but at least i've learned how to customize the options
20:54tehgeekmeisteri'll dig through the docs a bit more and try things now
20:54tehgeekmeisternow that i know how to do it right
20:54justin_smithtehgeekmeister: in general you aren't going to see code that looks for magic var names in your namespace, that's just not how we do things
20:54tehgeekmeisteryeah, it seemed oddd
20:55justin_smithif some var controls a functions global behavior, it'll be defined in the same project (if not the same namespace)
21:06justin_smithfrom now on, when I use agents in my clojure code, I will be naming them "smith"
21:24andyftehgeekmeister: If pprint isn?t bending to your will, you may want to take a look at aprint to see if it does what you want: https://github.com/razum2um/aprint
21:28dbronicoIf I am doing work in parallel that has prints, is there a way to guarantee no overlapping prints? I was hoping atoms with watches would work, but it's not the case.
21:28julianlevistondbronico: I would think a logger would have this covered.
21:28justin_smithdbronico: one option is (locking *out* (println ...)) - just make sure that nothing inside the println call tries to do the same of course
21:28justin_smithor yeah, the better option is a proper logger
21:29dbronicoA proper logger... Can you give a little more detail or a reference to where I can find out more?
21:29julianlevistondbronico: maybe you could redef println for your work.
21:30julianlevistonhttps://github.com/clojure/tools.logging
21:30justin_smithdbronico: check out clojure.tools.logging
21:30julianlevistonjust first google I found...
21:30justin_smithor what julianleviston said
21:30julianlevistonhaha :)
21:30sorenmacbethis there a not terrible way to resolve an aliases var to it's fully qualified self?
21:31justin_smithsorenmacbeth: you can get the mappings of an ns programmatically, and look it up in there - depending on what you are actually doing
21:31julianlevistondbronico: core async channels could be good… :-)
21:31justin_smith,(.getMappings *ns*)
21:31clojurebot{primitives-classnames #'clojure.core/primitives-classnames, +' #'clojure.core/+', Enum java.lang.Enum, decimal? #'clojure.core/decimal?, restart-agent #'clojure.core/restart-agent, ...}
21:33dbronicojustin_smith, julianleviston: Thanks a lot. I'll check out the logging. Didn't realize it was an easily-Googlable term. =P
21:33justin_smithor ##(ns-refers *ns*) which is slightly higher level
21:33lazybot⇒ {primitives-classnames #'clojure.core/primitives-classnames, +' #'clojure.core/+', decimal? #'clojure.core/decimal?, restart-agent #'clojure.core/restart-agent, sort-by #'clojure.core/sort-by, macroexpand #'clojure.core/macroexpand, ensure #'clojure.core/ensure, chun... https://www.refheap.com/96882
21:33dbronicojulianleviston: Thanks for the suggestion. I hear a lot about core.async. I'll check that out, too.
21:33julianlevistondbronico: it’s fricking awesome.
21:34julianlevistondbronico: a really good way to make sure your one thing does only one thing at once (fanning in).
21:35sorenmacbethjustin_smith: cheers
21:35justin_smith,(ns-aliases *ns*) ; this may also be helpful
21:35clojurebot{}
21:36justin_smithand in general ##(clojure.repl/apropos #"^ns")
21:36lazybot⇒ (ns-unmap ns-publics ns-unalias ns-aliases ns-resolve ns-refers ns ns-name ns-map ns-interns ns-imports nss)
21:38dbronicojulianleviston: So I'd set up a channel, a sorta 'channel-reader' that's infinite loop (in theory) that just listens on the channel and prints whatever it gets, then just have my print messages get put on the channel.
21:38justin_smithdbronico: google isn't always reliable (ie. we phased out clojure.contrib much faster than google stopped giving results about clojure.contrib)
21:39justin_smithdbronico: yeah, that's the idea. I would write a function that takes varargs and puts them on the chan to be printed (so that your code doesn't have to look like core.async code, it can just be your-ns/println)
21:39julianlevistondbronico: yeah, you could have one go block with a channel set up around your main functionality that just blocks then prints, and your main functionality then passes that channel to the rest of the code, and then all your calls to println become a call to put! the channel instead.
21:40julianlevistonjustin_smith: wait… clojure.contrib is phased out?
21:40TEttingerjulianleviston: yeah since 1.2
21:40justin_smithjulianleviston: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
21:40amalloyjulianleviston: the old old old thing of a single clojure-contrib jar is out
21:40amalloyclojure contrib as a collection of independent libraries still exists
21:40julianlevistonoh phew.
21:41justin_smithoh yeah, good point :)
21:41justin_smithbut we don't have the clojure.contrib.whatever naming any more either
21:41justin_smitheven if they are contrib projects
21:41dnoleniOS ClojureScript REPL is blowing my mind, all thanks to mfikes
21:41dnolenhttps://github.com/omcljs/ambly
21:41julianlevistonbmabey: .… of rspec/cucumber fame?
21:42julianlevistondnolen: haha… wow…. that’s so fricking cool
21:43dbronicojustin_smith, julianleviston: OK, I'm checking out core.async. Thanks again.
21:46julianlevistondnolen: so what are the ramifications of this that give you so much excitement?
21:46dnolenjulianleviston: well later React Native
21:46julianleviston(that I’m not doubt missing)
21:46dnolenjulianleviston: but really this just means you can script any iOS application given you've added adequate bridging
21:47dnolenjulianleviston: React Native just ships with a bunch of free bridging
21:47dnolenjulianleviston: but this just means you can build real iOS apps (no WebView) with ClojureScript with the expect REPL driven workflow
21:47julianlevistondnolen: hey what do you think of Relay, btw? I spent the last like 6 months wrangling my own with Om/CLJS and… I’m tired. :-)
21:48julianlevistondnolen: ah… yeah, react native… huzzah… does it transpile to the objc/swift runtime? For some reason I thought it was running a javascript vm inside it. lol.
21:49julianleviston(no idea if transpile is the right word to use there)
21:49dnolenjulianleviston: Apple shipped real JavaScript bindings into Objective-C run time w/ iOS 7
21:49dnolenjulianleviston: this is old news
21:49julianlevistondnolen: oh. I think I missied that. What does real JS bindings mean, tho?
21:49dnolenjulianleviston: but yes embedded JS that talks to native components
21:50dnolenjulianleviston: like a real native embedded language bridge
21:50julianlevistonooh
21:50dnolenjulianleviston: the same way V8 talks to C++
21:50julianlevistondnolen: or Nu or CocoaRuby
21:51dnolenyep
21:51julianlevistonwow
21:52julianlevistonOMFG so we might get true native performance running clj in the browser in iOS… and on Om apps… oh this is nuts.
21:54dnolenjulianleviston: well you're limited by JSC, no JIT yet, but this doesn't matter for many apps
21:54dnolenjulianleviston: FB is already building real apps w/ stuff
21:54dnolenand the perf is good
21:55rkneufeldIf anyone out there is using or has considered using Simulation Testing, I'd love to get your input: http://www.rkn.io/2015/02/03/state-of-sim-testing-2015/
21:56tehgeekmeister@justin_smith we found fipp, it does the style of printing we're after
21:56julianlevistondnolen: that’s really cool
21:56tehgeekmeisterbut thanks for the pointers, they'll definitely help us get up to speed
21:56justin_smithtehgeekmeister: oh, nice
21:57bbloomtehgeekmeister: let me know if fipp works out for you
21:57tehgeekmeisterbbloom: it does so far, in like <5 minutes of use
21:57tehgeekmeisterwill get back to you though, for sure
21:57mfikesdnolen: The perf of React Native is actually much better than what the FB Groups app would lead you to believe. (There is a lot of FB infrastructure that is unrelated to React Native in its init sequence.)
21:58justin_smithbbloom: oh, now that I see you are around, I'm thinking you may be one of the people who could give me a good answer to this question I just posted on the ml https://groups.google.com/forum/#!topic/clojure/Le_McSEy1_c
21:58dnolenmfikes: good to hear
22:01mfikesdnolen: I was concerned because the ClojureScript / native hybrid app I built starts up much (much) more quickly than FB Groups, and Vjeux esentially explained that plain-vanilla React Native apps start up instantaneously :)
22:02mfikesjulianleviston: Also, this will all lead to Android, and (for someone like me) perhaps the ability to build decent web apps :)
22:02julianlevistonhaha :)
22:04n0n3suchquick question: i have spent the last 2 years learning scala and building a big project in scala and now want to learn another language while i develop my scala skills further. I am considering haskell and clojure.
22:04mfikesjulianleviston: It is an amazing thought: You can learn Clojure(Script) for front and backend (1 language), and React for several front ends.
22:04julianlevistonmfikes: it really is…
22:04n0n3suchHow will learning clojure help me improve as a software developer ?
22:04mfikesjulianleviston: And all of it is very functional
22:04julianlevistonn0n3such: learn them both. They’re both excellent.
22:05n0n3suchjulianleviston: which is a better investment of my limited time and brainpower ?
22:05julianlevistonn0n3such: clojure is a lot easier to approach, so start with that… but learn a little haskell every day.
22:05mfikesn0n3such: Yes, you need to at least read through the Haskell O'Reilly book. It will _force_ you to look at things a certain way.
22:06n0n3suchmfikes: Real World Haskell ?
22:06sharmshow do I make 'lein ring server' auto-reload?
22:06mfikesn0n3such: Yep. I liked that one. Brian O'Sullivan IIRC
22:07julianlevistonsharms: I think the help tells you doesn’t it?
22:07codestorm444I looked into many FP languages, and chose Elixir
22:07n0n3suchcodestorm444: why ?
22:07julianlevistoncodestorm444: why choose one?
22:07sharmsjulianleviston: no, running 'lein help ringer server' gives no help
22:08codestorm444Elixir runs on the Erlang VM which has some awesome features. It incorporates some of the better features from clojure, but has a friendly Ruby-like syntax
22:08codestorm444julianleviston: gotta start somewhere
22:09codestorm444clojure was my #1 until I learned about Elixir, haskell would have been #3 choice
22:09n0n3suchwhy clojure #2 ?
22:09julianlevistoncodestorm444: I guess, as always, it comes down to… what are you trying to do? :)
22:10julianlevistonsharms: If the LEIN_NO_DEV environment variable is not set, the server will monitor your source directory for file modifications, and any altered files will automatically be reloaded. https://github.com/weavejester/lein-ring
22:11sharmsjulianleviston - thanks, I am not sure for whatever reason that is working, however if I add :auto-reload? true to my project.clj it works now
22:11codestorm444why #2? well, clojure pros: large base of JVM libraries... concurrency features... macros
22:11julianlevistonsharms: oh yeah, sorry… it’s been a while since I’ve used it.
22:12julianlevistoncodestorm444: erm… what about the persistent data structures? OMG
22:12julianlevistoncodestorm444: and the immutability…
22:13codestorm444yeah, elixir has those too
22:13codestorm444i guess most FP languages do
22:13julianlevistoncodestorm444: erm… no?
22:13julianlevistoncodestorm444: not that I know of.
22:14codestorm444Elixir does
22:14codestorm444Scala hedges with val and var
22:14julianlevistoncodestorm444: it has persistent data structures?
22:14codestorm444yes
22:14julianlevistoncodestorm444: can you point me to where this is true?
22:15julianlevistoncodestorm444: using the same trie structures as Clojure?
22:16TEttingerthere are probably other data structures that are persistent that are better for certain tasks
22:16TEttingeras in, not 32-trie based
22:18julianlevistonTEttinger: sure. As always, it depends what you’re trying to do ;-)
22:18codestorm444julianleviston: I don't have a hnady link for you, but that's how elixir works. You add something to a list, you get a different list, the original is untouched
22:18julianlevistonTEttinger: these ones have some nice properties, tho… to put it mildly ;-)
22:19amalloycodestorm444: that's not necessarily the same thing as persistent
22:19TEttingerah, it's immutable not necessarily persistent
22:19amalloyyou can implement that property using copy-on-write arraylists or something, which supports a functional style but is immensely slow
22:19julianlevistoncodestorm444: can I suggest before you go down any of these paths, watch some rich hickey talks about persistent data structures...
22:20amalloyi don't know how elixir's data structures actually are, just pointing out that your example doesn't necessarily answer the question
22:20julianlevistoncodestorm444: that was why I asked you four times… I should have asked you to define persistent data structure instead, it seems.
22:21julianlevistoncodestorm444: the end rub is… these are incredibly fast for most of the types of things most coders do most of the time, and support concurrency really well.
22:22amalloyhttp://comments.gmane.org/gmane.comp.lang.elixir.general/442 suggests that the answer is complicated
22:25julianlevistonamalloy: hm… it seems pretty cut and dry to me… it relies on what the erlang vm does… which isn’t aware of this stuff. What about vectors? sorted collections? the whole idea of the sequence abstraction? For the guts of most coding practice, I’m yet to see a language that encourages a programmer to pay as much attention to the upsides of the structures they pick (and why) as it does to the downsides.
22:35julianlevistonI love that where other languages say “Don’t look into this box”, “Don’t worry about how that works”, or “I’ll handle that for you”, clojure says “It’s hard, but you can absolutely do it, let me show you how, and what the costs/benefits are of choosing each thing are”.
22:37tehgeekmeisterso if i want to pipe a java buffered stream to stdout in clojure, how do i do that idiomatically?
22:38tehgeekmeisterrather than reading the whole thing in, and then printing it out
22:38tehgeekmeisteri mean i know i can read a small chunk, write it, etc, but i figure there has to be a better way
22:39Lewixhi gentlemen
22:39julianlevistontehgeekmeister: https://www.safaribooksonline.com/library/view/clojure-cookbook/9781449366384/ch04.html
22:39Lewix (+ (cons (nth [1 2 3] 0) [1 2 3]) )
22:39LewixI expected this to work
22:40Lewixwhat's the logic behind it not working?
22:40ToxicFrogNethack bot written in Clojure achieves the first fully automated ascension: https://www.reddit.com/r/nethack/comments/2tluxv/yaap_fullauto_bot_ascension_bothack
22:40justin_smithoh wow, awesome
22:41julianlevistonLewix: you’re trying to add a cons cell
22:41julianlevistonLewix: what does that mean?
22:41julianlevistonmaybe you want (apply + (cons (nth [1 2 3] 0) [1 2 3]) )
22:42sdegutisWhat's a good GUI toolkit for writing a budget app?
22:42Lewixjulianleviston: cons produces a list
22:42julianlevistonsdegutis: MYOB
22:42julianlevistonsdegutis: too sarcastic? :-)
22:43sdegutisoh
22:43Lewixjulianleviston: which makes me wonder why apply is needed - it's not a vector
22:43julianlevistonLewix: + takes numbers.
22:43julianlevistonLewix: you passed it a cons cell
22:43julianlevistonLewix: nothing to do with vectors.
22:44julianleviston,(doc +)
22:44clojurebot"([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"
22:44Lewixjulianleviston: i see so the first evaluator cares about the others evaluators
22:44Lewixstrange
22:44julianlevistonLewix: what’s an evaluator?
22:44Lewixjulianleviston: anyways, i expected (cons (nth [1 2 3] 0)) to return a list and be treated as such
22:45julianlevistonLewix: apply takes a function (ƒ) and a collection of some kind, and calls it as though you’ve poured the contents of the collection into arguments of calling that function (ƒ).
22:45Lewixjulianleviston: However, from what you're saying + cares that it was called with cons
22:45bbloom(doc cons)
22:45clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
22:45Lewixjulianleviston: i don't have apply here
22:45julianleviston,(+ ‘(1 2))
22:46clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ‘ in this context, compiling:(NO_SOURCE_PATH:0:0)>
22:46julianleviston,(+ [1 2])
22:46clojurebot#<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentVector to java.lang.Number>
22:46Lewixwhihc makes sense
22:46Lewix(+ (1 2 3))
22:46Lewix,(+ (1 2 3))
22:46clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
22:46julianleviston,(+ '(1 2))
22:46clojurebot#<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number>
22:46Lewix,(+ 1 2 3)
22:46clojurebot6
22:47Lewix,(+ (1 2 3))
22:47clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
22:47Lewixreally
22:47Lewixhere is my issue
22:47julianleviston,(cons 1 nil)
22:47clojurebot(1)
22:47tehgeekmeister@julianleviston seems like that just shows how to do bytes at a time, not just plugging two streams together
22:47julianleviston,(+ (cons 1 nil))
22:47clojurebot#<ClassCastException java.lang.ClassCastException: Cannot cast clojure.lang.PersistentList to java.lang.Number>
22:47julianlevistonsee?
22:48julianlevistontehgeekmeister: what does that mean? Sorry… not really sure what plugging two streams looks like. Prolly not the best guy to answer your Q, really...
22:48tehgeekmeisterah okay
22:48tehgeekmeisternbd
22:48julianlevistontehgeekmeister: ask it in java… someone can explain it idiomatically in clojure.
22:48tehgeekmeisteri basically mean, if i have a stream that produces data
22:48tehgeekmeisterand one that can consume data
22:48tehgeekmeisteri just want to redirect all content from the producer to the consumer
22:48julianlevistontehgeekmeister: yeah… why can’t you just plug them together?
22:49tehgeekmeisterin java you'd do this imperatively, i think
22:49julianlevistontehgeekmeister: isn’t that just a matter of plugging the one into the other? (out (in))
22:49dbronicojulianleviston: Thanks for recommending core.async. For what I needed it for (non-overlapping, parallel printing), the setup was really easy and it seems to be working with 7 threads.
22:49julianlevistontehgeekmeister: Using a streamreader and streamwriter tho
22:49amalloytehgeekmeister: clojure.java.io/copy ?
22:49tehgeekmeisteri would like it to be that simple, i just don't know
22:49tehgeekmeister@amalloy checking
22:49julianlevistondbronico: yeah it’s great, isn’t it! :)
22:49julianlevistontehgeekmeister: it is that simple.
22:49amalloydon't touch readers and writers if you want to use bytes. those are for characters
22:50tehgeekmeisteri just want straight redirection.
22:50julianlevistontehgeekmeister: what amalloy said!
22:51julianlevistonLewix: grok or no grok?
22:52Lewixjulianleviston: my problem was simply that I assumed list and a serie of number was the same thing
22:52Lewix(+ 1 2 3 4)
22:52clojurebot*suffusion of yellow*
22:52julianlevistonLewix: ah!
22:52tehgeekmeisteramalloy: that's synchronous, I imagine, so I couldn't copy two streams in parallel? oh wait, there's gotta be a thing for that. i can figure this out.
22:52amalloytehgeekmeister: future
22:52Lewix(+ (1 2 3 4))
22:52amalloyuse threads
22:52Lewixnot the same thing
22:52julianlevistonadd( list( 1, 2) ) // -> what is this? add doesn’t understand a list.
22:52julianlevistonapply(add, list( 1, 2) ) // -> I will do as you wish
22:53Lewixjulianleviston: thats right
22:53julianlevistonLewix: sometimes I found shifting things to C syntax helped in the past.
22:54bbloomthink of ( and ) like you might [ and ] when initializing an array or something
22:54bbloomparens in C are for precedence, but in a lisp they construct a data structure like [ and ] can do
22:55julianlevistonbbloom: which if you look at the AST C produces, is a data structure...
22:55bbloomjulianleviston: that AST is an implementation detail of a particular compiler
22:55julianlevistonbbloom: so really, it’s the same thing. Precedence, or data structure… LISP just lets you know what is going on under the hood.
22:55bbloomjulianleviston: in clojure it's an abstraction provided to the object program
22:56bbloomjulianleviston: i disagree with the notion of "under the hood"
22:56julianlevistonbbloom: Ok.
22:56julianlevistonbbloom: i disagree with the notion of disagreement.
22:57julianlevistonbbloom: also, parens are not only for precedence in C. The parens I was talking about are for function call notation.
22:58julianlevistonbbloom: which can be viewed as a data structure indicating to the compiler to call a function… which is what a list is used for in LISP
22:58julianlevistonbbloom: granted C is in no way homoiconic, but the parallel is there IMHO.
23:00julianlevistonbbloom: what’s your point? :-)
23:01Lewixbbloom: good point
23:01julianlevistonbbloom: I like that clojure adds vectors so that linear data collections can have a separate reader syntax to program form syntax, though. That alone makes understanding clojure code so much easier than, say, scheme, or CLISP.
23:01dnolenjulianleviston: I think you missed the simple point that C source isn't data structure the way Lisp and the benefits derived therein. In you have to go all the way to the AST. In Lisp you don't. Thank god. But the real AST is there in those rare cases that you need.
23:01Lewixthe documention of closure sucks
23:01Lewix,(doc cons)
23:01clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
23:02Lewixreally? you dont tell me how to use it
23:02bbloomLewix: every single function would have to tell you how to use it
23:02bbloomLewix: the clojure docs are not for beginners
23:02julianlevistonLewix: sure it does… the [] is the arument list - it takes two… x and a seq…
23:02bbloomat least the functions are
23:02LewixI dont know i can do this
23:02dnolenLewix: http://clojuredocs.org
23:02Lewix,(cons "doc didnt help" (1 2 3))
23:02clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
23:02Lewix,(cons "doc didnt help" [1 2 3])
23:02clojurebot("doc didnt help" 1 2 3)
23:03bbloomLewix: you're trying to do multiple things at once & you don't understand the primitives
23:03bbloomtype (1 2 3) in to your REPL by itself
23:03bbloomnote that a leading comma uses a repl here
23:03Lewix,(cons "doc didnt help" `(1 2 3))
23:03clojurebot("doc didnt help" 1 2 3)
23:03julianlevistonLewix: sadly we’re not QUITE at the self-describing pedagogical language we’d all love… but CLJ is a huge step there compared to other modern languages.
23:03bbloom,(1 2 3)
23:03clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>
23:03LewixI still think the doc sucks
23:03julianlevistonLewix: no way, man.
23:04julianlevistonLewix: it’s there for people who know how to read it.
23:04Lewixjulianleviston: it doesnt tell me what it return
23:04Lewixtheres many form of sequences from what I read
23:04julianlevistonLewix: (source cons) does tho
23:04bbloom(doc cons)
23:04clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
23:04bbloom"returns" is literally the first word of the doc string
23:04Lewixi don't know if it's a list or a lazsequence for example
23:04julianlevistonLewix: ah… it’s a SEQ.
23:04gfredericksthat's usually not important
23:05julianlevistonLewix: that’s a thing.
23:05Lewix,(list? (cons "doc didnt help" `(1 2 3)))
23:05clojurebotfalse
23:05bbloom~list?
23:05clojurebotexcusez-moi
23:05bbloom~list
23:05clojurebotexcusez-moi
23:05bbloomdammit clojure-bot
23:05julianleviston(seq? (cons ‘yay nil))
23:05julianlevistonLewix: erm… how would you impove it?
23:06julianlevistonany less terse and you’d annoy people who don’t want to wade thru crap to get to the info.
23:06julianlevistonLewix: read this: http://clojure.org/sequences
23:06Lewixjulianleviston: just be more specific. There's no excuses - some others languages have good doc
23:06julianlevistonLewix: I don’t follow… that *IS* very specific.
23:06bbloomLewix: you're wishing for the wrong solution to your problem
23:06julianlevistonit returns a seq. That’s what it does.
23:06bbloomLewix: typical clojure users quite like clojure's docstrings
23:06LewixI'm no wishing for anything
23:06bbloomLewix: you need a book
23:06bbloom~book
23:06clojurebotbook is programming clojure
23:07Lewixjulianleviston: a list is considered a seq
23:07julianlevistonbbloom: agreed!
23:07julianlevistonLewix: um… what?
23:07julianlevistonLewix: dude… learn more.
23:07julianlevistongo read that link I just sent you.
23:07bbloomjulianleviston: that's not helpful
23:07julianlevistonbbloom: no but the link may be. :)
23:07bbloom~colls
23:07clojurebotcolls is seqs and colls
23:07bbloom~seqs
23:07clojurebotseqs is http://www.brainonfire.net/files/seqs-and-colls/main.html
23:07julianlevistonbbloom: I’m just explaining that he needs to learn more.
23:07bbloom^^ that link is more helpful
23:07bbloombut still, it's not helpful at all
23:08gfredericksjulianleviston: a list is a seq though
23:08Lewixso wait
23:08bbloomLewix: try http://www.braveclojure.com/
23:08julianlevistonbbloom: Sure it is :) You just hate me :)
23:08Lewixyou guys are telling me that list are not seq ?
23:08julianlevistonbbloom: oh god not that!
23:08Lewix(seq? `(1 2 3 4))
23:08Lewix,(seq? `(1 2 3 4))
23:08clojurebottrue
23:08julianleviston,(type `(1 2 3 4))
23:08clojurebotclojure.lang.Cons
23:08amalloylists are seqs for sure
23:09tomjackbbloom: hey! after years of willful ignorance, oleg/filinski/delimc/effects/etc have come back around and bit me on the ass. just curious, is getting ext_test.clj in eclj to work a TODO, or is it supposed to work?
23:09Lewixamalloy: exactly which bring me back to my point.
23:09Lewixthe doc could be more specific
23:09gfredericksamalloy: I have though heard it argued that lists being seqs is an impl detail
23:09amalloyhm
23:09gfredericksLewix: more specific how?
23:09gfrederickssaying it returns a list?
23:09Lewixgfredericks: saying that it returns a seq is confusing
23:09bbloomtomjack: nothign in eclj is supposed to work :-P
23:10Lewix,(seq? `(1 2 3 4))
23:10clojurebottrue
23:10bbloomtomjack: it's totally me exploring stuff. not sure what state i left it in
23:10Lewix,(list? (cons "doc didnt help" `(1 2 3)))
23:10clojurebotfalse
23:10tomjackah, ok
23:10tomjackwell, thanks for it, quite inspiring
23:10julianlevistonLewix: I think if you find the docs confusing, then it’s probably because you need to increase your knowledge of clojure. They’re not there to teach you clojure. They’re there to explain how things work once you know.
23:10bbloomtomjack: cool. glad you like it
23:10gfredericksLewix: not sure what the confusion is, what else would it say?
23:10Lewixjulianleviston: you just told me that list are not a seq, in my defense
23:10julianlevistonLewix: it isn’t.
23:11julianlevistonLewix: they’re not identical.
23:11amalloyjulianleviston: it one million percent is. if you're going to condescend to Lewix at least be right
23:11julianlevistonLewix: the relationship is inclusive.
23:11Lewixfrom what i gather list and lazyseq are both seq
23:11julianlevistonamalloy: I wasn’t aware I was being condescending. Apologies!
23:11julianlevistonamalloy: me recommending someone else learn more doesn’t preclude me from not being ignorant!
23:12bbloomjulianleviston: "learn more" is just a dick way to say anything
23:12gfredericks(inc bbloom)
23:12julianlevistonbbloom: is it? I thought it was concise.
23:12gfrederickssometimes concision is dickish
23:12julianlevistonbbloom: sorry for being a dick!
23:12gfredericksdespite intentions
23:12julianlevistonhaha :) ok.
23:13julianlevistonapologies for my dick.
23:13julianlevistonish.
23:13julianlevistonness.
23:13gfredericksespecially on the internet where people can't see your face
23:13julianlevistonLewix: dude… apologies… I am on your side.
23:13julianlevistonLewix: I am here to help, and I’m interesed in all of our betterment.
23:13amalloygfredericks: upcoming project: replace every website with a picture of my face
23:14jonh, (type (cons "doc didnt help" `(1 2 3)))
23:14clojurebotclojure.lang.Cons
23:14Lewixjulianleviston: no worries
23:15jonhLewix: so my guess is that is why list? does not return true
23:15julianlevistonLewix: also, I need to learn as much, if not more, than you…
23:15Lewixjulianleviston: I doubt. I started three days ago. You'll probably know more
23:15LewixYou*
23:16julianlevistonthis might help…
23:16julianleviston,(list)
23:16clojurebot()
23:16julianleviston,(list? (list))
23:16clojurebottrue
23:16julianleviston,(seq? (list))
23:16clojurebottrue
23:17julianleviston,(list? (seq))
23:17clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/seq--4091>
23:17julianleviston,(list? (seq (list)))
23:17jonhpwnd
23:17clojurebotfalse
23:17julianlevistondoes that help?
23:17gfredericksamalloy: I'm writing a movie script based on the premise that you somehow succeed at doing so despite the various reasons it's impossible
23:17gfredericksamalloy: experts are baffled
23:18amalloygfredericks: sequel to The Core?
23:18gfredericksyeah bruce willis and a small team are going to hack into the internet to take those amalloy photos down
23:18gfredericksusing guns
23:19gfredericksa side plot would involve the efforts by web designers to adapt their UIs to the new constraint of having amalloy's photo in the middle of the page
23:20julianleviston,(type (seq [1 2]))
23:20clojurebotclojure.lang.PersistentVector$ChunkedSeq
23:20gfredericks,(deftype ChocolateChunkedSeq [])
23:20clojurebotsandbox.ChocolateChunkedSeq
23:20julianleviston,(list? (seq [1 2]))
23:20clojurebotfalse
23:21julianleviston,(type (seq (list 1 2)))
23:21clojurebotclojure.lang.PersistentList
23:21julianlevistonobviously that’s a list, whereas a seq’d vector isn’t, right?
23:21julianlevistonbut both are seq’s… right?
23:21gfredericksright
23:21julianlevistonLewix: ergo… some seqs ARE lists, others aren't...
23:21julianlevistonLewix: but all lists are seqs.
23:22gfredericksjulianleviston: I think that's what Lewix meant, you were just misinterpreting
23:22julianlevistongfredericks: oh ok. Sorry, I thought he thought List == Seq or something with semantic equivalency.
23:24raspasovhey guys, atom/STM question
23:24julianlevistonLewix: it doesn’t help much that there are a bunch of things that make you think they’re all the same coz they start with the letters s e q, but they’re not exactly the same…
23:24raspasovso if from one thread I do something like (def x (atom 0)) (swap! x + 1) @x
23:25jonhLewix initial example was a cons though, thats why list? says false
23:25raspasovI am guaranteed to get @x to be 1, that's clear
23:25raspasovwhat about other threads though? if there's updates coming to the x atom, are all other threads guaranteed to see "latest" state or just a "valid" state when deref-ing x?
23:26Lewixjulianleviston: What I was saying all along is - vectors, lists, lazyseq are all sequential, lists and lazyseq are both seq and they're all collection. So when we document what we return, shouldn't we used the right term to avoid confusion
23:26Lewixs/used/use
23:27gfredericksLewix: and what's the right term in the case of cons?
23:27Lewixif we return lazyseq we don't want to say we return seq - it leads to confusion. That was all i was trying to say - I guess there was some confusion or I didn't express myself properly
23:27Lewix(doc cons)
23:27clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
23:27Lewix,(doc cons)
23:27julianlevistonLewix: I’m curious if that precision has any real world ramifications, though? The docs seem to explicitly refer to the level of detail that is particular to the context… so if “seq” (meaning the abstraction) is the guarantee, they tend to say that… perhaps I’m wrong, tho… it’s usual.
23:27clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
23:28Lewixjulianleviston: even if it doesn't have real implications - better be safe than sorry especially when it does not cost much
23:28jonh,(type (cons 1 [2 3]))
23:28clojurebotclojure.lang.Cons
23:28julianlevistonLewix: not if the level of “vagueness” is actually what’s precisely intended, tho…
23:28Lewixgfredericks: right term is lazyseq I think
23:29gfredericksLewix: it's not a lazy seq
23:29Lewixgfredericks: If it's a seq and it's not a list, chances are it's a lazy seq I thought
23:29gfredericksthere are other kinds of seqs besides lazy & list; and the idea is that you shouldn't have to care what kind it is
23:29julianlevistonLewix: a seq is something that adheres to that protocol, isn’t it? that’s the limit of the guarantee of that function signature, righ?
23:30julianleviston(inc gfredericks)
23:30julianlevistonnice explanation!
23:30Lewixgfredericks: I dislike that train of though. I really care about precision
23:30Lewixthought*
23:30julianlevistonLewix: it *is* precise.
23:31julianlevistonLewix: precisely not detailed.
23:31amalloyclojure, the best precisely-vague language
23:31julianlevistonamalloy: lol. Protocols are “precisely vague” :)
23:31Lewixif you expect it to return a seq then it would mean that it could also return a list. How precise is that?
23:32Lewix(However in our situation it does not return a list)
23:32julianlevistonLewix: It’s precise because if you choose something that builds or deals with seqs, you care about the properties of seq’ing… and not the extra properties.
23:32julianlevistonLewix: if you wanted a list, don’t ask for a seq. Likewise if you want a set, don’t use a vector!
23:35julianlevistonraspasov: I don’t really remember, but I remember that the rich hickey ants talk goes into it quite well… https://www.youtube.com/watch?v=dGVqrGmwOAw
23:36raspasovjulianleviston: yea I thought it does (I have seen this video multiple times - maybe a time for a re-watch) lol, it uses java AtomicReferences, which should ensure that changes are visible to all threads
23:36julianlevistonraspasov: he explains the different types of refs and what you want to use each for, and the guarantees of each.
23:36jonhLewix: (list? (cons 1 nil)) :)
23:37Lewixjonh: I'm still looking for the simple and easy part - especially after your example...
23:37raspasovjulianleviston: I think problem is in my code most likely, so investigating there first : ) pretty sure changes are always visible
23:37julianlevistonraspasov: oh it depends on “when” you’re talking about, I guess… from what I understand, everything happens in atomic sets… so you have a consistent view of the world… so they would all see the state, but only at the point in time at which you ask for the value (by dereffing)… does that cover your q?
23:38raspasovjulianleviston: yes, basically...
23:39jonhLewix: leaky abstractions, kinda feels javascript esque
23:39julianlevistonraspasov: yeah, gotta make sure each thread isn’t getting its own separate atom
23:39raspasovjulianleviston: or like, a different state of the same atom
23:39Lewixjonh: exactly
23:39julianlevistonjonh: whatcha mean?
23:39jonh, (list? (cons 1 nil))
23:39clojurebottrue
23:40julianlevistonraspasov: um… yeah, I think you might not want an atom, depending on what you’re after… you need dosync and whatnot. no?
23:40justin_smithLewix: the easy /simple part is concreyr types rarely matter. what matters are thr interfaces.
23:40julianlevistonjonh: Sorry… not really sure waht your point is :S
23:41justin_smith*concrete that is
23:41raspasovjulianleviston: yea, thanks, I'm familiar with refs, etc thanks for your input :) debugging now
23:41julianlevistonraspasov: sorry :)
23:42jonhsorry to hear that
23:42julianlevistonjonh: I’d love to know, if you care to explain :)
23:42julianleviston,(type (cons 1 nil))
23:42clojurebotclojure.lang.PersistentList
23:43julianlevistonThat seems to be a list.
23:43julianleviston… and it has returned a seq. Just like the docs for cons say it should.
23:44julianlevistonyour abstraction has to be reified in SOME concrete entity, right? It happens to be a list from cons at clojure’s current version.
23:45julianlevistonjonh: not really sure how that’s a leaky abstraction… ?
23:46justin_smithLewix: imagine if I were asking what type '/' returns...
23:46codestorm777http://stackoverflow.com/questions/4104805/erlang-persistent-data-structures
23:46julianlevistonjustin_smith: I just had a thought - maybe they want typed clojure!
23:46julianlevistonjustin_smith: should send them to that project.
23:49julianlevistonLewix: you might like this: https://github.com/clojure/core.typed
23:50julianlevistonLewix: and judging from our convos here, I think you’d LOVE haskell, if you haven’t already learned it.
23:51Lewixjustin_smith:
23:51Lewix,(type \/)
23:51clojurebotjava.lang.Character
23:52julianlevistonLewix: erm… \/ is the backslach char…
23:52justin_smithLewix: I meant the division operator, and what it returns varies based on context but the applicable interface is Number
23:52julianlevistonbackslash even.
23:52justin_smithjulianleviston: it's forwardslash
23:52julianlevistonjustin_smith: soz… guh. Yeah.
23:53justin_smithLewix: the rules for what kind of Number you get back don't belong in the docs for '/', they belong in the docs on the math operators
23:54Lewixjustin_smith: like most languages
23:54justin_smithLewix: similarly, seq suffices for documenting cons, but there is extensive clojure documentation on what a seq means, and which things can be considered seqs, etc.
23:54justin_smithLewix: most of the time, "seq" or "Number" are enough to go on
23:54Lewix./ is not a data structure
23:54justin_smithLewix: sometimes, you really want to get into the details
23:55justin_smithLewix: nor is cons
23:55justin_smithcons RETURNS a data structure
23:55Lewixlist is
23:55julianlevistonLewix: it *would* be nice if there was a bit by bit path pedagogical learning environment, like Racket has…
23:55justin_smithLewix and in fact, / can return data structures, for example ##(/ 2 3)
23:55justin_smiththat is a data structure
23:55Lewixjustin_smith: my issue is not about cons
23:56Lewixmy issue is if you tell me it return a bottle i expect a bottle
23:56Lewixif you tell me it returns a seq i expect a seq
23:56justin_smithLewix: and there are at least 20 things that are seqs
23:56justin_smithseq is a general category
23:56Lewixexactly
23:56justin_smithlike Number
23:56justin_smithreturns a Number
23:56justin_smithsame thing
23:56julianlevistonLewix: what if you return a number, and I give you 5.0 ? But… that’s not a number… yes it is…. it’s a float… which is a number.
23:56justin_smitherr
23:56justin_smith / returns a number
23:56justin_smithcons returns a seq, same thing
23:57Lewixnot the same thing
23:57justin_smithNumber is an interface describing many numeric types
23:57justin_smithseq is an interface describing many ordered collections
23:57julianleviston:)
23:57Lewixlet's just agree to disagree
23:58julianlevistonum… no, justin_smith isn’t incorrect.
23:58Lewix,(doc /)
23:58clojurebot"([x] [x y] [x y & more]); If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators."
23:58justin_smithLewix: can you describe to me how the disparate classes Double, Float, Rational etc. can all be Numbers, but somehow a list can't be a seq?
23:58Lewixmuch better than
23:58Lewix,(doc cons)
23:58clojurebot"([x seq]); Returns a new seq where x is the first element and seq is the rest."
23:58justin_smithLewix: in fact, the docs for seq are much more precise
23:58justin_smith / doesn't even mention numbers
23:58Lewixwhich doesnt tell you that in its seq it does not include list unless you provide nil as the second arg
23:58julianlevistonLewix: are you having a problem with the fact that one of the arguments is named seq there?
23:59Lewixjustin_smith: right but its better in the sense that its not incorrect
23:59justin_smithLewix: it explicitly says it returns a seq
23:59Lewixor partially incorrect
23:59justin_smithand it always does
23:59julianlevistonLewix: the docs for / don’t actually tell you the type it returns at all!