2011-08-16
| 00:24 | amalloy | i guess we'll never know |
| 00:30 | grant_ | it was a macro bug :) |
| 01:32 | grant_ | is there a good way (in emacs/slime) to stop a thread thats spamming me with printlns in the background? |
| 01:42 | ShreeMulay | if anyone's awake and can help me with getting the following loop to work, I'd LOVE it! |
| 01:42 | ShreeMulay | (fn [n] (loop [n] (if (empty? (next n)) (n) (recur (next n))))) |
| 01:43 | ShreeMulay | trying to solve http://www.4clojure.com/problem/19#prob-title |
| 01:46 | kephale | the true clause |
| 01:49 | amalloy | grant_: go back in time and don't start that thread |
| 01:50 | amalloy | ShreeMulay: you don't want (n), which would call n as a function |
| 01:50 | cemerick | ShreeMulay: Loop needs pairs of binding name/values in its vector. Why next? And (n) won't ever work. |
| 01:51 | grant_ | amalloy: but that's O(make a time machine) :( |
| 01:51 | amalloy | cemerick seems to be a better reader than me |
| 01:52 | cemerick | I don't know what the hell I'm still doing up, but I'm glad I'm not ground beef yet. |
| 02:14 | amalloy | hm, 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:17 | jeffrey04 | erm, may I know what these warning means? |
| 02:17 | jeffrey04 | Warning: *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:17 | jeffrey04 | get those after using duck-streams in my script |
| 02:19 | amalloy | duck-streams is super-old and you're using it with the super-new clojure 1.3 |
| 02:20 | jeffrey04 | amalloy: oh, ok |
| 02:23 | amalloy | honestly 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:24 | jeffrey04 | so if i don't use duck-streams |
| 02:24 | jeffrey04 | erm... what should i use? |
| 02:24 | jeffrey04 | BufferedReader? |
| 02:24 | clojurebot | Reader syntax of collections has gotchas |
| 02:24 | amalloy | *chuckle* thanks, clojurebot |
| 02:24 | jeffrey04 | lol |
| 02:24 | amalloy | jeffrey04: most of duck-streams is in clojure.java.io now |
| 02:25 | amalloy | just like you shouldn't use str-utils2 or whatever nonsense, because it's in clojure.string now |
| 02:25 | jeffrey04 | http://richhickey.github.com/clojure/clojure.java.io-api.html <- this |
| 02:25 | jeffrey04 | ? |
| 02:26 | amalloy | http://clojure.github.com/clojure/clojure.java.io-api.html |
| 02:26 | amalloy | oh, and slurp/spit are in clojure.core |
| 02:27 | jeffrey04 | erm is there a tutorial on how to read a file the proper way? |
| 02:29 | amalloy | i guess it depends what you mean by "read a file" and "the proper way" |
| 02:30 | jeffrey04 | amalloy: is clueless right now lol |
| 02:30 | amalloy | (probably also the definition of "tutorial" will come into play) |
| 02:30 | amalloy | jeffrey04: what do you want to do with the contents of the file you're reading? |
| 02:30 | jeffrey04 | create a hadoop sequencefile |
| 02:30 | jeffrey04 | http://stackoverflow.com/questions/7062327/generating-a-sequencefile/7063762#7063762 |
| 02:30 | amalloy | then you probably don't want to read a file at all, just ask hadoop to do it? |
| 02:32 | jeffrey04 | i still need to pass the content to hadoop sequencefile writer no? |
| 02:32 | amalloy | or, frankly, this looks like a pretty complicated first task in clojure |
| 02:33 | jeffrey04 | lol |
| 02:34 | jeffrey04 | if 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:36 | amalloy | if you're writing a sequence file, can't you do that offline in whatever language you want? |
| 02:37 | jeffrey04 | afaik sequencefile is usually created with some hadoop api |
| 02:37 | jeffrey04 | http://hadoop.apache.org/common/docs/current/api/org/apache/hadoop/io/SequenceFile.Writer.html |
| 02:42 | amalloy | well, i can point you at ##(doc line-seq) and ##(doc clojure.java.io/reader) |
| 02:42 | lazybot | (doc line-seq) ⇒ "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader." |
| 02:42 | lazybot | (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:42 | amalloy | since i guess you want to do something for each line of the input file |
| 02:50 | jeffrey04 | amalloy: thanks |
| 04:59 | lnostdal | does lein have a "verbose mode"? .. seems it hangs waiting around for something at times (e.g. when doing `lein uberjar' just now) |
| 05:47 | pyr | doseq has no :when guards ? |
| 05:47 | pyr | it seems |
| 05:50 | ejackson | hmm... that's contrary to the docs :( |
| 05:51 | pyr | i may be using it wrong |
| 05:52 | pyr | ,(doseq [a [0 1 2]] :when even? (println a)) |
| 05:52 | clojurebot | 0 |
| 05:52 | clojurebot | 1 |
| 05:52 | clojurebot | 2 |
| 05:53 | pyr | same thing for #(even? a) |
| 05:53 | pyr | :let works though |
| 05:54 | mrBliss | ,(doseq [a [0 1 2], :when (even? a)] (println a)) |
| 05:54 | clojurebot | 0 |
| 05:54 | clojurebot | 2 |
| 05:55 | pyr | erf |
| 05:55 | pyr | it's too early i guess... :) |
| 05:56 | thorwil | how can i turn this naive recursive function into a loop-recurse? http://paste.pocoo.org/show/459250/ |
| 05:56 | pyr | mrBliss: thx |
| 06:00 | clgv | thorwil: if you keep it lazy you won't need loop-recur |
| 06:01 | clgv | thorwil: otherwise you need some "work-queue" |
| 06:02 | clgv | thorwil: does the result have to resemble the hierarchic structure of the data? or is a flat collection as output ok? |
| 06:08 | clgv | thorwil: here is a recur version for a flat result list: http://paste.pocoo.org/show/459254/ |
| 06:08 | thorwil | clgv: the queries are via appengine datastore, so nothing lazy about that, i assume |
| 06:09 | clgv | thorwil: You used map so your function itself is lazy |
| 06:09 | thorwil | clgv: in the end i want to render this in html with nested divs |
| 06:10 | clgv | thorwil: 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:13 | thorwil | clgv: ok, i'll have a look at prewalk and/or using an accumulator. thanks! |
| 06:14 | clgv | thorwil: but I think your lazy implementation via map should be fine too |
| 06:15 | clgv | unless you force it all at once - that might blow the stack |
| 06:16 | thorwil | clgv: do i not have a problem with a growing stack, given my implementation? |
| 06:16 | thorwil | bbiab |
| 06:17 | clgv | not in general - that depends how you use the lazyseq that is the result of your function |
| 07:10 | lnostdal | seems 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:12 | lnostdal | (the ring jetty adapter) |
| 07:14 | manutter | Hmm, 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:15 | lnostdal | ok, clojure being a dynamic language needs to present run-time errors; compile-time ain't enough :) |
| 07:16 | lnostdal | ..digging through jetty.clj now, ...hm |
| 07:17 | manutter | I'm not sure about Ring proper, but I know Compojure likes to use a wrap-stacktrace middleware that does exactly that |
| 07:17 | manutter | tho now that I think about it, I believe Ring is the source for that middleware |
| 07:19 | lnostdal | http://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:20 | manutter | I wonder if the exception would bubble-up to slime without the middleware? I suspect not, due to threads. |
| 07:21 | lnostdal | dunno .. i'm only using the jetty middleware at the moment |
| 07:21 | manutter | There 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:22 | manutter | I bet you could do something similar with embedded code that would "read" from an atom or something |
| 07:22 | manutter | then it would work across threads. |
| 07:26 | clgv | manutter: the break or also called debug-repl from JoC is great |
| 07:35 | manutter | Yeah, I was pretty impressed |
| 07:35 | manutter | I tried to write one in PHP, but oh well :P |
| 08:08 | wunki | anyone 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:10 | raek | wunki: 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:10 | wunki | raek: would this work for compojure and jetty? |
| 08:11 | raek | moustache is a lib that does routing and middleware composition. (it fills the same place as compojure) |
| 08:11 | raek | I suspect compojure can do something similar |
| 08:13 | wunki | raek: could you explain what ``app ["a"]`` stands for? |
| 08:13 | wunki | is that a set of routes? |
| 08:14 | manutter | wunki: I havent tried it in Compojure, but there's no reason it wouldn't work |
| 08:14 | raek | yes, app is the route macro from Moustache |
| 08:14 | wunki | manutter: I'm really green on this, are you willing to create a gist example for me/ |
| 08:15 | manutter | well, willing in theory, but I'm at work, so I can't really take the time to go into detail |
| 08:15 | wunki | manutter: ok, no problem, will do trial-by-error |
| 08:15 | manutter | why do you want to use different wrappers for different parts of your app? |
| 08:16 | wunki | manutter: because I have some views that need a authentication wrapper (creates a basic-auth request) |
| 08:16 | manutter | ah, that makes sense |
| 08:16 | wunki | raek: so, that would be defroutes in compojure? |
| 08:16 | raek | wunki: 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:16 | manutter | You might want to look up the sandbar lib if you haven't already |
| 08:17 | manutter | sandbar lets you specify access on a route-by-route basis |
| 08:17 | raek | wunki: basicaly yes. Moustache and Compojure fill the same function, but you do things in different styles |
| 08:17 | wunki | ok, thanks for the help guys, I'm going to try some stuff out |
| 08:18 | raek | wunki: so where do you put the middleware in your defroutes form? |
| 08:19 | wunki | raek: https://gist.github.com/37acc39ae1856652f1cf |
| 08:20 | wunki | defroutes combines all the routes, then app adds all the middleware |
| 08:20 | wunki | finally, app get's served |
| 08:21 | wunki | I would like to have a "auth-app" or something, that add the authentication wrapper also |
| 08:21 | wunki | and serve those two together |
| 08:21 | raek | wunki: this might work: in the (defroutes routes ...) code, maybe you can wrap the individual items there with middleware |
| 08:22 | wunki | raek: how do I wrap something? :/ |
| 08:22 | raek | (defroutes routes (-> episto.users.core/user-routes wrap-foo wrap-bar) (-> episto.auth.core/auth-routes wrap-baz wrap-quux)) |
| 08:22 | raek | wunki: like you do in (def app |
| 08:22 | raek | a wrapper is just a function that takes a handler and returns a wrapped handler |
| 08:24 | manutter | Yes, that should work fine in Compojure |
| 08:24 | wunki | ok, I'm gonna do that. Don't want to repeat the wrappers for every route though. Will look how to DRY that up |
| 08:24 | manutter | If 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:25 | raek | wunki: you can compose wrappers just like ordinary functions |
| 08:25 | wunki | raek: good idea, will do that |
| 08:25 | raek | (def wrap-json-and-error-handling (comp wrap-error-handling wrap-json-params)) |
| 08:26 | manutter | I believe you could use defroutes more than once |
| 08:27 | manutter | (defroutes auth-routes foo bar baz), then wrap auth-routes, then (defroutes routes regular unleaded auth-routes) |
| 08:28 | manutter | or rather (defroutes routes regular unleaded wrapped-auth-routes) |
| 08:28 | manutter | I'm leaving a couple steps as "an exercise for the reader" but you get the idea |
| 08:30 | raek | but doesn't he already do that? |
| 08:32 | manutter | I 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:33 | manutter | and I'm assuming he's using defroutes in episto.auth.core--if so, he's 90% of the way there |
| 08:33 | wunki | sorry guys, just got some people over. I'm logging this however :) |
| 09:05 | manutter | ,(doc println) |
| 09:05 | clojurebot | "([& more]); Same as print followed by (newline)" |
| 09:06 | manutter | yay, clojurebot is alive again |
| 09:06 | manutter | clojurebot: help |
| 09:06 | clojurebot | http://www.khanacademy.org/ |
| 09:06 | manutter | lol, ok, that's actually MORE help than I necessarily wanted. |
| 09:58 | pyr | ,(let [a "s"] (case (class a) java.lang.String :found :not-found)) |
| 09:58 | clojurebot | :not-found |
| 09:58 | pyr | ,(class "s") |
| 09:58 | clojurebot | java.lang.String |
| 09:59 | pyr | i'm not getting what I'm doing wrong |
| 09:59 | pyr | i know that the right idiom is multi-method in this case |
| 10:00 | manutter | ,(let [a "s"] (class a)) |
| 10:00 | clojurebot | java.lang.String |
| 10:01 | manutter | ,(let [a "s"] (case (class a) 'java.lang.String :found :not-found)) |
| 10:01 | clojurebot | :not-found |
| 10:01 | manutter | hrmmm |
| 10:01 | Bronsa | ,(let [a "s"] (case (class a) 'java.lang.String :found (class a))) |
| 10:01 | clojurebot | java.lang.String |
| 10:01 | manutter | ,(= (class "s") java.lang.String) |
| 10:01 | clojurebot | true |
| 10:01 | pyr | yep tried all of this |
| 10:02 | manutter | ,(doc case) |
| 10:02 | clojurebot | "([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:04 | manutter | ,(let [a "s"] (case (class a) (class "s") :found :not-found)) |
| 10:04 | clojurebot | :not-found |
| 10:04 | manutter | lol |
| 10:04 | manutter | that's messed up |
| 10:05 | lobotomy | ,(let [a 1] (case (< a 2) :yes :no)) |
| 10:05 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: true> |
| 10:05 | lobotomy | hmm, apparently i don't know how to use case ;p |
| 10:06 | tufflax | ,(let [a 1] (case (< a 2) true :yes :no)) |
| 10:06 | clojurebot | :yes |
| 10:06 | raek | pyr: case uses compile-time constants (and does not evaluate them). so you get the java.lang.String _symbol_, not the class. |
| 10:06 | manutter | case is a simplification of cond -- it works faster because the first element of each pair has to be a literal |
| 10:06 | pyr | raek: that's what I figured by running macroexpand |
| 10:07 | raek | pyr: 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:07 | raek | pyr: https://gist.github.com/997652 |
| 10:08 | pyr | raek: thanks |
| 10:08 | pyr | raek: i was misled by this article: http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure |
| 10:09 | raek | hrm. that code doesn't work, right? |
| 10:09 | pyr | nope |
| 10:09 | raek | "that code" = (case (class a) ...) |
| 10:09 | pyr | yep |
| 10:10 | TimMc | Anyone know of an Clojure graph layout libraries along the lines of Vijual? |
| 10:11 | manutter | lacij? |
| 10:11 | TimMc | Ooh, thanks! |
| 10:11 | manutter | Don't know anything about either one, but I think I saw something about graph layout in connection with lacij |
| 10:12 | manutter | daveray is also playing with something he calls Dorothy |
| 10:12 | manutter | clojure interface to graphviz |
| 10:12 | TimMc | (I'm getting fed up with client-side (JS) graph layout libraries.) |
| 10:14 | manutter | I hear ya :) |
| 10:16 | TimMc | I'm tempted to use a server-side lib to generate layouts and then animate any differences on the client side, |
| 10:17 | TimMc | . |
| 10:20 | cemerick | raek, 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:21 | manutter | ,(let [a "s"] (case (str (class a)) "java.lang.String" :found (str (class a)))) |
| 10:21 | clojurebot | "class java.lang.String" |
| 10:22 | manutter | *snap* |
| 10:24 | wunki | what do you call a "->" in clojure? |
| 10:24 | cemerick | It's a threading macro. |
| 10:25 | wunki | cemerick: thanks, looking it up |
| 10:26 | wunki | ah, good piece: http://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/ |
| 10:26 | cemerick | also: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/ |
| 10:27 | wunki | I started reading the book "The Joy of Clojure" yesterday, awesome book |
| 10:43 | TimMc | manutter: 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:44 | manutter | Yeah, sounds like a tricky set of requirements |
| 10:45 | TimMc | (Background: I'm trying to write a good display for what is effectively an RDF explorer.) |
| 11:21 | duck1123 | TimMc: sounds interesting. github link? |
| 11:22 | TimMc | duck1123: Sorry, it's a project for work. |
| 11:22 | TimMc | Although, any supporting code I write might make it onto GitHub. |
| 11:24 | TimMc | This 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:25 | TimMc | Project leader is pretty friendly to open-sourcing components, though. |
| 11:26 | duck1123 | That's cool. It's good to see companies give back |
| 11:28 | TimMc | Yeah, it can be a really nice symbiosis. |
| 11:45 | Pupeno | Where do you put the connection calls when using lobos? |
| 11:51 | manutter | Looks like you can def a map with the db connection specs, then pass the map to (with-connection db-spec &body) |
| 11:52 | manutter | check out the code at the bottom of the frontend docs on the Lobos site |
| 11:56 | cemerick | What's the state of Clojure sandboxes these days? Is clojail the only game out there (aside from the one embedded in clojurebot)? |
| 11:58 | TimMc | clojurebot doesn't use clojail? |
| 11:59 | TimMc | I kind of assumed it did. |
| 11:59 | cemerick | clojurebot predates clojail |
| 12:00 | cemerick | It'd be nice if there was one obvious sandboxing option. |
| 12:01 | Pupeno | manutter: 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:04 | TimMc | cemerick: When it comes to security, I kind of like having diversity. |
| 12:06 | TimMc | Although... that is predicated on having at least two *comprehensive* options. |
| 12:07 | cemerick | TimMc: Probably wise. But, when the different options aren't readily comparable (short of understanding their source top to bottom), it's tough. |
| 12:08 | dnolen | nice looks like the pattern matching / predicate dispatch talk at NYC Clojure tomorrow will definitely get recorded |
| 12:08 | TimMc | cemerick: Is your abhorrence based on choice paralysis or the problem where 100% of the libraries solve 80% of the problem? |
| 12:08 | technomancy | dnolen: woo |
| 12:09 | cemerick | TimMc: I was trolling a bit, but I think choice paralysis is a big source of friction generally. |
| 12:09 | cemerick | Just about every X is an 80% solution in any case. |
| 12:10 | TimMc | Oh hey, there's a Clojure meetup on Thursday in Boston. |
| 12:11 | TimMc | I have to make it to that. |
| 12:11 | technomancy | TimMc: absolutely |
| 12:13 | dnolen | the fact that the JVM can optimize call sites when you're pulling fns out of arrays is pretty astounding. |
| 12:15 | dnolen | fast predicate dispatch might not be as hard as I thought... |
| 12:17 | symbole | dnolen: Will there be a recording of the talk on Wednesday? |
| 12:17 | dnolen | symbole: 90% chance it seems like. |
| 12:22 | TimMc | What would you call a HOF that is the opposite of partial, e.g. (fn a b c d e) -> (fn d e) ? |
| 12:24 | symbole | dnolen: I'll email the organizer then. |
| 12:27 | TimMc | (defn unpartial [f n] #(apply f (drop n %&))) |
| 12:28 | amac | I think unpartial [f & n], no? |
| 12:29 | amac | and then drop the count of the number of args passed in |
| 12:29 | TimMc | Why? |
| 12:29 | clojurebot | why not? |
| 12:30 | TimMc | clojurebot: Glad to see you aren't flailing around helplessly today. |
| 12:30 | sjl | Hmm, if I (def foo (force (delay (some-fn huge-argument))) is that going to prevent huge-argument from being garbage collected? |
| 12:30 | clojurebot | what should I do today, it is the weekend and all |
| 12:30 | TimMc | amac: With my definition, ((unpartial + 2) 1 10 100 1000) => 1100 |
| 12:30 | sjl | Or will it allow it to be GC'ed once it's forced and the argument isn't necessary any longer? |
| 12:31 | sjl | (assuming there aren't any other references to huge-arg anywhere else, of course) |
| 12:31 | amac | ok, I see where you're going |
| 12:32 | TimMc | I guess it is basically a member of a class of HOFs that do something to the arglist and reapply it. |
| 12:32 | amac | I thought you wanted to define more of an... anti?-prototype |
| 12:34 | TimMc | (defn modarg [f m] #(apply f (m %&))) |
| 12:34 | TimMc | ((modarg + (partial drop 2)) 1 10 100 1000) |
| 12:36 | manutter | ,(letfn [(skip-args [f c &args] (apply f (drop c args)))] (skip-args + 2 1 10 100 1000)) |
| 12:36 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: args in this context, compiling:(NO_SOURCE_PATH:0)> |
| 12:36 | manutter | oops |
| 12:36 | manutter | ,(letfn [(skip-args [f c & args] (apply f (drop c args)))] (skip-args + 2 1 10 100 1000)) |
| 12:36 | clojurebot | 1100 |
| 12:37 | manutter | TimMc: ^^^ |
| 12:37 | nollidj | is there a good reference for all the internal clojure interfaces that define behaviors, like IObj, ILookup, and IPersistentMap? |
| 12:38 | nollidj | i 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:39 | nollidj | okay, let me modify that: i can look at the javadoc, but it's really not that informative. |
| 12:39 | symbole | nollidj: They're mostly under one package, so looking at the source will give a list. |
| 12:39 | nollidj | anything better that actually explains things? |
| 12:41 | symbole | They'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:42 | nollidj | hm, ok. thanks. |
| 12:42 | clgv | nollidj: yeah you should make some noice that clojure.core starts documenting their implementation jvm and clj more! :) |
| 12:42 | clgv | *noise |
| 12:42 | nollidj | there's little documentation to explain, for example, what meta and withMeta do and why i should implement them in something |
| 12:43 | nollidj | hm. i guess it's worth opening an issue |
| 12:43 | clgv | nollidj: you want to know that? that's easy, it's the emtadata support |
| 12:43 | clgv | the one assigns meta the other reads it |
| 12:44 | nollidj | i 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:45 | nollidj | i'm not saying that's bad, i'm just saying there's a bit of a gotcha there |
| 12:45 | clgv | nollidj: I totally agree with you that they should document more |
| 12:45 | nollidj | sure, thanks for the feedback |
| 12:45 | clgv | some of the clojure.core implementation would be a lot easier to understand with some comments in it |
| 12:49 | nollidj | oh, there's an attempt at developing a literate programming-style book documenting things. that's fantastic |
| 12:49 | clgv | link? |
| 12:49 | clojurebot | your link is dead |
| 12:50 | Scriptor | docco? |
| 12:51 | nollidj | found this: http://groups.google.com/group/clojure/browse_thread/thread/460417fe45f314c3?pli=1 |
| 12:51 | nollidj | the pdf and source are linked there |
| 12:51 | clgv | thx |
| 12:59 | TimMc | manutter: Yeah, but mine is a HOF. So neener neener. |
| 13:02 | manutter | ,(letfn [(skip-args [f c] (fn [& args](apply f (drop c args))))] ((skip-args + 2) 1 10 100 1000)) |
| 13:02 | clojurebot | 1100 |
| 13:02 | manutter | :) |
| 13:04 | TimMc | ,(letfn [(marg [f m] #(apply f (m %&)))] ((marg - reverse) 1 10)) |
| 13:04 | clojurebot | 9 |
| 13:05 | TimMc | I guess the arguments should really go the other way. |
| 13:06 | TimMc | ,(letfn [(marg [m f] #(apply f (m %&)))] ((marg reverse -) 1 10)) |
| 13:06 | clojurebot | 9 |
| 13:07 | manutter | Surgeon 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:47 | amac | ,(defn predmap [p m & c] (apply map #(if (p %) (m %) %) c)) |
| 13:47 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 13:51 | amac | ,((fn [p m & c] (apply map #(if (p %) (m %) %) c)) even? inc (range 1 11)) |
| 13:51 | clojurebot | (1 3 3 5 5 ...) |
| 13:53 | TimMc | amac: You might call it ifmap |
| 13:53 | TimMc | Or... hmm, maybe not. |
| 13:54 | amac | I run into this usecase surprisingly often |
| 13:54 | TimMc | You could also turn it inside out. |
| 13:54 | amac | ? |
| 13:55 | TimMc | let me work something up |
| 13:57 | amac | :) |
| 13:58 | TimMc | ,(letfn [(xif [p f] #(if (p %) (f %) %))] (map (xif even? inc) (range 1 11))) |
| 13:58 | clojurebot | (1 3 3 5 5 ...) |
| 13:58 | amalloy | amac: something like this is in useful |
| 13:58 | TimMc | xif = "transform-if" |
| 13:59 | amalloy | TimMc: 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:59 | TimMc | nice! |
| 13:59 | amac | TimMc: neat, much clearer |
| 13:59 | TimMc | That's a good name. |
| 14:00 | amalloy | well, actually to-fix returns the function like xif; fix applies it immediately. same thing |
| 14:00 | TimMc | amac: Of course, if you are really going to be mapping almost all of the time, predmap would actually be more useful. |
| 14:00 | amalloy | (map (to-fix even? inc, string? read-string) [3 2 "1"]) ;=> (3 3 1) |
| 14:00 | TimMc | amalloy: And I suppose yours takes &args. |
| 14:01 | TimMc | Ah, yours does something like case. |
| 14:01 | amalloy | more like condp |
| 14:01 | TimMc | right |
| 14:02 | amalloy | ninjudd 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:08 | TimMc | amalloy: I could also see reworking it to take multiple args for the predicate and transformation functions. |
| 14:09 | TimMc | The tricky bit would be the else case. |
| 14:09 | amalloy | TimMc: 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:09 | amalloy | (finally caught up on the backlog) |
| 14:10 | manutter | I did 2 versions of skip-args tho |
| 14:10 | TimMc | Is it? Mine returns a function. |
| 14:10 | manutter | 2nd one returned a function instead of just processing its args |
| 14:10 | TimMc | I'm actually not clear on the technical definition of HOF. |
| 14:10 | amalloy | skip-args takes a first-order function and returns a value; mod-args takes two first-order functions and returns a first-order function |
| 14:11 | amalloy | TimMc: http://www.eecs.usma.edu/webs/people/okasaki/jfp98.ps |
| 14:11 | TimMc | thanks |
| 14:14 | TimMc | "map is second-order" means that as far as map is concerned, the input function doesn't need to be higher order, right? |
| 14:14 | TimMc | Because in (map f ls) map can't actually *know* that f isn't something fancy. |
| 14:15 | amalloy | i can't see a way for the alternative to be meaningful: every function would be nth-order |
| 14:15 | TimMc | except inc |
| 14:15 | amalloy | every function (with any function argument at all) |
| 14:16 | Pupeno | I'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:16 | TimMc | There's probably a formalization of that statement using the phrase "point-free equivalent". |
| 14:16 | amalloy | &(format "%d" "test") |
| 14:16 | lazybot | java.util.IllegalFormatConversionException: d != java.lang.String |
| 14:16 | amalloy | Pupeno: ^ |
| 14:17 | TimMc | That's a confusing error message. |
| 14:17 | Pupeno | amalloy: ok… I'll grep all the sources for %d. |
| 14:18 | amalloy | TimMc: yeah, it is. tbh i've never seen it before, but what else could have caused it? |
| 14:22 | manutter | Pupeno: 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:23 | Pupeno | manutter: the library that most likely is causing this is only using %s. |
| 14:23 | amalloy | TimMc: 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:23 | Pupeno | A stack trace would be kinda useful. |
| 14:24 | amalloy | &(format "%x" "test") ;; i think this throws a different error message |
| 14:24 | lazybot | java.util.IllegalFormatConversionException: x != java.lang.String |
| 14:24 | manutter | ,(format "%s" 20) |
| 14:24 | clojurebot | "20" |
| 14:24 | manutter | ,(format "%s" :some) |
| 14:24 | clojurebot | ":some" |
| 14:24 | amalloy | manutter: %s calls .toString on its argument, so it's never inapplicable |
| 14:24 | manutter | I was about to draw the same conclusion myself :) |
| 14:25 | Pupeno | So, it's definitely a %d. |
| 14:25 | amalloy | Pupeno: so it says no source file, and gives you no stacktrace at all? |
| 14:25 | Pupeno | amalloy: correct. |
| 14:27 | Pupeno | I found the REPL sometimes fails to give proper stack traces. |
| 14:28 | Pupeno | Ok, now I got a file and line number, but it's not helpful: https://gist.github.com/1149795 |
| 14:29 | Pupeno | bbl |
| 14:29 | amalloy | Pupeno: one of the libraries you're require'ing has an error at macroexpansion time, i think |
| 14:30 | Pupeno | amalloy: I see. |
| 14:30 | amalloy | so if you try requiring them one at a time, you can narrow down which it is |
| 14:30 | amalloy | not that this is an ideal solution, but lacking a stacktrace... |
| 14:31 | TimMc | Doesn't *e give you the error object? |
| 14:31 | TimMc | I thought I remember something about that. |
| 14:31 | amalloy | also a good point |
| 14:32 | TimMc | (.printStackTrace *e) |
| 14:32 | manutter | Pupeno: looks like you're both (use)'ing and (require)ing lobos.core, maybe that's an issue? |
| 14:32 | amalloy | shouldn't be |
| 14:33 | manutter | I can't see how it would matter, but it does look like there's a problem with the libs he's pulling in |
| 14:33 | manutter | and it just seemed a little odd |
| 14:33 | amalloy | agreed, he should change it. but it also shouldn't fix the problem if we live in a half-sane world |
| 14:35 | manutter | A half-sane world? WIth computers in it?? |
| 14:35 | TimMc | use just expands to require + refer, right? |
| 14:35 | manutter | :D |
| 14:35 | amalloy | yes |
| 14:36 | manutter | Sorry, I'm a PHP programmer by trade, I just have a hard time grasping the concept of sanity in programming. |
| 14:36 | amalloy | manutter: there's still time to jump overboard |
| 14:38 | manutter | Don't think I'm not tempted |
| 14:38 | amalloy | return array_filter(function ($x) use ($foo, $bar, $baz) { return ... ;}, $someArray); // not enough punctuation and noise yet |
| 14:39 | amalloy | assuming you're on a version of php that even *has* closures |
| 14:39 | symbole | Is there a way to require a function to accept a type that extends a particular protocol? |
| 14:39 | Scriptor | argh, those don't count as closures |
| 14:40 | nollidj | symbole: do you know of type annotations on function parameters? |
| 14:40 | manutter | lol, I'm working on a system that has mixins and extensible classes |
| 14:40 | manutter | home grown PHP extensions |
| 14:40 | amalloy | Scriptor: 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:41 | symbole | nollidj: Yes. |
| 14:42 | nollidj | symbole: protocols automatically generate a corresponding interface. see (doc defprotocol) |
| 14:43 | Scriptor | amalloy: a bit exaggerating, I guess, but mainly because it only allows enclosing of varriables in the same scope |
| 14:43 | Scriptor | er |
| 14:43 | Scriptor | in the scope directly above it |
| 14:43 | nanarpuss | anybody familiar with clojurescript? |
| 14:43 | amalloy | nollidj: ack no don't use those |
| 14:43 | symbole | nollidj: Thanks. |
| 14:43 | nollidj | amalloy: ok. |
| 14:43 | nollidj | symbole: maybe you should listen to amalloy instead of me |
| 14:44 | amalloy | (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:44 | nollidj | ah, right |
| 14:45 | amalloy | symbole: just add a precondition or an assertion that checks ##(doc satisfies?) |
| 14:45 | lazybot | ⇒ "([protocol x]); Returns true if x satisfies the protocol" |
| 14:46 | nanarpuss | I 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:46 | symbole | I'll give preconditions a try. |
| 14:47 | ibdknox | nanarpuss: it would only make sense to do so for objects, which I assume deftype uses, though I haven't looked into it |
| 14:50 | nanarpuss | hmm, 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:50 | symbole | Is 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:51 | symbole | As supposed to passing maps. |
| 14:52 | symbole | I guess that doesn't make much sense, because if some object doesn't extend a protocol, it would signal an error anyway. |
| 14:54 | symbole | I'm just thinking about how to create interfaces which are enforced and not giving the user the ability to just pass anything in. |
| 14:55 | amalloy | symbole: use a statically typed language |
| 14:56 | ibdknox | nanarpuss: The only advantage provided by prototype functions is that they are not redeclared per instance of an object. |
| 14:57 | ibdknox | nanarpuss: 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:58 | nanarpuss | thanks, that is the insight I was looking for. |
| 14:59 | amalloy | so, 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:59 | technomancy | are you sure it isn't fixed at compile-time? |
| 15:00 | amalloy | no, i'm not. i guess it would be simple to test |
| 15:00 | technomancy | I guess it would be fixed to the current value of the var if it were |
| 15:00 | technomancy | which isn't usually desirable |
| 15:00 | amalloy | right, which seems like the way 1.3 is going |
| 15:01 | technomancy | except 1.3 will detect recompilation and clear relevant caches |
| 15:01 | technomancy | but I don't think it would catch this unless you did #'foo |
| 15:01 | ibdknox | what is the real perf loss here? |
| 15:01 | ibdknox | did you test? |
| 15:02 | ibdknox | I can't imagine it's much at all |
| 15:02 | amalloy | ibdknox: i agree, but it's galling, just like compiling (+ 1 2) into an actual addition |
| 15:03 | ibdknox | amalloy: haha yeah. |
| 15:04 | ibdknox | I bet the real cost is in GC'ing all the extra functions you would make |
| 15:04 | amalloy | technomancy: okay, i've changed my mind, i'm no longer sure it's easy to test |
| 15:05 | ibdknox | haha |
| 15:05 | technomancy | there 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:06 | technomancy | comp may or may not be the same, I just remember enough to not trust my initial intuition. |
| 15:06 | ibdknox | how can it make those guarantees with things like thread-level binding? |
| 15:06 | ibdknox | I guess in 1.3 you have :dynamic |
| 15:07 | ibdknox | so you can know up front |
| 15:07 | bpr | technomancy: 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:07 | bpr | err.. compile-time v. run-time anyhow |
| 15:07 | arohner | ,(source comp) |
| 15:07 | clojurebot | Source not found |
| 15:08 | amalloy | technomancy: 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:08 | technomancy | bpr: counting .class files on disk after an AOT run IIRC |
| 15:08 | technomancy | been a while |
| 15:08 | bpr | technomancy: ah, pretty simple. thanks |
| 15:08 | TimMc | technomancy 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:08 | bpr | lol |
| 15:08 | arohner | comp calls (fn []) on every invocation |
| 15:08 | TimMc | *24-bit color |
| 15:09 | ibdknox | TimMc: who doesn't? |
| 15:09 | ibdknox | :D |
| 15:10 | TimMc | For fun he writes programs that, when transformed in the above manner, appear to be Shakespearean plays. |
| 15:10 | TimMc | ibdknox: n00bs like me who can only read the hex |
| 15:11 | technomancy | TimMc: only for erlang code |
| 15:11 | technomancy | I don't use a lot of actors in clojure |
| 15:11 | TimMc | ba-dum tish |
| 15:11 | ibdknox | (inc technomancy) |
| 15:11 | lazybot | ⟹ 3 |
| 15:11 | ibdknox | so bad, but it deserved +1 |
| 15:12 | amalloy | maybe 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:12 | amalloy | then you don't need any compile-time support |
| 15:12 | technomancy | relevant: http://shakespearelang.sourceforge.net/report/shakespeare/#SECTION00090000000000000000 |
| 15:12 | ibdknox | hah I haven't seen that in a while |
| 15:22 | edbond | How to deal with peer not authenticated [Thrown class javax.net.ssl.SSLPeerUnverifiedException] in clj-http or other apache http client based? |
| 15:25 | symbole | edbond: I don't understand your question. |
| 15:30 | edbond | symbole: I am trying to read https response from server with self-signed cert and get an exception. |
| 15:31 | grumpytoad | so in scala you can use zip to combine two collections - is this possible in clojure ? |
| 15:32 | scgilardi | combine as in one collection becomes keys in a map and the other becomes corresponding values? |
| 15:32 | amalloy | scgilardi: zip questions are usually answered with map |
| 15:32 | amalloy | &(map list '[a b c] '[1 2 3]) |
| 15:32 | lazybot | ⇒ ((a 1) (b 2) (c 3)) |
| 15:32 | grumpytoad | hmm.. not sure, too unfamiliar, at best a tuple if that exists |
| 15:33 | grumpytoad | hmm ok.. will try that |
| 15:33 | scgilardi | amalloy: thanks. was trying to understand "combine" |
| 15:33 | ibdknox | yeah it wasn't clear to me if he actually wanted concat |
| 15:33 | ibdknox | but given he was referencing zip.. |
| 15:33 | amalloy | scgilardi: yeah, combine is vague. i've learned that "zip" means "i'm coming from haskell or scala and where is the zip function" |
| 15:33 | amalloy | thus: map lis |
| 15:34 | scgilardi | yes, looks right. generating an alist |
| 15:34 | amalloy | more like a list of tuples; i think the similarity to an alist is a coincidence |
| 15:35 | symbole | edbond: I don't believe clj-http handles self-signed certificate. |
| 15:35 | scgilardi | or it's a rose |
| 15:35 | amalloy | i wonder how haskell/scala do a three-way zip, since they don't have &rest args |
| 15:36 | grumpytoad | yes a list of tuples as i need/want to access each in pairs (x - y coordinates) |
| 15:36 | TimMc | amalloy: ANy reason to use (map list ...) over (map vector ...) here? |
| 15:37 | amalloy | grumpytoad: 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:37 | TimMc | in Scala, I presume |
| 15:37 | amalloy | TimMc: two characters shorter. as you're doubtless aware i strive to avoid wasted characters, which tire out my fingers unnecessarily |
| 15:37 | grumpytoad | euhmm .. hehe i would shriek and run far away |
| 15:38 | grumpytoad | it's possible to have tuples of tuples or some similar construct |
| 15:40 | grumpytoad | so why doesn't merge do what i need ? |
| 15:40 | amalloy | because it does something different |
| 15:40 | amalloy | and map does do what you need |
| 15:42 | grumpytoad | though map cannot be used on a LazySeq ? |
| 15:44 | clj-noob | how to call mysql stored procedure with INOUT parameter using clojure.java.jdbc and print the OUT parameter? |
| 15:46 | amalloy | apparently haskell has zip, zip3, zip4...up to some arity N |
| 15:46 | amalloy | *shudder* |
| 15:47 | grumpytoad | it worked ;-) |
| 15:47 | ibdknox | (map3 list (range 10) (range 10) (range 10)) |
| 15:47 | technomancy | the price of currying is eternal arities. |
| 15:48 | amalloy | indeed. i feel silly for actually asking in #haskell instead of just hoogling for it though |
| 15:48 | ibdknox | did they scoff at you? lol |
| 15:48 | grumpytoad | where does that word come from arities |
| 15:48 | amalloy | nah |
| 15:48 | grumpytoad | it's like an indian side dish |
| 15:48 | amalloy | they're friendly dudes over there too |
| 15:49 | technomancy | arities and naan go particularly well together |
| 15:49 | grumpytoad | lol |
| 15:49 | amalloy | technomancy: just don't order it with the curry? |
| 15:50 | ibdknox | now that I think about it, I don't think I heard the term before I started messing with Clojure |
| 15:51 | opqdonut | amalloy: that's because generic type-safe tuples would be a PITA. but you can look up HList if you want |
| 15:51 | pdk | does haskell not support varargs or something |
| 15:51 | technomancy | grumpytoad: arity just means the number of arguments a function takes |
| 15:51 | opqdonut | (generic in the sense of having a generic first operation etc) |
| 15:51 | technomancy | pdk: that's correct, you can't have currying with varargs |
| 15:51 | amalloy | pdk: no. and it has a reason, just like clojure has for using lots of parens :P |
| 15:52 | grumpytoad | technomancy: yes, seems so, but it's my first encounter since trying clojure |
| 15:52 | opqdonut | and besides, for many of the use cases of zipN, transpose is the correct function |
| 15:52 | amalloy | *nod* |
| 15:52 | opqdonut | sorry, just venting |
| 15:53 | amalloy | opqdonut: yes, i can see that most of the time you don't really need zipN |
| 15:53 | grumpytoad | currying brings a lot of syntax sugar in statically typed languages, AFAICS |
| 15:54 | amalloy | it'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:54 | opqdonut | grumpytoad: I have no idea what you mean with that |
| 15:54 | amalloy | which 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:54 | grumpytoad | opqdonut: you get some shortcuts instead of having to wrap functions and their definitions |
| 15:55 | opqdonut | grumpytoad: yeah sure, partial application is great for writing functional code succinctly |
| 15:56 | choffstein | Hey 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:56 | choffstein | into 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:56 | choffstein | Any thoughts on this one? I can't seem to figure it out. |
| 15:56 | AWizzArd | Anyone here on Java 7? |
| 15:57 | TimMc | grumpytoad: bin*ary*, tern*ary*, quatern*ary* <- arities |
| 15:57 | TimMc | oh, and not to mention nullary and unary |
| 15:57 | grumpytoad | so... now i want to curry something.. i guess that's not possible |
| 15:58 | pdk | did they go through with the stuff talking about closures in java 7 |
| 15:58 | bpr | does 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:58 | TimMc | As far as I can tell it is a sort of back-formation. |
| 15:58 | AWizzArd | There 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:58 | pdk | seems 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:58 | pdk | same story with c++0x |
| 15:59 | TimMc | AWizzArd: (Paths/get ...) probably |
| 15:59 | AWizzArd | Well, I tried that. |
| 15:59 | AWizzArd | The funny thing is that the get method is overloaded. |
| 15:59 | TimMc | Oh, is it varargs? |
| 15:59 | AWizzArd | yes |
| 15:59 | amalloy | pdk: no, closures were delayed to jdk8 i think |
| 15:59 | choffstein | Any idea on my issue, oh clojure wizards? |
| 15:59 | TimMc | It probably wants a string array |
| 15:59 | AWizzArd | Either it is a vararg String... or an URI |
| 16:00 | pdk | did that at least suggest other stuff that makes closures useful |
| 16:00 | TimMc | ,(doc strings) |
| 16:00 | clojurebot | Excuse me? |
| 16:00 | pdk | like real lambdas/higher order functions |
| 16:00 | AWizzArd | But 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:00 | AWizzArd | Clojure sees that I call with one argument and tries to call the method taking the URI |
| 16:00 | TimMc | Haha, weird! |
| 16:00 | AWizzArd | yup |
| 16:00 | opqdonut | try hinting? |
| 16:00 | AWizzArd | yes |
| 16:01 | amalloy | AWizzArd: javadoc for the new thingy? |
| 16:01 | opqdonut | ^"[java.lang.String;" or however it goes |
| 16:01 | amalloy | ^"[Ljava.lang.String;" |
| 16:01 | opqdonut | that |
| 16:01 | AWizzArd | but also (Paths/get ^"[Ljava.lang.String;" (into-array String ["c:" "temp"])) doesn't help. |
| 16:02 | AWizzArd | Excetpion: [Ljava.lang.String; cannot be cast to java.net.URI |
| 16:02 | opqdonut | oh, that sucks |
| 16:03 | choffstein | Anyone ever seen a java.lang.NoClassDefFoundError: Could not initialize class classname__init (NO_SOURCE_FILE:0) |
| 16:03 | TimMc | choffstein: Yeah, usually when I am flailing around trying to create a new project tree. |
| 16:03 | choffstein | any idea where it might be stemming from? |
| 16:03 | TimMc | I suppose Clojure can't resolve varargs because of the whole dynamic typing thing. |
| 16:03 | TimMc | *automatically |
| 16:04 | dnolen | AWizzArd: is that a Java var args method? |
| 16:04 | AWizzArd | http://download.oracle.com/javase/7/docs/api/java/nio/file/Paths.html |
| 16:05 | amalloy | AWizzArd: it takes two args |
| 16:05 | amalloy | first, then an array of more |
| 16:05 | AWizzArd | ah okay |
| 16:05 | AWizzArd | Good, that works. |
| 16:05 | amalloy | (inc javadoc) |
| 16:05 | lazybot | ⟹ 1 |
| 16:05 | AWizzArd | Phew :-) |
| 16:06 | amalloy | i 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:06 | AWizzArd | Excellent (: |
| 16:06 | choffstein | i'm about to punch a baby seaturtle |
| 16:06 | choffstein | what. the. hell. |
| 16:06 | AWizzArd | I also didn't understand it, especially since hinting also didn't help |
| 16:07 | AWizzArd | Because Java also needs some way to differentiate. |
| 16:07 | AWizzArd | I just didn't see from that example code that there is a first arg. |
| 16:07 | technomancy | choffstein: what you're describing should work as long as you restart your jvms after running deps |
| 16:07 | AWizzArd | Paths.get("d:", " temp"); |
| 16:07 | choffstein | restarting my jam? |
| 16:07 | choffstein | jvm? |
| 16:08 | TimMc | AWizzArd: That's a great example of example code biting you in the ass. |
| 16:11 | technomancy | I would not presume to instruct you in when your jams should be started and/or restarted. |
| 16:11 | technomancy | only that they should be periodically pumped up. |
| 16:14 | amalloy | just the other day we were discussing how everything is the jam's fault |
| 16:15 | choffstein | autocorrect … how I love thee. |
| 16:17 | choffstein | …double-you, tee, eff. Now lein install is broken because it can't find the namespace? What in the world have I done?! |
| 16:17 | TimMc | Ooh, that's good news! |
| 16:18 | TimMc | It probably means something is wrong more globally, not with your project. |
| 16:18 | choffstein | This might be a very, very, very stupid question |
| 16:18 | amalloy | TimMc: and if his computer catches fire, it's time to throw a party, because something *very* global is broken? |
| 16:18 | ibdknox | lol |
| 16:18 | TimMc | Well, at least he will know what is wrong. |
| 16:18 | ibdknox | (inc amalloy) |
| 16:18 | lazybot | ⟹ 1 |
| 16:19 | choffstein | But 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:19 | amalloy | huh. lazybot, when did you forget all the karmas? |
| 16:19 | technomancy | choffstein: you're right; C shouldn't need to mention B in project.clj |
| 16:19 | leonid__ | (amalloy) |
| 16:19 | leonid__ | ,(amalloy) |
| 16:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0)> |
| 16:19 | choffstein | technomancy: that is what I thought. herrm…. intriguing. |
| 16:19 | leonid__ | ,amalloy |
| 16:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0)> |
| 16:19 | choffstein | might just try starting a fresh project |
| 16:20 | leonid__ | tetris! |
| 16:20 | amalloy | oh, haha. when we renamed him from sexpbot to lazybot, he started reading from the lazybot database instead of the sexpbot database |
| 16:21 | technomancy | remember to merge-with + when you port the data over |
| 16:22 | choffstein | can you guys check out this gist real quick? https://gist.github.com/1150013 |
| 16:22 | TimMc | WHen did sexpbot become lazybot? |
| 16:22 | choffstein | The errors are at the bottom. They confuse me. |
| 16:22 | amalloy | a few weeks ago? |
| 16:23 | TimMc | choffstein: As far as I can tell it is some sort of compile-time error in the ns declaration. |
| 16:24 | choffstein | I would certainly not disagree with that deduction :) |
| 16:24 | choffstein | I'm just confused as to what the hell it is though. |
| 16:24 | TimMc | Yeah, I'm not sure where to go from there. |
| 16:25 | TimMc | I'm guessing it's a case of clojure.core taking its sweet time in checking for nil. |
| 16:26 | TimMc | I can paste that into the REPL without getting that error (and instead getting Not Found errors.) |
| 16:27 | tufflax | How 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:27 | choffstein | that confuses me and frustrates me and intimidates me. |
| 16:27 | amalloy | no quotes |
| 16:28 | technomancy | tufflax: have you considered require :as? |
| 16:28 | tufflax | yes briefly |
| 16:28 | tufflax | but, I'm just curious now :p |
| 16:28 | amalloy | technomancy: something wrong with :use/:rename? i mean, when i use clojure.string i usually do requre/as, but use/rename is viable too |
| 16:29 | TimMc | choffstein: 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:29 | TimMc | Unless that hashmap disallows null, and the symbol is somehow null. |
| 16:30 | tufflax | amalloy: sigh, tried that but got an unrelated error and didn't check it :p |
| 16:30 | tufflax | thanks |
| 16:30 | technomancy | amalloy: it works, but it's less obvious |
| 16:30 | TimMc | Looks like a b0rken project. |
| 16:30 | choffstein | TimMc: So just wipe it and re-create? |
| 16:31 | TimMc | Yeah. Create a new project and start reinstating pieces until the error shows up (or doesn't). |
| 16:32 | TimMc | I can't think of anything more clever. |
| 16:33 | choffstein | i'll give it a go. |
| 16:33 | choffstein | I think it has to do with clj-logging-config to be quite honest, since that's when the project broke. |
| 16:42 | choffstein | hmmm …. it was in importing the last two classes. that is interesting. |
| 16:56 | grumpytoad | hmm.. enjoying this. thx & laters |
| 16:57 | amalloy | well, i've managed to accidentally give everyone twice the karma they used to have. that's almost like rescuing the old values |
| 16:59 | amalloy | there |
| 17:01 | mattmitchell | is there a built in sum function? |
| 17:01 | amalloy | mattmitchell: it's called + |
| 17:01 | mattmitchell | ahh ok just use apply :) |
| 17:01 | amalloy | indeed |
| 17:02 | dnolen | ,(time (reduce + (range 100000))) |
| 17:02 | clojurebot | "Elapsed time: 167.327 msecs" |
| 17:02 | clojurebot | 4999950000 |
| 17:02 | dnolen | ,(time (apply + (range 100000))) |
| 17:02 | clojurebot | "Elapsed time: 83.701 msecs" |
| 17:02 | clojurebot | 4999950000 |
| 17:02 | dnolen | ,(time (reduce + (range 100000))) |
| 17:02 | clojurebot | "Elapsed time: 54.336 msecs" |
| 17:02 | clojurebot | 4999950000 |
| 17:02 | dnolen | ,(time (apply + (range 100000))) |
| 17:03 | clojurebot | "Elapsed time: 49.355 msecs" |
| 17:03 | amalloy | dnolen: practicing your hotspot optimizations? |
| 17:03 | clojurebot | 4999950000 |
| 17:03 | dnolen | amalloy: ;) I feel like reduce is usually quicker than apply. |
| 17:03 | dnolen | ,*clojure-version* |
| 17:03 | clojurebot | {:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"} |
| 17:03 | amalloy | i don't see why that would be the case |
| 17:03 | amalloy | apply just calls reduce |
| 17:03 | amalloy | (for the particular case of +) |
| 17:05 | amalloy | and for some functions, of course, apply will be faster than reduce |
| 17:05 | dnolen | amalloy: apply calls reduce when using + ? line? |
| 17:06 | dnolen | ,(time (reduce + (range 1000000)) |
| 17:06 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 17:06 | dnolen | ,(time (reduce + (range 1000000))) |
| 17:06 | clojurebot | "Elapsed time: 523.616 msecs" |
| 17:06 | clojurebot | 499999500000 |
| 17:06 | amalloy | $source + |
| 17:06 | lazybot | + is http://is.gd/zh9ARG |
| 17:06 | dnolen | ,(time (apply + (range 1000000))) |
| 17:06 | clojurebot | "Elapsed time: 536.39 msecs" |
| 17:06 | clojurebot | 499999500000 |
| 17:06 | kephale | oh heh, i didnt know that either |
| 17:06 | amalloy | https://github.com/clojure/clojure/blob/1.2.x/src/clj/clojure/core.clj#L809 |
| 17:06 | dnolen | amalloy: that's 1.2 |
| 17:07 | dnolen | amalloy: but you're right + calls reduce1 in 1.3 |
| 17:07 | grumpytoad | ,(repeat 1) |
| 17:07 | clojurebot | (1 1 1 1 1 ...) |
| 17:07 | amalloy | right. and if it changed, i would expect apply to be the one that got faster, not reduce |
| 17:07 | grumpytoad | heh no explode? shame |
| 17:10 | amalloy | &(time (= (apply str (repeat 1e7 "test")))) |
| 17:11 | amalloy | hm. too many zeros |
| 17:11 | lazybot | Execution Timed Out! |
| 17:11 | amalloy | &(time (= (apply str (repeat 1e5 "test")))) |
| 17:11 | lazybot | ⇒ "Elapsed time: 112.653346 msecs" true |
| 17:11 | amalloy | &(time (= (reduce str (repeat 1e5 "test")))) |
| 17:11 | lazybot | Execution Timed Out! |
| 17:14 | mattmitchell | is 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:14 | clojurebot | Roger. |
| 17:14 | dnolen | amalloy: huh interesting. for + case, reduce / apply are pretty much the same. |
| 17:14 | amalloy | dnolen: sure, because no interesting optimizations can happen for + |
| 17:15 | amalloy | but for str, they can; and only apply can take advantage because it knows all the args ahead of time |
| 17:15 | amalloy | mattmitchell: https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L51 |
| 17:16 | mattmitchell | amalloy: slice yeah! that's it. thank you. |
| 17:16 | amalloy | mattmitchell: well, that's an external library you'll have to depend on |
| 17:16 | amalloy | it's not in core or anything |
| 17:18 | kephale | i wonder about + with something like a recursive (map + (partition 2 coll)) |
| 17:19 | aaelony | hi 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:19 | aaelony | (. s3service (.getObject (S3Bucket. bucket-name) (. (.listObjects (S3Bucket. bucket-name)) (.getKey )))) |
| 17:19 | aaelony | java.lang.IllegalArgumentException: No matching field found: listObjects for class org.jets3t.service.model.S3Bucket (NO_SOURCE_FILE:0) |
| 17:20 | aaelony | I'm likely abusing the dot macro somehow |
| 17:26 | TimMc | Looks like a good opportunity for the stitching macros. |
| 17:27 | TimMc | Anyway, I recommend sequentially binding those values to names so you can see what you are doing. |
| 17:27 | aaelony | I think it is the dot special form, but something is not quite right |
| 17:27 | aaelony | perhaps getting more coffee will help... |
| 17:27 | TimMc | (let [bucket (S3Bucket. bucket-name), objects (.listObjects bucket)] ...) |
| 17:28 | raek | aaelony: could you write what you are trying to do in java syntax? |
| 17:28 | aaelony | sure |
| 17:28 | TimMc | aaelony: (.listObjects (S3Bucket. bucket-name)) is saying new S3Bucket(bucket-name).listObjects() |
| 17:29 | aaelony | it is something like this: |
| 17:29 | aaelony | final S3Bucket s3Bucket = new S3Bucket(bucketName); |
| 17:29 | aaelony | for (final S3Object s3Object : s3Service.listObjects(s3Bucket)) { |
| 17:29 | aaelony | S3Object completeObject = s3Service.getObject( s3Object.getKey() ); |
| 17:29 | TimMc | Is s3Service a class or an object? |
| 17:30 | aaelony | => (class s3service) |
| 17:30 | aaelony | org.jets3t.service.impl.rest.httpclient.RestS3Service |
| 17:30 | aaelony | it is an instance of that class with credentials needed to talk to the bucket |
| 17:30 | TimMc | ah, OK |
| 17:31 | aaelony | somehow my chaining is garbled |
| 17:31 | TimMc | s3Object vs. S3Object is pretty confusing also |
| 17:31 | aaelony | yes, sorry |
| 17:32 | aaelony | s3Object is just an instance of an S3Object |
| 17:33 | aaelony | I am referencing this: http://jets3t.s3.amazonaws.com/toolkit/code-samples.html |
| 17:33 | TimMc | So yeah, naming your intermediate values (and naming them well) is probably the best approach to finding your problem. |
| 17:33 | raek | (let [s3-bucket (S3Bucket. bucket-name)] (for [s3-object (.listObject s3-service)] (let [complete-object (.getObject s3-service (.getKey se-object))] ...)) |
| 17:33 | raek | this would be a literal translation of your code |
| 17:34 | raek | if the for body only does side-effects, you should replace for with doseq |
| 17:34 | aaelony | ok. cool. let me study this. |
| 17:35 | dnolen | amalloy: 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:35 | dnolen | apply does not know how many arguments it gets, it uses a Seq |
| 17:41 | aaelony | hmmm, how would I translate this? s3Service.listObjects(s3Bucket) |
| 17:42 | aaelony | would it be: (. (s3Service (.listObjects s3Bucket))) ??? |
| 17:43 | ShreeMulay | alright 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:43 | ShreeMulay | The following is my solution: (fn [[f & rest] x] (if (= 0 x) f (recur rest (dec x)))) |
| 17:43 | ShreeMulay | why am I getting that problem? |
| 17:43 | TimMc | aaelony: (.listObjects s3Service s3Bucket) |
| 17:44 | TimMc | ,(macroexpand-1 '(.listObjects s3Service s3Bucket)) |
| 17:44 | clojurebot | (. s3Service listObjects s3Bucket) |
| 17:44 | aaelony | thanks, TimMc... pondering it... |
| 17:46 | TimMc | aaelony: dot by itself gives you the Java ordering: (. object method args...) |
| 17:47 | TimMc | A symbol beginning with a dot is a special form that makes for a functional programming ordering of names: (.function object args...) |
| 17:47 | TimMc | It expands into the other form. |
| 17:47 | aaelony | TimMc: thanks.. this worked but brought me to a org.jets3t.service.S3ServiceException: S3 GET failed ... |
| 17:47 | TimMc | Ah, but now you have the right syntax, it would seem! |
| 17:47 | aaelony | ... The specified key does not exist |
| 17:47 | aaelony | getting closer ;) |
| 17:48 | aaelony | TimMc: Thanks for now... |
| 17:53 | amalloy | dnolen: 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:53 | amalloy | ShreeMulay: destructuring ([f & rest]) expands into a use of nth |
| 17:54 | amalloy | kinda annoying imo, but it means you can't use it to solve the nth problem |
| 17:55 | Raynes | amalloy: That is very unfortunate. |
| 17:55 | amalloy | dnolen: for example, conj could be written so that (apply conj foo xs) used transients like into does |
| 17:56 | amalloy | in which case, apply conj would be faster than reduce conj |
| 17:56 | amalloy | Raynes: i agree, but what can we do? |
| 17:56 | Raynes | Nothing, I suppose. I wish sandboxing wasn't so unscientific. |
| 17:56 | dnolen | amalloy: I recall having this conversation with you before. Yuck. |
| 17:57 | dnolen | ;) |
| 17:57 | amalloy | *chuckle* |
| 17:59 | Raynes | amalloy: 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:00 | Chousuke | :P |
| 18:00 | Chousuke | It's kind of difficult to let people do whatever they want without letting them to do whatever they want |
| 18:00 | amalloy | imo the root cause of this particular issue is that (let [[x y] foo]) uses nth instead of first/rest |
| 18:01 | arohner | holy crap, why didn't anyone tell me midje is awesome? |
| 18:01 | AWizzArd | arohner: example please |
| 18:01 | Raynes | amalloy: Submit a patch. And then go ahead and decline it and save them the trouble. ;p |
| 18:01 | amalloy | srsly |
| 18:01 | arohner | AWizzArd: https://github.com/marick/Midje/wiki/Midje-mode |
| 18:03 | AWizzArd | arohner: I saw that mode but never took a closer look at it. I will watch that vid now. |
| 18:05 | amalloy | arohner: those are terrible keybindings |
| 18:06 | arohner | amalloy: so rebind them. it is emacs after all |
| 18:06 | amalloy | i know |
| 18:06 | arohner | the point is, there is an emacs mode, and it works |
| 18:07 | amalloy | it'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:07 | amalloy | *grumble grumble get off my lawn* |
| 18:08 | Raynes | amalloy: We must hunt him. |
| 18:18 | technomancy | amalloy: http://p.hagelb.org/pay.png |
| 18:19 | amalloy | technomancy: i'm trying to find the "right" bindings for minor modes. what is it, C-x <letter>? |
| 18:43 | wilfredh | what's the Clojure equivalent of Python's zip()? Do I have to use map? |
| 18:43 | jeremyheiler | ,(doc zipmap) |
| 18:43 | clojurebot | "([keys vals]); Returns a map with the keys mapped to the corresponding vals." |
| 18:43 | jeremyheiler | wilfredh: does that work for yoU? |
| 18:44 | wilfredh | I was hoping for a list of lists, but I could make do with that |
| 18:45 | wilfredh | thanks :) |
| 18:45 | amalloy | (12:34:47 PM) grumpytoad: so in scala you can use zip to combine two collections - is this possible in clojure ? |
| 18:45 | amalloy | (12:36:17 PM) amalloy: &(map list '[a b c] '[1 2 3]) |
| 18:45 | amalloy | wilfredh: ^ |
| 18:46 | wilfredh | oh, of course. Perfect. |
| 18:46 | amalloy | and now i've added another language to my list of "languages from which people ask about zip" |
| 18:46 | raek | wilfredh: map vector or map list... choose your preferred tuple type :-) |
| 18:47 | wilfredh | raek: exactly. Python mindset still showing through... |
| 18:55 | technomancy | amalloy: if you still need it: (info "(elisp)Key Binding Conventions") |
| 18:57 | amalloy | technomancy: yeah, i found that. it seems to be a list of things not to do |
| 18:57 | amalloy | no suggestion about things to actually do, for minor modes |
| 18:57 | technomancy | "Sequences consisting of `C-c' followed by any other punctuation character are allocated for minor modes." ? |
| 18:58 | amalloy | ah, yes. i guess that seemed like a pretty small set of things, and i thought there were more |
| 18:58 | amalloy | but in Keymaps and Minor Modes i just found "The key sequences bound in a minor mode should consist of `C-c' |
| 18:58 | amalloy | followed by one of `.,/?`'"[]\|~!#$%^&*()-_+='", and i guess it couldn't get any clearer |
| 19:32 | amalloy | omg. 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:39 | amalloy | &(time (dorun (apply concat (for [x (range 100)] (range x))))) |
| 19:39 | lazybot | ⇒ "Elapsed time: 24.139846 msecs" nil |
| 19:40 | amalloy | &(time (dorun (for [x (range 100), y (range x)] y))) |
| 19:40 | lazybot | ⇒ "Elapsed time: 896.231447 msecs" nil |
| 19:40 | amalloy | these 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:40 | tufflax | amalloy i think it's a list monad |
| 19:41 | tufflax | in the beginning of http://intensivesystems.net/tutorials/monads_101.html you can learn about them. more than that i dunno |
| 19:45 | tufflax | hm, maybe not. the source is some kind of monster |
| 19:45 | tufflax | I was just guessing really |
| 19:46 | amalloy | i'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:52 | bpr | amalloy: that is odd |
| 19:52 | bpr | the timings, that is |
| 19:53 | amalloy | bpr: 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:54 | amalloy | ie, the version with apply concat gets 25 times slower and the version without stays about the same :P |
| 19:54 | bpr | wow |
| 20:52 | amalloy | bpr: 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:55 | amalloy | specifically, 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:04 | amalloy | ninjudd: what do you think about https://gist.github.com/f30273d77ae8301d2852? |
| 21:05 | amalloy | hm, wrong channel. oh well, he's in here too |
| 21:30 | livingston | I'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:30 | livingston | how do I get around this: git://gist.github.com/1150606.git |
| 21:32 | livingston | sorry I guess that's actually here: https://gist.github.com/1150606 |
| 21:37 | livingston | the answer is that I used free variables instead of gensyms it should be kb-creator# |
| 21:38 | zakwilson | livingston: 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:39 | livingston | thanks. I'm familiar with capture, I just didn't realize that's how it was done in clj, (I'm used to commonlisp) |
| 22:01 | amalloy | livingston: it's usually not - when possible you should use gensyms |
| 22:02 | livingston | amalloy: what's usually not? |
| 22:03 | amalloy | using 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:03 | amalloy | if 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:04 | livingston | I 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:04 | amalloy | eg, you could use it as (kb-test test-kb-up test-triples [kb] (is kb)) |
| 22:04 | amalloy | okay |
| 22:04 | amalloy | basically clojure defaults to making accidental capture impossible |
| 22:05 | Pupeno | I wrote a post called Why I love Lisp, featuring Clojure… yesterday it got 11k views :) |
| 22:05 | livingston | amalloy: yeah. it would have been generally safe there, but it's guaranteed safe this way. |
| 22:06 | jeremyheiler | Pupeno: Care to share the link? |
| 22:07 | Pupeno | jeremyheiler: sure: http://pupeno.com/2011/08/16/why-i-love-lisp/ |
| 22:07 | Pupeno | Someone +1 it on G+, I wonder if I could find those comments, if any. |
| 22:13 | jeremyheiler | Pupeno: nice little blog post +1 |
| 22:13 | livingston | so 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:13 | Pupeno | jeremyheiler: thanks :) |
| 22:16 | Pupeno | Is it possible to use a library from source instead of a jar? with lein? how? |
| 22:16 | arohner | Pupeno: yes, read the section about checkout dependencies in the lein FAQ |
| 22:17 | Pupeno | arohner: thanks. |
| 22:20 | mattmitchell | i 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:20 | mattmitchell | here and beyond? |
| 22:21 | mattmitchell | maybe bad example... but |
| 22:21 | livingston | woah |
| 22:21 | mattmitchell | it's the procedural thing that feels wrong |
| 22:22 | hiredman | (update-in m [:id] (fn [m] ...)) |
| 22:22 | livingston | mattmitchell: there's no variability in that... I'm assuming one of those is a parameter of some function? |
| 22:24 | mattmitchell | livingston: 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:24 | mattmitchell | hiredman: thanks, will check that out |
| 22:24 | Pupeno | How should I run the REPL so it picks the checkouts if I'm not using lein to run the REPL? |
| 22:25 | amalloy | mattmitchell: there's something in ninjudd's/my useful that might make this a little more visually pleasing |
| 22:25 | livingston | typically rows or nests of if's beg for cond |
| 22:26 | mattmitchell | amalloy: ok great. i think i was just browsing through that this afternoon |
| 22:26 | livingston | but this is just weird. |
| 22:26 | mattmitchell | livingston: ha well, my example? yeah, need something real world. |
| 22:26 | livingston | could you share a more real function, that might help |
| 22:27 | amalloy | mattmitchell: https://gist.github.com/1150681 |
| 22:27 | mattmitchell | livingston: i would have to dig around a little bit. I'll come back with something that better describes the "issue" I'm having. |
| 22:28 | amalloy | uses useful.fn/given |
| 22:28 | livingston | mattmitchell: a more specific question will get more specific feedback, I'm sure. |
| 22:29 | mattmitchell | livingston: yep totally. i'll post a real example tomorrow sometime |
| 22:29 | mattmitchell | amalloy: that's nice, yeah more declarative and less ify |
| 22:29 | livingston | a list of functions and reduce also comes to mind, but again... depends on what |
| 22:30 | mattmitchell | livingston: using apply and reduce on a list of functions? |
| 22:30 | amalloy | just reduce, really |
| 22:31 | livingston | just reduce with an initial value being your map that's being progressively modified, each function returns a new map. |
| 22:31 | amalloy | &(let [fixers [#(if (= 1 (:id %)) (assoc % :id 2) %)] (reduce #(%2 %1) {:id 1} fixers)) |
| 22:32 | lazybot | java.lang.IllegalArgumentException: let requires an even number of forms in binding vector |
| 22:32 | amalloy | &(let [fixers [#(if (= 1 (:id %)) (assoc % :id 2) %)]] (reduce #(%2 %1) {:id 1} fixers)) |
| 22:32 | lazybot | ⇒ {:id 2} |
| 22:32 | mattmitchell | ahh that's interesting, cool |
| 22:33 | livingston | I mean there are a million things to do (merge (if test {new-key-vals} {}) (merge (if test2 {other-new} {}) original)) etc. |
| 22:35 | mattmitchell | livingston: oh ok, multiple args to merge, need to remember that. |
| 22:36 | livingston | that too |
| 22:57 | srid | (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:58 | livingston | ,(doc find-doc) |
| 22:58 | clojurebot | "([re-string-or-pattern]); Prints documentation for any var whose documentation or name contains a match for re-string-or-pattern" |
| 22:58 | amalloy | &(doc map) |
| 22:58 | lazybot | ⇒ "([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:58 | livingston | ,(doc doc) |
| 22:58 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 23:00 | srid | ah, thx. just figured that by looking at http://clojure.org/cheatsheet |
| 23:14 | livingston | nice |
| 23:19 | amalloy | &(doc *print-level*) |
| 23:19 | lazybot | ⇒ "; *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:20 | amalloy | hm, not quite |
| 23:20 | amalloy | &(doc *print-length*) ;; srid |
| 23:20 | lazybot | ⇒ "; *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 |