2010-03-01
| 00:08 | brian_ | hi , i have a noobie question about libraries, this might not be specific toclojure,but I am encounteringit for the first time with a clojure library, that is a clojure api for an external database library. What I don't get is that it isn't apparent how the api "knows" where the database library is, as there isn't anyplace for meto configure the api to know where it is.Is there some other way that this information gets shared by progr |
| 00:08 | brian_ | ams these days? |
| 00:26 | brian_ | this is specifically tokyocabinet |
| 00:27 | TheBusby | brian: I can't help you with your question specifically, but I suspect you'll have the best luck looking at the source code/documentation |
| 00:28 | TheBusby | if that doesn't help, it might be valuable to contact the author of the library and ask |
| 01:17 | nunb | is this the right place to ask about leiningen? |
| 01:19 | nunb | For leinengen, which is the checkout director? I am trying to do the step >>Then run "lein-stable deps" in your checkout.<< from the github instructions README |
| 01:19 | nunb | *directory, |
| 01:20 | Chousuke | nunb: the dir containing the project.clj file, usually |
| 01:26 | nunb | I can only see ~/.m2 and that doesn't have a project.clj |
| 01:27 | Chousuke | nunb: you didn't download the sources? :( |
| 01:27 | Chousuke | :/* even |
| 01:28 | nunb | I did `lein-stable self-install` after downloading the shell-script |
| 01:28 | nunb | Do you mean the clojure sources? |
| 01:28 | Chousuke | hm |
| 01:28 | nunb | I guess I just don't know what dir. they are in. |
| 01:28 | Chousuke | no, I mean whatever project you're trying to install I guess :P |
| 01:30 | nunb | Chousuke: Ok, I've made a project.clj using the text on github: `~/programming/clojure-stuff/leiningen] tallinn: cat > project.clj` |
| 01:31 | nunb | And now lein-stable deps works! |
| 01:32 | Chousuke | what are you donloading the deps for, though? |
| 01:33 | Chousuke | I mean, creating an empty project.clj downloads the dependencies for an empty project, and I don't see why you'd do that. :/ |
| 01:34 | Chousuke | if you're following the "hacking" section on leiningen, that's only needed if you want to do something with the git version of leiningen |
| 01:35 | Chousuke | in which case you'd have a leiningen git checkout :) |
| 02:14 | nunb | Chousuke: yes, that was what I was trying to do. I see now, the original was just a small shell-script, I should have git-cloned the full thing. |
| 02:16 | nunb | Also, I am not sure if leiningen or clojureX is the way to go (I am on OSX) |
| 03:24 | talios | anyone awake? |
| 03:25 | TheBusby | only the few who are up during the witching hours |
| 03:26 | talios | :) When did symbolmacro's first appear in clojure? Are they a 1.2 thing? Never seen them before |
| 03:32 | replaca_ | talios: symbolmacros, really? where do you see them? |
| 03:33 | spariev | afaik it from contribs master branch - http://richhickey.github.com/clojure-contrib/macro-utils-api.html |
| 03:33 | talios | in clojure-contrib - http://gist.github.com/318201 |
| 03:33 | talios | that test fails under clojure-maven-compiler:1.3.2-SNAPSHOT - and it's holding me back making a release :( Only, I don't know why it failing under one version of my plugin and not the prior |
| 03:34 | talios | I know I've changed the way the clojure:test goal runs slightly, but this failure isn't quite the failure I expected to see :( |
| 03:35 | replaca_ | Ah, yes. I think that's an experiment from Konrad Hinsen is doing, not an official language direction |
| 03:52 | esj | Hello all |
| 04:02 | AWizzArd | Moin esj |
| 04:12 | Leafw | I'd appreciate help building clojure contrib |
| 04:13 | Leafw | never mind |
| 04:15 | talios | 'lo |
| 04:17 | Leafw | so duck streams has disappeared from clojure contrib? |
| 04:17 | Leafw | is there anywhere where it's documented hwhat's happening with clojure contrib? |
| 04:17 | talios | There was talk the other day of somethings from contrib moving to core |
| 04:18 | Leafw | I have the impression that clojure dev suddenly closed up. I can't find relevant info anymore. |
| 04:18 | talios | clojure-contrib was going through some reorg, moving to maven etc. some things moving to core. |
| 04:18 | Leafw | find -iname "*duck*" lists nothing on either c or c.c repos. |
| 04:19 | Leafw | so it got moved to some IO package |
| 04:19 | Leafw | (I hope) |
| 04:19 | talios | ahh clojure.io went ahead did it? |
| 04:19 | Leafw | no idea |
| 04:20 | Leafw | I lost track. I guess all of this is happening in emails |
| 04:20 | Leafw | looks like there is a c.c.io, it's new to me |
| 04:20 | Leafw | commit c8be49609099ffca541f95b827a41179cbe83080 |
| 04:20 | Leafw | Author: Stuart Sierra |
| 04:20 | AWizzArd | Contrib still contains the old duck-streams |
| 04:20 | Leafw | AWizzArd: in c.c.io I guess |
| 04:20 | AWizzArd | but now io is the new version, and the one which will imporve |
| 04:21 | Leafw | AWizzArd: latest pull on c.c. master does not show any *duck* file |
| 04:21 | AWizzArd | In the clojure-contrib.jar file that you can download from build.clojure.org |
| 04:21 | AWizzArd | There still is a duck-streams.clj |
| 04:21 | Leafw | not in master. |
| 04:21 | AWizzArd | So that old code won't break |
| 04:21 | AWizzArd | Right, in the repo itself there is no such file anymore. |
| 04:22 | AWizzArd | I guess by using this Maven thing one can build a clojure-contrib.jar which will include the old duck-streams.clj. |
| 04:23 | Leafw | it's a bit appaling that there isn't a simple way to build c.c.jar without going and learning an entirely new build system, aka mvn |
| 04:23 | talios | as opposed to using the the old build system you had to learn? |
| 04:23 | talios | or using leiningen, if they went that way |
| 04:23 | talios | or make. |
| 04:24 | Leafw | ant may be horrible, but at least just about all devs and their tools can use it |
| 04:24 | Leafw | same for make |
| 04:24 | Leafw | never mind. AS usual, we'll find a way around. |
| 04:24 | talios | install maven. "mvn install". thats all you need. |
| 04:25 | Leafw | it would have been the 'obvious' thing to just use clojure itself to build c.c. |
| 04:25 | Leafw | "all you need", you are kidding right. |
| 04:25 | Leafw | this is idle talk anyway. |
| 04:26 | Leafw | how funny that io.clj reads, in its first line: ";;; duck_streams.clj -- duck-typed I/O streams for Clojure" |
| 04:26 | talios | it would have been cool to see it use leiningen, but I'm glad Stuart decided to use my plugin. maven gives a lot of other benefits as well |
| 04:28 | Leafw | talios: to use mvn, I had to download it manually from apache website, and create a bash alias, and setup a JAVA_HOME to my JVM install. All of this because, otherwise, apt-get install mvn would result in about 400 Mb install of gcj and other stuff I really don't need in this tiny machine. |
| 04:29 | talios | use a real os :) anything that installs gcj these days isn't worth running |
| 04:29 | talios | must be a skank redhat based thing? |
| 04:29 | talios | :) |
| 04:29 | Leafw | ubuntu 9.10, but I do lots of java dev, and we have our own battery of JVM to test against. |
| 04:29 | talios | I bet if you installed ant via apt-get you'd have the same issue |
| 04:30 | Leafw | redhat users RPM, not APT. |
| 04:30 | Leafw | yes, ant had the same issue. But ant is part of a standard build chain of many apps. |
| 04:30 | Leafw | mvn is just new. I am sure it's better than ant. That is not hard. |
| 04:30 | talios | and so is maven. more and more these days |
| 04:31 | talios | mvn does have many an issue tho, a lot of them are fixed in the upcoming 3 release tho |
| 04:31 | Leafw | never mind, talios. |
| 04:31 | Leafw | I have heard that song before. |
| 04:31 | talios | hey - it's irc. we're meant to bitch :) |
| 04:31 | Leafw | indeed XD |
| 04:31 | eevar2 | Leafw: learn to use aptitude ;) -- gcj might be a recommended dependency, but if you have openjdk you probably shouldn't have to install it |
| 04:31 | Leafw | but this channel has always very constructive conversations. Let's keep it like that. |
| 04:31 | talios | seriously tho, maven 3 doesn't actually solve a lot of the pain points of m2 |
| 04:32 | talios | er, does |
| 04:32 | Leafw | nice slip. |
| 04:32 | talios | hur |
| 04:34 | Leafw | eevar2: I am sure it can be solved. The point here is that I'd rather not learn yet another piece of trivia. |
| 04:34 | Leafw | totally orthogonal to my task. |
| 04:43 | AWizzArd | Leafw: this maven approach is also complicated for people behind a firewall, because maven tries to download a few exabytes of data each time you use it. So I just switched to download from http://build.clojure.org/ |
| 04:44 | Leafw | AWizzArd: I noticed. |
| 04:47 | eevar2 | Leafw: if you'd rather build & maintain packages on your own, that a valid option too |
| 04:48 | Leafw | eevar2: it's all about a coherent build system for fiji, which needs both clojure and c.c jars (http://pacific.mpi-cbg.de) |
| 04:48 | eevar2 | but personally, I'd take 15 minutes to get to know aptitude better |
| 04:49 | eevar2 | debian repos aren't neccessarily cutting edge either, so you might not always have a choice. -- but installing gcj really _is_ optional |
| 04:58 | tomoj | gcj? |
| 04:59 | tomoj | oh, I thought it was a clojure tool |
| 04:59 | Leafw | no need for "gnu clojure", it's already under an open license :) |
| 05:06 | ordnungswidrig | Leafw: you know: (not (= 'open 'open)) :-) |
| 05:13 | talios | was interesting - I had to go through last week and add EPL headers to all the code for the clojure-maven-plugin cause the Debian guys wanted to include the plugin in the distro |
| 05:13 | talios | so there's some sign of cutting edgeness there |
| 05:14 | ordnungswidrig | talios: cool |
| 05:14 | ordnungswidrig | talios: it was a long way for maven to enter debian. (Maven is very hard to bootstrap cleanly) |
| 05:14 | talios | yeh, which is why I really want to get a new release out, only it breaks clojure-contrib now :( |
| 05:15 | talios | ordnungswidrig: yeh, I saw that with JPackage back in the day, trying to package all plugins and dependencies just seems like a fools gain of duplicated effort |
| 05:16 | talios | will be interesting to see how Jigsaw will help or hurt there |
| 05:16 | ordnungswidrig | Debian is very strict about building from source only. |
| 05:16 | ordnungswidrig | Jigsaw? |
| 05:16 | talios | Jigsaw's the module system coming in Java 7 |
| 05:16 | talios | source level modularity |
| 05:17 | talios | kinda like a poor mans OSGi, but with the advantage of being compile time |
| 05:17 | talios | and without OSGi lifecycle/services |
| 05:38 | vy | chouser: AFAIR, you have a clj library for JNA bindings. Do you know how can I make com.sun.jna.Function/getFunction to load a static library? (It always looks for a .so file, but I have an .a, and I don't want to convert it to a shared library.) |
| 05:42 | vy | chouser: People say I can't: http://stackoverflow.com/questions/1277034/jna-load-a-lib-library But I can easily bind static libraries using Native.register() method in Java. |
| 06:00 | tomoj | is there any support yet in leiningen for pushing a project to a maven repo? |
| 06:01 | tomoj | oh, I see, we can just scp the pom |
| 06:01 | tomoj | and jar |
| 06:02 | talios | I thought it had a deploy option? |
| 06:02 | talios | I thought I saw something about automatically deploying to clojars |
| 06:11 | tomoj | hmm |
| 06:11 | tomoj | maybe in the clojars plugin |
| 06:12 | tomoj | I don't want to deploy to clojars though :( |
| 06:13 | talios | that may be why people still like to use my maven plugin, having the rest of maven's infrastructure and project support is handy |
| 06:14 | talios | I really need to do some more work on Polyglot Maven as well: http://polyglot.sonatype.org/clojure.html |
| 06:14 | talios | maven pom files written in clojure |
| 06:14 | talios | (and scala, groovy, yaml, ruby) |
| 06:15 | talios | the problem with that however is things like the maven release plugin want to rewrite an XML file with version number changes, not some weird scripty thing |
| 06:17 | talios | 'lo rich |
| 06:17 | rhickey | hi |
| 06:21 | talios | oh well - night all. |
| 06:28 | raek | is the convention to name namespaces in singular or plural? i.e. x.y.bar or x.y.bars for a library that works with "bars"? |
| 06:29 | esj | i'm guessing singular |
| 06:32 | bsteuber | seems to be about 50:50 in clojure-contrib |
| 06:45 | dsop | rhickey: may I use the clojure logo from your brother in an CC non-commercial licensed work? |
| 06:46 | rhickey | dsop: the Clojure logo should only be used to refer to Clojure itself |
| 06:47 | dsop | rhickey: well I wanted to create a wallpaper for clojure |
| 06:47 | rhickey | not for distribution |
| 06:47 | dsop | okay |
| 06:47 | dsop | thanks |
| 06:47 | rhickey | thabks for asking |
| 06:47 | rhickey | thanks |
| 06:56 | zmila | hello, rhickey! just my appreciations of your great work. i'm studying the language while solving ProjectEuler problems. |
| 06:56 | rhickey | zmila: Hi, have fun! |
| 06:56 | vy | Does "seq" command _clone_ the original object? |
| 06:57 | rhickey | vy: no |
| 06:58 | vy | I want to create a copy of an int[] returned from a C function (of Pointer return type) call via JNA. Is Arrays.copyOf my only way? |
| 07:00 | bsteuber | vy: why not just put it in a clojure vector? |
| 07:02 | vy | bsteuber: Right! That's what I was looking for! |
| 07:06 | bsteuber | rhickey: I was very amazed when learning you're a Go player! Though I guess you don't have much time left to play... |
| 07:09 | bsteuber | I'm a german 6d and usung Clojure to manage my Go problem collection, so I find this very cool |
| 07:09 | bsteuber | *using |
| 07:09 | rhickey | bsteuber: yeah, I've been slacking off with my Go, but Go is a lifelong process... |
| 07:10 | rhickey | so hopefully I'll get back to it |
| 07:11 | rhickey | bsteuber: I never quite made it to US 1D, was playing at 2k at my last peak, so a long way to go |
| 07:11 | AWizzArd | Aren't computers around that lvl? 2k / 1k? |
| 07:12 | vy | How can I make "ints" work? (ints [0 1 3 4 6 8 10]) complains that "clojure.lang.PersistentVector cannot be cast to [I". |
| 07:12 | rhickey | AWizzArd: what are you implying? :) |
| 07:12 | bsteuber | rhickey: If you need any lessons, just tell me :) |
| 07:12 | rhickey | bsteuber: thanks! |
| 07:12 | AWizzArd | vy: can you somehow use into-array? |
| 07:13 | AWizzArd | ,(into-array Integer/TYPE [10 20 30]) |
| 07:13 | clojurebot | #<int[] [I@14d8dd6> |
| 07:13 | AWizzArd | ,(vec (into-array Integer/TYPE [10 20 30])) |
| 07:13 | clojurebot | [10 20 30] |
| 07:13 | vy | My bad! Thanks. |
| 07:14 | bsteuber | awizzard: I believe the best bots are already past 1st dan |
| 07:14 | AWizzArd | bsteuber: do you think this is mostly because of improvements in software or thanks to hardware which gets exponentially faster? |
| 07:16 | bsteuber | awizzard: I guess both - those Monte Carlo algorithms sort of kick ass, even if they're brute force like anything else |
| 07:17 | AWizzArd | In chess they left the brute force approach behind. Those programs are so very good now, they only need ordinary desktop hardware, (notebooks, single core, etc). That is enough to beat Grand Masters. |
| 07:19 | AWizzArd | Rybka for example does not even have an opening book anymore, and instead calculates its moves itself. Simply because this is better than everything humans produced within the past hundred years. Crazy stuff. |
| 07:19 | bsteuber | definitely |
| 07:20 | vy | In SLIME, C-c C-c'ing an expression -- when *warn-on-reflection* is enabled -- doesn't output anything neither in repl buffer, nor in inferior lisp buffer. Everytime I have to paste the code into repl manually. Any solutions for this? |
| 07:20 | AWizzArd | vy: can you try C-c C-k and see if that changes anything? |
| 07:21 | vy | AWizzArd: No changes. |
| 07:32 | bsteuber | das programm ist ziemlicher mist :) |
| 07:32 | bsteuber | hab nach einer woche auch schon wieder die lust verloren |
| 07:32 | AWizzArd | bsteuber: wrong window :) |
| 07:32 | dsop | hrhr |
| 07:32 | bsteuber | ich hab halt versucht die gängigen algorithmen nachzubauen und war schnell frustriert wie viel langsamer mein zeug war als der C-kram |
| 07:32 | bsteuber | oh, sorry :) |
| 07:32 | dsop | but I wonder what he's talking about |
| 07:33 | AWizzArd | seems to be german I guess :) |
| 07:33 | dsop | I know that it's german |
| 07:33 | dsop | but I wonder the context |
| 07:33 | bsteuber | I was talking about my lousy efforts to start a Go programming framework in Common Lisp |
| 07:33 | dsop | okay |
| 07:33 | bsteuber | http://sourceforge.net/projects/cl-go/ |
| 07:33 | bsteuber | it really sucks, so don't read it :) |
| 07:34 | bsteuber | but I might try again with clojure |
| 07:34 | vy | Can anybody help with this reflection/coersion related problem, please: http://privatepaste.com/d95ec79026 |
| 07:35 | bsteuber | I'm glad I wasn't talking 'bout porn links :) |
| 07:42 | dsop | bsteuber: :) |
| 08:07 | AWizzArd | vy: you are calling the .invoke function and from your paste it is not obvious that you have type hinted all arguments in those calls. |
| 08:25 | danlei | what's the preferred way to remove a first occurence from a sequence? (in cl, remove(-if) takes a count parameter ...) no big deal to write a remove-first, but maybe I've missed something obvious ... |
| 08:27 | danlei | i.e. something better than: (defn remove-first [pred [head & tail]] (lazy-seq (if (pred head) tail (cons head (remove-first pred tail))))) |
| 08:34 | bsteuber | sth. must be wrong with my (ELPA) swank-clojure setup |
| 08:34 | bsteuber | I only have M-x clojure-mode available after starting swank |
| 08:35 | bsteuber | which means I don't have syntax highlighting before starting a REPL |
| 08:35 | bsteuber | that's not how it should be, is it? |
| 08:35 | rhickey | does "mvn -Denv=local package" still work for contrib? Not in readme anymore |
| 08:36 | licoresse | is this necessary? (map #(int (* 10 %)) (take 4 (repeatedly rand))) |
| 08:36 | licoresse | ,(map #(int (* 10 %)) (take 4 (repeatedly rand))) |
| 08:36 | clojurebot | (7 1 2 2) |
| 08:37 | licoresse | what is a terser form to represent 4 random numbers in a list |
| 08:38 | rhickey | ,(doc rand-int) |
| 08:38 | clojurebot | "([n]); Returns a random integer between 0 (inclusive) and n (exclusive)." |
| 08:39 | bsteuber | so (take 4 (repeatedly #(rand-int 10))) is best? |
| 08:39 | AWizzArd | yes |
| 08:40 | licoresse | ah, the # |
| 08:40 | licoresse | (doc repeatedly) |
| 08:40 | clojurebot | "([f]); Takes a function of no args, presumably with side effects, and returns an infinite lazy sequence of calls to it" |
| 08:40 | licoresse | I forgot the # |
| 08:41 | licoresse | thanks |
| 08:41 | danlei | did someone answer my remove question? (was disconnected for about 2 minutes) |
| 08:42 | AWizzArd | danlei: nein |
| 08:42 | AWizzArd | so, what you suggested seems plausible |
| 08:42 | danlei | AWizzArd: danke |
| 08:43 | danlei | > ok, maybe an optional parameter like :count would be nice to have? |
| 08:44 | ordnungswidrig | danlei: no need because repeatedly is lazy. |
| 08:45 | danlei | ordnungswidrig: hm? |
| 08:45 | bsteuber | anderes thema :) |
| 08:46 | danlei | wir könnten ja schon fast nen deutschen clojure-kanal aufmachen ;) |
| 08:46 | AWizzArd | there already is one.. |
| 08:46 | ordnungswidrig | danlei: #clojure.de |
| 08:46 | danlei | oh |
| 08:46 | danlei | thanks |
| 08:48 | Leafw | I am just starting to explore defprotocol/reify and I wonder: is it necessary for a protocol to be defined with always at least one argument (which is the 'this' or 'self', IIUC). It makes sense later on when calling (method instance), but why should defprotocol be contaminated with that idea? |
| 08:48 | Leafw | it's not like that argument won't ever be the first one. Python shows it, java hides it. |
| 08:49 | AWizzArd | I think that when you want to use “this” you add a “:as this” to your declaration. |
| 08:49 | AWizzArd | This is how I did it so far. |
| 08:49 | AWizzArd | But the fns themselves don’t need to explicitly list this arg. |
| 08:50 | Leafw | ,(defprotocol A (do-a [] "")) |
| 08:50 | clojurebot | java.lang.Exception: Unable to resolve symbol: defprotocol in this context |
| 08:50 | Leafw | hum the bot doesn't know. that fails, though. It needs an arg. |
| 08:50 | AWizzArd | The bot does not run the freshest clojure.jar |
| 08:51 | Leafw | so, AWizzArd: do your defprotocol declarations not have an arg at least in each method listed? |
| 08:51 | AWizzArd | Correct. |
| 08:51 | Leafw | how? Doesn't run. |
| 08:51 | AWizzArd | Leafw: look at line 32: http://gist.github.com/306174 |
| 08:51 | Leafw | paste the above in your repl. To work, it needs (defprotocol A (do-a [a] "")) |
| 08:52 | Leafw | deftype, not defprotocol |
| 08:52 | AWizzArd | ah okay |
| 08:52 | clojurebot | Leafw: aye aye skipper |
| 08:52 | Leafw | deftype is like defprotocol but more like a java class declaration |
| 08:55 | rhickey | danlei, bsteuber: repeatedly now takes n arg, so (repeatedly 4 #(rand-int 10)) works |
| 08:56 | danlei | rhickey: nice, but I was talking about remove |
| 08:58 | rhickey | danlei: where (remove n pred coll) would remove some but not the rest of them? |
| 08:58 | danlei | tm rhickey yes |
| 08:58 | danlei | s/tm// |
| 09:00 | danlei | rhickey: if I wanted to remove only the first occurence, the best I came up with was: (defn remove-first [pred [head & tail]] (lazy-seq (if (pred head) tail (cons head (remove-first pred tail))))). A "count" argument to remove would be nice, imho |
| 09:06 | rhickey | is there paredit magic for turning (a (b ...)) into (b (a ...)) ? |
| 09:07 | danlei | rhickey: just transpose-words if you're between a and ( |
| 09:09 | danlei | (anywhere between a and b actually) |
| 09:10 | rhickey | actually it's often (a b (c d (...)) ==> (c d (a b (...)) that I want |
| 09:11 | danlei | hm ... |
| 09:15 | chouser | danlei: (defn remove-n [n p s] (apply concat (map #(if (< %2 n) (when-not (p %1) [%1]) [%1]) s (seq/reductions #(if (zero? %2) (inc %1) %1) 0 s)))) |
| 09:16 | chouser | danlei: I'd bet there's an even better solution. |
| 09:17 | danlei | chouser: thanks |
| 09:17 | danlei | (gotta read up on seq/reductions) |
| 09:18 | bsteuber | chouser: (apply concat (map ... => (mapcat ... |
| 09:18 | bsteuber | or am I wronng? |
| 09:18 | bsteuber | -n |
| 09:18 | chouser | bsteuber: heh. nope, not wrong. |
| 09:20 | chouser | I don't really like wrapping every element in a one-item vector, but it's the simplest way to support nil and false values in the input seq |
| 09:21 | chouser | (seq/reductions #(if (zero? %2) (inc %1) %1) 0 s) might warrant its own name. "counting" or something. |
| 09:21 | chouser | er |
| 09:21 | chouser | whoops |
| 09:21 | chouser | (defn remove-n [n p s] (mapcat #(if (< %2 n) (when-not (p %1) [%1]) [%1]) s (seq/reductions #(if (p %2) (inc %1) %1) 0 s))) |
| 09:22 | chouser | had a stray 'zero?' in the original |
| 09:26 | rhickey | it's interesting, would you want the same n arg for filter, and how would you describe what it does? |
| 09:26 | rhickey | since remove is just sugar for filter |
| 09:28 | danlei | rhickey: (remove-if-not #'evenp '(1 2 3 4 5 6 7) :count 2) => (2 4 5 6 7) |
| 09:28 | danlei | rhickey: in other words just the same as remove but for (complement pred) |
| 09:28 | rhickey | danlei: n arg to remove is written, just wondering about the filter question |
| 09:29 | chouser | remove-if-not == filter :-P |
| 09:29 | danlei | rhickey: yes, I mean: filter could do the same as remove, but with (complement pred) |
| 09:30 | rhickey | yes, remove is filter (complement pred), the question is, while n seems to make complete sense for remove, does it for filter? |
| 09:30 | chouser | I appreciate the relative scarceness of numeric indexes and counters in the clojure core fns. |
| 09:30 | danlei | chouser: learned about reductions from your solution, seems to be handy |
| 09:30 | chouser | I'm not sure n makes sense for core filter or remove |
| 09:31 | rhickey | chouser: but remove-n is clearly not easy with core fns |
| 09:31 | danlei | I second that (not easy enough) |
| 09:32 | rhickey | and the n arg doesn't really fit with filter, IMO |
| 09:32 | chouser | I'd rather seen filter/remove support extra seqs like map does |
| 09:33 | chouser | if "counting" were defined, and remove took extra seqs, remove-n would be just: |
| 09:33 | chouser | (defn remove-n [n p s] (remove #(< %2 n) s (counting p s))) |
| 09:34 | rhickey | ? |
| 09:34 | chouser | oh. maybe not. |
| 09:34 | chouser | er. nevermind. |
| 09:35 | danlei | rhickey: I agree that n doesn't make as much sense for filter as for remove (at least intuitively), but do you think it would hurt? |
| 09:35 | chouser | I should never ever post code without testing. |
| 09:37 | danlei | (where "hurt" = have negative consequences) |
| 09:43 | chouser | (defn remove-n [n p s] (remove #(and (< %2 n) (p %1)) s (counting p s))) |
| 09:43 | chouser | there |
| 09:43 | chouser | that's what I meant. |
| 09:46 | chouser | that looks easy enough to me, and I've wanted multi-seq filter and remove before. |
| 09:46 | danlei | hm |
| 09:47 | Leafw | how is case different than condp ? |
| 09:47 | Leafw | I guess case is a new fn, that compiles to a switch statement? |
| 09:47 | chouser | case requires all your test values to be constant at compile time |
| 09:47 | Leafw | chouser: ok, so a switch. Thanks. |
| 09:48 | danlei | chouser: the thing is, I sometimes need (remove n ... but I havent had the need for a multi-seq remove/filter up to now |
| 09:48 | Leafw | I'm reading http://gist.github.com/306174 that AWizzard posted. It's the first coherent non-trivial code that uses defprotocol, deftype and so on that I have seen. |
| 09:48 | danlei | chouser: on the other hand, you're right in that it's not too complicated like that |
| 09:49 | chouser | hm. I've never needed remove n. :-) |
| 09:49 | danlei | chouser: how would you implement (shuffle ...)? ;) |
| 09:49 | chouser | danlei: shuffle as in randomize the order of a seq? |
| 09:50 | Leafw | by the way, can deftype extend a type that has already been defined, to avoid writing in all its functions/methods? |
| 09:50 | danlei | chouser: yes, my first approach would be: |
| 09:50 | danlei | chouser: (defn shuffle [s] (loop [s s acc nil] (if (seq s) (let [e (seq/rand-elt s)] (recur (remove 1 #{e} s) (conj acc e))) acc))) |
| 09:50 | danlei | chouser: (given a working (remove n ...) |
| 09:50 | chouser | danlei: I wouldn't implement it at all. I would use seq/shuffle. :-) |
| 09:50 | danlei | chouser: yes ;) |
| 09:50 | danlei | chouser: you know what I mean ;) |
| 09:51 | chouser | and, note how it's defined |
| 09:51 | danlei | uses java interop, i guess |
| 09:52 | chouser | right, because Java's array shuffle is so much faster than anything that would likely be built on seq. |
| 09:53 | danlei | it was just an example of a situation, where you'd need something like (remove n, when you're trying to solve with them means of clojure.core |
| 09:54 | Leafw | and would anyone elaborate on how is definterface different than defprotocol? |
| 09:54 | Leafw | (definterface doesn't have any doc string) |
| 09:56 | chouser | sure. I can certainly see that remove-n could be useful in some apps, but in my mind there's always a tension between getting everything that might be useful into core (or even contrib) and keeping those as small and general as possible. |
| 09:56 | danlei | chouser: in general, I'm not against your proposal (remove/filter taking multiple seqs) |
| 09:57 | chouser | danlei: well, that's good. But I think rhickey is. :-) |
| 09:57 | chouser | I believe I've mentioned it before and was rejected. |
| 09:57 | Leafw | he, I second that chouser. An extremely horizontal API makes it hard to internalize, more even for a beginner. |
| 09:57 | danlei | chouser: I guess that most of the time it would be used for doing (remove n ...) ;) |
| 09:57 | chouser | danlei: :-P |
| 10:00 | danlei | chouser: btw, do you have admin rights in clojure-dev? I applied for it, but haven't been accepted till now (has been a while) |
| 10:00 | chouser | danlei: nope, sorry. |
| 10:00 | danlei | chouser: ok |
| 10:02 | AWizzArd | Nice, finally the #() in ` is fixed. |
| 10:14 | danlei | Is there going to be a #: reader macro for types? |
| 10:15 | AWizzArd | danlei: to read deftypes back in? |
| 10:16 | danlei | AWizzArd: yes |
| 10:16 | AWizzArd | The question is how we would read them back in with the corresponding deftype declaration missing. |
| 10:16 | danlei | missing -> errror |
| 10:17 | danlei | (my first intuition, not properly reflected) |
| 10:21 | danlei | sorry, got disconnected again |
| 10:23 | rhickey | chouser: sorry, got called away. What does it mean for a filter to take multiple seqs? What's getting fitlered? |
| 10:23 | rhickey | filtered |
| 10:23 | chouser | rhickey: would just items from the first seq. the others would be passed to the predicate though, as in map |
| 10:23 | rhickey | meh |
| 10:23 | chouser | s/just/just return/ |
| 10:24 | chouser | I think your response was stronger in the negative last time, so perhaps I'm making progress. :-) |
| 10:24 | chouser | but it would avoid this kinds of wrap-in-a-vector/mapcat dance |
| 10:24 | AWizzArd | Funnily I missed such a filter fn some days ago. |
| 10:25 | rhickey | so, given a fast zip, don't you really want filter-key? |
| 10:25 | AWizzArd | well, zip would also be good |
| 10:25 | rhickey | or something that split out predicate and return |
| 10:25 | AWizzArd | With zip in place such a multi filter wouldn't be required |
| 10:27 | AWizzArd | in c.l.l some days ago someone wanted to keep those elements from the first coll where at the same position in the second coll it says true: (filter (fn [a b] b) [10 20 30 40] [true false true true]) |
| 10:28 | AWizzArd | or even better: (filter #(second %) (zip [10 20 30 40] [true true false true])) |
| 10:28 | AWizzArd | (filter second (zip coll1 coll2)) |
| 10:28 | rhickey | #(second %) == second |
| 10:28 | AWizzArd | yes :) |
| 10:30 | chouser | (for [[x i] (zip s (counting p s)) :when (and (< i n) (p i))] x) |
| 10:30 | chouser | this is what you mean by a "fast zip"? |
| 10:30 | danlei | AWizzArd: using series: (choose #z(t nil t) #z(1 2 3)) => #z(1 3) |
| 10:30 | AWizzArd | in Haskell probably a fold on a zip |
| 10:32 | rhickey | chouser: one absolutely minimizing the expense of the tuple and any other overheads |
| 10:32 | AWizzArd | I don't find choose orthogonal enough to filter+zip, but that's just my opinion. |
| 10:33 | rhickey | 'counting' seems weird also |
| 10:33 | chouser | :-( |
| 10:34 | rhickey | the recursive direct lazy-seq definition is pretty clean |
| 10:34 | AWizzArd | Would this zip take exactly two colls or optionally more? |
| 10:40 | AWizzArd | btw, my filter above should have been a reduce of course |
| 10:43 | LauJensen | Hey guys |
| 10:44 | rhickey | chouser: is that right? (for [[x i] (zip s (counting p s)) :when (and (< i n) (p i))] x) |
| 10:49 | bsteuber | what's the most idiomatic way to represent a 2d array? |
| 10:50 | bsteuber | An array of arrays? A flat array? A specific construct? |
| 10:50 | AWizzArd | (make-array String 10 5) |
| 10:51 | AWizzArd | 2d arrays can idiomatically represent 2d arrays. |
| 10:51 | rhickey | chouser: (take 10 (counting even? (range 10))) == (0 1 1 2 2 3 3 4 4 5) ? |
| 10:51 | chouser | rhickey: *sigh* no, because :when is not remove |
| 10:51 | chouser | yeah |
| 10:51 | Chousuke | ignoring the fact taht arrays are not really idiomatic in clojure :P |
| 10:51 | Chousuke | sometimes you do need them, though. |
| 10:52 | Leafw | bsteuber: if you need very large arrays, be careful: each subarray is an Object, and can quickly blow up memory usage. For a 2D array to represent an image or a matrix, use the old trick of a one dimensional array with a 'width' to operate on its 'lines'. |
| 10:52 | bsteuber | well, I just want to represent a Go board |
| 10:53 | Leafw | that is small. Anything goes then. |
| 10:53 | AWizzArd | Maybe a simple vector is okay then? |
| 10:53 | chouser | (defn remove-n [n p s] (for [[x i] (map vector s (counting p s)) :when (or (>= i n) (not (p x)))] x)) |
| 10:53 | chouser | (defn counting [p s] (seq/reductions #(if (p %2) (inc %1) %1) 0 s)) |
| 10:53 | Chousuke | bsteuber: use vectors, then. arrays will just bring trouble for you :) |
| 10:54 | rhickey | chouser: I don't think it is supported by your argument for more generality |
| 10:54 | bsteuber | yeah, I guess I meant vectors, not array - have to be more precise with my language |
| 10:55 | rhickey | chouser: i.e. the role of the two seqs is hardwired |
| 10:58 | chouser | yeah, I can see that zip in for feels better than multi-seq filter/remove. |
| 10:59 | AWizzArd | yes |
| 11:00 | chouser | if when-not is an acceptible function, is :when-not an acceptible option for for/doseq? |
| 11:00 | rhickey | not today |
| 11:00 | rhickey | :) |
| 11:01 | chouser | (defn remove-n [n p s] (for [[x i] (zip s (counting p s)) :when (not (and (< i n) (p x)))] x)) |
| 11:01 | rhickey | chouser: but this remove-n still is. So this counting thingy generator keeps running long after its utility is over |
| 11:01 | rhickey | as does zip |
| 11:02 | rhickey | whereas the recursive definition of remove-n drops the recursion as soon as possible and returns the tail |
| 11:02 | chouser | ah |
| 11:03 | rhickey | (if (pos? n) |
| 11:03 | rhickey | (if (pred (first s)) |
| 11:03 | rhickey | (removex (dec n) pred (rest s)) |
| 11:03 | rhickey | (cons f (removex n pred (rest s)))) |
| 11:03 | rhickey | s) |
| 11:03 | rhickey | that's what I don't like about counting and its ilk |
| 11:04 | AWizzArd | rhickey sees such things on the first glimpse, fascinating :) |
| 11:07 | powr-toc | Does anyone know how to read a clob out of a database using c.c.sql, and with-query-results? I get a SQLException even when forcing the seq inside with-query-results: "You cannot invoke other java.sql.Clob/java.sql.Blob methods after calling the free() method or after the Blob/Clob's transaction has been committed or rolled back." |
| 11:11 | duncanm | morning rhickey |
| 11:11 | rhickey | duncanm: hi |
| 11:13 | rhickey | also recursive version calls pred only once per item |
| 11:15 | AWizzArd | powr-toc: you can do a doall inside the with-query-results on the results |
| 11:15 | rhickey | but does hardwire counting those dropped, vs say, those kept |
| 11:15 | powr-toc | AWizzArd: it doesn't work, as I get the exception above |
| 11:16 | powr-toc | I have this inside with-query-results: (doall (map (fn [r] (slurp* (. (:clobdata r) getAsciiStream))) rs)) |
| 11:18 | bsteuber | Is it actually possible to directly download something from clojars over http or do people need to use leiningen etc.? |
| 11:20 | bsteuber | I'd like to give users a download-url for my jar |
| 11:21 | pjstadig | AFAIK, lein uses maven which uses http, so should be possible |
| 11:21 | pjstadig | http://clojars.org/repo/ |
| 11:21 | pjstadig | as a starting point |
| 11:22 | bsteuber | nice, thank you |
| 11:23 | bsteuber | actually this is a nice way of browsing clojars projects |
| 11:24 | rhickey | it would be nice if the clojars site had a directory page with at least one-line descriptions of the jars there, vs this file listing |
| 11:32 | cemerick | rhickey: it's just a maven repo -- that kind of directory info is sorta orthogonal to that. |
| 11:33 | cemerick | Nexus or nexus pro might allow one to search across project descriptions.... |
| 11:34 | cemerick | outside of that, it wouldn't be particularly difficult to use the maven APIs to pull together a page/site like you're describing. |
| 11:35 | danlarkin | I think _ato's got something in the works |
| 11:35 | danlarkin | don't know what's become of it though |
| 11:47 | brandonw | speaking of ato, has anyone used ato's nailgun .jar on clojars? i think it is version 0.7.1 |
| 11:47 | brandonw | it doesn't work for me-- gives me an error about the POM not being 4.0.0 compliant |
| 11:48 | Raynes | brandonw: It still grabs it. |
| 11:48 | Raynes | AFAIK |
| 11:57 | brandonw | Raynes: it is only a warning, and i googled it and people said nothing went wrong even though they got the error |
| 11:57 | brandonw | however, when i do `lein nailgun` it shows an error, and `lein help` doesn't display nailgun as a task |
| 11:58 | bsteuber | is there any difference between [org.clojure/clojure-contrib "1.2.0-SNAPSHOT"] and [org.clojure/clojure-contrib "1.2.0-master-SNAPSHOT"] ? the former seems newer |
| 11:59 | danlarkin | stuart removed the "-master" part from the pom in early February |
| 12:00 | danlarkin | not sure why |
| 12:00 | bsteuber | all this master/new/nothing inconsistency is a bit annoying |
| 12:00 | Raynes | Late January, actually. |
| 12:00 | Raynes | bsteuber: I agree. |
| 12:01 | Raynes | The build breakage which means no new contrib snapshots in the last month is annoying as well. Especially after the name changes. |
| 12:02 | bsteuber | I wasn't aware of that - so you currently can't compile contrib? |
| 12:27 | cemerick | bsteuber, Raynes: you should fundamentally not be depending upon any SNAPSHOT version, unless you're accepting of breakage. That's essentially definitional. |
| 12:29 | stuartsierra | Clojure-contrib builds fine. |
| 12:29 | stuartsierra | There are some errors reported by test, something JMX related. |
| 12:37 | bsteuber | cemerick: I know, but for a toy project, I'm willing to deal with breakage for new features :) |
| 12:47 | AWizzArd | cemerick: at least cells show up now, and rhickey depends on defprotocol and deftype. So it is a sign that those things get more stable :) |
| 12:50 | cemerick | AWizzArd: yeah, my only point is that things can change at any time. Protocols et al. could get pushed out to 1.3 on a whim. If one needs to depend on things in a non-release version, it's best to clone the git repo, and use a built artifact pulled from your own maven repo -- or, at the very least, fix your snapshot versions to a specific snapshot timestamp so you're not following HEAD on every zig and zag. |
| 12:51 | AWizzArd | yes, a little bit care on the end-user site makes sense for non-toy projects |
| 12:52 | bsteuber | huh, I just tried to install clojure-test-mode via ELPA, but I get an error about swank-clojure.el already existing |
| 12:53 | bsteuber | of course it exists :) |
| 12:53 | bsteuber | so do I really need to delete it first? |
| 12:57 | bsteuber | hm, this worked, but in general ELPA seems quite unreliable to me |
| 13:30 | derefed | I'm following this tutorial to set up clojure with emacs: http://riddell.us/tutorial/slime_swank/slime_swank.html and I'm running into a problem in the Configure Emacs section |
| 13:31 | derefed | emacs can't find swank-clojure-autoload |
| 13:31 | derefed | I can't find it in any of the subdirectories of what I installed either |
| 13:32 | derefed | also, on the add-to-list line just after ;; swank-clojure, that path doesn't exist |
| 13:33 | derefed | have these been changed to something else? |
| 13:34 | dnolen | derefed: save yourself some time, setup Clojure via ELPA |
| 13:34 | derefed | what's ELPA? |
| 13:34 | dnolen | if you go the ELPA route it's easy to use your own builds of Clojure via symlinks. |
| 13:35 | dnolen | Emacs Lisp Package Archive |
| 13:36 | dnolen | derefed: if you already have Emacs installed this will walk you through the steps, http://www.formconstant.net/diagrams/?p=54 |
| 13:36 | dnolen | just ignore the part about Aquamacs |
| 13:36 | derefed | excellent... thanks, dnolen! |
| 13:37 | dnolen | derefed: no problem. Clojure will be installed in a folder in your home directory called .swank-clojure, you can symlink your own jars there. |
| 13:38 | dnolen | derefed: oh yeah, where it says Option key, I of course mean Meta key. |
| 13:43 | eyeris | I am reading the implementation of clojure.core.pmap. Could someone tell me why the initial call to step drops the first n rets? http://github.com/richhickey/clojure/blob/49a7d6b8e14050a45df5332e768ba6647752215d/src/clj/clojure/core.clj#L4714 |
| 13:54 | rhickey | eyeris: that second copy of the sequence is used to bound the walk |
| 13:57 | eyeris | Oh, I see now. |
| 13:57 | eyeris | What it's returning is still based on rets, from the first argument. |
| 13:57 | eyeris | Thanks. |
| 14:07 | stuartsierra | I've been thinking about primitive types. |
| 14:08 | rhickey | stuartsierra: and? |
| 14:08 | stuartsierra | And why they conflict with the Object arg interfaces in IFn. |
| 14:09 | stuartsierra | What if functions that take primitive args were compiled with two different "invoke" methods? |
| 14:09 | stuartsierra | One that matches the IFn interface declarations, i.e. all args are Objects. |
| 14:09 | stuartsierra | One with the primitive argument types, called "invokePrimitive" or something. |
| 14:10 | stuartsierra | When the compiler knows it's dealing with primitives, it can call the primitive version; otherwise, it falls back on the boxed Object version. |
| 14:10 | rhickey | stuartsierra: I have worked on this a good deal. As you think it through you'll find the real problems are with return types |
| 14:10 | stuartsierra | Oh I'm sure there are legions of problems I haven't thought of. :) |
| 14:11 | ankou | hi, I have a data structure for which another print-method is defined. Is there a function to print the structure itself? |
| 14:12 | hiredman | ankou: change the type of the structure |
| 14:12 | stuartsierra | rhickey: Is calling Java methods that take primitives OK (unboxed) when using loop primitives? |
| 14:13 | rhickey | stuartsierra: sure, that's how fast native math works. it is just calling static methods taking primitives |
| 14:13 | stuartsierra | ok |
| 14:14 | hiredman | I've been thinking about something like #^{:signature [[int int] double]} (some-fn x y) |
| 14:14 | rhickey | providing exact match |
| 14:15 | stuartsierra | right |
| 14:16 | stuartsierra | rhickey: And that works because the Java methods have declared return types? |
| 14:18 | rhickey | stuartsierra: yes. The tricky bit for a generic invoke[Primitive] interface is that while it can be overloaded on argtypes, can't be on return types (at least not without breaking Java compatibility) |
| 14:19 | timcharper | is there any chance an "unless" macro will make it into clojure core ? |
| 14:19 | rhickey | ,(doc when-not) |
| 14:19 | clojurebot | "([test & body]); Evaluates test. If logical false, evaluates body in an implicit do." |
| 14:19 | stuartsierra | rhickey: Yes. I was thinking invokePrimitive would not be declared in any interface, just a public method of an individual Fn class. |
| 14:20 | timcharper | awesome! thanks, rhickey |
| 14:20 | timcharper | (for clojure too) |
| 14:20 | fogus | timcharper: (defmacro unless [& args] `(when-not ~@args)) ;-) |
| 14:20 | timcharper | thanks fogus - since when-not is already there, I'll just use that |
| 14:21 | timcharper | coming from ruby-land, was expecting unless, but willing to adopt when-not instead |
| 14:21 | fogus | The term unless always confused me. |
| 14:22 | fogus | I guess when-not is more clear to my mind |
| 14:22 | rhickey | stuartsierra: hrm, you need to set your sights higher, else higher-order use of such fns won't be primitive-enabled |
| 14:22 | stuartsierra | oh, forgot about that |
| 14:23 | Raynes | cemerick: If I want to use deftype and defprotocol, I don't really have a choice. I'm perfectly fine with dealing with breakage. |
| 14:24 | Raynes | I don't do nothing in which breakage would really cause much of a problem. |
| 14:28 | stuartsierra | What if the invoke method called the invokePrimitive method, with appropriate coercions? Could the JVM inline that? |
| 14:29 | rhickey | stuartsierra: in my design whichever version you supplied would get called by the ones you didn't, but no, the JVM wouldn't necessarily get rid of the Objects passed via ordinary invoke, at this time. |
| 14:30 | stuartsierra | Ah. Oh well, it was a nice idea while it lasted ... :) |
| 14:31 | rhickey | stuartsierra: I think I'm close on this, but not working on it right now |
| 14:31 | stuartsierra | ok, that's fine, just got curious |
| 14:35 | hiredman | ooo |
| 14:57 | duncanm | stuartsierra: what's so cool about the scala command line executables? |
| 15:01 | hiredman | duncanm: I guess they have them, and they are standard? |
| 15:02 | stuartsierra | dunconm, hiredman: yes |
| 15:02 | stuartsierra | They've just put some more effort into the installation/packaging/setup process. |
| 15:04 | duncanm | oh right - the only standard thing in Clojure is java -cp clojure.jar clojure.main |
| 15:04 | stuartsierra | We'll get there. |
| 15:04 | duncanm | i wanted to write a REPL with Swing |
| 15:05 | duncanm | i looked into using the Netbeans stuff, and got sucked into all the NB infrastructure |
| 15:05 | stuartsierra | duncanm: it's been done a few times |
| 15:05 | duncanm | stuartsierra: right - i wanted to make a stand-alone REPL thing using the netbeans/clojure work |
| 15:05 | chouser | I think part of our "problem" is we may have more fractured startup states than some others: plain terminal (windows/linux/mac), slime/swank, various IDEs, nailgun, etc... |
| 15:05 | duncanm | that's probably the nicest setup, since the netbeans deps are part of the JDK now |
| 15:06 | stuartsierra | chouser: Yes. But Scala has some of the same issues. They're just more organized: http://www.scala-lang.org/downloads |
| 15:06 | chouser | hiredman: do you use it regularly? |
| 15:06 | hiredman | http://github.com/hiredman/Repl |
| 15:06 | hiredman | no |
| 15:07 | hiredman | I haven't touched it in months |
| 15:07 | stuartsierra | ~stuartsierra |
| 15:07 | clojurebot | stuartsierra is volunteering |
| 15:07 | duncanm | http://www.scala-lang.org/node/36 -- this is a better listing |
| 15:07 | chouser | stuartsierra: hm, yes, that's all very tidy-looking. |
| 15:08 | stuartsierra | But hey, we're only on 1.1 |
| 15:09 | duncanm | is there a timeline for 1.2? |
| 15:09 | stuartsierra | "when it's ready" |
| 15:11 | kotarak | Hopefully it's not "when it's done"... |
| 15:34 | brandonw | anyone up for helping me figure out what is wrong here? -- http://paste.pocoo.org/show/184431/ is my project.clj and http://paste.pocoo.org/show/184430/ is output of lein help |
| 15:35 | brandonw | nailgun doesn't show up as a task for some reason |
| 15:35 | brandonw | i've been told, and found on google, that the warning of the POM not being a valid 4.0 POM shouldn't prevent the nailgun task from working. it doesn't show up for me, though, and i'm not sure why |
| 15:42 | Raynes | brandonw: You might have to catch technomancy|away when he isn't |away. |
| 15:42 | brandonw | okay. on another note, as a java build-chain newbie, i am actually having trouble with the basic workflow, too. |
| 15:42 | hiredman | brandonw: http://clojars.org/org.clojars.ato/nailgun <-- not a nailgun plugin |
| 15:43 | hiredman | http://clojars.org/lein-nailgun <-- a nailgun plugin |
| 15:43 | brandonw | aahhh that would explain it |
| 15:43 | brandonw | yeah that is what i use, but i saw the nailgain from ato and thought it was updated somehow (even though the nailgun client source is a single file that hasn't been modified). |
| 16:03 | bsteuber | is there a function returning both rem and quot like CL had? |
| 16:04 | dnolen | bsteuber: Clojure doesn't have multiple value returns. |
| 16:04 | bsteuber | right - but it could return a vector |
| 16:05 | bsteuber | just wanted to make sure I didn't overlook anything |
| 16:05 | hiredman | you could use binding to simulate it |
| 16:09 | brandonw | if i use `lein new foo` to create a new project, specify the nailgun dep, modify foo/src/foo/core.clj to have a single function with a single println call, call `lein nailgun` to start the ng server, and then start up vim-- i get a FileNotFoundException about locating foo/core.clj on classpath. What could I be doing wrong? |
| 16:10 | brandonw | i haven't changed any of the defaults except to create a function to make sure the repl is working, and to add the nailgun dep in project.clj |
| 16:11 | bsteuber | hiredman: simulate multiple return values? how so? |
| 16:11 | hiredman | lisppaste8: url? |
| 16:11 | hiredman | dag nabbit |
| 16:11 | duncanm | if i have a map {:a 1 :b 2} and i want to transform it to {:a (f 1) :b (f 2)} - what do i write? |
| 16:12 | duncanm | ,(map #(inc (second %)) {:a 1 :b 2}) |
| 16:12 | clojurebot | (2 3) |
| 16:13 | hiredman | http://paste.lisp.org/display/95795 |
| 16:13 | hiredman | bsteuber: thats for you |
| 16:14 | bsteuber | hiredman: nice, although using state feels a bit creepy |
| 16:14 | bsteuber | does that compose? |
| 16:15 | duncanm | ,(map (fn [x] { (first x) (inc (second x)) }) {:a 1 :b 2}) |
| 16:15 | clojurebot | ({:a 2} {:b 3}) |
| 16:15 | duncanm | eek |
| 16:15 | hiredman | bsteuber: the state is threadlocal |
| 16:16 | hiredman | bsteuber: is composable |
| 16:16 | hiredman | you just have to remember to wrap binding around all the calls |
| 16:18 | bsteuber | ic |
| 16:18 | bsteuber | good to have that technique as an option |
| 16:18 | duncanm | booo |
| 16:19 | hiredman | the docs for binding actually explicitly mention that case and don't mention the other cases where binding is used at all |
| 16:19 | hiredman | "Bindings created with binding can be assigned to, which provides a means for a nested context to communicate with code before it on the call stack." |
| 16:19 | hiredman | doesn't say anything about implicit argument passing |
| 16:20 | duncanm | ,(let [m {:a 1 :b 2}] (zipmap (keys m) (map inc (vals m)))) |
| 16:20 | clojurebot | {:b 3, :a 2} |
| 16:20 | duncanm | i guess that's one way |
| 16:20 | hiredman | ,(doc fmap) |
| 16:20 | clojurebot | "([f s]); Applies function f to each item in the data structure s and returns a structure of the same kind." |
| 16:20 | hiredman | ,`fmap |
| 16:20 | clojurebot | clojure.contrib.generic.functor/fmap |
| 16:21 | hiredman | ,(fmap inc {:x 1 :y 2}) |
| 16:21 | clojurebot | {:x 2, :y 3} |
| 16:21 | duncanm | ahh, it's not part of the standard API |
| 16:21 | duncanm | hiredman: thanks! |
| 16:22 | duncanm | hiredman: "each item in the data structure" - how come it doesn't try to (inc :x) ? |
| 16:22 | hiredman | no idea |
| 16:23 | ysph | maybe it knows to get values instead of keys? how would you print the source of fmap? |
| 16:24 | hiredman | ~def fmap |
| 16:24 | brandonw | interesting. if i comment out (ns foo.core) in foo/src/foo/core.clj then it works fine |
| 16:25 | duncanm | heh |
| 16:25 | duncanm | (into (empty m) (for [[k v] m] [k (f v)])) |
| 16:25 | duncanm | ysph: it specializes for IPersistentMap |
| 16:25 | brandonw | if i leave it in, though, then the nailgun server complains about not being able to find foo/core__init.class or foo/core.clj on classpath |
| 16:25 | brandonw | lein test does work, however... |
| 16:26 | ysph | cool, all the way around |
| 16:26 | duncanm | hiredman: generic.functor - i would never think of looking in there |
| 16:26 | hiredman | *shrug* |
| 16:26 | duncanm | hiredman: i thought functors have to do with modules and what not (like in ML) |
| 16:27 | hiredman | http://en.wikipedia.org/wiki/Functor |
| 16:28 | duncanm | basically the default map ought to be like fmap |
| 16:28 | hiredman | then map could not be lazy |
| 16:28 | hiredman | or as lazy as it is |
| 16:28 | hiredman | :/ |
| 16:28 | duncanm | hmm |
| 16:29 | stuartsierra | You can also write (zipmap (keys m) (map f (vals m))) |
| 16:29 | duncanm | stuartsierra: that's what i did |
| 16:29 | duncanm | 16:20 <duncanm> ,(let [m {:a 1 :b 2}] (zipmap (keys m) (map inc (vals m)))) |
| 16:30 | stuartsierra | Or, my favorite, (reduce (fn [m [k v]] (assoc m k (f v))) {} the-map) |
| 16:30 | hiredman | (comp (partial apply zipmap) (juxt keys (comp (partial map f) vals)) |
| 16:30 | duncanm | show-offs |
| 16:30 | stuartsierra | :) |
| 16:30 | hiredman | I wonder if that works |
| 16:31 | hiredman | it doesn't |
| 16:31 | hiredman | because of the f |
| 16:31 | kotarak | And then hiredman pulls off his mask and Sean jumps out. |
| 16:31 | duncanm | hiredman can type out point-free style code directly |
| 16:31 | duncanm | i just haven't learned how to do that |
| 16:31 | opqdonut | what's juxt? |
| 16:32 | hiredman | juxt is awesome |
| 16:32 | duncanm | ,(doc juxt) |
| 16:32 | clojurebot | "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]" |
| 16:32 | kotarak | ,((juxt :a :b) {:a 1 :b 2}) |
| 16:32 | clojurebot | [1 2] |
| 16:32 | duncanm | crazy stuff |
| 16:32 | opqdonut | ah |
| 16:32 | kotarak | ,((juxt inc dec) 1) |
| 16:32 | clojurebot | [2 0] |
| 16:33 | opqdonut | so kinda like ()comp map (flip apply x) |
| 16:33 | opqdonut | gah! |
| 16:33 | opqdonut | so kinda like (comp (partial map (flip apply x)) vector) |
| 16:33 | opqdonut | if flip exists :) |
| 16:33 | stuartsierra | ,(let [m {:a 1 :b 2 :c 3}] ((apply juxt (keys m)) m)) |
| 16:33 | clojurebot | [1 2 3] |
| 16:33 | stuartsierra | That's a really awkward way to write 'vals'. |
| 16:34 | kotarak | stuartsierra: well, you can choose order, though |
| 16:34 | stuartsierra | True. |
| 16:34 | bsteuber | ,(map #(% {:a 1 :b 2}) [:a :b]) |
| 16:34 | clojurebot | (1 2) |
| 16:35 | bsteuber | that's what I used to do |
| 16:35 | opqdonut | yeah I tried to write #(% x) more neatly as (flip apply x) |
| 16:35 | bsteuber | but juxt might be more clear as an idiom |
| 16:36 | stuartsierra | bsteuber: That's essentially what juxt does. |
| 16:36 | opqdonut | bsteuber: indeed |
| 16:36 | bsteuber | ,(doc flip) |
| 16:36 | clojurebot | "([x]); takes a function and returns a function that takes arguments in the opposite order" |
| 16:36 | kotarak | opqdonut: where the definition of "neat" is open to discussion |
| 16:36 | hiredman | flip is a lie |
| 16:36 | hiredman | ,`flip |
| 16:36 | clojurebot | sandbox/flip |
| 16:36 | opqdonut | probably needs a partial in there somewhere |
| 16:36 | opqdonut | one of these days I'll write a macro that partials everything |
| 16:36 | opqdonut | I'm spoiled by haskell |
| 16:37 | hiredman | orly |
| 16:37 | duncanm | haha |
| 16:37 | duncanm | O RLY! |
| 16:37 | brandonw | hum. has anyone else had issues with the lein-nailgun plugin not setting the classpath correctly? |
| 16:37 | chouser | if a reify doesn't close over anything, only one instance of it would ever have to be made, right? |
| 16:38 | brandonw | if i manually start it with the correct classpath, it works fine. `lein nailgun` doesn't set the classpath correctly, though... |
| 16:38 | chouser | I guess this is pretty rare |
| 16:38 | rhickey | chouser: theoretically, yes, actually, not yet |
| 16:38 | chouser | ooh, I like "yet" :-) |
| 16:39 | rhickey | yet == after ccinc |
| 16:39 | chouser | huh. ok. |
| 16:39 | hiredman | ,(pl (↕map (replicate 3 (↕apply vector $ (↕map range $ 10 inc · inc · inc) call · ⌽* $ 10 · call · (⌽+ -2) map)) shuffle)))) |
| 16:39 | clojurebot | ((10 100 90 40 80 20 70 60 30 50) (100 40 70 10 60 90 20 80 30 50) (30 90 10 20 40 100 50 60 80 70)) |
| 16:39 | rhickey | I can't bear too many more enhancements in Javaland |
| 16:39 | opqdonut | ccinc? |
| 16:40 | kotarak | clojure compiler in clojure |
| 16:40 | opqdonut | hiredman: yeah, I'm aware of pl |
| 16:40 | opqdonut | ah, yes |
| 16:40 | duncanm | ccinc? |
| 16:40 | chouser | you keep saying that and then keep doing things like fn metadata |
| 16:40 | duncanm | oh oh |
| 16:40 | duncanm | i'm slow |
| 16:41 | duncanm | what's PL? |
| 16:41 | duncanm | ,(doc pl) |
| 16:41 | clojurebot | "([& forms]); replaces a $ b with (a b) walking right to left replaces a · b with (comp a b) left to right ⌽a with (uncurry a) left to right ↕a with (flip a) left to right" |
| 16:41 | rhickey | chouser: true, must stop that |
| 16:41 | bsteuber | ,`pl |
| 16:41 | clojurebot | sandbox/pl |
| 16:42 | bsteuber | crazy |
| 16:42 | duncanm | it's like writing Haskell in Clojure |
| 16:42 | opqdonut | no it's not :) |
| 16:42 | chouser | dynamic haskell |
| 16:42 | opqdonut | dynamic strict haskell without types |
| 16:42 | hiredman | nah, haskell is much more concise about it |
| 16:42 | opqdonut | indeed |
| 16:42 | opqdonut | so, more like eager lambda calculus |
| 16:43 | hiredman | ,(pl (λx (inc x) 1)) |
| 16:43 | bsteuber | by the way, was there any sort of conclusion about this "-> ->> enhancement" debate? |
| 16:43 | clojurebot | 2 |
| 16:44 | duncanm | i like -> so much, i stopped using .. |
| 16:44 | hiredman | sure, who uses ..? |
| 16:44 | bsteuber | I'd love to do something like (-> x (/ 3) (- 2 _)) |
| 16:45 | duncanm | it took me a while to discover -> |
| 16:45 | hiredman | ,(-> 1 (/ 3) (->> (- 2))) |
| 16:45 | clojurebot | 5/3 |
| 16:46 | bsteuber | hiredman: nice, but it won't work the other way round, would it? |
| 16:46 | bsteuber | but I have to remember at least using ->> inside -> |
| 16:46 | stuartsierra | -> is slightly evil |
| 16:46 | bsteuber | stuartsierra: I agree |
| 16:47 | duncanm | why is that? |
| 16:47 | duncanm | i haven't been following the debate |
| 16:47 | kotarak | bsteuber: It's even more crazy: (doto (JFrame.) (-> .getContentPane do-stuff)) |
| 16:47 | chouser | cgrand has a patch to allow arbitrary switching back and forth between -> and ->> |
| 16:47 | stuartsierra | That's definitely evil. |
| 16:48 | rhickey | chouser: not sure I like that at all |
| 16:48 | chouser | yeah |
| 16:48 | hiredman | I've done that |
| 16:48 | duncanm | kotarak: why write that and not (-> (JFrame.) .getContentPane do-stuff) ? |
| 16:48 | duncanm | oh wait |
| 16:48 | duncanm | oh, i get it |
| 16:48 | rhickey | but I quite like -> and ->> |
| 16:49 | duncanm | kotarak: hmm.... i see now, tricky |
| 16:49 | bsteuber | after seeing the proposal using _ I tried to implement some deep replacement of _ while macroexpanding inner stuff first |
| 16:49 | bsteuber | that was evil :) |
| 16:49 | kotarak | duncanm: imagine some more (.setTitle ) and such things |
| 16:50 | stuartsierra | I like -> and ->> too, I just think they tempt people to try to avoid 'let' altogether. |
| 16:50 | hiredman | I still haven't gotten into the habit of using ->> |
| 16:50 | stuartsierra | Leading to monstrosities like -..$?>> |
| 16:51 | chouser | ,(->> 3 (- a) (/ 4) (let [a 7])) |
| 16:51 | clojurebot | 1 |
| 16:51 | duncanm | i haven't learned how ->> macroexpands |
| 16:51 | hiredman | chouser: cute |
| 16:51 | chouser | that is absolutely abusive. |
| 16:52 | rhickey | stuartsierra: yeah, well, that's a problem, knowing when to stop |
| 16:52 | stuartsierra | Programmers never know when to stop. |
| 16:52 | chouser | I get such abuse out of my system here so I'm less tempted to do it in real code. |
| 16:53 | bsteuber | so the general opinion is sth like "anything beyond -> and ->> is way too evil"? |
| 16:53 | duncanm | did the other lisps come up with syntactic florishes like this? i don't think i ever saw them working with Scheme, and I don't know about CL |
| 16:53 | chouser | ,(-> [x (range 5)] (for (+ x 3))) |
| 16:53 | clojurebot | (3 4 5 6 7) |
| 16:53 | rhickey | bsteuber: I haven't been persuaded by any further 'enhancements' so far |
| 16:54 | stuartsierra | duncanm: Arc has syntactic sugar for composition, but the point-free style seems to be unique to Clojure. |
| 16:54 | kotarak | chouser: This smells terrible about "#define FOO 5;"... |
| 16:54 | chouser | kotarak: yes, roughly the same level of abuse I think. |
| 16:55 | stuartsierra | I'll admit I was briefly tempted by -> with a placeholder, but at that point you might as well write 'let'. |
| 16:55 | chouser | #define begin { // look, it's pascal! |
| 16:55 | tomsw | I'm trying to create an Eclipse plugin that will add Clojure as a scripting shell, but I can't get past a classpath error: "java.io.FileNotFoundException: Could not locate clojure/core__init.class or clojure/core.clj on classpath" |
| 16:56 | hiredman | http://github.com/hiredman/clojurebot/blob/master/src/hiredman/clojurebot/factoids.clj#L166 horrid |
| 16:57 | tomsw | if it can load the RT class why can't it load core__init, which is in the same jar? |
| 16:59 | bsteuber | stuartsierra: but by let you cross the bridge away from point-free-land :) |
| 17:00 | bsteuber | ok you can do (let [_ .. |
| 17:02 | stuartsierra | That's the point. point-free only takes you so far, at some point it impedes readability. |
| 17:02 | kotarak | ... where it turns into point-less. |
| 17:02 | chouser | bsteuber: more like you come back home after brief sojourn into the land of point-free |
| 17:03 | hiredman | tomsw: most likely a classloader issue, RT is loaded by a classloader that can find the jar, but then RT maybe tries to load clojure.core and whatever classloader it uses doesn't see the jar |
| 17:03 | tomsw | hiredman: that makes sense - but then how do I get RT to use a different classloader? |
| 17:04 | bsteuber | ,(-> 1 (/ 3) #(- 5 %)) |
| 17:04 | clojurebot | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector |
| 17:04 | chouser | so it's ok to AOT compile code that includes raw fns as long as thost fns aren't closures? |
| 17:04 | bsteuber | oh, I expected that to work |
| 17:04 | bsteuber | too bad |
| 17:05 | hiredman | tomsw: very painfully |
| 17:05 | hiredman | bsteuber: you need double parens |
| 17:05 | kotarak | bsteuber: (-> 1 (/ 3) (#(- 5 %))) |
| 17:06 | bsteuber | oh, because #( is a reader macro, true |
| 17:06 | hiredman | chouser: why wouldn't it be fine if they are closures? |
| 17:07 | bsteuber | ok so I'll use that if feel like staying in point-free-land for a little longer :) |
| 17:07 | chouser | I think I'm explaining what I mean poorly. |
| 17:08 | tomsw | hiredman: painfully as in hacking RT.java, or not quite so bad? |
| 17:08 | rhickey | chouser: I think definline does |
| 17:08 | kotarak | bsteuber: #(+ 5 %) is not really point-free, no? |
| 17:09 | bsteuber | kotarak: you got me :) |
| 17:09 | chouser | ah, good -- the error shows up with eval too. |
| 17:09 | chouser | ,(let [a 1] (eval `(~(fn [b] (+ a b)) 2))) |
| 17:09 | clojurebot | DENIED |
| 17:09 | chouser | bleh. |
| 17:09 | chouser | anyway, that fails. but this works: |
| 17:09 | chouser | ,(let [a 1] (eval `(~(fn [b] (+ 1 b)) 2))) |
| 17:09 | clojurebot | DENIED |
| 17:09 | hiredman | tomsw: I think hacking RT.java |
| 17:09 | kotarak | bsteuber: I wouldn't worry to much about point-free. Just wastes time. |
| 17:10 | chouser | rhickey: ok, I see that. thanks. |
| 17:12 | bsteuber | ok, so I think I learnt from that discussion that I should invest more time in really mastering what clojure currently gives me instead of thinking too hard about improving it |
| 17:13 | bsteuber | well, maybe that's a bad way to say it |
| 17:13 | bsteuber | anyways, thanks :) |
| 17:23 | tomsw | hiredman: think I might have figured it out, I need to change the current thread's classloader when I try and startup clojure |
| 17:24 | hiredman | that makes sense, baseloader does fall back to that |
| 17:27 | tomsw | hiredman: wayhey! It's working. I'm off to bed. Thanks |
| 17:52 | defn | wow. twitter at 50mil tweets a day. that's 2x as many as there were 4mos ago. |
| 18:28 | timcharper | why does range use chunk-buffer? Is it an optimization? |
| 18:28 | timcharper | I'm implementing a function that returns an infinite sequence for use in a for loop. |
| 18:28 | hiredman | clojurebot: seq-1 |
| 18:28 | clojurebot | make a note of http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php it is yet another article about picking c or c++ for performance being naive |
| 18:29 | kotarak | for is not a loop |
| 18:29 | hiredman | clojurebot: worthless git |
| 18:29 | clojurebot | gitorious mirror is http://gitorious.org/clojure/clojure |
| 18:29 | kotarak | clojurebot: for |
| 18:29 | clojurebot | for is not used often enough. |
| 18:29 | timcharper | kotarak: what do you mean? how is it not a for ? |
| 18:30 | timcharper | how is for not a loop ? |
| 18:30 | kotarak | timcharper: for is a list comprehension and not a loop. doseq is a loop. |
| 18:30 | danlei | it's a list comprehension |
| 18:30 | kotarak | timcharper: for returns a lazy sequence |
| 18:31 | timcharper | ok, fair enough (was aware of both aspects, but as far as I'm concerned it's implementing a loop-like pattern) |
| 18:32 | AWizzArd | timcharper: under the hood for is a loop. Conceptually it is something higher level. |
| 18:32 | hiredman | AWizzArd: not really |
| 18:32 | danlei | but if you think "for=loop" you'll get surprised if you use side-effects inside it |
| 18:33 | hiredman | it's not a loop at any level |
| 18:33 | danlei | (but there's dorun to the rescue) |
| 18:33 | AWizzArd | hiredman: so no jmp command in assembler? |
| 18:33 | hiredman | AWizzArd: I doubt it |
| 18:33 | hiredman | it expands to a call to lazy-seq |
| 18:33 | hiredman | :P |
| 18:34 | AWizzArd | Does not work, Wizards always come back. |
| 18:34 | hiredman | yes, but do WizzArds? |
| 18:35 | mabes | quick poll.. who here is using 1.2 on a production app? I'd like to start using 1.2 (for deftype) so I've trying to weigh the risks of being on the edge so much.. |
| 18:35 | AWizzArd | mabes: I do |
| 18:36 | mabes | AWizzArd: are you using Leinigen and just grab the most recent snapshot whenever that might be pushed out? |
| 18:36 | AWizzArd | I don't use Leiningen yet, but it is likely that I will look at it in the coming weeks/months. |
| 18:37 | AWizzArd | mabes: I update from http://build.clojure.org/ |
| 18:43 | timcharper | kotarak: FYI: http://clojure.org/macros - "for" is listed under "Looping". Is there a commonly accepted standard of what constitutes a "loop" in computer science? |
| 18:45 | timcharper | (trying to understand your position on how for is NOT performing a what fundamentally appears to be a loop operation) |
| 18:45 | chouser | it's not an imperative loop like 'for' in C or Java |
| 18:46 | chouser | it's a factory for lazy seqs |
| 18:46 | timcharper | chouser: how would you define a loop ? |
| 18:48 | AWizzArd | a block of code that contains a jump back to its starting point |
| 18:52 | bsteuber | what's the difference between = and == ? |
| 18:53 | AWizzArd | there is a ==? |
| 18:53 | AWizzArd | ,(doc ==) |
| 18:53 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the same value, otherwise false" |
| 18:56 | AWizzArd | ,(== "a" "a") |
| 18:56 | clojurebot | false |
| 18:56 | AWizzArd | false is non-nil, so the both nums have the same value :) |
| 18:57 | timcharper | AWizzArd: ok, that sounds reasonable. So would you say loop / recur in clojure implement a loop? |
| 18:58 | AWizzArd | yes |
| 18:58 | danlei` | if you consider that tail-recursion IS iteration in e.g. scheme: yes |
| 18:58 | bsteuber | so == is like = for numbers and like identical? otherwise? |
| 18:58 | AWizzArd | rhickey mentioned some months ago that recur basically is "goto" |
| 18:59 | timcharper | so, if the for macro, under the hood, uses loop and recur, would you classify it as performing a loop like operation ? |
| 18:59 | bsteuber | but it's a very harmless goto :) |
| 18:59 | timcharper | (in spite of it occurring within the context of a lazy-seq) ? |
| 19:00 | AWizzArd | As for potentially executes the same block of code multiple times I could imagine that it at some low level point is solved by a looping construct. But this is not so important. I also don't try to imagine about the molecular activities inside the cpu while it runs my programs :) |
| 19:00 | danlei | I think that's the point: one doesn't THINK about for as a loop. |
| 19:01 | AWizzArd | When I think about for, I think about list comprehension |
| 19:01 | AWizzArd | danlei: exactly |
| 19:01 | timcharper | but can you say it isn't a loop? |
| 19:01 | AWizzArd | Yes |
| 19:01 | timcharper | why ? |
| 19:01 | AWizzArd | Would you say that filter is a loop? |
| 19:01 | timcharper | I agree it exhibits more properties than a simple loop |
| 19:01 | AWizzArd | or map? |
| 19:02 | timcharper | yes, I would say both filter, map, and reduce implement a loop |
| 19:02 | danlei | implement a != is |
| 19:02 | AWizzArd | Okay, then you should see "for" also as a looping construct. |
| 19:02 | danlei | you wouldn't say a house is a stone, would you? |
| 19:02 | timcharper | no, but I would say a mansion is a house |
| 19:02 | AWizzArd | But then you could as well go some levels deeper and not see it as loops, but some patterns of electrons :) |
| 19:03 | timcharper | hahah, there is only 1's and 0's, in the end. |
| 19:03 | AWizzArd | I think even that is already a simplification |
| 19:03 | AWizzArd | Probably there are no 1's and 0's, but instead some electrical charges |
| 19:03 | danlei | but do you think in 1s and 0s? |
| 19:04 | timcharper | hahah |
| 19:04 | timcharper | danlei: there are 10 types of people that think in 1s and 0s |
| 19:04 | danlei | ;) |
| 19:04 | timcharper | those that do, and those that don't |
| 19:04 | danlei | old one ;) |
| 19:04 | bsteuber | oh yeah - and 3 types of mathematicians |
| 19:04 | bsteuber | have we reached that level yet? |
| 19:05 | AWizzArd | timcharper: (for ..) is a construct that can do map / filter |
| 19:06 | timcharper | AWizzArd: yes, it's very awesome |
| 19:06 | timcharper | I'm a big fan of clojure's for |
| 19:06 | AWizzArd | it lacks the powers of (reduce ...), which is the most general one (map and filter are special cases of reduce). |
| 19:06 | danlei | timcharper: you could approach it philosophically: the whole is more than the sum of its parts. for might be done using loops or whatever, but it's something different. |
| 19:08 | timcharper | I see your point of view. Thanks for taking time to explain it to me |
| 19:08 | danlei | (or maybe linguistically and say that loops are a meronyme of for, but thats problematic) |
| 19:42 | timcharper | is there a simple debugger tool that fires up a repl in the middle of a running clojure program ? |
| 19:43 | danlei | if I have (defprotocol P (a [x]) (b [x])), and (extend-class Object P (a [x] :foo) (b [x] :bar)), is it possible, given (extend-class Number P (a [x] :bar)), to have (b 1) return :bar? |
| 19:43 | danlei | timcharper: I'd use swank, but you can also use a repl-on-a-socket using server-socket in contrib |
| 19:44 | danlei | (which may not be what you asked for) |
| 19:44 | timcharper | Nice! I didn't know you could fire one up like that. |
| 19:45 | timcharper | already using emacs, so this looks like a slam dunk |
| 19:45 | timcharper | (swank/start-repl) |
| 19:47 | timcharper | hmm, it appears that swank fires it up in a different thread, instead of halting the current thread so I can inspect it. is that how it works for you ? |
| 19:47 | timcharper | (danlei) |
| 19:47 | danlei | yes |
| 19:48 | danlei | it depends on what you want to do exactly, for my needs, swank is ok |
| 19:48 | arohner | timcharper: http://georgejahad.com/clojure/debug-repl.html |
| 19:48 | timcharper | trying to debug some code |
| 19:48 | timcharper | been using (prn)... but that gets tedious |
| 19:50 | timcharper | arohner: thanks, I'll give that a try. |
| 19:58 | danlei | looks interesting, a small step towards some things CL debuggers provide. bummer it doesn't work in slime |
| 19:59 | danlei | (but mostly, I'm get along well with (print ...)) |
| 19:59 | danlei | *getting |
| 20:01 | danlei | to put my former defprotocol question differently: is it possible to make Type2 use Type1's implementation of a protocol funcion, if C2 isa? C1, and C2 implemented another function of that protocol (but not the whole protocol) |
| 20:02 | danlei | C1/2 -> Type1/2 |
| 20:03 | hiredman | danlei: no, protocols don't inherit |
| 20:03 | hiredman | you can mix and match maps of cuntions |
| 20:03 | hiredman | functions |
| 20:04 | danlei | ok |
| 20:04 | hugod | is there a better way than this of capturing the source line number? http://gist.github.com/319010 |
| 20:05 | danlei | but I'll have to do it by hand? I'm asking, since if Type2 doesn't implement some protocol functions, it's enough to implement them in Type1, but that won't work anymore if I implement a part of P |
| 20:05 | hiredman | danlei: what you are asking for is some form of inheritence, which protocols don't provide |
| 20:05 | tomoj | should I use fnparse for high-permormance parsing of a simple language? |
| 20:05 | tomoj | or just do it raw |
| 20:05 | danlei | hiredman: ok, thanks! |
| 20:06 | hiredman | is fnparse high performance? |
| 20:10 | tomoj | hiredman: I dunno :( |
| 20:11 | arohner | tomoj: IIRC, parsec (parser combinator lib for haskell) is slower than doing it by hand |
| 20:11 | arohner | of course, fnparse / parsec is probably faster to code |
| 20:12 | tomoj | thanks |
| 20:12 | arohner | how fast do you need this to be? |
| 20:13 | tomoj | that is unclear |
| 20:13 | tomoj | but, learning fnparse would have significant overhead, I think |
| 20:13 | tomoj | last time I looked at it I couldn't make any sense of it |
| 20:17 | hiredman | huh |
| 20:17 | hiredman | clojurebot: logs? |
| 20:17 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 20:20 | hiredman | ,((fp/semantics (fp/rep+ (fp/lit \x)) (comp symbol (partial apply str))){:remainder (seq "xxxyxxx")}) |
| 20:20 | clojurebot | [xxx {:remainder (\y \x \x \x)}] |
| 20:34 | tomoj | I find myself wanting haskell.. I'm considering making a protocol for this language, and then using extend to give clojure and java types implementations |
| 20:35 | tomoj | but I would want to be able to give implementations of a read-bson method which has a polymorphic return value and dispatches on the return type |
| 20:35 | tomoj | and I can't imagine any way to do that in clojure |
| 20:36 | tomoj | I had a similar problem earlier and the solution I opted for was a protocol with the methods that are called on instances of implementing types, and a separate multimethod which accepts a symbol arg for the return type |
| 20:37 | tomoj | implementers then have to provide an implementation of the protocol and a corresponding method |
| 20:37 | tomoj | for the multimethod, I mean |
| 20:37 | tomoj | does this sound sane? |
| 20:38 | chouser | not bad. specifying the desired return type is common in clojure |
| 20:38 | chouser | making that an open set by using a multimethod seems natural |
| 20:40 | hiredman | really, dispatching on return type seems weird |
| 20:40 | tomoj | hmm, maybe I want multiprotocols? |
| 20:40 | hiredman | stuartsierra had a macro for double dispatch protocols |
| 20:41 | hiredman | what would multiprotocols be? |
| 20:42 | tomoj | bottom of http://www.assembla.com/wiki/show/clojure/Protocols |
| 20:43 | tomoj | I dunno |
| 20:43 | tomoj | I guess I still couldn't really dispatch on the return value type |
| 20:44 | tomoj | without creating a dummy object just to call the function |
| 20:45 | tomoj | hmm |
| 20:46 | hiredman | so you mean dispatching on the return value of another function? |
| 20:46 | tomoj | I mean, say I have a JSON protocol |
| 20:46 | tomoj | I'd want it to have read and write functions |
| 20:47 | tomoj | the problem is how to allow implementers of the protocol to make their type readable |
| 20:48 | tomoj | where read is a function that takes a string or some bytes and returns a clojure/java type |
| 20:48 | hiredman | hmm |
| 20:48 | tomoj | er, a value of a clojure/java type |
| 20:48 | hiredman | right |
| 20:49 | tomoj | in haskell you could dispatch on the return type, and instances can define the read method even though it doesn't take a value of their type as the first argument |
| 20:49 | hiredman | dispatching on return type just seems so odd |
| 20:49 | tomoj | yeah, but it's awesome in haskell |
| 20:50 | tomoj | probably not so awesome in clojure's dynamic world |
| 20:50 | tomoj | but how else to do it? |
| 20:57 | hiredman | dispatching on the return value works by propagating type information backwards then? it sees what type you are using the return value as? |
| 20:57 | tomoj | yeah |
| 20:57 | hiredman | wild |
| 20:59 | tomoj | so e.g. minBound is a 0-ary function which is polymorphic in return type. minBound :: Int is -2147483648, minBound :: Bool is False |
| 20:59 | tomoj | if you try to use minBound as a boolean it dispatches on that type and gives you False |
| 20:59 | tomoj | in clojure, I was planning to just pass the return type as an argument to the function |
| 21:01 | tomoj | if I implement the protocol on Class and have a function that takes a class as the first arg and a string/bytes as the second... |
| 21:01 | tomoj | :) |
| 21:01 | tomoj | that sounds evil |
| 21:02 | hiredman | hmmm |
| 21:02 | tomoj | hmm, that won't even help |
| 21:02 | hiredman | it sure won't |
| 21:03 | tomoj | guess i want to be able to implement a protocol on a singleton object |
| 21:03 | tomoj | monkey-patch it in |
| 21:07 | atrerus | does anyone have an example of referencing a maven repository from lein's project.clj? |
| 21:08 | tomoj | atrerus: :repositories {"apache-snapshots" "http://people.apache.org/maven-snapshot-repository/"} |
| 21:10 | atrerus | and when you reference the dependency would you use org.apache.people/class-youre-referencing ? |
| 21:11 | tomoj | no, I'd use the group and artifact id for whatever I wanted |
| 21:11 | atrerus | ok... I'm totally unfamiliar with Maven repos |
| 21:12 | tomoj | e.g. [org.apache.solr/solr-core "1.5-SNAPSHOT"] |
| 21:12 | tomoj | the repo stores artifacts, each artifact has a groupid and an artifactid |
| 21:12 | tomoj | in leiningen you put [groupid/artifactid "version"] |
| 21:13 | atrerus | ok |
| 21:13 | tomoj | if you're browsing a maven repo with your browser, the directory path is the groupid, with the last directory before the version numbers being the artifactid |
| 21:14 | atrerus | AH! |
| 21:14 | atrerus | that's what I was looking for |
| 21:14 | tomoj | e.g. [org.apache.solr/solr-core "1.5-SNAPSHOT"] is at /org/apache/solr/solr-core/1.5-SNAPSHOT/ in the repo above |
| 21:14 | atrerus | so this guy for instance: http://mvnrepository.com/artifact/hsqldb/hsqldb |
| 21:14 | tomoj | yeah, [hsqldb/hsqldb "1.7.2"] or something |
| 21:15 | atrerus | right, makes sense |
| 21:15 | tomoj | I think that's in the central maven repo |
| 21:15 | tomoj | so you won't need to add a :repositories, probably |
| 21:15 | atrerus | ok |
| 21:15 | atrerus | if I did need to would it just be http://mvnrepository.com ? |
| 21:16 | tomoj | doubtful |
| 21:16 | tomoj | I think that's just a search engine |
| 21:16 | atrerus | is there a trusty way for finding the actual URL I'd need to refer leiningen to? |
| 21:17 | tomoj | pretty sure you don't need to refer leiningen to a URL |
| 21:17 | tomoj | otherwise you just have to find out for each project where they're pushing the artifacts to |
| 21:17 | atrerus | yeah, I'm just wondering for down the road if I need to refer to a non-standard repo |
| 21:20 | cljneo | Hi, newbie question. In ClojureBox 1.1 REPL, the form (use 'clojure.contrib.io) throws FileNotFoundException |
| 21:22 | brandonw | do you have clojure.contrib set in the classpath when running clojure.main ? |
| 21:22 | cljneo | how can I check? |
| 21:22 | brandonw | how are you starting the repl? |
| 21:23 | cljneo | using swank. It starts automatically when I start ClojureBosx |
| 21:23 | brandonw | okay i'm not familiar with swank |
| 21:24 | atrerus | I haven't used ClojureBox, but I do use swank |
| 21:25 | atrerus | I found it to be a big pain to manage classpaths myself |
| 21:25 | atrerus | leiningen makes it quite a bit easier |
| 21:26 | atrerus | it will download dependencies for you and add them to your classpath |
| 21:27 | cljneo | I checked the swank-clojure-classpath and the clojure.contrib.jar is in it |
| 21:28 | Raynes | If new people didn't have problems with swank-clojure and Emacs, this channel probably wouldn't get any attention at all. |
| 21:29 | Raynes | :p |
| 21:29 | atrerus | haha! |
| 21:29 | atrerus | so that's why you guys leave some loose ends hanging ;) |
| 21:31 | brandonw | atrerus: try (use 'clojure.contrib.duck-streams) |
| 21:31 | cljneo | actually the problem is CLASSPATH |
| 21:31 | brandonw | err cljneo, sorry |
| 21:32 | cljneo | duck-streams worked but I deleted some path from the env varialbe on my machine |
| 21:32 | cljneo | but io still throws exception |
| 21:33 | dnolen | getting a working Clojure setup is something like a right of passage... fortunately it's a lot more rewarding after the initial hurdle. it's still easier than getting a working Common Lisp environment in my experience. |
| 21:33 | dnolen | cljneo: duck-streams became io |
| 21:33 | brandonw | if you don't have a duck-streams was renamed to io recently, but if you don't have a .jar from later than feb 1st, you won't get the change |
| 21:33 | cljneo | hmmm, so it's picking another jar? |
| 21:33 | brandonw | s/if you don't have a/ |
| 21:33 | cljneo | I have 1.1 |
| 21:33 | brandonw | it will be duck-streams then |
| 21:34 | dnolen | 1.1 has duck-streams. I believe io is 1.2 right? |
| 21:34 | cljneo | I see |
| 21:36 | brandonw | my turn for a question :) -- when defining a macro, what is the difference between `(require '~'com.martiansoftware.nailgun.NGServer) and `(require 'com.martiansoftware.nailgun.NGServer) ? |
| 21:37 | brandonw | to my un-trained eyes, '~' appears to quote an expression, then immediately unquote it |
| 21:38 | hiredman | `~'a |
| 21:38 | hiredman | ,`~'a |
| 21:38 | clojurebot | a |
| 21:38 | hiredman | ,`'~'a |
| 21:38 | clojurebot | (quote a) |
| 21:39 | brandonw | ,`(require '~'foo) |
| 21:39 | clojurebot | (clojure.core/require (quote foo)) |
| 21:39 | brandonw | ,`(require 'foo) |
| 21:39 | clojurebot | (clojure.core/require (quote sandbox/foo)) |
| 21:39 | brandonw | ahhh |
| 21:39 | brandonw | is that relevant? |
| 21:40 | brandonw | one seems to be in the sandbox namespace, but the other isn't? or is that inconsequential in clojurebot's repl |
| 21:41 | brandonw | `(foo '~'bar) looks the same as `(foo 'bar) except for the sandbox/ |
| 21:41 | brandonw | ,(macroexpand-1 `(require '~'foo)) |
| 21:41 | clojurebot | (clojure.core/require (quote foo)) |
| 21:42 | brandonw | ,(macroexpand-1 `(require 'foo)) |
| 21:42 | clojurebot | (clojure.core/require (quote sandbox/foo)) |
| 21:42 | hiredman | http://clojure.org/reader#The%20Reader--Macro%20characters |
| 21:42 | hiredman | see syntax-quote (`) |
| 21:43 | brandonw | is that referred to as symbol capture? |
| 21:43 | brandonw | resolving the symbol in the current context? |
| 21:44 | cljneo | brandonw: duck-streams works for now. How can I find what functions are available in this ns? |
| 21:44 | cljneo | tried ns-aliases but it throws errors |
| 21:44 | brandonw | i still look at the clojure contrib api web page |
| 21:44 | brandonw | probably a better way, though |
| 21:45 | cljneo | the web page refers to io but I have duck-streams :) |
| 21:45 | brandonw | i don't think the content of the namespace was changed |
| 21:46 | brandonw | the docs on the contrib.api will still be applicable |
| 21:46 | cljneo | sorry. There is a 1.1 branch at the top of the docs page |
| 21:46 | hiredman | brandonw: it is not symbol capture |
| 21:54 | brandonw | hiredman: i'm sorry: i can see the difference between `(foo bar) and `(foo ~bar) but i still don't understand the difference of `(foo '~'bar) vs `(foo 'bar) |
| 21:54 | brandonw | what is the usage of ' in the scope of ` |
| 21:55 | hiredman | ,`'bar |
| 21:55 | clojurebot | (quote sandbox/bar) |
| 21:55 | brandonw | and if ~ un-quote's something in a syntax quoted list, wouldn't a |
| 21:55 | hiredman | ,`'~'bar |
| 21:55 | clojurebot | (quote bar) |
| 21:55 | brandonw | ' directly after it cancel that? |
| 21:56 | hiredman | do you see the difference between (quote sandbox/bar) and (quote bar) ? |
| 21:58 | brandonw | `'bar expands to bar in the current namespace, while `'~' expands to bar in whatever namespace executes the macro? |
| 21:58 | hiredman | sandbox/bar is a namespace qualified symbol, bar is just a symbol |
| 21:59 | brandonw | okay |
| 22:00 | brandonw | would the application of the latter be in evaluating bar in the scope of whatever namespaces are currently being used when the macro is called? |
| 22:02 | hiredman | ,`'~'bar |
| 22:02 | clojurebot | (quote bar) |
| 22:02 | hiredman | that will not evaluate to anything besides the symbol bar |
| 22:02 | hiredman | it's quoted |
| 22:02 | brandonw | well, i mean when the macro is called |
| 22:02 | brandonw | it would have to evaluate what bar is |
| 22:02 | hiredman | why would it? |
| 22:03 | brandonw | oh wait, right |
| 22:03 | brandonw | well, if it eventually gets called |
| 22:03 | brandonw | and bar needed to be evaluated |
| 22:04 | hiredman | but it doesn't |
| 22:04 | hiredman | because it is quoted |
| 22:04 | hiredman | (well it does, it just self evalutes, because that is what quoting is) |
| 22:04 | hiredman | ,(macroexpand-1 '`'~'bar) |
| 22:04 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote bar)))) |
| 22:05 | brandonw | i mean, when the macro is called, it expands into the symbol of foo, which is used in the scope of another function |
| 22:05 | brandonw | which tries to evaluate foo |
| 22:05 | hiredman | brandonw: but it doesn't expand into a symbol, it expands to a quoted symbol |
| 22:06 | brandonw | ohhhkay, something kind of clicked in my head |
| 22:07 | brandonw | okay that makes sense now, because the context of what i am looking at is ns-resolve and it is passing a quoted symbol |
| 22:07 | brandonw | which it would never need to evaluate, like you are saying |
| 22:09 | brandonw | okay, i think the rest just clicked, too |
| 22:09 | brandonw | am i right in saying `bar is quoting the symbol bar, which has a namespace, which is why it is returning sandbox/bar |
| 22:10 | hiredman | nope |
| 22:10 | brandonw | nevermind, i don't know what i was thinking. i understand how the end results are different, but i don't quite understand why `'~' and `' do different things |
| 22:10 | hiredman | did you read the link I posted? |
| 22:10 | brandonw | yes |
| 22:10 | hiredman | bar does not have a namespace |
| 22:11 | hiredman | "For Symbols, syntax-quote resolves the symbol in the current context, yielding a fully-qualified symbol (i.e. namespace/name or fully.qualified.Classname)." |
| 22:11 | brandonw | it said for symbols, syntax quote resolves the symbol in the current context |
| 22:11 | brandonw | so `foo would definitely be wrong |
| 22:11 | hiredman | no |
| 22:12 | hiredman | it is fine |
| 22:12 | hiredman | `foo is just like 'foo, but syntax quote namespace qualifies the symbols |
| 22:12 | brandonw | but if you use (use 'foo), wouldn't that be different than (use `foo) ? |
| 22:13 | brandonw | sorry, i'm thinking in the scope of ns-resolve still |
| 22:14 | hiredman | brandonw: yes |
| 22:15 | brandonw | so if you want to explicitly use the namespace "foo" with any namespace macros, it has to be quoted, not syntax quoted |
| 22:16 | brandonw | is '~' the way of quoting what would become the namespace qualified symbol *before* it gets qualified? |
| 22:17 | brandonw | i'm trying to wrap my head around the order of quoting something, then unquoting, then quoting again, then syntax quoting, and how the result is foo being quoted but nto namespace qualified |
| 22:18 | hiredman | ok |
| 22:18 | hiredman | here |
| 22:18 | hiredman | `(foo ~x) |
| 22:18 | hiredman | ,`(foo ~x) |
| 22:18 | clojurebot | java.lang.Exception: Unable to resolve symbol: x in this context |
| 22:18 | brandonw | right |
| 22:19 | brandonw | tries to eval x because of unquote |
| 22:19 | hiredman | let me start over |
| 22:19 | hiredman | ,`(foo x) |
| 22:19 | clojurebot | (sandbox/foo sandbox/x) |
| 22:19 | hiredman | so that namespace qualifies x, but what if we don't want that |
| 22:20 | hiredman | ,`(foo ~x) |
| 22:20 | clojurebot | java.lang.Exception: Unable to resolve symbol: x in this context |
| 22:20 | brandonw | oh okay, x doesn't exist in the current namespace |
| 22:20 | hiredman | that stops it from being namespace qualified, but it makes it resolve, which we don't want, we want it quoted |
| 22:20 | brandonw | right |
| 22:20 | hiredman | ,`(foo ~'x) |
| 22:20 | clojurebot | (sandbox/foo x) |
| 22:22 | hiredman | and what if we want to pass the symbol x to foo? |
| 22:22 | brandonw | ohhhh okay. so ~' is the way to get something to not resolve, but the extra quote was purely because it needed to retain the quote because it was being used by a namespace macro which requires a quoted symbol |
| 22:23 | brandonw | s/needed to retain the quote because it/ |
| 22:23 | brandonw | so the thing that was throwing me for a loop was looking a a namespace sitation at the same time as learning about having something not be namespace qualified |
| 22:28 | brandonw | thanks for all the help hiredman |
| 23:50 | brandonw | what is the best way to debug macros involving other macros? can i exclude some macros from expanding? i write out the code i am aiming for, but it has macros already in it (import, for example). i don't want import to expand, i just want the other pieces of the macro to expand |
| 23:52 | wooby | bradbeveridge, macroexpand-1 perhaps? |
| 23:53 | wooby | woops, meant brandonw |
| 23:53 | brandonw | (macroexpand-1 `(NGServer/main (into-array String addr-port))) |
| 23:54 | brandonw | ,(macroexpand-1 `(NGServer/main (into-array String addr-port))) |
| 23:54 | clojurebot | (NGServer/main (clojure.core/into-array java.lang.String sandbox/addr-port)) |
| 23:54 | hiredman | brandonw: don't use syntax quote there |
| 23:54 | brandonw | there already is a syntax quote in an upper level expression |
| 23:55 | brandonw | there is a `(do expr above this, and everything is inside of it |
| 23:55 | hiredman | so? |
| 23:55 | clojurebot | paredit source is http://mumble.net/~campbell/emacs/paredit.el |
| 23:55 | brandonw | basically, what i am trying to do is port http://github.com/technomancy/leiningen/blob/master/lein-swank/src/leiningen/swank.clj over to a lein-nailgun plugin that sets the classpath |
| 23:56 | brandonw | i've got the import working, but the actual call to NGServer/main is giving me trouble |
| 23:57 | brandonw | so unquote the whole (NGServer/main expression? |
| 23:58 | brandonw | or don't use syntax quote, use the regular quote |