#clojure logs

2015-08-30

00:19frefeCan you use compojure contexts like this (defroutes approutes (context "/a" [] (context "/c" [] ...) (context "/c" [] ...) )
01:04ben_vulpeswhat's the hot jam for working on the clojurescript/browser part of a webapp while also working on the clojure/jvm part of the application simultaneously in emacs?
01:05justin_smithben_vulpes: I guess cider has a thing, but I got fed up and I use terminal windows for repls like a cave man
01:16ben_vulpeswhat about compiling code into the running clojure/script 'images'?
01:16ben_vulpes(load-file 'wherever)?
01:16justin_smiththat's what the :reload arg to require is for
01:17justin_smithsee also :reload-all
01:17ben_vulpeshow does that handle code saved in a useless state?
01:17ben_vulpesi write buffers when they lose focus, not when my code compiles.
01:17justin_smithit'll throw an error if the file needs fixing, you can require and :reload again later
01:17justin_smithben_vulpes: I have a key combo that lists all unsaved buffers
01:18justin_smithso that I can usually keep files valid, without losing track either
01:18ben_vulpesi refuse to waste mental cycles tracking which files have not been written to disk.
01:18justin_smithben_vulpes: I refuse to waste mental cycles figuring out how the hell cider is supposed to work - and like I said, it's a key combo, I hit the key, it tells me what is unsaved
01:19ben_vulpesthat there is even a distinction between text in a buffer i'm working on and text on disk offends my sensibilities (dramatic exaggeration)
01:19ben_vulpesno i know i'm just being dramatic
01:19justin_smithand the worst case is clojure says "I could not compile that" and you fix the file and hit up arrow and require again - it's very straightforward
01:22ben_vulpesjustin_smith: d'you use or eschew figwheel?
01:22justin_smithI use figwheel
01:23justin_smithinside a terminal with rlwrap
01:23justin_smiththe same (require 'some.ns :reload) works there
01:23justin_smithit also auto-loads though
01:23justin_smithbut I find sometimes it gets confused
01:28ben_vulpesjustin_smith: do you use cider in any way?
01:28justin_smithno, I gave up on it, it was wasting too much of my time
01:29ben_vulpesraw lisp-mode buffers with paredit and actual terminals for clojure/script?
01:30ben_vulpesor do you SLIME at all?
01:30justin_smithclojure-mode with paredit, no slime, actual terminal
01:30ben_vulpes(i went on a common lisp sojurn recently and now want to make some changes to my clojure emacs setup is why i ask)
01:31justin_smithif you consider clojure-mode part of cider I guess you can say I use the parts of cider that don't do any magic and don't connect to clojure
01:31justin_smithyeah, the slime integration with emacs is pretty neat
01:33ben_vulpes2000s-era ripoff of SMBX terminals
01:33ben_vulpeswritten in the post-dotcom doldrums
01:34Bronsajustin_smith: setting up clojure with slime is still quite easy FWIW
01:34justin_smithBronsa: that's good to know, maybe some day
01:34ben_vulpesSTAND BACK I'M UNINSTALLING CIDER
01:34BronsaI actually tried the new cider a few hours ago
01:35Bronsaseems like it become quite usable
01:35justin_smithhow was it?
01:35justin_smithinteresting
01:35BronsaI might consider doing the upgrade
01:36BronsaI then got sidetracked trying to switch auto-complete for company
01:36Bronsaand trying to use the emacs package managers rather than git submodules
01:36Bronsabroke everything and reverted to slime+auto-complete+git submodules
01:36Bronsabut maybe one day.
01:38ben_vulpesjustin_smith: what are you using for running the browser repl?
01:38justin_smithfigwheel
01:38justin_smithin a terminal, with rlwrap
01:38ben_vulpesright sorry sorry
01:40justin_smithben_vulpes: this all became especially acute when I moved to a distributed onyx / kafka system for our computation intensive tasks - suddenly I have two clojure repls, and one clojurescript one, and it was so much easier to keep them sorted out, and isolated, in regular terminal windows as compared to juggling connections in emacs
01:44ben_vulpeshow does kafka affect your dev loop?
01:44justin_smithit's another piece that can brak
01:44justin_smith*break
01:45ben_vulpesso cljvm crashes? myriad functions never return for want of a kafka connection?
01:45justin_smithalso, unlike eg. http where you have request response, you have N messages from A to B followed by N from B to A
01:45ben_vulpes"Of course, you can concurrently take advantage of all of nREPL's other facilities, including connecting to the same nREPL server with other clients (so as to easily modify Clojure and ClojureScript code via the same JVM), and interrupting hung ClojureScript invocations: "
01:45ben_vulpes^^ WANT
01:46justin_smithben_vulpes: it doesn't crash things, but misbehaving (related eg. to sleeping the computer - kafka hates suspend) can cause delays and inactivity followed by piling on masses of activity all at once.
01:47justin_smithben_vulpes: it ends up being one more factor that might be causing the odd behavior of an app
01:47justin_smithalong side bad code, or network hiccups, whatever
01:47justin_smithben_vulpes: I found when clojure was inside emacs that added a few other things that could go wrong
01:48justin_smith(eg. locking up the editor if I print certain kinds of values)
01:50justin_smithand locking up a clojure thread if it is trying to print faster than emacs is using its output... (also seen this problem with tmux - people running an app inside tmux, going into scroll-back mode, forgetting to leave it, the app stops doing anything when the tmux buffer fills)
02:07ben_vulpeshttps://github.com/cemerick/piggieback/blob/master/src/cemerick/piggieback.clj#L282
02:45BronsaI finally managed to implement prefer-proto
02:52oymyakonhi! newbie question: what does it mean when the first element of a sequence is a keyword. For example: (:something 1)
02:53Bronsaoymyakon: what it always mean in clojure: a function invocation
02:53Bronsaoymyakon: keywords are also functions in clojure
02:53oymyakonBronsa: thanks yes, so the keyword evaluates to itself right.
02:53oymyakonbut the whole expresion returns nil
02:54Bronsathey look themselves up in the arg which should be an associative collection
02:54oymyakonI don't understand what the semantics of that is
02:54Bronsa,(:foo {:foo 1})
02:54clojurebot1
02:54amalloythe keyword evaluates to itself, and then when called as a function it looks itself up in its argument, expected to be a map
02:54luxbock,(:foo #{:foo})
02:54clojurebot:foo
02:55Bronsahttp://dev.clojure.org/jira/browse/CLJ-1807
02:55luxbocksets work as well I guess
02:55Bronsayup
02:55amalloyanything that implements ILookup
02:57oymyakonamalloy: ok, so it means that when we have a keyword as the first element in a sequence the second element should be a map or an assoc data structure
02:57oymyakonyes?
02:57amalloyif you are evaluating that sequence, then yes
02:58oymyakonok, I get it. Thank you
06:24domokatoI have two lists of numbers. I want to create a seq that contains the averages of the elements at each index in the lists. Is there an O(1) space solution that doesn't require loop/recur?
06:31tcrayford____domokato: so like (my-fn [5 4 6] [5 6 4]) -> [5 5 5] ?
06:32tcrayford____domokato: (map (fn [x y] (/ (+ x y) 2)) [5 4 6] [5 5 5])
06:34domokatoah, map can take multiple colls!
06:34domokatothanks
06:35tcrayford____welcome :)
06:48jeayedomokato: That's linear time, mind you. You need to traverse the full sequence once.
07:54expezwhy isn't splicing allowed at toplevel?
08:09puredangerBecause reading a single form would then produce multiple forms and there is no easy way to push read forms back onto the stream
08:10expezaha
08:10expezpuredanger: any plans for clojure in terms of project jigsaw?
08:11expezjar hell is by far my biggest gripe with the platform atm
08:25zeroware_Hello ! I have a quick question on core.async. Is this the right place ?
08:29expezzeroware_: fire
08:32zeroware_I'm looking at the pipeline async function. The docs says that only n operations will be executed. But looking at the code, I can see that the async fn will be called without waiting from the previous one when parallelism is set to 1.
08:34zeroware_For example : if I have a channel with filenames, and my async function is reading files. If I fire the pipeline async , all file will be read at the same time even if n is set to 1.
08:37expezzeroware_: n controls the parallelism in play, everything on the from channel will be consumed
08:39zeroware_expez: Okay , what should i do if i want to read the files with only one file opened at a time ?
08:40expezzeroware_: if n=1 then the files should be read sequentially
08:44zeroware_expez: Looking at the source code, the job channel will be read without waiting for the async function to complete.
08:46expezzeroware_: You're calling pipline-async so some async behavior is to be expected :) Still, the async processing is only happening on a single thread.
08:50zeroware_expez: i'm really new to clojure, maybe i'm reading the code wrong. Do you know where I can find some example of this pipeline-async function ?
08:55expezzeroware_: think of it this way: The from channel is read from and the data is put on a conveyor belt. When that is done the pipeline-async returns control to the caller. In some background threads, controlled by the value n, data is taken from the conveyor belt, given to the work function af, and then the result is put on the to channel.
09:00zeroware_expez: okay , but when the af function is called, the next value is taken without waiting for the af returned channel to finish
09:01zeroware_expez: if I open files into my af function , I will have all files opened sequentially but not in a serial fashion
09:01expezzeroware_: That makes sense, though, right? The af function is off in its own thread working as hard as it can to transform the data on the from channel and put it into the to channel.
09:02zeroware_expez: my use case is that in my af function i'm calling an API and I don't want to have 25 requests made at the same time… Maybe pipelin-async is not the function I need.
09:04zeroware_I could make the af function blocking but the docs says that the function has to return immediately
09:05expezzeroware_: do you want to make your requests in a blocking manner, sequentially?
09:07zeroware_expez: Yes, I thought that the n parameter would do this but apparently it's not designed that way.
09:08expezzeroware_: Just do your requests in a doseq loop over your URLs if you want sequential and blocking.
09:11zeroware_expez: I will do like this yes. Thanks for your answers !
09:55ska-fanHow does https://gist.github.com/mbertheau/3fef571a1a5391387a75 look in clojure? Parens of the dead impressed me with clojures terse syntax for manipulating lists and maps. My day job is still Python and I'm trying to use a more functional, stateless, pure style. I wonder what the python in the link looks like in clojure?
10:14broquaintska-fan: I added a thing.
10:26spaceplukcan I use figwheel with clojure jvm?
10:31broquaintspacepluk: I don't believe so, what's your use case?
10:31spacepluknothing specific, I just like the workflow
11:14ska-fanbroquaint: Thanks. So a list comprehension with let. Awkward to do with python.
11:36broquaintfunction unfavourite(tweet) { let $tweet = (sel) => jQuery(sel, tweet);
11:36broquaint $tweet('.js-actionFavorite:visible').click();
11:36broquaint console.log(
11:36broquaint "Unfavourited:\n",
11:36broquaint $tweet('.tweet-text').text(),
11:36broquaint "\nby ", $tweet('.username').text(), '[ ', $tweet('.js-permalink').text(), ' ]'
11:36broquaint );
11:36broquaint}
11:36broquaintlet tweets = document.querySelectorAll('#stream-items-id > li');
11:36broquaintlet step = 0;
11:36broquaintfor(let tweet of Array.from(tweets).reverse()) {
11:36justin_smithbroquaint: don't do that
11:36broquaint setTimeout(function() {
11:36broquaint unfavourite(tweet);
11:36broquaint }, step++ * 500 );
11:36broquaint}
11:36broquaintjustin_smith: A misclick in putty, apologies, could've sworn irssi would prompt me :/
11:37justin_smithbroquaint: worst is erc in emacs, which has a special feature where it slows multi line pastes down to ensure all the lines go through and you don't get kicked
11:37justin_smithunderstood, just making sure you knew it's something we don't intentionally do here
11:38broquaintYup, understood :)
11:39broquaintHrm, my paste_verify_line_count is at 5, wonder what happened there (mosh confusion maybe?).
11:50broquaints/setTimeout.* );/setTimeout(unfavourite.bind(undef, tweet), step++ * 500);/s ; Couldn't let that bug just sit there looking daft.
12:00expezska-fan: added another solution
12:11ska-fanexpez: Isn't net unbound in line 5?
12:12expezska-fan: yeah, that's actually true
12:13expezupdated :)
12:17ska-fanOk, so now the difference to broquaint's solution is that you're getting gross by destructuring the argument of the anonymous mapping function, whereas broquaint uses an explicit let and a list comprehension. Both solutions calculate net with an explicit let.
12:18ska-fanI wonder if this can be done with some kind of threading macro?
12:18ska-fanI can't get my head around it though.
12:20expezNo, you can't, because you have to refer to the map twice. Once to get the value of net out of it and once to assoc something new onto it. You could use the as-> threading macro to name intermediary value but it won't really improve readability imo.
12:47ska-fanHmm, can (fn [discount] (as-> discount ...)) be shortened somehow?
12:48justin_smith#(as-> % ...)
12:49justin_smithI mean that's what it would need to be for that last exampleto actually work
13:21jack0Hi! Does anyone know the GSoCers from Clojure?
14:21ska-fanHmm that's not too bad.
14:21dnolenjack0: yes
14:22jack0dnolen: Can I private message you?
14:54expezBronsa: Is this not a valid token? ::str/bar (str is alias for clojure.string in the ns). I just bumped tools.reader to 0.10-alpha3 and it no longer allows this token.
14:57expezBronsa: false alarm, *ns* wasn't being bound properly when reading to do an API change in tools.namespace.
15:41kanjaIs there a way to memoize on multiple items? Ie I pass in a screen name or an id and expect to get the same return value
15:41kanjawhere both values are in the RV
16:04justin_smithkanja: perhaps a pre-processor that produces equivalent input to a memoized function for a given id or screen name?
16:13kanjajustin_smith: I'm pretty new to clojure - The only way I see doing that is storing a hash in memory of screen name to id mapping and mutating that after each call of the memoized function. isn't that a side effect/mutation/cardnal sin?
16:14justin_smithkanja: how do you find the screen name for a given id or visa versa?
16:14kanjajustin_smith: api call - twitter lets you use id or screen name to pull user data, and the resulting hash has both parts included
16:15kanjahence why I want to memoize it and avoid extra http requests :)
16:15justin_smithOK so it's the same api call that you are memoizing
16:15kanjajustin_smith: right but with different but equivant calling args
16:17justin_smithI'd put a map of unsername -> id or visa versa (depending on which should be "canonical") in an atom, and update the atom after getting the memoized result, and check the atom before calling the memoized function
16:17kanjaah and wrap the function in a non memoized wrapper
16:17justin_smithexactly
16:17kanjathat way I can do the mutation outside the memoization
16:17justin_smithright
16:17kanjathat makes sense
16:18kanjais there some good docs on atoms? I already read the clojure ref documentation but I'd love something with a little more exposition
16:18justin_smithatoms are different from refs, the clojure docs on them are the best source of information
16:19justin_smiththe most important thing I see people forgetting is that swap! can retry so you should not have side effects inside swap!
16:19kanjaah sorry meant Reference Documentation not documentaion on refs :)
16:19kanjahave not read the refrence documentation on refs :)
16:19justin_smithyeah, this is the best info http://clojure.org/atoms
16:19kanjayeah that's what I've red
16:20kanjaok cool
16:20kanjathakns
16:20kanjaI'll give this a try
16:20justin_smithkanja: another thing to look out for is using deref / @ inside swap!
16:20justin_smiththat can lead to trouble
16:21kanjathat is above my head right now
16:21kanjaI haven't read anything on refs/derefs or @
16:22justin_smith,(def a (atom 0))
16:22clojurebot#'sandbox/a
16:22justin_smith,a
16:22clojurebot#object[clojure.lang.Atom 0x75869acd {:status :ready, :val 0}]
16:22justin_smith,@a
16:22clojurebot0
16:22justin_smith,(deref a)
16:22clojurebot0
16:22Rurikcan anyone explain what atoms are?
16:22justin_smith,(swap! a inc)
16:22clojurebot1
16:22justin_smith,@a
16:22clojurebot1
16:22rhg135! Functions always make you so exciting
16:22kanjaso you're implicly dealing with an object when working with atoms unless you deref them?
16:23justin_smithkanja: you need deref if you want the actual value in the atom
16:23kanjaand mutation functions are smart enough to operate over the object
16:23kanjaand then deref pulls out the value
16:23justin_smithRurik: atoms are a mutable container designed to hold immutable data
16:23justin_smithkanja: right
16:23kanjaright that makes sense becuase the atom itself is just holding a pointer right?
16:23kanjaand mutating it is just switching out the pointer?
16:24justin_smithkanja: not just "smart enough" - they need the atom itself in order to change its state - the value inside would not be sufficient
16:24kanjaright bad choice of words
16:24justin_smithkanja: pretty much that's it, yeah
16:24justin_smithkanja: which reminds me, the other gotcha is putting a mutable data type inside an atom
16:24kanjaso what's special about using the atom then? gives you transactional assignment for thread safety?
16:25justin_smithbecause swap! can retry and that does not do what we want if the data in the atom is mutable
16:25kanjajustin_smith: oh crazy yeah
16:25Rurikjustin_smith, so if you apply a function on an atom the contents get changed permanently?
16:25justin_smithkanja: exactly - it calculates a result optimistically, and retries if there is concurrent modification
16:25kanjajustin_smith: because you could swap the value and then attempt to retry against a totally different set of data
16:25kanjadoes it ever make sense to stick mutable data into an atom then?
16:26kanjathat seems like a pretty strong anti-pattern
16:26justin_smithRurik: swap! and reset! have the power to mutate an atom. The contents are still immutable, you are just putting new contents in.
16:26justin_smithkanja: I suspect there are no reasonable examples of putting a mutable object directly in an atom
16:27TimMchmmm
16:28TimMcjustin_smith: Does this count? https://gist.github.com/samn/5843422
16:28TimMcIt's a delay inside an atom.
16:28justin_smithhmm - delays are in a liminal space re: mutation though...
16:28TimMcEh, I suppose not. Delays only barely count as mutable.
16:29kanjawhat's the ~ operator do?
16:29justin_smithwho was it who was saying case effectively compiles to a hash map lookup?
16:29kanjaI've seen in it some code but have yet to figure out where the docs for it are
16:29justin_smithkanja: it's a special operator inside `
16:29justin_smithunquote
16:29kanjajustin_smith: I have said that in the past w/r/t other languages but not on this room :)
16:29justin_smithwhere ` is known as quasiquote
16:31kanjajustin_smith: ` != ' right?
16:31kanjaoy that's kind of confusing
16:33justin_smithyeah, those are two different things - quasiquote and quote
16:33TimMcquasiquote is the cooler version of quote
16:34kanjareading a message board posting on it now
16:34kanjait's used for delaying the execution of macros?
16:34justin_smithquotation is used as a tool to simplify constructing the value returned from a macro
16:34justin_smitha macro needs to return the form that will replace it
16:34justin_smith(its expnsion)
16:35justin_smithfancy kinds of quoting make generating a specific form simpler
16:35TimMc&(first `[a b c])
16:35lazybot⇒ clojure.core/a
16:35kanjayea that makes sort of sense
16:35TimMckanja: ^ You can use it anywhere.
16:36kanjaso the quasiquote return is namespaced?
16:36TimMcIt namespace-qualifies symbols, yes.
16:36kanjais (first '[a b c]) == (first `[a b c])
16:36TimMctry it
16:36kanjagood point :)
16:37kanjano
16:37TimMcMy main use of it outside of macros is with ~@ like so:
16:38TimMc&`[1 2 3 ~@(map char (range 40 50))]
16:38lazybot⇒ [1 2 3 \( \) \* \+ \, \- \. \/ \0 \1]
16:39TimMcbut even that is very, very rare
16:40kanjahaha I'm a little confused still! If I quote that rather than quasiquote it, the inner function isn't evualuated
16:40kanjadoes quasiquote force evaluation of everything inside of it?
16:41kanjabut then when that first example wouldn't that throw an error since a b or c isn't defined?
16:41kanja&'[1 2 3 ~@(map char (range 40 50))]
16:41lazybot⇒ [1 2 3 (clojure.core/unquote-splicing (map char (range 40 50)))]
16:42kanjaI might just need to read up more on macros
16:42justin_smithkanja: quasiquote prevents evaluation, just as quote does. It also adds namespaces to symbols (even if the symbols are not currently available bindings)
16:42kanjaI am weak on them
16:42justin_smiththis is not about macros at all (yet) - it's a tool that makes macros easier to write, but can be used outside macros as TimMc shows
16:43kanjagot it
16:43kanjaso why did the example with the quasiquote get evaluated and the one w/ a quote not?
16:43justin_smithquasiquote is a version of quote that namespace qualifies symbols and allows controlled unquoting via ~
16:43justin_smithwhat got evaluated?
16:44kanjathe (map char (range 40 50))
16:44justin_smiththat was inside a form expanded via ~
16:44justin_smithwell, ~@ more specifically
16:44justin_smithso it was explicitly unquoted
16:45kanjabut isn't that true for the quoted version as well?
16:45justin_smithkanja: ' does not allow unquoting
16:45kanjaoh which brings us back full circle to ~
16:45justin_smith,'(:a ~@[:b :c])
16:45clojurebot(:a (clojure.core/unquote-splicing [:b :c]))
16:46kanja~ only makes sense in a quasiquote because it's an unquote?
16:46clojurebotCool story bro.
16:46justin_smithyes
16:46kanjaok well now I have to figure out how to use them :)
16:46kanjawhat does @ do in this example?
16:47justin_smith~@ is unquote-splicing
16:47clojurebotRoger.
16:47kanjawhich is a different operator than @
16:47kanjawhich is deref
16:47kanjagot it
16:47justin_smith,`[:a ~[:b :c]]
16:47clojurebot[:a [:b :c]]
16:47justin_smith,`[:a ~@[:b :c]]
16:47clojurebot[:a :b :c]
16:47justin_smiththats' what ~@ does
16:47kanjaoh awesome
16:48Rurikjustin_smith, it yanks stuff out of a data structure?
16:49justin_smithit effectively concats into the thing surrounding it, yeah
16:49kanjawithout breaking it out of the quoting right?
16:50justin_smithwell, what's inside is evaluated
16:50kanjabut only what's unquoted right?
16:50justin_smith,`[(+ 1 2) ~@[(+ 1 2)]]
16:50clojurebot[(clojure.core/+ 1 2) 3]
16:52Rurik,`[(+ 1 2) ~@[(+ 1 2) (+ 1 3)]]
16:52clojurebot[(clojure.core/+ 1 2) 3 4]
16:52Rurikcool
16:52Rurikjustin_smith, what if I wanted to get it out unevaluated?
16:53justin_smith,`[(+ 1 2) ~@['(+ 1 2)]]
16:53clojurebot[(clojure.core/+ 1 2) (+ 1 2)]
16:53justin_smithor even...
16:53justin_smith,`[(+ 1 2) ~@[`(+ 1 2)]]
16:53clojurebot[(clojure.core/+ 1 2) (clojure.core/+ 1 2)]
16:57Rurikah
17:14kanjais there a way to test a private function?
17:14kanjaI
17:14kanja'm not seeing it in the testing namespace
17:14kanjawhich makes sense since it's private
17:23tcrayford____kanja: yeah you can just refer to the var
17:24tcrayford____like (is (= 2 (#'clojure.core/+ 1 1))
17:25Rurikhmmn
17:25Rurikwhat if
17:25Rurik,(def a '( (+ 1 2) (+ 1 3))
17:25clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
17:25Rurik,(def a '( (+ 1 2) (+ 1 3)))
17:25clojurebot#'sandbox/a
17:25Rurik, `(1 ~@a)
17:25clojurebot(1 (+ 1 2) (+ 1 3))
18:11supremekai2hi
18:20justin_smithhello
19:38simon1234Hi there! I was wondering, is there such a thing as datascript but in clojure? (and not clojurescript?)
19:38simon1234Hm that would be core.logic maybe
19:57Trioxinhas clojure implemented user defined reader macros?
20:05dnolensimon1234: datascript already supports Clojure(Script)
20:05dnolenTrioxin: no, and probably never will
20:08simon1234dnolen: oh great, thanks! (and btw, thanks so much for your work, it's awe-inspiring)
20:15crazydiamondHi. Is there an efficient algorithm to invert "multivalue map"? I.e. for {:a [1 2 3] :b [3 4]} it should return {1 [:a] 2 [:a] 3 [:a :b] 4 [:b]}?
20:16mdeboardIsn't there a groupby like that
20:16mdeboardfor map
20:16mdeboardhashmap*
20:17mdeboardThere is something in the stdlib I do believe for it
20:17crazydiamondI've implemented it like (defn maplist-invert [m] (into {} (map (fn [[k v]] [k (map second v)]) (group-by first (mapcat (fn [[k v]] (map #(do [% k]) v)) m)))))
20:18crazydiamondbut doesn't seem to finish :P
20:18Trioxindnolen, why not? it's useful
20:18crazydiamond(on huge map)
20:19dnolenTrioxin: go through old IRC logs and the mailing lists on this topic to figure out why they aren't ever going to get included into Clojure
20:19dnolensimon1234: np
20:20Trioxin"Since most users won't be aware of the meaning of reader macros one has created they are rarely used and to avoid the confusion altogether Rich Hickey decided to remove the ability to have user defined reader macros in Clojure"
20:20Trioxinseems like a lame reason
20:20simon1234Yeah, I guess you hear that all the time, but I feel obliged :)
20:24amalloycrazydiamond: (apply merge-with into (for [[k vs] m, v vs] {v [k]})) would be the easiest way i think
20:26rhg135But that's not very efficient I think
20:27amalloyrhg135: why would you think that?
20:28amalloyi mean certainly you can use more efficient operations if you want to write a longer function, but the complexity is as good as you can do
20:28rhg135Apply X into, amalloy, but then again I can't think of a better way
20:28amalloyhuh?
20:30rhg135Not sure why actually
20:32crazydiamondamalloy, thanks. I'll try that!
20:34rhg135I suppose apply is actually quite efficient on functions of varargs
20:52BronsaTrioxin: we have tagged literals
20:56Trioxindoes clojure have solid/vetted mobile development for android & ios?
20:57Trioxinjust trying to pick a lisp and I'm stuck between CL, clojure, and racket
21:01dnolenTrioxin: for iOS people use ClojureScript (via React Native or other embedded JavaScriptCore thing). On Android a lot of progress has been made - though in theory React Native could also work there eventually.
21:08shiranaihitoTrioxin: i bet Clojure is the most practical Lisp for getting stuff done
21:09hfaafbjohn carmack uses racket
21:09shiranaihitohfaafb: so? :p
21:10Trioxinto me, the JVM and scripting make it both attractive and repulsive at the same time
21:11rhg135http://www.reactnativeandroid.com/
21:13shiranaihitoTrioxin: the real problem with Java is the shitload of pointless libraries just about everything depends on
21:13shiranaihitocommons-<whatever>.jar
21:15Trioxinclojure obviously shares that aspect then
21:34kanjaI can't figure out why my inner function isn't getting called in this snippet http://pastebin.com/pLWqdtpr
21:35kanjathe log at the end is missing the "sending tweet" text but the above and below calls are working right
21:35kanjabecause I'm shadowing it with the passed in arg
21:35kanjaUG
21:37kanjahow do I test a function that only has side effects?
21:42shiranaihitoTrioxin: yeah, sadly Clojure comes with Java's baggage
21:45taliosjava doesn't ship with any commons-*.jar - mind you - if you removed the JVM from Clojure, you'd have every other lisp on the planet - a dead language
21:45Bronsashiranaihito: you're painting a picture of the clojure ecosystem that doesn't match the one i know
21:46shiranaihitoi'm not sure what you're arguing against
21:47shiranaihitomost widely used Java libs depend on a shitload of jars, so if your Clojure project depends on them, then you're carrying Java's baggage
21:49Bronsayou have the choice to use those libs or to not use them
21:50Bronsato me it matters a whole lot more that I have the option to depend on those libs if I need to than how many jars a dependency depends on
21:56shiranaihitodude, sometimes you just need a specific library, even if it does depend on a shitload of jars..
21:57shiranaihitobut people in the Java and Clojure ecosystem don't seem to have seen this stuff as a problem
21:57shiranaihitowe've got Maven and Lein to deal with scraping together that steaming pile of jars, after all
21:57Trioxinis there a prolog implementation for clojure?
21:58Bronsashiranaihito: are you complaining about package managers? I don't understand. Most languages have those
21:58BronsaTrioxin: there's core.logic, not a prolog implementation but a logic engine nonetheless
21:58shiranaihitoBronsa: ok, now i think you're trolling me, so i'll just stop here
21:59Bronsathat's the first time I've been accused of trolling, nice
21:59shiranaihitoyou're welcome! :p
21:59taliosshiranaihito - bloat of distribution is definitely a problem IN GENERAL, but in the scheme of things - of getting a working solution, someones extra bytes is better than reimplementing everything all the time
21:59dnolenshiranaihito: can't remember the last time I used an actually popular Java dep that pulled in tons of deps. The popular ones don't do this for the obvious reasons - you actually want people to use it.
21:59Trioxinsilly arguing. I think if you learned clojure because you're a java fanboy you did it for the wrong reason
22:00taliosdnolen - obviously never had to pull in a CXF dep then :)
22:00dnolentalios: emphasis on "popular", is it Jetty / Netty / Joda / Guava popular ?
22:00shiranaihitotalios: yes, in general.. but i think the problem has been largely caused by people thinking they should always just get a lib from somewhere instead of implementing even a little thing by themselves
22:01taliosdnolen - yep - its pretty much the only game left around if you need to interact with SOAP on the JVM
22:01dnolentalios: wow ok SOAP
22:02taliosdnolen - yes sad. We had to intergrate with something recently, sadly their SOAP API wraps their RMI API - goood lord the classes that got generated ;p
22:02Trioxinthis seems to be the most popular Lisp around. Hopefully not just because of Java coders who decided to have some extra fun.
22:02hfaafbTrioxin: is there a wrong reason to learn a new language?
22:03hfaafbyou can love the jvm and hate java, that's a legal thing to do
22:03Trioxinhfaafb, if you've ever started in a language and then stopped before getting to know it well you'd know the correct answer to that.
22:05hfaafbyou could be learning clojure right now... it doesn't take a whole lot of investment
22:05hfaafblearn a few lisps
22:05hfaafbgo for it
22:05macromancerlearning intercal to learn how to be more polite might count as the wrong reason
22:06justin_smithlearning forth because you want to be more like yoda
22:06Trioxini think i'll go watch farscape and think about how lame java can be before I decide to commit to clojure
22:07Trioxinlanguages almost always get popular for the wrong reasons
22:07macromancerplatforms aswell
22:08macromancerpopular because of "popularity"
22:08hfaafbwhat a bizarre mindset, to only want to learn something if you think the few days diving into it are going to be somehow wasted
22:09hfaafbor rather not wasted
22:09Trioxinhfaafb, learn brainfuck then
22:09Trioxinyour time won't be wasted
22:09Trioxini promise
22:11BronsaTrioxin: why would java be a factor in deciding whether or not to learn it?
22:12Bronsawe share the jvm with java, as an alternative language with entirely different principles
22:13Trioxinbut you're all pink on the inside
22:14Bronsawhat does that even mean?
22:14Trioxinlol
22:14Trioxinbytecode...
22:14Bronsayes, that's a word we use
22:14Bronsawhat about it?
22:15Trioxinyou're all filled with toffee
22:15Bronsaare you just trolling now?
22:15Trioxinjust tired
22:17BronsaTrioxin: we're trying to be helpful and answering your questions, don't waste other people's time by trolling if you're tired please
22:18hfaafbnever written a line of java in my life
22:18hfaafbuse clojure semi regularly for hobby stuff
22:18macromanceri've never seen a one-liner in java before
22:20Trioxinother lisps arent JIT though
22:20rhg135I have, but it was very long
22:21Trioxinnot in the traditional sense
22:21macromancertrioxin: looks like racketlang may be run on a JIT compiler
22:22justin_smithyes, racket has jit
22:22macromancertrioxin: sbcl seems to be JIT, if you call it that. You type code into the REPL and it produces machine code.
22:22Trioxinthat would make sense with what it claims to do
22:23justin_smithmacromancer: I'd call that a compiler hooked up to a repl, I think jit promises a bit more
22:24Bronsasbcl is definitely AOT
22:24Bronsait just does "interactive" AOT compilation
22:25macromancerfeels like a grey area, like saying javascript is an interpreted language.
22:25Bronsamacromancer: no, not really. once sbcl emits machine code it's done.
22:26macromancerbronsa: how would a JIT be different?
22:26Bronsamacromancer: compare with the jvm, which compiles the bytecode into machine code at runtime
22:26TrioxinCL is incrementally compiled
22:26Bronsamacromancer: compilation happens during execution
22:27macromancerbronsa: why doesn't the REPL count as "at runtime"?
22:27Trioxinduring runtime. and is there garbage collection?
22:27Trioxini think so
22:27Bronsamacromancer: the jvm can compile the bytecode while it is executing it
22:28Bronsamacromancer: that's just compiling + loading in memory immediately after
22:29macromancerbronsa: what about a call to "eval"? sbcl will compile it, then execute it.
22:29Bronsamacromancer: right, you said it. compare then execute
22:29justin_smithmacromancer: but it doesn't compile it in the midst of executing it
22:29Bronsathat's ahead of time compilation
22:29Bronsajust in time compilation means it will compile it or parts of it *while* it is executing it
22:29justin_smithmacromancer: the point of JIT is it uses some information only available when running the code to optimize said code
22:30macromanceryou mean, it is executing it, and compiling it, and the on the second run through it will execute the compiled version, but interpreted it the first time?
22:30Bronsathat's one possible scenario
22:31justin_smithmacromancer: it will take notes during the first 100 or so executions, and use that statistical data to decide if and how to produce a new optimized version
22:31Bronsarealistically it will be much more complex and require many executions
22:31justin_smithyeah
22:31macromancerso, if instead of running the 100 scenarios, it executes zero of them, is it still a JIT?
22:32Bronsaff a tree falls in a forest and no one is around to hear it, does it make a sound?
22:32macromancereven if it regenerates the machine code every time through.
22:32justin_smithmacromancer: no because it isn't using runtime data - it isn't just running 100 random calls, it is waiting for you to call the code so it can get real profiling
22:32macromancerbronsa: my point is, JIT seems like an overloaded word, which has dragged along new improvements in the technology with it, and called that the baseline for what a JIT is.
22:33justin_smithmacromancer: as Bronsa already said what SBCL does has a name, it is AOT compilation
22:33macromancerIt seems that all that is needed is that no code be interpreted, but there is no compile/link phase prior to interpreting the code.
22:33macromancerok
22:33TrioxinI was just making the distinction between JVM bytecode and CL machine code
22:33justin_smithif you aren't using profiling data to transform a function that is already running, that isn't JIT
22:33justin_smithTrioxin: OK, JIT generates machine code
22:35Trioxinbytecode... I've been coding c# for a long time and don't consider it to be native compilation
22:35justin_smithTrioxin: AOT generates byte code, JIT generates machine code
22:35BronsaTrioxin: javac and the clojure compiler compile byte code, JVM's JIT compile machine code from that byte code
22:36justin_smithTrioxin: it's not a question of "what we consider machine code" the vm outputs machine code that replaces the byte code
22:36Trioxino i thought you were trying to put one in place of the other
22:36Bronsano
22:37macromancerjustin_smith: by that definition, a C compile isn't an AOT compiler, because it produces machine code, assuming we differentiate between byte code and machine code
22:37Bronsamacromancer: AOT doesn't mean "compiler file; ./a.out",JIT doesn't mean a REPL
22:37justin_smithmacromancer: there's more than one factor here, but no, a C compile is AOT
22:38macromanceraccording to "Aycock -- A brief history of Just in time", the original LISP paper described JIT compilation, which I imagine didn't include any profiling.
22:39justin_smithI wouldn't be surprised that the terms changed meaning, it wouldn't be the only CS term to do so.
22:40macromanceri don't think it has changed meaning... i think what you might actually mean is a tracing-jit
22:40Bronsamacromancer: from the abstract of that paper "Broadly, JIT compilation includes any translation performed dynamically, after a program has started execution"
22:40macromancersbcl falls into that category
22:41Bronsareplace "program" with "compilation unit" for better clarity
22:41Bronsano.
22:41macromanceryes
22:41Bronsano
22:41macromancer:)
22:41justin_smith~gentlemen
22:41clojurebotYou can't fight in here. This is the war room.
22:41macromanceri have to politely disagree
22:42Bronsamacromancer: once you input an expression into sbcl, that gets compiled and only after it is executed
22:42Bronsasee my previous comment, "replace 'program' with 'compilation unit'"
22:42macromancerare you saying the jvm can execute code before it has been compiled?
22:42Bronsayes
22:42macromancerand the sbcl performs no interpration?
22:42Bronsait executes a whole lot of code before compiling it into machine code
22:43macromanceraccording the the docs, sbcl can interpret lisp code, and it can also compile code, at runtime.
22:44macromanceri must be missing a nuance that just isn't obvious.
22:45BronsaI don't know how else to explain this
22:45macromancerok,... broken down: code is either interpreted or compiled (effectively interpreted at a hardware level).
22:46macromancerwe're arguing about when the interpretation by software or compilation/interpretation by hardware happens.
22:46Bronsamacromancer: it seems to me that you're drawing the distinction between AOT and JIT to whether or not it produces a compiled file
22:46BronsaAOT doesn't imply output to file, outputting to memory is still AOT
22:47macromancerbut if I interpret code, then partially compile some of it, without any profiling, according to the literature, that is still "just-in-time"
22:48Bronsamacromancer: if you do that compilation dynamically, while that code is executing, sure
22:48macromancerif "eval" compiles the code before executing it, that is just in time..
22:49Bronsano
22:49macromancerto be clear, if it's not interpreted, then it must be compiled, otherwise it can't be executed
22:49Bronsathat just means there's an interpreter or resident compiler available at runtime
22:49Bronsait doesn't tell you anything about the style of compilation that's going on
22:50macromancerthere seems to be no difference between a JIT compiler and what I think you mean by a "resident compiler"
22:50macromancerif its all in memory.
22:50macromancerat runtime
22:51macromancerthis really just seems like a slider which moves the compilation step to an arbitrary point in time.
22:51macromancerJIT just means "as late as possible"
22:51macromancerit still has to be compiled.
22:52BronsaI'm sorry, I give up
22:52Bronsaagain, no.
22:52justin_smithif no code can run without being compiled first, I don't think you can call that JIT
22:52macromanceri'm sorry you couldn't convince me
22:52Bronsathe jvm will make no guarantee whether or not some bytecode will be ever compiled to machine code
22:53macromancerhow does a JIT execute without compiling it first? it must be interpreting it
22:53justin_smiththe vm interprets bytecode, some bytecode is eventually compiled for performance reasons
22:53macromanceri'm sure I could patch sbcl to randomly decide to interpret or compile a bit of code, during runtime, and fill the criteria
22:54Bronsamacromancer: the jvm will interpret some bytecode, compile some to machine code, recompile some to optimized machine code, recompile some to unoptimized bytecode and much else
22:54macromancerokay, the JVM does all this, but that isn't the minimum necessary condition for calling a thing a JIT compiler...
22:54Bronsaway after that bytecode has been loaded by the vm
22:55macromanceri'm arguing about the minimum conditions, not about the state of the art
22:56macromancerok, time for lunch. Good discussion, even if I'm not convinced. I'll do some reading, and make up my mind, somehow.
22:56Bronsamacromancer: look, you (eval '(defun foo )) in sbcl. if sbcl is done with foo after eval returns, that's AOT compilation. if sbcl some time after and during execution will recompile foo or do other stuff to it, that's JIT
22:56Bronsawill possibly*
22:58tali713yes, in sbcl eval is more or less (execute (compile ...)) the compilation will happen right then, before it is executed and will not happen again for that object. uiui
22:58Bronsamacromancer: I think the confusion arises in lisps because lisp usually don't really have the same notion of program as other languages -- usually a lisp program is a compilation unit
22:58Bronsawhich can be any lisp form
22:59tali713in other words the moment you evaluate a function definition it is compiled, compilation is not deferred for when that function is called.
23:52joness2hi. what is the clojure's equivalent of famous haskell's fibonaci example? "fibs = 0 : 1 : zipWith (+) fibs (tail fibs)" I used to have it but I can't find it now
23:58joness2IIRC there's a lazy clojure equivalent that also does auto-memoization. anyone knows what i am takling about? or am i imagioning things?
23:59justin_smith,(def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq))) ; joness2 is this the one you were thinking of?
23:59clojurebot#'sandbox/fib-seq
23:59justin_smith,fib-seq
23:59clojurebot(0 1 1 2 3 ...)
23:59joness2,(take 10 fib-seq)
23:59clojurebot(0 1 1 2 3 ...)
23:59justin_smith,(drop 5 fib-seq)
23:59clojurebot(5 8 13 21 34 ...)
23:59justin_smith,(drop 10 fib-seq)
23:59clojurebot(55 89 144 233 377 ...)
23:59joness2yes thanks! that seems to be it