#clojure logs

2011-08-16

00:24amalloyi guess we'll never know
00:30grant_it was a macro bug :)
01:32grant_is there a good way (in emacs/slime) to stop a thread thats spamming me with printlns in the background?
01:42ShreeMulayif anyone's awake and can help me with getting the following loop to work, I'd LOVE it!
01:42ShreeMulay(fn [n] (loop [n] (if (empty? (next n)) (n) (recur (next n)))))
01:43ShreeMulaytrying to solve http://www.4clojure.com/problem/19#prob-title
01:46kephalethe true clause
01:49amalloygrant_: go back in time and don't start that thread
01:50amalloyShreeMulay: you don't want (n), which would call n as a function
01:50cemerickShreeMulay: Loop needs pairs of binding name/values in its vector. Why next? And (n) won't ever work.
01:51grant_amalloy: but that's O(make a time machine) :(
01:51amalloycemerick seems to be a better reader than me
01:52cemerickI don't know what the hell I'm still doing up, but I'm glad I'm not ground beef yet.
02:14amalloyhm, i'm reading over the compiler, and it looks like the 1.3 primitive-function support only works for top-level vars? like, i couldn't pass around a function and then eventually treat it as something taking a primitive long, even if i have a primitive in scope. anyone who knows about 1.3 primitive stuff care to confirm that for me?
02:17jeffrey04erm, may I know what these warning means?
02:17jeffrey04Warning: *default-encoding* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *default-encoding* or change the name. Warning: *buffer-size* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *buffer-size* or change the name. Warning: *byte-array-type* not declared dynamic and th
02:17jeffrey04get those after using duck-streams in my script
02:19amalloyduck-streams is super-old and you're using it with the super-new clojure 1.3
02:20jeffrey04amalloy: oh, ok
02:23amalloyhonestly if duck-streams were completely removed that might be better. a few people would be sad about having to upgrade, but a lot of new people would *realize* they shouldn't use it even though their book uses it
02:24jeffrey04so if i don't use duck-streams
02:24jeffrey04erm... what should i use?
02:24jeffrey04BufferedReader?
02:24clojurebotReader syntax of collections has gotchas
02:24amalloy*chuckle* thanks, clojurebot
02:24jeffrey04lol
02:24amalloyjeffrey04: most of duck-streams is in clojure.java.io now
02:25amalloyjust like you shouldn't use str-utils2 or whatever nonsense, because it's in clojure.string now
02:25jeffrey04http://richhickey.github.com/clojure/clojure.java.io-api.html <- this
02:25jeffrey04?
02:26amalloyhttp://clojure.github.com/clojure/clojure.java.io-api.html
02:26amalloyoh, and slurp/spit are in clojure.core
02:27jeffrey04erm is there a tutorial on how to read a file the proper way?
02:29amalloyi guess it depends what you mean by "read a file" and "the proper way"
02:30jeffrey04amalloy: is clueless right now lol
02:30amalloy(probably also the definition of "tutorial" will come into play)
02:30amalloyjeffrey04: what do you want to do with the contents of the file you're reading?
02:30jeffrey04create a hadoop sequencefile
02:30jeffrey04http://stackoverflow.com/questions/7062327/generating-a-sequencefile/7063762#7063762
02:30amalloythen you probably don't want to read a file at all, just ask hadoop to do it?
02:32jeffrey04i still need to pass the content to hadoop sequencefile writer no?
02:32amalloyor, frankly, this looks like a pretty complicated first task in clojure
02:33jeffrey04lol
02:34jeffrey04if i can't figure out how to do it in clojure, would probably just write it in java (java is not my first language either, so would be equally just as tough)
02:36amalloyif you're writing a sequence file, can't you do that offline in whatever language you want?
02:37jeffrey04afaik sequencefile is usually created with some hadoop api
02:37jeffrey04http://hadoop.apache.org/common/docs/current/api/org/apache/hadoop/io/SequenceFile.Writer.html
02:42amalloywell, i can point you at ##(doc line-seq) and ##(doc clojure.java.io/reader)
02:42lazybot (doc line-seq) ⇒ "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader."
02:42lazybot (doc clojure.java.io/reader) ⇒ "([x & opts]); Attempts to coerce its argument into an open java.io.Reader. Default implementations always return a java.io.BufferedReader. Default implementations are provided for Reader, BufferedReader, InputStream, File, URI, URL, Socket, byte arrays, character a... http://gist.github.com/1148555
02:42amalloysince i guess you want to do something for each line of the input file
02:50jeffrey04amalloy: thanks
04:59lnostdaldoes lein have a "verbose mode"? .. seems it hangs waiting around for something at times (e.g. when doing `lein uberjar' just now)
05:47pyrdoseq has no :when guards ?
05:47pyrit seems
05:50ejacksonhmm... that's contrary to the docs :(
05:51pyri may be using it wrong
05:52pyr,(doseq [a [0 1 2]] :when even? (println a))
05:52clojurebot0
05:52clojurebot1
05:52clojurebot2
05:53pyrsame thing for #(even? a)
05:53pyr:let works though
05:54mrBliss,(doseq [a [0 1 2], :when (even? a)] (println a))
05:54clojurebot0
05:54clojurebot2
05:55pyrerf
05:55pyrit's too early i guess... :)
05:56thorwilhow can i turn this naive recursive function into a loop-recurse? http://paste.pocoo.org/show/459250/
05:56pyrmrBliss: thx
06:00clgvthorwil: if you keep it lazy you won't need loop-recur
06:01clgvthorwil: otherwise you need some "work-queue"
06:02clgvthorwil: does the result have to resemble the hierarchic structure of the data? or is a flat collection as output ok?
06:08clgvthorwil: here is a recur version for a flat result list: http://paste.pocoo.org/show/459254/
06:08thorwilclgv: the queries are via appengine datastore, so nothing lazy about that, i assume
06:09clgvthorwil: You used map so your function itself is lazy
06:09thorwilclgv: in the end i want to render this in html with nested divs
06:10clgvthorwil: ok then you need a hierarchic output - that's more complicated. but you might not need to implement it yourself. you could use clojure.walk/prewalk similar to the replace functionality in there
06:13thorwilclgv: ok, i'll have a look at prewalk and/or using an accumulator. thanks!
06:14clgvthorwil: but I think your lazy implementation via map should be fine too
06:15clgvunless you force it all at once - that might blow the stack
06:16thorwilclgv: do i not have a problem with a growing stack, given my implementation?
06:16thorwilbbiab
06:17clgvnot in general - that depends how you use the lazyseq that is the result of your function
07:10lnostdalseems sort of random which exception/stack-trace ends up in the Slime debugger and which one ends up in the terminal .. i'm using Ring, so i'm guessing it is something thread related(?)
07:12lnostdal(the ring jetty adapter)
07:14manutterHmm, I haven't looked at it extensively, but I have a rough impression that the terminal gets "logged" exceptions (i.e. caught and logged by middleware) and Slime gets the exceptions that Ring can't catch (e.g. compile errors)
07:15lnostdalok, clojure being a dynamic language needs to present run-time errors; compile-time ain't enough :)
07:16lnostdal..digging through jetty.clj now, ...hm
07:17manutterI'm not sure about Ring proper, but I know Compojure likes to use a wrap-stacktrace middleware that does exactly that
07:17manuttertho now that I think about it, I believe Ring is the source for that middleware
07:19lnostdalhttp://mmcgrana.github.com/ring/ring.middleware.stacktrace-api.html ..? but that isn't useful while developing (perhaps for testers); exceptions needs to go to Slime where people can click stack-frames and get to the source
07:20manutterI wonder if the exception would bubble-up to slime without the middleware? I suspect not, due to threads.
07:21lnostdaldunno .. i'm only using the jetty middleware at the moment
07:21manutterThere was some really interesting code at the end of The Joy Of Clojure that involved writing your own debugger into your code -- you could set break points and evaluate functions and such with very little effort
07:22manutterI bet you could do something similar with embedded code that would "read" from an atom or something
07:22manutterthen it would work across threads.
07:26clgvmanutter: the break or also called debug-repl from JoC is great
07:35manutterYeah, I was pretty impressed
07:35manutterI tried to write one in PHP, but oh well :P
08:08wunkianyone familiar with jetty, I currently use wrappers for an entire app. Is it possible to split the app so I can use a different set of wrappers on them, finally serving it up as one app?
08:10raekwunki: in Moustache this is pretty simple: (def master-handler (app ["a"] [wrapper-a sub-handler-a] ["b"] [wrapper-b1 wrapper-b2 sub-handler-b]))
08:10wunkiraek: would this work for compojure and jetty?
08:11raekmoustache is a lib that does routing and middleware composition. (it fills the same place as compojure)
08:11raekI suspect compojure can do something similar
08:13wunkiraek: could you explain what ``app ["a"]`` stands for?
08:13wunkiis that a set of routes?
08:14manutterwunki: I havent tried it in Compojure, but there's no reason it wouldn't work
08:14raekyes, app is the route macro from Moustache
08:14wunkimanutter: I'm really green on this, are you willing to create a gist example for me/
08:15manutterwell, willing in theory, but I'm at work, so I can't really take the time to go into detail
08:15wunkimanutter: ok, no problem, will do trial-by-error
08:15manutterwhy do you want to use different wrappers for different parts of your app?
08:16wunkimanutter: because I have some views that need a authentication wrapper (creates a basic-auth request)
08:16manutterah, that makes sense
08:16wunkiraek: so, that would be defroutes in compojure?
08:16raekwunki: in theory, you could mix compojure and moustache (they both follow the Ring spec) but I think Compojure has its own way of doing what I showed in Moustache
08:16manutterYou might want to look up the sandbar lib if you haven't already
08:17manuttersandbar lets you specify access on a route-by-route basis
08:17raekwunki: basicaly yes. Moustache and Compojure fill the same function, but you do things in different styles
08:17wunkiok, thanks for the help guys, I'm going to try some stuff out
08:18raekwunki: so where do you put the middleware in your defroutes form?
08:19wunkiraek: https://gist.github.com/37acc39ae1856652f1cf
08:20wunkidefroutes combines all the routes, then app adds all the middleware
08:20wunkifinally, app get's served
08:21wunkiI would like to have a "auth-app" or something, that add the authentication wrapper also
08:21wunkiand serve those two together
08:21raekwunki: this might work: in the (defroutes routes ...) code, maybe you can wrap the individual items there with middleware
08:22wunkiraek: how do I wrap something? :/
08:22raek(defroutes routes (-> episto.users.core/user-routes wrap-foo wrap-bar) (-> episto.auth.core/auth-routes wrap-baz wrap-quux))
08:22raekwunki: like you do in (def app
08:22raeka wrapper is just a function that takes a handler and returns a wrapped handler
08:24manutterYes, that should work fine in Compojure
08:24wunkiok, I'm gonna do that. Don't want to repeat the wrappers for every route though. Will look how to DRY that up
08:24manutterIf you look at the code for defroutes, it's basically just passing the request to each of the handlers in turn until one returns non-nil
08:25raekwunki: you can compose wrappers just like ordinary functions
08:25wunkiraek: good idea, will do that
08:25raek(def wrap-json-and-error-handling (comp wrap-error-handling wrap-json-params))
08:26manutterI believe you could use defroutes more than once
08:27manutter(defroutes auth-routes foo bar baz), then wrap auth-routes, then (defroutes routes regular unleaded auth-routes)
08:28manutteror rather (defroutes routes regular unleaded wrapped-auth-routes)
08:28manutterI'm leaving a couple steps as "an exercise for the reader" but you get the idea
08:30raekbut doesn't he already do that?
08:32manutterI can't tell -- he's passing auth-routes to the main defroutes macro, but I'm not sure he realized he can wrap auth-routes before passing it to the main defroutes
08:33manutterand I'm assuming he's using defroutes in episto.auth.core--if so, he's 90% of the way there
08:33wunkisorry guys, just got some people over. I'm logging this however :)
09:05manutter,(doc println)
09:05clojurebot"([& more]); Same as print followed by (newline)"
09:06manutteryay, clojurebot is alive again
09:06manutterclojurebot: help
09:06clojurebothttp://www.khanacademy.org/
09:06manutterlol, ok, that's actually MORE help than I necessarily wanted.
09:58pyr,(let [a "s"] (case (class a) java.lang.String :found :not-found))
09:58clojurebot:not-found
09:58pyr,(class "s")
09:58clojurebotjava.lang.String
09:59pyri'm not getting what I'm doing wrong
09:59pyri know that the right idiom is multi-method in this case
10:00manutter,(let [a "s"] (class a))
10:00clojurebotjava.lang.String
10:01manutter,(let [a "s"] (case (class a) 'java.lang.String :found :not-found))
10:01clojurebot:not-found
10:01manutterhrmmm
10:01Bronsa,(let [a "s"] (case (class a) 'java.lang.String :found (class a)))
10:01clojurebotjava.lang.String
10:01manutter,(= (class "s") java.lang.String)
10:01clojurebottrue
10:01pyryep tried all of this
10:02manutter,(doc case)
10:02clojurebot"([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need not be quoted. If the expression is equal to a test-constant, the corresponding result-expr is returned. A single default expression can foll...
10:04manutter,(let [a "s"] (case (class a) (class "s") :found :not-found))
10:04clojurebot:not-found
10:04manutterlol
10:04manutterthat's messed up
10:05lobotomy,(let [a 1] (case (< a 2) :yes :no))
10:05clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: true>
10:05lobotomyhmm, apparently i don't know how to use case ;p
10:06tufflax,(let [a 1] (case (< a 2) true :yes :no))
10:06clojurebot:yes
10:06raekpyr: case uses compile-time constants (and does not evaluate them). so you get the java.lang.String _symbol_, not the class.
10:06manuttercase is a simplification of cond -- it works faster because the first element of each pair has to be a literal
10:06pyrraek: that's what I figured by running macroexpand
10:07raekpyr: it is actually possible to use case on classes, but you have to write a macro that expands to a case form which has class object instead of symbols in the code
10:07raekpyr: https://gist.github.com/997652
10:08pyrraek: thanks
10:08pyrraek: i was misled by this article: http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure
10:09raekhrm. that code doesn't work, right?
10:09pyrnope
10:09raek"that code" = (case (class a) ...)
10:09pyryep
10:10TimMcAnyone know of an Clojure graph layout libraries along the lines of Vijual?
10:11manutterlacij?
10:11TimMcOoh, thanks!
10:11manutterDon't know anything about either one, but I think I saw something about graph layout in connection with lacij
10:12manutterdaveray is also playing with something he calls Dorothy
10:12manutterclojure interface to graphviz
10:12TimMc(I'm getting fed up with client-side (JS) graph layout libraries.)
10:14manutterI hear ya :)
10:16TimMcI'm tempted to use a server-side lib to generate layouts and then animate any differences on the client side,
10:17TimMc.
10:20cemerickraek, pyr: It'd be safer to use symbols all around than to ensure that the constants provided to case were classes. Doing so would avoid issues if you were to AOT-compile the code using class-based case clauses, thus locking in their hashcodes at compile-time. I neglected this aspect as well before: http://cemerick.com/2010/08/03/enhancing-clojures-case-to-evaluate-dispatch-values/#comment-8
10:21manutter,(let [a "s"] (case (str (class a)) "java.lang.String" :found (str (class a))))
10:21clojurebot"class java.lang.String"
10:22manutter*snap*
10:24wunkiwhat do you call a "->" in clojure?
10:24cemerickIt's a threading macro.
10:25wunkicemerick: thanks, looking it up
10:26wunkiah, good piece: http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/
10:26cemerickalso: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/
10:27wunkiI started reading the book "The Joy of Clojure" yesterday, awesome book
10:43TimMcmanutter: Actually, the problem I'm having is finding a graph layout engine that provides relative stability over graph operations (don't completely rearrange everything when a single node is added) and can handle disconnected graphs with any gracefulness.
10:44manutterYeah, sounds like a tricky set of requirements
10:45TimMc(Background: I'm trying to write a good display for what is effectively an RDF explorer.)
11:21duck1123TimMc: sounds interesting. github link?
11:22TimMcduck1123: Sorry, it's a project for work.
11:22TimMcAlthough, any supporting code I write might make it onto GitHub.
11:24TimMcThis component of the project allows the user to see links between people and locations and such that have been derived from a bunch of documents. I'm currently using TheJIT's Force-Directed graph for it, but it kind of stinks with disconnected graphs.
11:25TimMcProject leader is pretty friendly to open-sourcing components, though.
11:26duck1123That's cool. It's good to see companies give back
11:28TimMcYeah, it can be a really nice symbiosis.
11:45PupenoWhere do you put the connection calls when using lobos?
11:51manutterLooks like you can def a map with the db connection specs, then pass the map to (with-connection db-spec &body)
11:52manuttercheck out the code at the bottom of the frontend docs on the Lobos site
11:56cemerickWhat's the state of Clojure sandboxes these days? Is clojail the only game out there (aside from the one embedded in clojurebot)?
11:58TimMcclojurebot doesn't use clojail?
11:59TimMcI kind of assumed it did.
11:59cemerickclojurebot predates clojail
12:00cemerickIt'd be nice if there was one obvious sandboxing option.
12:01Pupenomanutter: yes, I seen that, but there may be some commands that load some files automatically expecting them to define the connection. Apparently it's src/lobos/config.clj.
12:04TimMccemerick: When it comes to security, I kind of like having diversity.
12:06TimMcAlthough... that is predicated on having at least two *comprehensive* options.
12:07cemerickTimMc: Probably wise. But, when the different options aren't readily comparable (short of understanding their source top to bottom), it's tough.
12:08dnolennice looks like the pattern matching / predicate dispatch talk at NYC Clojure tomorrow will definitely get recorded
12:08TimMccemerick: Is your abhorrence based on choice paralysis or the problem where 100% of the libraries solve 80% of the problem?
12:08technomancydnolen: woo
12:09cemerickTimMc: I was trolling a bit, but I think choice paralysis is a big source of friction generally.
12:09cemerickJust about every X is an 80% solution in any case.
12:10TimMcOh hey, there's a Clojure meetup on Thursday in Boston.
12:11TimMcI have to make it to that.
12:11technomancyTimMc: absolutely
12:13dnolenthe fact that the JVM can optimize call sites when you're pulling fns out of arrays is pretty astounding.
12:15dnolenfast predicate dispatch might not be as hard as I thought...
12:17symbolednolen: Will there be a recording of the talk on Wednesday?
12:17dnolensymbole: 90% chance it seems like.
12:22TimMcWhat would you call a HOF that is the opposite of partial, e.g. (fn a b c d e) -> (fn d e) ?
12:24symbolednolen: I'll email the organizer then.
12:27TimMc(defn unpartial [f n] #(apply f (drop n %&)))
12:28amacI think unpartial [f & n], no?
12:29amacand then drop the count of the number of args passed in
12:29TimMcWhy?
12:29clojurebotwhy not?
12:30TimMcclojurebot: Glad to see you aren't flailing around helplessly today.
12:30sjlHmm, if I (def foo (force (delay (some-fn huge-argument))) is that going to prevent huge-argument from being garbage collected?
12:30clojurebotwhat should I do today, it is the weekend and all
12:30TimMcamac: With my definition, ((unpartial + 2) 1 10 100 1000) => 1100
12:30sjlOr will it allow it to be GC'ed once it's forced and the argument isn't necessary any longer?
12:31sjl(assuming there aren't any other references to huge-arg anywhere else, of course)
12:31amacok, I see where you're going
12:32TimMcI guess it is basically a member of a class of HOFs that do something to the arglist and reapply it.
12:32amacI thought you wanted to define more of an... anti?-prototype
12:34TimMc(defn modarg [f m] #(apply f (m %&)))
12:34TimMc((modarg + (partial drop 2)) 1 10 100 1000)
12:36manutter,(letfn [(skip-args [f c &args] (apply f (drop c args)))] (skip-args + 2 1 10 100 1000))
12:36clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: args in this context, compiling:(NO_SOURCE_PATH:0)>
12:36manutteroops
12:36manutter,(letfn [(skip-args [f c & args] (apply f (drop c args)))] (skip-args + 2 1 10 100 1000))
12:36clojurebot1100
12:37manutterTimMc: ^^^
12:37nollidjis there a good reference for all the internal clojure interfaces that define behaviors, like IObj, ILookup, and IPersistentMap?
12:38nollidji have gotten away with copy-pasting from others' code i find when googling, but it would be nice if there were a single javadoc-style go-to reference explaining things
12:39nollidjokay, let me modify that: i can look at the javadoc, but it's really not that informative.
12:39symbolenollidj: They're mostly under one package, so looking at the source will give a list.
12:39nollidjanything better that actually explains things?
12:41symboleThey're scattered through out. I know the book Joy Of Clojure mentions internal structures fairly often to give you a good understanding of things under the hood.
12:42nollidjhm, ok. thanks.
12:42clgvnollidj: yeah you should make some noice that clojure.core starts documenting their implementation jvm and clj more! :)
12:42clgv*noise
12:42nollidjthere's little documentation to explain, for example, what meta and withMeta do and why i should implement them in something
12:43nollidjhm. i guess it's worth opening an issue
12:43clgvnollidj: you want to know that? that's easy, it's the emtadata support
12:43clgvthe one assigns meta the other reads it
12:44nollidji figured that, but it wasn't clear that's what it meant. also, an experienced programmer learning clojure might need to learn about metadata support just to create a custom datatype
12:45nollidji'm not saying that's bad, i'm just saying there's a bit of a gotcha there
12:45clgvnollidj: I totally agree with you that they should document more
12:45nollidjsure, thanks for the feedback
12:45clgvsome of the clojure.core implementation would be a lot easier to understand with some comments in it
12:49nollidjoh, there's an attempt at developing a literate programming-style book documenting things. that's fantastic
12:49clgvlink?
12:49clojurebotyour link is dead
12:50Scriptordocco?
12:51nollidjfound this: http://groups.google.com/group/clojure/browse_thread/thread/460417fe45f314c3?pli=1
12:51nollidjthe pdf and source are linked there
12:51clgvthx
12:59TimMcmanutter: Yeah, but mine is a HOF. So neener neener.
13:02manutter,(letfn [(skip-args [f c] (fn [& args](apply f (drop c args))))] ((skip-args + 2) 1 10 100 1000))
13:02clojurebot1100
13:02manutter:)
13:04TimMc,(letfn [(marg [f m] #(apply f (m %&)))] ((marg - reverse) 1 10))
13:04clojurebot9
13:05TimMcI guess the arguments should really go the other way.
13:06TimMc,(letfn [(marg [m f] #(apply f (m %&)))] ((marg reverse -) 1 10))
13:06clojurebot9
13:07manutterSurgeon General's Warning: HOF's may be hazardous to your free time, and may cause spontaneous giggling in PHP programmers who aren't used to them.
13:47amac,(defn predmap [p m & c] (apply map #(if (p %) (m %) %) c))
13:47clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
13:51amac,((fn [p m & c] (apply map #(if (p %) (m %) %) c)) even? inc (range 1 11))
13:51clojurebot(1 3 3 5 5 ...)
13:53TimMcamac: You might call it ifmap
13:53TimMcOr... hmm, maybe not.
13:54amacI run into this usecase surprisingly often
13:54TimMcYou could also turn it inside out.
13:54amac?
13:55TimMclet me work something up
13:57amac:)
13:58TimMc,(letfn [(xif [p f] #(if (p %) (f %) %))] (map (xif even? inc) (range 1 11)))
13:58clojurebot(1 3 3 5 5 ...)
13:58amalloyamac: something like this is in useful
13:58TimMcxif = "transform-if"
13:59amalloyTimMc: hah, that's what i called the one in amalloy-utils. ninjudd convinced me to rename it (and rework it) to "fix" when i ported to useful: https://github.com/flatland/useful/blob/develop/src/useful/fn.clj#L16
13:59TimMcnice!
13:59amacTimMc: neat, much clearer
13:59TimMcThat's a good name.
14:00amalloywell, actually to-fix returns the function like xif; fix applies it immediately. same thing
14:00TimMcamac: Of course, if you are really going to be mapping almost all of the time, predmap would actually be more useful.
14:00amalloy(map (to-fix even? inc, string? read-string) [3 2 "1"]) ;=> (3 3 1)
14:00TimMcamalloy: And I suppose yours takes &args.
14:01TimMcAh, yours does something like case.
14:01amalloymore like condp
14:01TimMcright
14:02amalloyninjudd also built in a macro version with syntax more like update-in for better threading, but i haven't found any uses for it
14:08TimMcamalloy: I could also see reworking it to take multiple args for the predicate and transformation functions.
14:09TimMcThe tricky bit would be the else case.
14:09amalloyTimMc: i think mod-args is a function of the same order as skip-args, right? so you don't get to claim HOF superiority over manutter
14:09amalloy(finally caught up on the backlog)
14:10manutterI did 2 versions of skip-args tho
14:10TimMcIs it? Mine returns a function.
14:10manutter2nd one returned a function instead of just processing its args
14:10TimMcI'm actually not clear on the technical definition of HOF.
14:10amalloyskip-args takes a first-order function and returns a value; mod-args takes two first-order functions and returns a first-order function
14:11amalloyTimMc: http://www.eecs.usma.edu/webs/people/okasaki/jfp98.ps
14:11TimMcthanks
14:14TimMc"map is second-order" means that as far as map is concerned, the input function doesn't need to be higher order, right?
14:14TimMcBecause in (map f ls) map can't actually *know* that f isn't something fancy.
14:15amalloyi can't see a way for the alternative to be meaningful: every function would be nth-order
14:15TimMcexcept inc
14:15amalloyevery function (with any function argument at all)
14:16PupenoI'm running a function and all the errors I'm getting is this: java.util.IllegalFormatConversionException: d != java.lang.String (NO_SOURCE_FILE:0), any ideas how to get more details?
14:16TimMcThere's probably a formalization of that statement using the phrase "point-free equivalent".
14:16amalloy&(format "%d" "test")
14:16lazybotjava.util.IllegalFormatConversionException: d != java.lang.String
14:16amalloyPupeno: ^
14:17TimMcThat's a confusing error message.
14:17Pupenoamalloy: ok… I'll grep all the sources for %d.
14:18amalloyTimMc: yeah, it is. tbh i've never seen it before, but what else could have caused it?
14:22manutterPupeno: you probably should search for other numeric formatting chars too: %f, %x (I think--been a while since I've used old-style C formatting)
14:23Pupenomanutter: the library that most likely is causing this is only using %s.
14:23amalloyTimMc: btw thanks for making me talk about fix/given/etc. i've just found a nice use for the macro version i said i never used
14:23PupenoA stack trace would be kinda useful.
14:24amalloy&(format "%x" "test") ;; i think this throws a different error message
14:24lazybotjava.util.IllegalFormatConversionException: x != java.lang.String
14:24manutter,(format "%s" 20)
14:24clojurebot"20"
14:24manutter,(format "%s" :some)
14:24clojurebot":some"
14:24amalloymanutter: %s calls .toString on its argument, so it's never inapplicable
14:24manutterI was about to draw the same conclusion myself :)
14:25PupenoSo, it's definitely a %d.
14:25amalloyPupeno: so it says no source file, and gives you no stacktrace at all?
14:25Pupenoamalloy: correct.
14:27PupenoI found the REPL sometimes fails to give proper stack traces.
14:28PupenoOk, now I got a file and line number, but it's not helpful: https://gist.github.com/1149795
14:29Pupenobbl
14:29amalloyPupeno: one of the libraries you're require'ing has an error at macroexpansion time, i think
14:30Pupenoamalloy: I see.
14:30amalloyso if you try requiring them one at a time, you can narrow down which it is
14:30amalloynot that this is an ideal solution, but lacking a stacktrace...
14:31TimMcDoesn't *e give you the error object?
14:31TimMcI thought I remember something about that.
14:31amalloyalso a good point
14:32TimMc(.printStackTrace *e)
14:32manutterPupeno: looks like you're both (use)'ing and (require)ing lobos.core, maybe that's an issue?
14:32amalloyshouldn't be
14:33manutterI can't see how it would matter, but it does look like there's a problem with the libs he's pulling in
14:33manutterand it just seemed a little odd
14:33amalloyagreed, he should change it. but it also shouldn't fix the problem if we live in a half-sane world
14:35manutterA half-sane world? WIth computers in it??
14:35TimMcuse just expands to require + refer, right?
14:35manutter:D
14:35amalloyyes
14:36manutterSorry, I'm a PHP programmer by trade, I just have a hard time grasping the concept of sanity in programming.
14:36amalloymanutter: there's still time to jump overboard
14:38manutterDon't think I'm not tempted
14:38amalloyreturn array_filter(function ($x) use ($foo, $bar, $baz) { return ... ;}, $someArray); // not enough punctuation and noise yet
14:39amalloyassuming you're on a version of php that even *has* closures
14:39symboleIs there a way to require a function to accept a type that extends a particular protocol?
14:39Scriptorargh, those don't count as closures
14:40nollidjsymbole: do you know of type annotations on function parameters?
14:40manutterlol, I'm working on a system that has mixins and extensible classes
14:40manutterhome grown PHP extensions
14:40amalloyScriptor: really? i'm curious why you feel that way. rage i understand, but it's hard to see how those could be considered not closures
14:41symbolenollidj: Yes.
14:42nollidjsymbole: protocols automatically generate a corresponding interface. see (doc defprotocol)
14:43Scriptoramalloy: a bit exaggerating, I guess, but mainly because it only allows enclosing of varriables in the same scope
14:43Scriptorer
14:43Scriptorin the scope directly above it
14:43nanarpussanybody familiar with clojurescript?
14:43amalloynollidj: ack no don't use those
14:43symbolenollidj: Thanks.
14:43nollidjamalloy: ok.
14:43nollidjsymbole: maybe you should listen to amalloy instead of me
14:44amalloy(defprotocol Printable (print [this])) (extend-protocol Printable String (print [this] (println this))) ;; String satisfies Printable the protocol, but doesn't implement Printable the interface
14:44nollidjah, right
14:45amalloysymbole: just add a precondition or an assertion that checks ##(doc satisfies?)
14:45lazybot⇒ "([protocol x]); Returns true if x satisfies the protocol"
14:46nanarpussI was curious about the compiled javascript, it seams to not ever define function prototypes; is it just me, or does that sound like a performance bottleneck?
14:46symboleI'll give preconditions a try.
14:47ibdknoxnanarpuss: it would only make sense to do so for objects, which I assume deftype uses, though I haven't looked into it
14:50nanarpusshmm, deftype, i've never used that yet in clojurescript... let me try it now; but in the meantime, anybody else think this could be a point worth looking into? I'm no blackbelt in javascript, so input would be useful...
14:50symboleIs it a good idea to require records that extend a particular protocol as a way to enforce an interface? Seems like passing records would improve readability and create better self documenting code.
14:51symboleAs supposed to passing maps.
14:52symboleI guess that doesn't make much sense, because if some object doesn't extend a protocol, it would signal an error anyway.
14:54symboleI'm just thinking about how to create interfaces which are enforced and not giving the user the ability to just pass anything in.
14:55amalloysymbole: use a statically typed language
14:56ibdknoxnanarpuss: The only advantage provided by prototype functions is that they are not redeclared per instance of an object.
14:57ibdknoxnanarpuss: So since there are no objects in this code, except for those created by deftype, I don't see how there would be a benefit
14:58nanarpussthanks, that is the insight I was looking for.
14:59amalloyso, this isn't really a question or a proposal, but it annoys me that in something like (defn foo [x] (filter (comp bar baz) x)), the comp has to be reconstructed every time the function is called, even though it's a constant. i can (let) it around the defn, but that seems like overkill for something that's not a real performance hog. i guess what i want is automatic constant folding; anyone working on this or know how hard it would be?
14:59technomancyare you sure it isn't fixed at compile-time?
15:00amalloyno, i'm not. i guess it would be simple to test
15:00technomancyI guess it would be fixed to the current value of the var if it were
15:00technomancywhich isn't usually desirable
15:00amalloyright, which seems like the way 1.3 is going
15:01technomancyexcept 1.3 will detect recompilation and clear relevant caches
15:01technomancybut I don't think it would catch this unless you did #'foo
15:01ibdknoxwhat is the real perf loss here?
15:01ibdknoxdid you test?
15:02ibdknoxI can't imagine it's much at all
15:02amalloyibdknox: i agree, but it's galling, just like compiling (+ 1 2) into an actual addition
15:03ibdknoxamalloy: haha yeah.
15:04ibdknoxI bet the real cost is in GC'ing all the extra functions you would make
15:04amalloytechnomancy: okay, i've changed my mind, i'm no longer sure it's easy to test
15:05ibdknoxhaha
15:05technomancythere are a few places where I assumed a new function was being constructed at runtime with an fn literal where I was surprised to see it happened at compile-time
15:06technomancycomp may or may not be the same, I just remember enough to not trust my initial intuition.
15:06ibdknoxhow can it make those guarantees with things like thread-level binding?
15:06ibdknoxI guess in 1.3 you have :dynamic
15:07ibdknoxso you can know up front
15:07bprtechnomancy: how did you find that it was happening at run-time v. compile-time? I'm not sure how I would approach discovering that.
15:07bprerr.. compile-time v. run-time anyhow
15:07arohner,(source comp)
15:07clojurebotSource not found
15:08amalloytechnomancy: on 1.2.1 my simple foo is calling comp at runtime. (disclaimer: to prove this, i redefined clojure.core/comp, so conceivably it might be detecting that and turning off some optimization)
15:08technomancybpr: counting .class files on disk after an AOT run IIRC
15:08technomancybeen a while
15:08bprtechnomancy: ah, pretty simple. thanks
15:08TimMctechnomancy has the bytecode rendered as 24-color bitmaps combined into a 24fps video, and then watches the video out of the corner of his eye.
15:08bprlol
15:08arohnercomp calls (fn []) on every invocation
15:08TimMc*24-bit color
15:09ibdknoxTimMc: who doesn't?
15:09ibdknox:D
15:10TimMcFor fun he writes programs that, when transformed in the above manner, appear to be Shakespearean plays.
15:10TimMcibdknox: n00bs like me who can only read the hex
15:11technomancyTimMc: only for erlang code
15:11technomancyI don't use a lot of actors in clojure
15:11TimMcba-dum tish
15:11ibdknox(inc technomancy)
15:11lazybot⟹ 3
15:11ibdknoxso bad, but it deserved +1
15:12amalloymaybe the easiest solution would be to write a macro that looks for subexpressions consisting only of free variables and factors them out into a let
15:12amalloythen you don't need any compile-time support
15:12technomancyrelevant: http://shakespearelang.sourceforge.net/report/shakespeare/#SECTION00090000000000000000
15:12ibdknoxhah I haven't seen that in a while
15:22edbondHow to deal with peer not authenticated [Thrown class javax.net.ssl.SSLPeerUnverifiedException] in clj-http or other apache http client based?
15:25symboleedbond: I don't understand your question.
15:30edbondsymbole: I am trying to read https response from server with self-signed cert and get an exception.
15:31grumpytoadso in scala you can use zip to combine two collections - is this possible in clojure ?
15:32scgilardicombine as in one collection becomes keys in a map and the other becomes corresponding values?
15:32amalloyscgilardi: zip questions are usually answered with map
15:32amalloy&(map list '[a b c] '[1 2 3])
15:32lazybot⇒ ((a 1) (b 2) (c 3))
15:32grumpytoadhmm.. not sure, too unfamiliar, at best a tuple if that exists
15:33grumpytoadhmm ok.. will try that
15:33scgilardiamalloy: thanks. was trying to understand "combine"
15:33ibdknoxyeah it wasn't clear to me if he actually wanted concat
15:33ibdknoxbut given he was referencing zip..
15:33amalloyscgilardi: yeah, combine is vague. i've learned that "zip" means "i'm coming from haskell or scala and where is the zip function"
15:33amalloythus: map lis
15:34scgilardiyes, looks right. generating an alist
15:34amalloymore like a list of tuples; i think the similarity to an alist is a coincidence
15:35symboleedbond: I don't believe clj-http handles self-signed certificate.
15:35scgilardior it's a rose
15:35amalloyi wonder how haskell/scala do a three-way zip, since they don't have &rest args
15:36grumpytoadyes a list of tuples as i need/want to access each in pairs (x - y coordinates)
15:36TimMcamalloy: ANy reason to use (map list ...) over (map vector ...) here?
15:37amalloygrumpytoad: since you're here, care to satisfy my curiosity? what would you do if you had three lists, [a b], [x y], [1 2], and wanted [(a,x,1), (b,y,2)]?
15:37TimMcin Scala, I presume
15:37amalloyTimMc: two characters shorter. as you're doubtless aware i strive to avoid wasted characters, which tire out my fingers unnecessarily
15:37grumpytoadeuhmm .. hehe i would shriek and run far away
15:38grumpytoadit's possible to have tuples of tuples or some similar construct
15:40grumpytoadso why doesn't merge do what i need ?
15:40amalloybecause it does something different
15:40amalloyand map does do what you need
15:42grumpytoadthough map cannot be used on a LazySeq ?
15:44clj-noobhow to call mysql stored procedure with INOUT parameter using clojure.java.jdbc and print the OUT parameter?
15:46amalloyapparently haskell has zip, zip3, zip4...up to some arity N
15:46amalloy*shudder*
15:47grumpytoadit worked ;-)
15:47ibdknox(map3 list (range 10) (range 10) (range 10))
15:47technomancythe price of currying is eternal arities.
15:48amalloyindeed. i feel silly for actually asking in #haskell instead of just hoogling for it though
15:48ibdknoxdid they scoff at you? lol
15:48grumpytoadwhere does that word come from arities
15:48amalloynah
15:48grumpytoadit's like an indian side dish
15:48amalloythey're friendly dudes over there too
15:49technomancyarities and naan go particularly well together
15:49grumpytoadlol
15:49amalloytechnomancy: just don't order it with the curry?
15:50ibdknoxnow that I think about it, I don't think I heard the term before I started messing with Clojure
15:51opqdonutamalloy: that's because generic type-safe tuples would be a PITA. but you can look up HList if you want
15:51pdkdoes haskell not support varargs or something
15:51technomancygrumpytoad: arity just means the number of arguments a function takes
15:51opqdonut(generic in the sense of having a generic first operation etc)
15:51technomancypdk: that's correct, you can't have currying with varargs
15:51amalloypdk: no. and it has a reason, just like clojure has for using lots of parens :P
15:52grumpytoadtechnomancy: yes, seems so, but it's my first encounter since trying clojure
15:52opqdonutand besides, for many of the use cases of zipN, transpose is the correct function
15:52amalloy*nod*
15:52opqdonutsorry, just venting
15:53amalloyopqdonut: yes, i can see that most of the time you don't really need zipN
15:53grumpytoadcurrying brings a lot of syntax sugar in statically typed languages, AFAICS
15:54amalloyit's clearly something they *wish* they had or they wouldn't have written zip5, but it's something the type system constrains them to be unable to generically express
15:54opqdonutgrumpytoad: I have no idea what you mean with that
15:54amalloywhich doesn't seem like an unreasonable compromise: for all the benefits of haskell's powerful type system, you lose zipN. sounds good to me :)
15:54grumpytoadopqdonut: you get some shortcuts instead of having to wrap functions and their definitions
15:55opqdonutgrumpytoad: yeah sure, partial application is great for writing functional code succinctly
15:56choffsteinHey all. I am using leiningen to manage my projects and compiled & installed one of my libraries (aws-logging) via "lein install". I am using this library in another library, and after importing using "lein deps" I try to require it via the repl ("lein repl"), but get the error: java.lang.NoClassDefFoundError: Could not initialize class aws_logging.core__init (NO_SOURCE_FILE:0). "lein deps" moves the appropriate j
15:56choffsteininto the lib folder -- so the library is definitely there. The project file and core file for aws-logging can be seen here: https://gist.github.com/1150013
15:56choffsteinAny thoughts on this one? I can't seem to figure it out.
15:56AWizzArdAnyone here on Java 7?
15:57TimMcgrumpytoad: bin*ary*, tern*ary*, quatern*ary* <- arities
15:57TimMcoh, and not to mention nullary and unary
15:57grumpytoadso... now i want to curry something.. i guess that's not possible
15:58pdkdid they go through with the stuff talking about closures in java 7
15:58bprdoes anyone know if there's a way to get the byte length of a gloss codec? Assuming that the codec has a constant length? (which I can safely do)
15:58TimMcAs far as I can tell it is a sort of back-formation.
15:58AWizzArdThere is this powerful new class java.nio.file.Paths. I would like to call it from Clojure. How to do it? One Java example is this: Path path = java.nio.file.Paths.get("d:", " temp "","test.txt");
15:58pdkseems goofy as hell having closures alone without the rest of the functional stuff that makes them useful, it's like building an arch with one stone
15:58pdksame story with c++0x
15:59TimMcAWizzArd: (Paths/get ...) probably
15:59AWizzArdWell, I tried that.
15:59AWizzArdThe funny thing is that the get method is overloaded.
15:59TimMcOh, is it varargs?
15:59AWizzArdyes
15:59amalloypdk: no, closures were delayed to jdk8 i think
15:59choffsteinAny idea on my issue, oh clojure wizards?
15:59TimMcIt probably wants a string array
15:59AWizzArdEither it is a vararg String... or an URI
16:00pdkdid that at least suggest other stuff that makes closures useful
16:00TimMc,(doc strings)
16:00clojurebotExcuse me?
16:00pdklike real lambdas/higher order functions
16:00AWizzArdBut the funny thing is that (Paths/get (into-array String ["c:" "temp"])) warns me that a String array can not be cast to an URI
16:00AWizzArdClojure sees that I call with one argument and tries to call the method taking the URI
16:00TimMcHaha, weird!
16:00AWizzArdyup
16:00opqdonuttry hinting?
16:00AWizzArdyes
16:01amalloyAWizzArd: javadoc for the new thingy?
16:01opqdonut^"[java.lang.String;" or however it goes
16:01amalloy^"[Ljava.lang.String;"
16:01opqdonutthat
16:01AWizzArdbut also (Paths/get ^"[Ljava.lang.String;" (into-array String ["c:" "temp"])) doesn't help.
16:02AWizzArdExcetpion: [Ljava.lang.String; cannot be cast to java.net.URI
16:02opqdonutoh, that sucks
16:03choffsteinAnyone ever seen a java.lang.NoClassDefFoundError: Could not initialize class classname__init (NO_SOURCE_FILE:0)
16:03TimMcchoffstein: Yeah, usually when I am flailing around trying to create a new project tree.
16:03choffsteinany idea where it might be stemming from?
16:03TimMcI suppose Clojure can't resolve varargs because of the whole dynamic typing thing.
16:03TimMc*automatically
16:04dnolenAWizzArd: is that a Java var args method?
16:04AWizzArdhttp://download.oracle.com/javase/7/docs/api/java/nio/file/Paths.html
16:05amalloyAWizzArd: it takes two args
16:05amalloyfirst, then an array of more
16:05AWizzArdah okay
16:05AWizzArdGood, that works.
16:05amalloy(inc javadoc)
16:05lazybot⟹ 1
16:05AWizzArdPhew :-)
16:06amalloyi was going out of my mind (a) trying to find the javadocs, and (b) trying to imagine how it could be happening with the method signature you described
16:06AWizzArdExcellent (:
16:06choffsteini'm about to punch a baby seaturtle
16:06choffsteinwhat. the. hell.
16:06AWizzArdI also didn't understand it, especially since hinting also didn't help
16:07AWizzArdBecause Java also needs some way to differentiate.
16:07AWizzArdI just didn't see from that example code that there is a first arg.
16:07technomancychoffstein: what you're describing should work as long as you restart your jvms after running deps
16:07AWizzArdPaths.get("d:", " temp");
16:07choffsteinrestarting my jam?
16:07choffsteinjvm?
16:08TimMcAWizzArd: That's a great example of example code biting you in the ass.
16:11technomancyI would not presume to instruct you in when your jams should be started and/or restarted.
16:11technomancyonly that they should be periodically pumped up.
16:14amalloyjust the other day we were discussing how everything is the jam's fault
16:15choffsteinautocorrect … how I love thee.
16:17choffstein…double-you, tee, eff. Now lein install is broken because it can't find the namespace? What in the world have I done?!
16:17TimMcOoh, that's good news!
16:18TimMcIt probably means something is wrong more globally, not with your project.
16:18choffsteinThis might be a very, very, very stupid question
16:18amalloyTimMc: and if his computer catches fire, it's time to throw a party, because something *very* global is broken?
16:18ibdknoxlol
16:18TimMcWell, at least he will know what is wrong.
16:18ibdknox(inc amalloy)
16:18lazybot⟹ 1
16:19choffsteinBut if library A relies on library B, I build A and do a lein install, then include library A into library C -- C shouldn't have to know anything about B, right?
16:19amalloyhuh. lazybot, when did you forget all the karmas?
16:19technomancychoffstein: you're right; C shouldn't need to mention B in project.clj
16:19leonid__(amalloy)
16:19leonid__,(amalloy)
16:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0)>
16:19choffsteintechnomancy: that is what I thought. herrm…. intriguing.
16:19leonid__,amalloy
16:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0)>
16:19choffsteinmight just try starting a fresh project
16:20leonid__tetris!
16:20amalloyoh, haha. when we renamed him from sexpbot to lazybot, he started reading from the lazybot database instead of the sexpbot database
16:21technomancyremember to merge-with + when you port the data over
16:22choffsteincan you guys check out this gist real quick? https://gist.github.com/1150013
16:22TimMcWHen did sexpbot become lazybot?
16:22choffsteinThe errors are at the bottom. They confuse me.
16:22amalloya few weeks ago?
16:23TimMcchoffstein: As far as I can tell it is some sort of compile-time error in the ns declaration.
16:24choffsteinI would certainly not disagree with that deduction :)
16:24choffsteinI'm just confused as to what the hell it is though.
16:24TimMcYeah, I'm not sure where to go from there.
16:25TimMcI'm guessing it's a case of clojure.core taking its sweet time in checking for nil.
16:26TimMcI can paste that into the REPL without getting that error (and instead getting Not Found errors.)
16:27tufflaxHow do I use :rename within a :use? I'm trying this but it does not work :p' (:use [clojure.string :only (split split-lines replace) :rename {'replace 'srep}])
16:27choffsteinthat confuses me and frustrates me and intimidates me.
16:27amalloyno quotes
16:28technomancytufflax: have you considered require :as?
16:28tufflaxyes briefly
16:28tufflaxbut, I'm just curious now :p
16:28amalloytechnomancy: something wrong with :use/:rename? i mean, when i use clojure.string i usually do requre/as, but use/rename is viable too
16:29TimMcchoffstein: Namespace appears to be looking up a symbol in a hash map, and I'm not sure how that would successfully dispatch to the get method and still cause an NPE.
16:29TimMcUnless that hashmap disallows null, and the symbol is somehow null.
16:30tufflaxamalloy: sigh, tried that but got an unrelated error and didn't check it :p
16:30tufflaxthanks
16:30technomancyamalloy: it works, but it's less obvious
16:30TimMcLooks like a b0rken project.
16:30choffsteinTimMc: So just wipe it and re-create?
16:31TimMcYeah. Create a new project and start reinstating pieces until the error shows up (or doesn't).
16:32TimMcI can't think of anything more clever.
16:33choffsteini'll give it a go.
16:33choffsteinI think it has to do with clj-logging-config to be quite honest, since that's when the project broke.
16:42choffsteinhmmm …. it was in importing the last two classes. that is interesting.
16:56grumpytoadhmm.. enjoying this. thx & laters
16:57amalloywell, i've managed to accidentally give everyone twice the karma they used to have. that's almost like rescuing the old values
16:59amalloythere
17:01mattmitchellis there a built in sum function?
17:01amalloymattmitchell: it's called +
17:01mattmitchellahh ok just use apply :)
17:01amalloyindeed
17:02dnolen,(time (reduce + (range 100000)))
17:02clojurebot"Elapsed time: 167.327 msecs"
17:02clojurebot4999950000
17:02dnolen,(time (apply + (range 100000)))
17:02clojurebot"Elapsed time: 83.701 msecs"
17:02clojurebot4999950000
17:02dnolen,(time (reduce + (range 100000)))
17:02clojurebot"Elapsed time: 54.336 msecs"
17:02clojurebot4999950000
17:02dnolen,(time (apply + (range 100000)))
17:03clojurebot"Elapsed time: 49.355 msecs"
17:03amalloydnolen: practicing your hotspot optimizations?
17:03clojurebot4999950000
17:03dnolenamalloy: ;) I feel like reduce is usually quicker than apply.
17:03dnolen,*clojure-version*
17:03clojurebot{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"}
17:03amalloyi don't see why that would be the case
17:03amalloyapply just calls reduce
17:03amalloy(for the particular case of +)
17:05amalloyand for some functions, of course, apply will be faster than reduce
17:05dnolenamalloy: apply calls reduce when using + ? line?
17:06dnolen,(time (reduce + (range 1000000))
17:06clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
17:06dnolen,(time (reduce + (range 1000000)))
17:06clojurebot"Elapsed time: 523.616 msecs"
17:06clojurebot499999500000
17:06amalloy$source +
17:06lazybot+ is http://is.gd/zh9ARG
17:06dnolen,(time (apply + (range 1000000)))
17:06clojurebot"Elapsed time: 536.39 msecs"
17:06clojurebot499999500000
17:06kephaleoh heh, i didnt know that either
17:06amalloyhttps://github.com/clojure/clojure/blob/1.2.x/src/clj/clojure/core.clj#L809
17:06dnolenamalloy: that's 1.2
17:07dnolenamalloy: but you're right + calls reduce1 in 1.3
17:07grumpytoad,(repeat 1)
17:07clojurebot(1 1 1 1 1 ...)
17:07amalloyright. and if it changed, i would expect apply to be the one that got faster, not reduce
17:07grumpytoadheh no explode? shame
17:10amalloy&(time (= (apply str (repeat 1e7 "test"))))
17:11amalloyhm. too many zeros
17:11lazybotExecution Timed Out!
17:11amalloy&(time (= (apply str (repeat 1e5 "test"))))
17:11lazybot⇒ "Elapsed time: 112.653346 msecs" true
17:11amalloy&(time (= (reduce str (repeat 1e5 "test"))))
17:11lazybotExecution Timed Out!
17:14mattmitchellis there a function that is somewhat similar to partition, except that it creates a max number of groups based on a number? For example: (my-group-fn 2 [1 2 3 4 5 6 7 8]) => [[1 2 3 4] [5 6 7 8]])
17:14clojurebotRoger.
17:14dnolenamalloy: huh interesting. for + case, reduce / apply are pretty much the same.
17:14amalloydnolen: sure, because no interesting optimizations can happen for +
17:15amalloybut for str, they can; and only apply can take advantage because it knows all the args ahead of time
17:15amalloymattmitchell: https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L51
17:16mattmitchellamalloy: slice yeah! that's it. thank you.
17:16amalloymattmitchell: well, that's an external library you'll have to depend on
17:16amalloyit's not in core or anything
17:18kephalei wonder about + with something like a recursive (map + (partition 2 coll))
17:19aaelonyhi all, I'm trying to understand java inter-op better and dealing with 3 java objects from the jets3t.service library.. I'm currently not specifying the order of the classes correctly as listObjects should be associated with s3Service and not S3Bucket....
17:19aaelony (. s3service (.getObject (S3Bucket. bucket-name) (. (.listObjects (S3Bucket. bucket-name)) (.getKey ))))
17:19aaelonyjava.lang.IllegalArgumentException: No matching field found: listObjects for class org.jets3t.service.model.S3Bucket (NO_SOURCE_FILE:0)
17:20aaelonyI'm likely abusing the dot macro somehow
17:26TimMcLooks like a good opportunity for the stitching macros.
17:27TimMcAnyway, I recommend sequentially binding those values to names so you can see what you are doing.
17:27aaelonyI think it is the dot special form, but something is not quite right
17:27aaelonyperhaps getting more coffee will help...
17:27TimMc(let [bucket (S3Bucket. bucket-name), objects (.listObjects bucket)] ...)
17:28raekaaelony: could you write what you are trying to do in java syntax?
17:28aaelonysure
17:28TimMcaaelony: (.listObjects (S3Bucket. bucket-name)) is saying new S3Bucket(bucket-name).listObjects()
17:29aaelonyit is something like this:
17:29aaelonyfinal S3Bucket s3Bucket = new S3Bucket(bucketName);
17:29aaelonyfor (final S3Object s3Object : s3Service.listObjects(s3Bucket)) {
17:29aaelonyS3Object completeObject = s3Service.getObject( s3Object.getKey() );
17:29TimMcIs s3Service a class or an object?
17:30aaelony=> (class s3service)
17:30aaelonyorg.jets3t.service.impl.rest.httpclient.RestS3Service
17:30aaelonyit is an instance of that class with credentials needed to talk to the bucket
17:30TimMcah, OK
17:31aaelonysomehow my chaining is garbled
17:31TimMcs3Object vs. S3Object is pretty confusing also
17:31aaelonyyes, sorry
17:32aaelonys3Object is just an instance of an S3Object
17:33aaelonyI am referencing this: http://jets3t.s3.amazonaws.com/toolkit/code-samples.html
17:33TimMcSo yeah, naming your intermediate values (and naming them well) is probably the best approach to finding your problem.
17:33raek(let [s3-bucket (S3Bucket. bucket-name)] (for [s3-object (.listObject s3-service)] (let [complete-object (.getObject s3-service (.getKey se-object))] ...))
17:33raekthis would be a literal translation of your code
17:34raekif the for body only does side-effects, you should replace for with doseq
17:34aaelonyok. cool. let me study this.
17:35dnolenamalloy: still don't agree w/ you on the diff between apply and reduce perf. apply str is fast because of special case StringBuilder hack in str
17:35dnolenapply does not know how many arguments it gets, it uses a Seq
17:41aaelonyhmmm, how would I translate this? s3Service.listObjects(s3Bucket)
17:42aaelonywould it be: (. (s3Service (.listObjects s3Bucket))) ???
17:43ShreeMulayalright all, I'm trying to solve http://www.4clojure.com/problem/21#prob-title but I keep getting the following error message: You tripped the alarm! nth is bad!
17:43ShreeMulayThe following is my solution: (fn [[f & rest] x] (if (= 0 x) f (recur rest (dec x))))
17:43ShreeMulaywhy am I getting that problem?
17:43TimMcaaelony: (.listObjects s3Service s3Bucket)
17:44TimMc,(macroexpand-1 '(.listObjects s3Service s3Bucket))
17:44clojurebot(. s3Service listObjects s3Bucket)
17:44aaelonythanks, TimMc... pondering it...
17:46TimMcaaelony: dot by itself gives you the Java ordering: (. object method args...)
17:47TimMcA symbol beginning with a dot is a special form that makes for a functional programming ordering of names: (.function object args...)
17:47TimMcIt expands into the other form.
17:47aaelonyTimMc: thanks.. this worked but brought me to a org.jets3t.service.S3ServiceException: S3 GET failed ...
17:47TimMcAh, but now you have the right syntax, it would seem!
17:47aaelony... The specified key does not exist
17:47aaelonygetting closer ;)
17:48aaelonyTimMc: Thanks for now...
17:53amalloydnolen: right. that's why apply str is faster, no question. my point is that, when apply/reduce produce the same results, reduce will be faster iff it gets parallelized, and apply will be faster iff there's a special-case "global" optimization available like for str. i don't think it's out of the question to suppose that functions other than str will have global optimizations available
17:53amalloyShreeMulay: destructuring ([f & rest]) expands into a use of nth
17:54amalloykinda annoying imo, but it means you can't use it to solve the nth problem
17:55Raynesamalloy: That is very unfortunate.
17:55amalloydnolen: for example, conj could be written so that (apply conj foo xs) used transients like into does
17:56amalloyin which case, apply conj would be faster than reduce conj
17:56amalloyRaynes: i agree, but what can we do?
17:56RaynesNothing, I suppose. I wish sandboxing wasn't so unscientific.
17:56dnolenamalloy: I recall having this conversation with you before. Yuck.
17:57dnolen;)
17:57amalloy*chuckle*
17:59Raynesamalloy: I don't know why anybody would write such an awful sandboxing library when sandboxing is so impossibly diffi... Oh wait, that was us wasn't it?
18:00Chousuke:P
18:00ChousukeIt's kind of difficult to let people do whatever they want without letting them to do whatever they want
18:00amalloyimo the root cause of this particular issue is that (let [[x y] foo]) uses nth instead of first/rest
18:01arohnerholy crap, why didn't anyone tell me midje is awesome?
18:01AWizzArdarohner: example please
18:01Raynesamalloy: Submit a patch. And then go ahead and decline it and save them the trouble. ;p
18:01amalloysrsly
18:01arohnerAWizzArd: https://github.com/marick/Midje/wiki/Midje-mode
18:03AWizzArdarohner: I saw that mode but never took a closer look at it. I will watch that vid now.
18:05amalloyarohner: those are terrible keybindings
18:06arohneramalloy: so rebind them. it is emacs after all
18:06amalloyi know
18:06arohnerthe point is, there is an emacs mode, and it works
18:07amalloyit's just i'm morally offended that someone would create a minor mode that uses C-c <letter> bindings, which are specifically reserved for the user's personal use
18:07amalloy*grumble grumble get off my lawn*
18:08Raynesamalloy: We must hunt him.
18:18technomancyamalloy: http://p.hagelb.org/pay.png
18:19amalloytechnomancy: i'm trying to find the "right" bindings for minor modes. what is it, C-x <letter>?
18:43wilfredhwhat's the Clojure equivalent of Python's zip()? Do I have to use map?
18:43jeremyheiler,(doc zipmap)
18:43clojurebot"([keys vals]); Returns a map with the keys mapped to the corresponding vals."
18:43jeremyheilerwilfredh: does that work for yoU?
18:44wilfredhI was hoping for a list of lists, but I could make do with that
18:45wilfredhthanks :)
18:45amalloy(12:34:47 PM) grumpytoad: so in scala you can use zip to combine two collections - is this possible in clojure ?
18:45amalloy(12:36:17 PM) amalloy: &(map list '[a b c] '[1 2 3])
18:45amalloywilfredh: ^
18:46wilfredhoh, of course. Perfect.
18:46amalloyand now i've added another language to my list of "languages from which people ask about zip"
18:46raekwilfredh: map vector or map list... choose your preferred tuple type :-)
18:47wilfredhraek: exactly. Python mindset still showing through...
18:55technomancyamalloy: if you still need it: (info "(elisp)Key Binding Conventions")
18:57amalloytechnomancy: yeah, i found that. it seems to be a list of things not to do
18:57amalloyno suggestion about things to actually do, for minor modes
18:57technomancy"Sequences consisting of `C-c' followed by any other punctuation character are allocated for minor modes." ?
18:58amalloyah, yes. i guess that seemed like a pretty small set of things, and i thought there were more
18:58amalloybut in Keymaps and Minor Modes i just found "The key sequences bound in a minor mode should consist of `C-c'
18:58amalloyfollowed by one of `.,/?`'"[]\|~!#$%^&*()-_+='", and i guess it couldn't get any clearer
19:32amalloyomg. i just realized i can stop writing (apply concat (for [x xs] (make-a-list x))), and instead write (for [x xs, list-item (make-a-list x)] list-item)
19:39amalloy&(time (dorun (apply concat (for [x (range 100)] (range x)))))
19:39lazybot⇒ "Elapsed time: 24.139846 msecs" nil
19:40amalloy&(time (dorun (for [x (range 100), y (range x)] y)))
19:40lazybot⇒ "Elapsed time: 896.231447 msecs" nil
19:40amalloythese two are generating the same sequence (per my comment above). does anyone know why the second would be so much atrociously slower? i don't really understand how `for` works internally
19:40tufflaxamalloy i think it's a list monad
19:41tufflaxin the beginning of http://intensivesystems.net/tutorials/monads_101.html you can learn about them. more than that i dunno
19:45tufflaxhm, maybe not. the source is some kind of monster
19:45tufflaxI was just guessing really
19:46amalloyi'm now wondering if maybe it's to do with chunking. the first one preserves chunks, and the second one might be ripping them apart
19:52bpramalloy: that is odd
19:52bprthe timings, that is
19:53amalloybpr: i tried replacing (range x) with (take x (iterate inc 0)), and that gets the timings closer together. so i think it probably is a chunking thing
19:54amalloyie, the version with apply concat gets 25 times slower and the version without stays about the same :P
19:54bprwow
20:52amalloybpr: on further investigation, it seems to be something weird about lazybot's environment. in my repl, and on two other bots, the runtimes are comparable
20:55amalloyspecifically, he's always running with a profiler attached, so that when he starts misbehaving (as happens once a month or so) i can see where all the CPU is going; probably the profiler is slowing down allocs
21:04amalloyninjudd: what do you think about https://gist.github.com/f30273d77ae8301d2852?
21:05amalloyhm, wrong channel. oh well, he's in here too
21:30livingstonI'm having trouble with a macro that ultimately calls defn it's putting my parameter names in a namesapce and the complier really doesn't want them there.
21:30livingstonhow do I get around this: git://gist.github.com/1150606.git
21:32livingstonsorry I guess that's actually here: https://gist.github.com/1150606
21:37livingstonthe answer is that I used free variables instead of gensyms it should be kb-creator#
21:38zakwilsonlivingston: also google variable capture in Clojure if you find that you want variable capture in your macros. It's dangerous, of course, but useful.
21:39livingstonthanks. I'm familiar with capture, I just didn't realize that's how it was done in clj, (I'm used to commonlisp)
22:01amalloylivingston: it's usually not - when possible you should use gensyms
22:02livingstonamalloy: what's usually not?
22:03amalloyusing symbol capture is not usually how it's done. or were you saying you didn't realize you have to do it at all
22:03amalloyif you want to make it accessible from within the expanded body you can't use a gensym, so you can either make the user pass in the name to bind to, or do something anaphoric
22:04livingstonI just didn't realize that's how it was done in clj. I understand avoiding capture in general. that's just not a case were I think that it would have been an issue in say commonlisp so I wasn't thinking about it.
22:04amalloyeg, you could use it as (kb-test test-kb-up test-triples [kb] (is kb))
22:04amalloyokay
22:04amalloybasically clojure defaults to making accidental capture impossible
22:05PupenoI wrote a post called Why I love Lisp, featuring Clojure… yesterday it got 11k views :)
22:05livingstonamalloy: yeah. it would have been generally safe there, but it's guaranteed safe this way.
22:06jeremyheilerPupeno: Care to share the link?
22:07Pupenojeremyheiler: sure: http://pupeno.com/2011/08/16/why-i-love-lisp/
22:07PupenoSomeone +1 it on G+, I wonder if I could find those comments, if any.
22:13jeremyheilerPupeno: nice little blog post +1
22:13livingstonso I can trigger mvn clojure:test to run with the test phase, but it doesn't show up in the test report (probably because the java test plugin is unaware of the clojure?) is there a way to make it aware?
22:13Pupenojeremyheiler: thanks :)
22:16PupenoIs it possible to use a library from source instead of a jar? with lein? how?
22:16arohnerPupeno: yes, read the section about checkout dependencies in the lein FAQ
22:17Pupenoarohner: thanks.
22:20mattmitchelli have a question about modifying maps. I find myself doing a lot of this: https://gist.github.com/1150671 is there a better way than if... else... if else... ? i get the feeling that monads could help me, but i haven't been able to completely understand how to apply them. Not sure if I'm explaining myself well enough, but I guess the example (and a lot of stuff I write) feels procedural, and not very functional. Anyone else be
22:20mattmitchellhere and beyond?
22:21mattmitchellmaybe bad example... but
22:21livingstonwoah
22:21mattmitchellit's the procedural thing that feels wrong
22:22hiredman(update-in m [:id] (fn [m] ...))
22:22livingstonmattmitchell: there's no variability in that... I'm assuming one of those is a parameter of some function?
22:24mattmitchelllivingston: could be yes. A lot of code just seems to be this stack within a "let", then a series of "if"'s, and merging etc.
22:24mattmitchellhiredman: thanks, will check that out
22:24PupenoHow should I run the REPL so it picks the checkouts if I'm not using lein to run the REPL?
22:25amalloymattmitchell: there's something in ninjudd's/my useful that might make this a little more visually pleasing
22:25livingstontypically rows or nests of if's beg for cond
22:26mattmitchellamalloy: ok great. i think i was just browsing through that this afternoon
22:26livingstonbut this is just weird.
22:26mattmitchelllivingston: ha well, my example? yeah, need something real world.
22:26livingstoncould you share a more real function, that might help
22:27amalloymattmitchell: https://gist.github.com/1150681
22:27mattmitchelllivingston: i would have to dig around a little bit. I'll come back with something that better describes the "issue" I'm having.
22:28amalloyuses useful.fn/given
22:28livingstonmattmitchell: a more specific question will get more specific feedback, I'm sure.
22:29mattmitchelllivingston: yep totally. i'll post a real example tomorrow sometime
22:29mattmitchellamalloy: that's nice, yeah more declarative and less ify
22:29livingstona list of functions and reduce also comes to mind, but again... depends on what
22:30mattmitchelllivingston: using apply and reduce on a list of functions?
22:30amalloyjust reduce, really
22:31livingstonjust reduce with an initial value being your map that's being progressively modified, each function returns a new map.
22:31amalloy&(let [fixers [#(if (= 1 (:id %)) (assoc % :id 2) %)] (reduce #(%2 %1) {:id 1} fixers))
22:32lazybotjava.lang.IllegalArgumentException: let requires an even number of forms in binding vector
22:32amalloy&(let [fixers [#(if (= 1 (:id %)) (assoc % :id 2) %)]] (reduce #(%2 %1) {:id 1} fixers))
22:32lazybot⇒ {:id 2}
22:32mattmitchellahh that's interesting, cool
22:33livingstonI mean there are a million things to do (merge (if test {new-key-vals} {}) (merge (if test2 {other-new} {}) original)) etc.
22:35mattmitchelllivingston: oh ok, multiple args to merge, need to remember that.
22:36livingstonthat too
22:57srid(find-doc "map") prints a huge list of sections; is there a way to prune it to show only the one I intended (which is the core map function)?
22:58livingston,(doc find-doc)
22:58clojurebot"([re-string-or-pattern]); Prints documentation for any var whose documentation or name contains a match for re-string-or-pattern"
22:58amalloy&(doc map)
22:58lazybot⇒ "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. A... http://gist.github.com/1150725
22:58livingston,(doc doc)
22:58clojurebot"([name]); Prints documentation for a var or special form given its name"
23:00sridah, thx. just figured that by looking at http://clojure.org/cheatsheet
23:14livingstonnice
23:19amalloy&(doc *print-level*)
23:19lazybot⇒ "; *print-level* controls how many levels deep the printer will print nested objects. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum level to print. Each argument to print is at level 0; if an arg... http://gist.github.com/1150742
23:20amalloyhm, not quite
23:20amalloy&(doc *print-length*) ;; srid
23:20lazybot⇒ "; *print-length* controls how many items of each collection the printer will print. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum number of items of each collection to print. If a collection con... http://gist.github.com/1150746