2009-11-04
| 00:00 | Puzzler | I think he's saying he likes it so far, but finds it intimidating to get started and wishes it were easier to jump in. |
| 00:00 | G0SUB | Puzzler: hmm, I am sure you are right. |
| 00:01 | tomoj | hmm |
| 00:01 | tomoj | I can barely remember what it was like for clojure to feel intimidating |
| 00:02 | G0SUB | (ns foo (:use [clojure.contrib.str-utils :only (str-join)]) vs. (ns foo (:use [clojure.contrib.str-utils :only [str-join]]) |
| 00:02 | somnium | ,(take 50 (clojure.contrib.seq-utils/shuffle (take 100 (iterate inc 1)))) |
| 00:02 | clojurebot | (78 58 85 53 60 83 45 50 56 20 31 92 62 10 57 30 80 43 6 18 97 96 55 72 8 88 12 17 7 19 26 42 64 67 46 39 21 54 27 4 47 84 93 1 87 100 25 81 33 59) |
| 00:03 | G0SUB | both of them work, why is the first preferred over the second? |
| 00:04 | G0SUB | why use a list instead of a vector as an arg to :only? |
| 00:04 | somnium | G0SUB: not an answer, but (ns foo (use bar)) is also valid |
| 00:04 | tomoj | who says the first is preferred? |
| 00:04 | somnium | the macro doesn't seem to care as long as it get some kind of string and some kind of seq in the right places |
| 00:05 | tomoj | I think I like the first because it helps make the list of symbols look different than the vector wrapping the libspec |
| 00:05 | tomoj | but really it is absolutely only a stylistic matter |
| 00:10 | hiredman | ugh |
| 00:15 | tomoj | what's an efficient way to take a seq like '([a b] [c d] [e f]) and get '(a c e) and '(b d f) |
| 00:16 | somnium | ,(map first '([a b] [c d])) |
| 00:16 | clojurebot | (a c) |
| 00:16 | tomoj | sure |
| 00:16 | tomoj | but then we have to crawl the seq twice |
| 00:17 | somnium | ah, you probably need to reduce then, but only one return val |
| 00:17 | somnium | is [[a c e] [b d f]] ok? |
| 00:18 | tomoj | well I could see how to do that with a reduce |
| 00:18 | tomoj | but I'd rather have a pair of lazy seqs |
| 00:20 | tomoj | hmm, I think I'm not thinking straight |
| 00:20 | somnium | not sure I understand what return val is the goal |
| 00:20 | tomoj | if you have a pair of lazy seqs as the return val, then they will crawl separately, and so you'll crawl the original seq twice |
| 00:20 | somnium | you could use something mutable like an array and a doseq, but I don't think thats what youre after |
| 00:22 | somnium | maybe one lazy seq that conses onto n lists? |
| 00:22 | somnium | that way you only crawl once |
| 00:22 | somnium | so returns [[lazy-a ...] [lazy-b ...]] |
| 00:23 | tomoj | I don't see how to do it with one lazy seq |
| 00:23 | tomoj | I'm being given a seq like [[key1, val1], [key2, val2], ...] and I want a lazy seq of keys and a lazy seq of vals |
| 00:24 | somnium | (map #(list (first %) (last %)) (...)) |
| 00:24 | somnium | you still have to split them out, but each node gets processed only once, closer? |
| 00:24 | tomoj | that's pretty much the identity |
| 00:24 | somnium | er |
| 00:27 | tomoj | ,(map #(list (first %) (last %)) '([a b] [c d])) |
| 00:27 | clojurebot | ((a b) (c d)) |
| 00:27 | somnium | reduce isn't lazy is it... |
| 00:28 | tomoj | nope |
| 00:28 | tomoj | maybe I'm talking nonsense |
| 00:29 | somnium | can you do it with lazy-seq and cons somehow? |
| 00:29 | tomoj | seems like it might be impossible to split a seq of [[key, val], ..] into two lazy seqs of (key, ..) and (val, ..) |
| 00:29 | tomoj | I mean, without having each lazy seq crawl the seq on its own |
| 00:30 | tomoj | maybe having each lazy seq crawl the seq on its own is OK |
| 00:30 | somnium | (nth keyseq n) would have to get (nth valseq n) if they crawl together? |
| 00:32 | tomoj | hmm |
| 00:32 | tomoj | you know you may be right |
| 00:32 | tomoj | if you close over a lazy-seq of the keyval pairs |
| 00:33 | tomoj | and have each of the lazy seqs keep a reference to that |
| 00:35 | tomoj | I am utterly confused |
| 00:35 | somnium | I'm guessing laziness is key? if they both close over it will it ever get GCed? |
| 00:36 | somnium | I need to try out the new branch, been frustrated with performance of gen-class vs. java |
| 00:36 | tomoj | well i was thinking you could return a pair of lazy-seqs |
| 00:36 | tomoj | but they both reference the same lazy-seq in the background through the closure |
| 00:38 | tomoj | well |
| 00:38 | tomoj | then they both will crawl it separately anyway I guess |
| 00:40 | somnium | could you lazily reduce onto two lists? something like (cons n (reduce #(...) (take n key-vals)))? |
| 00:41 | somnium | er, the first n should be a list with the transformed lists, and you cons on them as needed with reduce, |
| 00:42 | somnium | tomoj: its been a nice break from my problem domain, what's it for, out of curiosity? |
| 00:43 | tomoj | well |
| 00:44 | tomoj | couchdb sends a list like [[key, val], ..] to the view server |
| 00:44 | tomoj | but the javascript view server calls reduce functions with a list of keys and a list of vals as parameters |
| 00:47 | tomoj | of course I don't have to make my clojure reduce functions act like javascript reduce functions, hmm |
| 01:55 | kjacs | Hello, I am trying to run the Norvig Spelling Corrector example and I'm running into issues with (or). What should (or () () '(1 2 3)) eval to? The example assumes '(1 2 3) but I am getting (). |
| 01:56 | arbscht | kjacs: that is CL code. in clojure, () is not NIL. |
| 01:57 | arbscht | ,(or () true) |
| 01:57 | clojurebot | () |
| 01:57 | arbscht | ,(or nil true) |
| 01:57 | clojurebot | true |
| 01:57 | arbscht | ,(nil? ()) |
| 01:57 | clojurebot | false |
| 01:58 | kjacs | hrm, is the example (http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Norvig_Spelling_Corrector) incorrect or am I doing something wrong? |
| 01:59 | noidi | ,(not (not ())) |
| 01:59 | clojurebot | true |
| 01:59 | arbscht | kjacs: I think that code may be obsolete. () used to be nil in clojure |
| 01:59 | kjacs | ah ok |
| 02:07 | kjacs | arbscht: thanks for your help. I found my problem. The example I posted actually works. I was using the example on (http://en.wikibooks.org/wiki/Learning_Clojure). The working example wraps the for loop in a seq returning nil and not (). |
| 02:17 | tomoj | I think the idiomatic way is to call seq in the test |
| 02:18 | kjacs | tomoj: ah, so (or (seq (fn1)) (seq (fn2))) ? |
| 02:28 | tomoj | I guess |
| 02:28 | tomoj | I mean, if you use seq in the test it will work no matter what sequential thing is passed in |
| 02:29 | tomoj | if you put it in the functions which generate the seq, then your test will only be guaranteed to work when it takes the results of those functions as input |
| 03:34 | tomoj | what should the type be for into-array when making an array of arrays of doubles? |
| 03:36 | tomoj | oh, it can figure it out on its own |
| 03:45 | hiredman | damn |
| 03:45 | hiredman | you cannot call clojure.xml/parse on appengine |
| 03:46 | hiredman | tomoj: Double/TYPE |
| 03:46 | tomoj | the type of an array of doubles is Double/TYPE? |
| 03:46 | hiredman | not really, but it is what you put in the type slot |
| 03:47 | hiredman | ,(make-array Double/TYPE 1) |
| 03:47 | clojurebot | #<double[] [D@1021e58> |
| 03:47 | tomoj | but that's an array of doubles |
| 03:47 | tomoj | I'm making an array of array of doubles |
| 03:47 | hiredman | Oh |
| 03:47 | hiredman | use into-array :P |
| 03:48 | tomoj | (into-array (map #(into-array Double/TYPE %) ...)) works |
| 03:48 | hiredman | well there you go |
| 03:48 | hiredman | if clojure.xml/parse doesn't work, I guess I'll switch to json |
| 03:48 | hiredman | hmm |
| 03:49 | hiredman | I must be doing something wrong |
| 03:49 | hiredman | ,(doc clojure.xml/parse) |
| 03:49 | clojurebot | "([s] [s startparse]); Parses and loads the source s, which can be a File, InputStream or String naming a URI. Returns a tree of the xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content. Other parsers can be supplied by passing startparse, a fn taking a source and a ContentHandler and returning a parser" |
| 03:51 | hiredman | there we go |
| 03:52 | hiredman | I was passing it a string that was not a url, which caused it to do something appengine did not like |
| 04:21 | hiredman | ,(doc merge-with) |
| 04:21 | clojurebot | "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)." |
| 04:49 | hiredman | ~hiredman |
| 04:49 | clojurebot | hiredman is an evil genius. |
| 04:49 | hiredman | ~hiredman |
| 04:49 | clojurebot | hiredman is slightly retarded |
| 04:49 | hiredman | theres the one |
| 05:36 | stephenj | #clojure |
| 05:37 | stephenj | (+ 1 2) |
| 05:37 | clojurebot | 3 |
| 05:37 | stephenj | ~*ns* |
| 05:37 | clojurebot | No entiendo |
| 05:37 | stephenj | *ns* |
| 05:41 | tomoj | why did clojurebot eval that? |
| 05:41 | tomoj | (+ 1 2) |
| 05:41 | clojurebot | 3 |
| 05:41 | tomoj | weird.. |
| 05:42 | hiredman | I have got a facebook app up and running on appengine in clojure |
| 05:42 | hiredman | (+ 2 3) |
| 05:42 | clojurebot | *suffusion of yellow* |
| 05:43 | hiredman | that was painful |
| 05:43 | hiredman | took me aroudn five hours |
| 05:44 | hiredman | for so little |
| 05:44 | hiredman | http://apps.facebook.com/agegraph/ |
| 05:45 | CalJunior | So facebookers are either 24, 28 or 43 (or don't know their age) :-) |
| 05:46 | CalJunior | right, I guess I have very few friends on facebook |
| 05:47 | CalJunior | hiredman: how did you go about it. where was the pain? |
| 05:47 | hiredman | mine are mostly unkown |
| 05:47 | hiredman | which is annoying because I made the app because I wanted to know |
| 05:47 | hiredman | CalJunior: the facebook api seems to be very php centric |
| 05:48 | CalJunior | now you know they don't want you to know. there's information in that. |
| 05:49 | hiredman | the range is 14 to 64 with a hump at around 20 for the known ages |
| 05:49 | CalJunior | Any pain in getting Clojure to play nice with GAE? |
| 05:49 | hiredman | not too much |
| 05:50 | hiredman | I wrote an appengine helper ant thing a while back, I did have to rip the multipart mime stuff out of compojure |
| 05:50 | hiredman | I should feed this stuff back into appengine-helper sometime |
| 05:51 | hiredman | http://github.com/hiredman/appengine-helper |
| 05:52 | hiredman | and appengine-helper needs a deploy target |
| 05:55 | CalJunior | thanks for the link. |
| 05:56 | hiredman | *cough* it hasn't had much testing |
| 06:01 | hiredman | now that I've finished that, it's 3am and I'm all keyed up |
| 06:17 | stephenj | (+ 1 1) |
| 06:17 | clojurebot | 2 |
| 06:17 | ordnungswidrig | (+ 1) |
| 06:17 | clojurebot | 1 |
| 06:17 | ordnungswidrig | () |
| 06:17 | ordnungswidrig | clojurebot: when do you eval? |
| 06:17 | clojurebot | eval is evil |
| 06:19 | hiredman | clojurebot: how much wood would a wood chuck chuck if a wood chuck could chuck wood? |
| 06:21 | hiredman | clojurebot: well? |
| 06:21 | clojurebot | No entiendo |
| 06:24 | hoeck | maybe clojurebot is confused when to treat `,' as whitespace |
| 06:24 | hiredman | I doubt that |
| 06:50 | AWizzArd_ | Is there an easy way to take a subarray of an array? |
| 06:52 | AWizzArd | ,(into-array Byte/TYPE [10 20 30]) |
| 06:52 | clojurebot | java.lang.IllegalArgumentException: argument type mismatch |
| 06:52 | tomoj | ,(into-array Byte/TYPE (map byte [10 20 30])) |
| 06:52 | clojurebot | #<byte[] [B@1a59727> |
| 06:53 | hiredman | you could use byte buffers to do it |
| 06:53 | hiredman | (I think) |
| 06:53 | AWizzArd | oki, I will have a look, thx |
| 07:04 | cemerick | rhickey: would you prefer early deftype/class feedback here or on the list? |
| 07:06 | avital | Hi. Just installed clojure-mode using ELPA and I can't seem to use clojure-contrib. I am trying to eval (use 'clojure.contrib.json.read) and I get a FileNotFoundException. Anything from clojure core works. It was my understanding that clojure-mode should support clojure-contrib immediately. I searched google and couldn't find any record of such an issue. Anyone have an idea? |
| 07:11 | liwp | avital: make sure that clojure-contrib has been installed |
| 07:11 | liwp | I can't remmeber is the clojure-mode installer installs it or not |
| 07:12 | avital | liwp: In src/ (the directory clojure-mode puts all the installation stuff) there is a clojure-contrib directory. Where else should I check? |
| 07:12 | liwp | avital: hmm, check that it's on your class path |
| 07:13 | liwp | try this in the repl: (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))) |
| 07:13 | liwp | you should see clojure-contrib in the output |
| 07:13 | tomoj | did you use clojure-install? |
| 07:13 | avital | Hmm. it's there |
| 07:13 | avital | tomoj: Yes |
| 07:14 | tomoj | and you added the config they told you to add? |
| 07:14 | liwp | avital: then check that it's been built |
| 07:14 | avital | Let me check the actual file it points to. |
| 07:14 | avital | tomoj: I added (clojure-slime-config) |
| 07:14 | tomoj | I guess if your src/ is in the default place that should work |
| 07:15 | avital | It points to a JAR that exists: ~/src/clojure-contrib/clojure-contrib.jar |
| 07:15 | avital | A friend just also did clojure-install and gets the same error. |
| 07:16 | tomoj | C-h v swank-clojure-classpath |
| 07:16 | liwp | avital: try running the repl from the command line using both the clojure.jar and clojure-contrib.jar that were installed by clojure-mode |
| 07:16 | tomoj | the correct path to clojure-contrib.jar is there? |
| 07:17 | avital | tomoj: It's there and I checked - the file is really there. |
| 07:17 | avital | liwp: Good idea, one minute. |
| 07:18 | liwp | FYI: my swank-clojure-classpath points to both the src and classes dirs in contrib, but not to the jar |
| 07:18 | tomoj | does clojure-install still install old stuff? |
| 07:18 | tomoj | maybe it got the 1.0 branch and that doesn't have json stuff? I dunno |
| 07:20 | liwp | avital: try also loading some other contrib stuff, maybe it's an issue with the json lib, like tomoj suggested |
| 07:21 | avital | Hmm. |
| 07:21 | avital | java -cp ../clojure-contrib/clojure-contrib.jar -jar clojure.jar |
| 07:21 | avital | I still don't have clojure.contrib.json.read |
| 07:21 | liwp | avital: the (use...) form works for me, but I'm not using the clojure-mode install |
| 07:21 | avital | I also tried clojure.contrib.monads |
| 07:21 | avital | Also fails |
| 07:21 | tomoj | jar -tf .../clojure-contrib.jar and see if json stuff is in there |
| 07:21 | liwp | avital: try putting both jars in the -cp option |
| 07:22 | avital | tomoj: json is there |
| 07:22 | hiredman | -jar and -cp are mutually exclusive , btw |
| 07:23 | liwp | avital: are the clojure and contrib directories git checkouts? maybe you can try moving to HEAD if they are checkouts of the 1.0 tag or something... |
| 07:23 | avital | liwp: Still doesn't work. |
| 07:23 | hiredman | if you use -jar java silently ignores -cp |
| 07:23 | avital | liwp: They are git checkouts, I think they are the 1.0 tag indeed. |
| 07:24 | avital | hiredman: I tried with just -cp on both and specifying clojure.main as the class to run. |
| 07:24 | avital | hiredman: still doesn't work |
| 07:24 | avital | liwp: But I see clojure.contrib.json.read is there... |
| 07:24 | tomoj | like java -cp .../clojure.jar:.../clojure-contrib.jar clojure.main ? |
| 07:25 | avital | avital@avital-laptop-2:~/src/clojure$ java -cp ../clojure-contrib/clojure-contrib.jar:clojure.jar clojure.main Clojure 1.0.0--SNAPSHOT user=> (use 'clojure.contrib.json.read) java.io.FileNotFoundException: Could not locate clojure/test__init.class or clojure/test.clj on classpath: (read.clj:0) |
| 07:25 | hiredman | oh |
| 07:25 | hiredman | you have an old version of clojure and a new version of contrib maybe |
| 07:25 | avital | Oh I just notices it's not json.read that it can't find! |
| 07:26 | tomoj | why would clojure-install check out mismatched versions? |
| 07:26 | hiredman | *shrug* |
| 07:26 | hiredman | I'm not an emacs user |
| 07:26 | tomoj | unless there's some reason you want to be on 1.0, check out master on both repos and rebuild |
| 07:27 | hiredman | clean and rebuild |
| 07:28 | tomoj | default target cleans for me |
| 07:28 | avital | oh wow i rebuilt clojure and now when i rebuild clojure-contrib i get errors |
| 07:28 | avital | let me try switching to head |
| 07:29 | tomoj | isn't switching to head like walking to here? |
| 07:32 | avital | I think they are on head. Is it possible that clojure-contrib is currently broken? Or did someone just say they tested it and it works? |
| 07:32 | avital | (when I run ant -Dclojure.jar=../clojure/clojure.jar in clojure-contrib I get errors) |
| 07:33 | avital | [btw thanks for all the help!] |
| 07:33 | tomoj | how did you get them to be "on head" ? |
| 07:34 | avital | I just looked at .git/config and it seems that they are already on head (how would you say that other than 'on head'?) |
| 07:34 | avital | [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = git://github.com/richhickey/clojure-contrib.git [branch "master"] remote = origin merge = refs/heads/master |
| 07:34 | tomoj | .git/config is irrelevant |
| 07:34 | avital | oh ok |
| 07:34 | liwp | avital: what does git branch -a say? |
| 07:34 | tomoj | I believe HEAD is whereever you currently are |
| 07:34 | tomoj | do git checkout master |
| 07:35 | tomoj | perhaps also git pull, though you should already have the latest |
| 07:37 | avital | oh wow clojure wasn't on head. now that it is clojure-contrib doesn't have compilation errors! |
| 07:37 | avital | let me try json.read again |
| 07:38 | liwp | avital: you should check if your contrib checkout is on clojure-1.0-compatible or on master |
| 07:38 | avital | liwp: it was and is on master |
| 07:38 | liwp | avital: ok |
| 07:38 | avital | OH WOW IT WORKS NOW WOW OW WO WO WO OW OW OW OW |
| 07:38 | avital | WOWOW |
| 07:38 | avital | wOWOWOWO |
| 07:38 | avital | THANKS |
| 07:39 | avital | ok |
| 07:39 | liwp | avital: that definitely won't work then if you had a 1.0 clojure |
| 07:39 | liwp | np |
| 07:39 | avital | to whom to i send the bug report about clojure-install? |
| 07:39 | avital | or a patch |
| 07:47 | liwp | avital: I think technomancy (Phil Hagelberg?) is the maintainer these days |
| 07:50 | patricius_ | is there some clever way to reset the Clojure REPL without restarting clojure (and java potentially)? |
| 07:50 | avital | liwp: Ok thanks, I'll send him a message on GitHub |
| 07:51 | noidi | patricius_, why do you need to reset it completely? |
| 07:51 | patricius_ | just to ensure that no agents are running and that all previous definitions have gone away... maybe that is a complete non-issue? |
| 07:53 | tomoj | patricius_: certainly not a non-issue |
| 07:53 | tomoj | developing on the repl can hide bugs that won't show up until you restart |
| 07:54 | tomoj | from moving/renaming/deleting functions |
| 07:55 | patricius_ | tomoj: yeah... that was what I was thinking |
| 07:55 | patricius_ | so the best thing to do is just restarting the REPL? |
| 07:56 | tomoj | that's what I do |
| 07:56 | patricius_ | ok |
| 07:56 | patricius_ | cool |
| 07:56 | tomoj | I think there could be a clever way to crawl through and unbind everything |
| 07:56 | tomoj | but I don't know of anything clever to do about agents |
| 07:56 | patricius_ | that's allright |
| 07:57 | patricius_ | I am asking because I have started using a SLIME-like thing for Vim, and I didn't want to have to restart clojure all the time to be sure that things would work right |
| 07:57 | tomoj | I tend to restart the repl often anyway since I work on a bunch of different things and use swank-clojure-project to get a repl for each different thing |
| 07:57 | patricius_ | and by the way, this SLIME-like thing works really well and is MUCH easier to setup than VimClojure in my opinion |
| 07:57 | patricius_ | oh ok |
| 07:58 | tomoj | what's this SLIME-like thing called? |
| 07:58 | patricius_ | slime.vim :) |
| 07:59 | patricius_ | it essentially just sends stuff to a screen session, so you don't run the REPL inside vim |
| 07:59 | patricius_ | but for me that doesn't matter |
| 08:39 | dabd | The ant build script does not include clj source files in clojure.jar so 'clojure.contrib.repl-utils/source' doesn't work. What can I include the sources? thx |
| 08:39 | dabd | Sorry I meant 'How can I include the sources?' thx |
| 08:50 | chouser | I usually just include the src dir in my classpath. Sorry that doesn't answer your question. |
| 08:54 | rhickey | in fact, I thought they were left there specifically for tools |
| 08:54 | dabd | well I am using enclojure and I get this error: http://paste.lisp.org/+1X9T |
| 08:55 | chouser | sure enough -- clojure.jar and clojure-slim.jar both seem to have the .clj files |
| 08:55 | rhickey | can't find clojure.contrib.repl-utils |
| 08:56 | chouser | dabd: you do need to 'require' a namespace before you use it |
| 08:57 | chouser | this is unlike Java classes that can be used without previous ceremony as long as you fully-qualify the class name. |
| 08:57 | cemerick | dabd: right, what chouser said: (require 'clojure.contrib.repl-utils), then (clojure.contrib.repl-utils/source reduce) |
| 08:58 | dabd | ok it works now. thanks |
| 08:59 | rhickey | or maybe (require '[clojure.contrib.repl-utils :as repl]) ... (repl/source reduce) |
| 08:59 | chouser | I'm going to have to find a way to subdivide the daily #clojure logs. total average daily traffic is definitely on an upward trend. |
| 09:00 | cemerick | dabd: in a real app, you'd put such requires, etc., in an ns declaration at the top of your source file, aliasing the namespace as rhickey did just now |
| 09:00 | dabd | ok I understand |
| 09:00 | dabd | thanks |
| 09:00 | chouser | rhickey: do you have any thoughts about default namespace aliases that would somehow still present a clear link between the usage of the alias and the actual namespace providing it? |
| 09:01 | rhickey | chouser: in favor of default aliases, unclear about what you mean by clear link |
| 09:03 | chouser | I mean if (uses com.foo.bar) (cfb/do-it) works, it's not at all obvious that cfb is the same as com.foo.bar. |
| 09:04 | rhickey | chouser: seems a general problem of nicknames, smaller, more likely to collide, less descriptive |
| 09:05 | rhickey | do you have ideas? |
| 09:05 | chouser | the explicit :as avoids the problem now, but I'd also like default aliases. |
| 09:05 | chouser | not good ideas, no. |
| 09:05 | cemerick | seems like c.f.bar is reasonable for com.foo.bar |
| 09:05 | cemerick | assuming the namespace components are longer than that :-) |
| 09:06 | rhickey | cemerick: that will drive people to very short namespace names |
| 09:06 | rhickey | for the last segment I mean |
| 09:07 | cemerick | yeah. I almost uniformly just alias the last component of the ns name, but that's obviously not a general approach. |
| 09:07 | chouser | generating the default alias is interesting though |
| 09:07 | cemerick | I'm not entirely sure default aliases are necessary, anyway. |
| 09:08 | chouser | one benefit of default aliases is that it would encourage everyone to use the same alias for common namespaces, which would have benefits across the board. |
| 09:09 | cemerick | it only matters within each namespace -- do I care what you alias seq-utils to in your ns? |
| 09:09 | chouser | cemerick: if you're reading a snippet of my code, yes. |
| 09:09 | chouser | if I alias it the same as you do, you won't even have to go look at the 'ns' block to know what's going on. |
| 09:10 | rhickey | (just musing here) - could do - not an exact classname ?, then is it an unambiguous shortening of a referenced ns? |
| 09:11 | rhickey | c.c.repl enough for repl utils |
| 09:11 | cemerick | :as is pretty darn easy, and idiomatic usage is, too. If auto aliasing could work well and be generally applicable, then we might as well make all namespaces one level deep. |
| 09:11 | rhickey | or even repl |
| 09:11 | chouser | like the last component? bar for com.foo.bar? or more general -- ah. hm. |
| 09:12 | rhickey | doesn't give you consistency |
| 09:12 | chouser | why does that remind me of VMS? |
| 09:12 | rhickey | but need not be declared nick, no conflicts possible |
| 09:14 | rhickey | any feedback on deftype/class/reify? |
| 09:14 | chouser | ship it |
| 09:14 | rhickey | heh |
| 09:15 | cemerick | rhickey: I've got a bunch...want it here or on list? |
| 09:15 | rhickey | that's another issue, whither 1.1? |
| 09:15 | rhickey | cemerick: either, short version here would be a good start, before I move deep into protocols |
| 09:16 | rhickey | I think we need to get a 1.1. out before pulling new into master |
| 09:16 | chouser | ah, interesting. |
| 09:17 | rhickey | only master gets the workout needed for pre-release |
| 09:18 | fogus_ | cemerick: If it's all the same, feedback is more easily consumed outside of IRC |
| 09:19 | rhickey | oh yes, not trying to discourage that, please post to group also |
| 09:20 | rhickey | just, we're both sitting here... |
| 09:21 | fogus_ | Understood. My IRC connection is perilous... so I would hate to miss something. :) |
| 09:23 | ordnungswidrig | fogus_: there is a irc log, isn't it :-> |
| 09:24 | cemerick | rhickey: I'll do a quick rundown here, and post if anything significant comes out of it. I'm recording a podcast at the moment. :-) |
| 09:25 | chouser | haha! |
| 09:37 | tknudsen | /home/tknudsen/Desktop/Working/enclojure/build.xml:2: Problem: failed to create task or type antlib:org.apache.ivy.ant:settings |
| 09:38 | tknudsen | Cause: The name is undefined. |
| 09:38 | tknudsen | peeps, any ideas? |
| 09:39 | fogus_ | ordnungswidrig: Yes, on chouser's site... but there is a lot of noise to filter through. |
| 09:43 | chouser | that would be a brilliant way to split up each day -- a list of threads at the top of the page. |
| 09:46 | fogus_ | chouser: I like that idea... it would make the IRC logs an invaluable resource. (more so than they are already) |
| 09:49 | cemerick | rhickey: so, my first question: was it intentional to make all non-primitive args into defclass ctors Object? |
| 09:51 | rhickey | there isn't yet the plumbing under the hood to distinguish locals of non-primitive types, but eventually I'd like to enforce via explicit types for construction and storage |
| 09:53 | cemerick | rhickey: FWIW, I'd be very happy with two ctors: one typed, and one untyped. The reason being, I'd like to be able to drop IDerefs into those ctors as desired, and I'd make the associated .field getters unpack those IDerefs as necessary. Perhaps stuff like that should go into a layer on top of defclass, but that's one aspect of our typical usage. |
| 09:55 | rhickey | cemerick: I don't get that, you couldn't put the IDeref into a field of the type of the thing it held |
| 09:56 | rhickey | what is the type of the field? |
| 09:56 | cemerick | rhickey: to be clear, we wouldn't be accessing fields anyway -- we have a set of interfaces that declare getter methods (without the "get" part) for each slot, and those are typed. |
| 09:56 | cemerick | So, we might end up just typing everything as Object. |
| 09:56 | rhickey | ok, then I don't see the typed/untyped ctor use case |
| 09:57 | cemerick | rhickey: That's for the impl of those interfaces for use by our Java-using customers :-) |
| 09:57 | rhickey | I wonder about a defstatic for factories etc. Exposing ctors is always a problem |
| 09:58 | cemerick | Yeah, that's a route we've experimented with using genclass, which seems to work very well. |
| 09:59 | rhickey | defstatic could be a great target for some higher-level 'package my Clojure up for Java' thing |
| 09:59 | cemerick | right |
| 09:59 | cemerick | anyway, the types on the ctor are irrelevant compared to my #2: please oh please provide a ctor that defaults metadata and expando maps to nil. |
| 10:00 | cemerick | adding two nils or ", null, null" in java to every defstruct ctor invocation is unpleasant :-) |
| 10:00 | chouser | cemerick: I'm pretty sure that's planned just not done yet. |
| 10:01 | rhickey | cemerick: I hear you on that, always trips me up and an asymmetry with deftype factory fns |
| 10:01 | cemerick | That's great. |
| 10:01 | chouser | oh, maybe I'm confusing with the factory fns. |
| 10:01 | rhickey | right now just a side effect of the ctor-generating code being on the Java side and completely ignorant of metadata etc |
| 10:02 | rhickey | the __ stuff is a bit precious, but I am already leveraging that in generating lookup thunks (I don't gen for __meta and __extmap) |
| 10:03 | rhickey | chouser: right, factory fns have 2 arities right now, ctors only one |
| 10:03 | rhickey | very convenient to sat (deftype Foo [a b c]) ... (Foo 1 2 3) |
| 10:03 | cemerick | so next up is: it's worth noting in the docs that arity overloads in method impls are broken out in the new regime, which is different from typical fns |
| 10:04 | AWizzArd | Does .read of an InputStream block until the data is available? |
| 10:05 | rhickey | cemerick: ah, is noted here: https://www.assembla.com/wiki/show/clojure/Datatypes |
| 10:05 | rhickey | "If a method is overloaded in an interface, multiple independent method definitions must be supplied." |
| 10:05 | cemerick | ah, I only skimmed reify, went straight to deftype/class |
| 10:07 | cemerick | my #4 is: all methods on defclasses are declared as throwing Exception. This is really, *really* painful on the Java side, and incongruent with the interfaces the defclasses are implementing. |
| 10:08 | chouser | :-( |
| 10:09 | rhickey | cemerick: that's a bug, see //todo don't hardwire this |
| 10:09 | cemerick | Nice, very good to hear. |
| 10:10 | cemerick | rhickey: finally, why specify interfaces after fields? That seems totally backwards to me (and putting the shorter vector after the longer one, which doesn't help readability). |
| 10:11 | rhickey | cemerick: because I hope for many use cases with no interfaces or methods at all |
| 10:11 | rhickey | simple struct-like things extended via protocols |
| 10:12 | cemerick | OK, I can get along with that. :-) |
| 10:12 | cemerick | rhickey: that's all I've got for now. I've dumped most usages of our PSM macros overboard, and all our tests are green. :-) |
| 10:13 | rhickey | great! and perf? |
| 10:13 | rhickey | I've got: |
| 10:13 | rhickey | interface methods should have interface exception types, not hardwired |
| 10:13 | rhickey | ctor without meta and extmap |
| 10:13 | rhickey | typed non-primitive fields |
| 10:14 | cemerick | yup, that's all of it |
| 10:15 | cemerick | only a slight bump in perf (maybe 5%?), but the hottest usage of the PSM macros hasn't yet been replaced, because it's particularly gnarly. I'm hoping to cut that knot this morning. |
| 10:16 | cemerick | I'm really looking forward to dumping that code, though. That'll be a big load off. |
| 10:17 | cemerick | Producing a couple of *simple* macros for autogenerating accessors and bean-compliant getters, etc., will be super-easy, I'm looking forward to that. |
| 10:18 | cemerick | I had stopped adding to our PSM macros because they became far too complicated to touch :-( gen-class is a beast! |
| 10:19 | liwp | cemerick: what's PSM? |
| 10:20 | chouser | PersistentStructMap |
| 10:20 | liwp | thank you |
| 10:30 | cemerick | using (.methodName) in reify, et al. was a great move |
| 10:33 | cemerick | rhickey: it would be convenient if (defclass Foo ...) were to emit an implicit (import 'my.ns.Foo) |
| 10:50 | manby-ace | Has anyone done any work getting slime / swank going with ClojureCLR? |
| 10:51 | liwp | manby-ace: I think swank-clojure supports only the JVM implementation of clojure |
| 10:52 | liwp | so you'd need a clojureclr implementation of swank, and I haven't heard of one |
| 10:52 | manby-ace | llwp: cheers, just wondering if that might have already been started. I'll commence hacking then :-) |
| 10:52 | liwp | manby-ace: carry on |
| 10:53 | liwp | manby-ace: I should add that I haven't really been following the ClojureCLR world at all, so there might be an impl, but I just haven't heard about it |
| 11:01 | cemerick | rhickey: just FYI, I just replaced the Java class that is instantiated and accessed the most in our main project (a simple rectangle struct) with defclass, and perf is identical. |
| 11:02 | cemerick | I think that's the only part of our data model that was still in Java. |
| 11:05 | rhickey | cool |
| 11:08 | danlarkin | awesome! |
| 11:08 | arohner | cemerick: was it in java because you needed the performance? |
| 11:08 | cemerick | arohner: yes. We were taking a 10-30% hit on perf if we used the gen-class version of the struct. |
| 11:08 | cemerick | (depending on the dataset benchmarked) |
| 11:09 | arohner | great |
| 11:12 | cemerick | reify should be quite a bit faster than proxy all around, correct? |
| 11:12 | rhickey | cemerick: oh yeah |
| 11:13 | cemerick | OK. I'm trying to prioritize the porting :-) |
| 11:13 | cemerick | basically: turn over everything! |
| 11:13 | rhickey | cemerick: matching exception types is up |
| 11:16 | cemerick | rhickey: excellent, thank you |
| 11:16 | rhickey | thanks for the feedback |
| 11:17 | cemerick | rhickey: thank you very much for the wonderful tools! :-D |
| 11:18 | cemerick | what does this indicate: Mismatched return type: containedBy, expected: java.util.Collection, had: java.lang.Object |
| 11:19 | cemerick | FWIW, containedBy is defined by an interface, as a return type of Collection |
| 11:19 | rhickey | cemerick: is it overloaded? |
| 11:19 | rhickey | or, derived from another interface with covariant return type? |
| 11:19 | cemerick | rhickey: no -- there are other methods on that interface that are overloaded, but not containedBy |
| 11:20 | rhickey | are you supplying type hints? |
| 11:20 | cemerick | not on any returned values, etc. |
| 11:20 | rhickey | at all on containedBy? |
| 11:21 | rhickey | i.e. on the signature |
| 11:22 | cemerick | rhickey: Yes, I had a type hint on the single argument. Removing it eliminated the exception. The type hint was correct, FWIW. |
| 11:22 | cemerick | Obviously not needed in reify, but should it cause an exception? |
| 11:22 | rhickey | cemerick: once you type hint anything you must get all the hints right, leaving off the return hint defaults to Object |
| 11:22 | cemerick | ah-ha |
| 11:23 | cemerick | even if the method isn't overloaded? |
| 11:23 | rhickey | yes |
| 11:23 | rhickey | why hint at all then? |
| 11:23 | cemerick | well, I had to with proxy :-) |
| 11:24 | rhickey | that was the old days |
| 11:24 | cemerick | a lot of stuff is going away with the porting |
| 11:24 | cemerick | yeah |
| 11:24 | cemerick | I'd update the docs to indicate that any type hinting requires complete hinting. Right now, my read of them is that they say that only incomplete hints on overloaded methods will cause problems. |
| 11:26 | rhickey | cemerick: its doesn't actually require complete hinting, just correct hinting, i.e. default of Object ok if Object - clarifying now |
| 11:26 | fradiavalo | Hi guys, I am having some trouble with re-matches..not sure why (re-matches #"ab+" "abc") returns nil, where as (re-matches #"[-+]?[0-9]+/[0-9]+" "22/7") returns "22/7" |
| 11:28 | rhickey | "if you supply any hints at all, no inference is done, so all hints (or default of Object) must be correct, for both arguments and return type" |
| 11:28 | cemerick | yeah, that's better :-) |
| 11:29 | cemerick | anything involving JIT is tough to peg, but my impression so far is that perf is plateauing a lot faster now (i.e. less warm-up to get JIT'ed code). |
| 11:31 | fradiavalo | ugh, I figured it out, I had a buggy regex. Sorry for the noise. |
| 12:31 | rhickey | cemerick: fields-only ctor is up |
| 12:44 | hiredman | clojurebot: max people? |
| 12:44 | clojurebot | max people is 255 |
| 12:44 | hiredman | clojurebot: really? |
| 12:44 | clojurebot | Huh? |
| 12:46 | cemerick | rhickey: gorgeous, thank you. |
| 12:47 | cemerick | rhickey: is there any perf penalty associated with the default IPersistentMap impl? |
| 12:47 | cemerick | on deftype/class, that is |
| 12:56 | chouser | optional interfaces list could come before a required fields list. ...is that too magical? |
| 13:03 | AWizzArd | hiredman: no, it's not true |
| 13:03 | AWizzArd | someone cheated and changed that var |
| 13:05 | cemerick | chouser: I suggested that earlier, but I think rhickey is expecting a lot of types unassociated with interfaces |
| 13:05 | chouser | sure, it can still be optional |
| 13:06 | hiredman | clojurebot: max people is 180ish |
| 13:06 | clojurebot | Ik begrijp |
| 13:06 | cemerick | I think it would read better with interfaces first (I like to have shorter forms before longer ones, etc), but it's fundamentally unimportant to me. |
| 13:06 | chouser | I saw you suggest changing the order, I'm just saying I don't see why the interfaces list being optional mean is has to come later. |
| 13:06 | cemerick | ah |
| 13:06 | hiredman | ,(Integer/parseInt "180ish") |
| 13:06 | clojurebot | java.lang.NumberFormatException: For input string: "180ish" |
| 13:06 | hiredman | nuts |
| 13:06 | chouser | ,(read-string "180ish") |
| 13:06 | clojurebot | java.lang.RuntimeException: java.lang.NumberFormatException: Invalid number: 180ish |
| 13:07 | chouser | ,(read-string "180 ...ish") |
| 13:07 | clojurebot | 180 |
| 13:07 | rsynnott | heh |
| 13:07 | hiredman | ,(Integer/valueOf "180ish") |
| 13:07 | clojurebot | java.lang.NumberFormatException: For input string: "180ish" |
| 13:08 | hiredman | clojurebot: max people? |
| 13:08 | clojurebot | max people is 255 |
| 13:09 | hiredman | haha |
| 13:11 | AWizzArd | clojurebot: max people is 188 |
| 13:11 | clojurebot | 'Sea, mhuise. |
| 13:12 | AWizzArd | ~max people |
| 13:12 | clojurebot | max people is 188 |
| 14:16 | ordnungswidrig | typing with my is still very hard... |
| 14:17 | Chousuke | typing with your? |
| 14:17 | ordnungswidrig | argh, my alphagrip i mean |
| 14:17 | ordnungswidrig | bgb |
| 14:18 | ordnungswidrig | ...but fun! |
| 14:22 | patrkris | A question I want to ask to ensure that I understand Clojure correctly: It doesn't make much sense to have a reference (be that a var, a ref or an agent) to an object from Java-world, since that object can mutate, and thus we cannot get a consistent "snapshot" of that object's state/value? |
| 14:27 | chouser | patrkris: you're thinking about it correctly, but the answer may depend. For example if you can treat that java object as if it were immutable (copy on write, for example) it might be useful to keep in a reference object. |
| 14:28 | chouser | Or if the object is immutable despite coming from Java-world, like java.lang.String. |
| 14:28 | patrkris | chouser: yeah ok, I see your point |
| 14:29 | chouser | but yes, if it's a big ol' regular Java application object with pile of getters and setters and no sane way to make copies ... Clojure can't do much to help you with the concurrency nightmare that will ensue. |
| 14:29 | chouser | maybe you can put it in an agent and promise not to use the mutators directly (even though nothing is actually stopping you) and *maybe* that'll be better than a lock. |
| 14:34 | patrkris | yeah, it's not something I plan on trying :) |
| 14:34 | chouser | :-) good |
| 14:36 | patrkris | If i establish a root-binding for a var called A, and in an agent's action say (def A "someothervalue"), that will establish a new root binding, changing the value for all threads? |
| 14:36 | chouser | yes. don't do that either. :-) |
| 14:36 | chouser | using 'def' anywhere other than the top level of a .clj file is at least a yellow flag if not red. |
| 14:37 | patrkris | good... just adding to my understanding :) |
| 14:37 | chouser | (loop [] ... (def x ...)) ; do not want! |
| 14:37 | ordnungswidrig | re |
| 14:38 | chouser | the change is atomic via lock on the var, so you're never going to see a half-updated var, but that's as far as the safety goes. |
| 14:38 | Chousuke | a slightly better way to redef vars is to use alter-var-root! I suppose |
| 14:38 | chouser | alter-var-root is slightly more idiomatic, but I'm not sure I've ever seen it used. |
| 14:39 | ordnungswidrig | what is the idiom for a changed variable x? x_ x+ x1 x_ ?? |
| 14:40 | The-Kenny | I remember there was a convention in haskell for this... I would use it in clojure too. |
| 14:40 | ordnungswidrig | The-Kenny: i think in haskell it's x' but this is not allowed in clojure |
| 14:41 | ordnungswidrig | I've seen x, x+, x++ but I don't like it. |
| 14:41 | The-Kenny | ordnungswidrig: Oh yes, that was the convention. |
| 14:41 | djork | is cond not tail-recursive? |
| 14:42 | Chousuke | what do you mean? |
| 14:42 | The-Kenny | I would prefer x_ from the list you've mentioned. |
| 14:42 | chouser | djork: use :else for the default condition |
| 14:42 | djork | yes but I mean the cond macro itself seems like it may not use tail-call |
| 14:42 | chouser | The-Kenny: what do you mean a changed variable? you can re-use the same name in a series of bindings in a let |
| 14:42 | The-Kenny | djork: As far as I know, there is no tail-recursion in the jvm. |
| 14:43 | djork | yeah but there is in Clojure |
| 14:43 | Chousuke | djork: if cond itself is in the tail position, then all the branches are in tail position as well |
| 14:43 | Chousuke | djork: it just expands to a series of ifs |
| 14:43 | djork | it doesn't seem to be |
| 14:43 | patrkris | there isn't, and rhickey has been explicit about clojure not using tail-call optimization |
| 14:43 | The-Kenny | chouser: I think you want to highlight ordnungswidrig ;) |
| 14:43 | chouser | djork: each value of a cond form is a tail position iff the cond itself is in a tail position. |
| 14:43 | chouser | ordnungswidrig: what The-Kenny said. ;-) |
| 14:44 | djork | oh, so recur in the tail position is not tail call optimization? |
| 14:44 | djork | I thought it was |
| 14:44 | djork | it avoids blowing the stack |
| 14:44 | djork | right? |
| 14:44 | ordnungswidrig | huh? |
| 14:44 | chouser | ordnungswidrig: what do you mean a changed variable? you can re-use the same name in a series of bindings in a let |
| 14:44 | Chousuke | djork: TCO and recur are different things. |
| 14:44 | patrkris | djork: sorry, i probably misunderstood then |
| 14:44 | chouser | patrkris: you're correct |
| 14:44 | ordnungswidrig | Chousuke: really? that'd be both nice and weired |
| 14:45 | chouser | djork: you're probably correct but you might be using the wrong words. |
| 14:45 | Chousuke | djork: but recur *is* a tail call. it's just to to an arbitrary function. |
| 14:45 | twbray | djork: recur achieves the same effect as a recursive call to the function it's in when it's in tail position and TCO is applied. |
| 14:45 | The-Kenny | ordnungswidrig: (let [a 42] (let [a (inc a)] a)) is valid, as far as I know |
| 14:45 | The-Kenny | (and it will return 43) |
| 14:45 | ordnungswidrig | ,(let [a 1 a (inc a) a (inc a)] a) |
| 14:45 | clojurebot | 3 |
| 14:45 | ordnungswidrig | ah. |
| 14:46 | djork | recur is manual tail call optimization |
| 14:46 | chouser | ,(-> 1 inc inc) |
| 14:46 | clojurebot | 3 |
| 14:46 | chouser | djork: yes |
| 14:46 | djork | k |
| 14:46 | Chousuke | an easy way to determine is some expression is in tail position: try replacing it with a suitable recur and see if you get an exception :P |
| 14:46 | djork | yes :) |
| 14:46 | djork | but let me try to test my assumptions here... |
| 14:46 | Chousuke | it's easy |
| 14:46 | chouser | well, manual tail self-call optimization |
| 14:46 | Chousuke | ,(fn foo [] (foo)) |
| 14:46 | clojurebot | #<sandbox$eval__3597$foo__3599 sandbox$eval__3597$foo__3599@8c3770> |
| 14:47 | Chousuke | ,((fn foo [] (foo))) |
| 14:47 | clojurebot | java.lang.StackOverflowError |
| 14:47 | Chousuke | ,((fn foo [] (recur))) |
| 14:47 | ordnungswidrig | chouser: that makes me wonder why the compiler does not offer an option for it. |
| 14:47 | clojurebot | Execution Timed Out |
| 14:47 | ordnungswidrig | Chousuke: for automatic tail self-call optimization. Or is it a runtime exception that'll occur? |
| 14:47 | ordnungswidrig | s/Chousuke/chouser/ |
| 14:47 | rhickey | cemerick: no perf penalty on default IPersistentMap impl |
| 14:48 | cemerick | rhickey: OK, good to know. |
| 14:48 | ordnungswidrig | is flip in contrib? |
| 14:48 | chouser | ordnungswidrig: the compiler could replace some self-calls with 'recur' automatically, but recur does not act the same as a self call (different stack impact) so it'd be up to the programmer to correctly understand the meaning the compiler would assign in each case. |
| 14:49 | ordnungswidrig | chouser: that's why clojure does no optimization? The provide clear semantics, right? |
| 14:49 | cemerick | rhickey: is this 'default implementation' injection something that will be opened up eventually. Magic markers like the IPM interface are handy, but...magical. :-) |
| 14:49 | chouser | ordnungswidrig: rhickey has correctly determined this is undesirable. :-) 'recur' is clear, specific, and what it can and can't do is easy to understand. |
| 14:50 | rhickey | cemerick: how that will work is still TBD |
| 14:50 | rhickey | cemerick: would you rather defstruct2 that had map impl? |
| 14:52 | rhickey | we also had chouser's keywords-as-triggers (def Foo [a b c] [:map IThis IThat] ...) |
| 14:52 | cemerick | rhickey: I would think that deftype + default IPM impl would simply replace defstruct *shrug* |
| 14:52 | chouser | cemerick: excellent blog post. |
| 14:53 | cemerick | chouser: ah, thanks. I'm glad I didn't get anything obviously wrong. |
| 14:53 | cemerick | I tripped over the lazy-seq binding capture issue on Monday, after a solid 3 hrs of debugging, so I figured I'd really boil the fundamentals into my head through writing. |
| 14:54 | Chousuke | rhickey: I suppose keywords would at least be more portable if the interface names ever change, like in port to a new platform or if they get refined or something |
| 14:54 | Chousuke | +a |
| 14:54 | chouser | it's interesting (to me anyway) to trace the potential problems to any combination of closure and dynamic binding |
| 14:55 | cemerick | rhickey: well, I don't really see :map there as anything like IThis or IThat. The latter just adds an interface, the former actually injects implementations. The two are totally separate beasts in my head. |
| 14:55 | rhickey | cemerick: presuming deftype won't have IPM as default (it won't, because making your types map when they are not otherwise collections is a big deal that will eventually bite you once you have more protocols in play), something that *did* have it by default might qualify for another name. I'd love to replace defstruct with defstruct on deftype but it has a few capabilities that don't work well |
| 14:56 | rhickey | one problem is that anything like that will need 2 version (type and class) |
| 14:56 | cemerick | I think it's worth thinking about whether lazy-seq and friends should automatically capture the bindings of the current thread-local. I'm sure that's something that's been mulled over; I'm not sure I have an opinion at the moment. |
| 14:56 | cemerick | rhickey: well, there's always the option of simply eliminating defstruct. |
| 14:57 | chouser | lazy-seqs and high-order functions all use closures, and we think of closures in terms of their lexical scope, but once they're getting passed around their dynamic scope can be who-knows-what (other thread, outside the (binding ...), on a different terracotta server, etc.) |
| 14:57 | rhickey | cemerick: you will run interference on that? :) |
| 14:57 | cemerick | I suppose some people like the error-on-dissoc |
| 14:58 | cemerick | rhickey: are people really that attached to it, and its slowness and inflexibility? ;-) |
| 14:58 | djork | I actually like recur over optimizing for tail calls, as it is more explicit and I think it makes for better reading. |
| 14:58 | rhickey | cemerick: I'm sure they will switch to deftype, but forcing them to is another story |
| 14:59 | cemerick | FWIW, if the magic behind IPM injection were more generalized, then we could have an IPersistentStruct (or whatever) that injected an impl that errors on dissoc'ing a core slot. |
| 14:59 | rhickey | cemerick: but people have been using defstruct without any type tags other than convention - once they have them they'll think twice about being IPM |
| 14:59 | chouser | djork: yes, me too |
| 14:59 | Kjellski | Hiho =) |
| 14:59 | Chousuke | cemerick: but what if your lazy-seq-function does something like (defn make-lazy-seq [...] (let [foo (do-something-with *var*)] (when blah (lazy-seq (cons (operate-on foo) (make-lazy-seq ...)))? |
| 14:59 | djork | I'm just trying to understand the source of cond |
| 14:59 | djork | the code |
| 14:59 | technomancy | I've started seeing errors like "java.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found"; I may have screwed my build up (using git master). any idea what kind of problem would cause an exception like that? |
| 14:59 | Chousuke | cemerick: if the var access were inside lazy-seq, something could be done, but... |
| 14:59 | djork | I should be macroexpand'ing it |
| 15:00 | rhickey | cemerick: yes, certainly, and many other auto-implementors , just haven't generalized it yet |
| 15:00 | cemerick | technomancy: you have to rebuild any sources built with older clojure versions...any classfiles are sorta hosed with HEAD. |
| 15:00 | Raynes | technomancy: That's the exact error I receive in Slime when I use the experimental Clojure branch. |
| 15:00 | technomancy | cemerick: ah... actually the stack trace looks like it's coming from loading contrib; didn't think to double-check that. |
| 15:00 | technomancy | thanks. |
| 15:00 | cemerick | Chousuke: Yeah, I have no suggestions about how to actually go about it. |
| 15:01 | technomancy | Raynes: you mean the maven branch of swank-clojure? |
| 15:01 | Raynes | technomancy: Not sure. The swank-clojure that was installed by clojure-install about a week ago. |
| 15:01 | cemerick | rhickey: I think my only point is that, if there were such a generalization, then people could compose whatever set of impls and therefore semantics on top of deftype without having all these siloed def-* sitting around. |
| 15:02 | rhickey | cemerick: I'm not diasgreeing |
| 15:02 | rhickey | have you got a generalized mechanism? |
| 15:02 | cemerick | rhickey: I know, just clarifying my position, if only to myself. :-) |
| 15:02 | technomancy | Raynes: should work better on the maven branch; if you still run into problems could you report them on http://groups.google.com/group/swank-clojure ? |
| 15:02 | Raynes | Sure thing. I'll note that. I have to leave right now, but I'll try that out later. |
| 15:02 | rhickey | cemerick: it's really quite complex, as any set of such auto-impls won;t necessarily compose |
| 15:03 | rhickey | and the presumptions made might also conflict |
| 15:03 | Chousuke | cemerick: though I think there is a ticket on assembla about providing a function wrapper that captures the dynamic environment and re-establishes it when the function gets called |
| 15:03 | rhickey | cemerick: so overall, I don't think injection should be emphasized |
| 15:04 | cemerick | rhickey: Yeah, I know. I presume we wade straight into the maw of trait-like issues. My talk about having a generalized mechanism is pretty much hand-waving, hoping you'll pull another rabbit out of your hat. |
| 15:04 | drewr | what's the safest way to do (read-string ":foo")? |
| 15:04 | rhickey | and tempted by chouser's suggestion to leave it out |
| 15:04 | djork | drewr: what's wrong with the way you're doing it |
| 15:04 | Chousuke | drewr: bind *read-eval* to false first. |
| 15:05 | cemerick | Chousuke: yeah, I saw that some time ago, but didn't really grok what was going on there at the time |
| 15:05 | rhickey | cemerick: for now, I'm standing pat until protocols are inplace |
| 15:05 | cemerick | Sounds good to me. I'm in a happy place. :-) |
| 15:06 | drewr | Chousuke: ah, I didn't see that arbitrary sexps had to be in #=() |
| 15:06 | drewr | wait no, that's not correct |
| 15:06 | drewr | they're just not evaled after reading |
| 15:06 | patrkris | is using release-pending-sends bad practice? |
| 15:07 | Chousuke | drewr: nothing is evaled by default when reading, except if you use the #= reader macro. |
| 15:07 | Chousuke | drewr: but setting *read-eval* to false disables that. |
| 15:08 | ordnungswidrig | still didn't find a "flip" |
| 15:08 | drewr | ,(binding [*read-eval* false] (read-string "(+ 1 1)")) |
| 15:08 | Chousuke | flip? as in, a function to reverse argument order? |
| 15:08 | clojurebot | (+ 1 1) |
| 15:08 | drewr | ,(binding [*read-eval* true] (read-string "(+ 1 1)")) |
| 15:08 | clojurebot | (+ 1 1) |
| 15:09 | Chousuke | drewr: there's no difference in that case. |
| 15:09 | drewr | ,(binding [*read-eval* true] (read-string "#=(+ 1 1)")) |
| 15:09 | clojurebot | 2 |
| 15:09 | drewr | that's what I meant :-) |
| 15:09 | ordnungswidrig | Chousuke: yes ((flip f) a b) is (f b a) |
| 15:09 | Chousuke | ordnungswidrig: there's flip in contrib I think |
| 15:10 | Chousuke | ,`flip |
| 15:10 | clojurebot | sandbox/flip |
| 15:10 | Chousuke | (doc flip) |
| 15:10 | clojurebot | It's greek to me. |
| 15:10 | Chousuke | hm, apparently not. |
| 15:10 | Kjellski | What is the best way to sum the values of a map? |
| 15:10 | ordnungswidrig | flip is from hiredman's odds-and-ends as it seems |
| 15:10 | ordnungswidrig | http://github.com/hiredman/odds-and-ends/blob/8a84e6ddbad9d71f714ba16c3e1239633228a7eb/functional.clj |
| 15:11 | hiredman | klafter (comp (partial reduce +) values) |
| 15:11 | chouser | #(f %2 %1) |
| 15:12 | hiredman | flip works for than two args |
| 15:12 | chouser | does it reverse them? |
| 15:12 | ordnungswidrig | hiredman: I need it just for two |
| 15:12 | chouser | or put the last one first? |
| 15:12 | chouser | or the first one last? |
| 15:12 | hiredman | chouser: it reverse the order of all the args |
| 15:12 | ordnungswidrig | or swap to last and the first |
| 15:12 | ordnungswidrig | what would haskell do? |
| 15:13 | hiredman | (fn [fn] (fn [& args] (apply fn (reverse args)))) |
| 15:13 | hiredman | er |
| 15:13 | hiredman | (fn [fn-] (fn [& args] (apply fn- (reverse args)))) |
| 15:13 | hiredman | the pointfree lib on github has a fn that just flips the first two args |
| 15:13 | Chousuke | Kjellski: (apply + (vals themap)) :P |
| 15:14 | hiredman | right |
| 15:14 | hiredman | vals not values |
| 15:14 | Chousuke | you take that pointfree thing too far sometimes. |
| 15:14 | hiredman | ,((comp (partial reduce +) vals) {:a 1 :b 2}) |
| 15:14 | clojurebot | 3 |
| 15:14 | Kjellski | Chousuke : once again... sometimes it just hurts how easy things are... but, rewireing is on the go... thanks! |
| 15:15 | ordnungswidrig | hiredman: what is then the "official" source for a decent flip? Your functional.clj? |
| 15:15 | hiredman | ordnungswidrig: I dunno that there is one, if you need one you might ask rhickey about adding one to core, when I asked he said he had never needed one, and I realized I never used it outside of golfing |
| 15:16 | ordnungswidrig | hmm |
| 15:17 | ordnungswidrig | hiredman: I have a function that takes to args and I want to partial it but I need to fix the second arg so (partial (flip f) a) would be a perfect fit. I realize that (fn [b] (f a b)) would work also. |
| 15:18 | ordnungswidrig | hiredman: so you and rhickey might be right |
| 15:18 | hiredman | well no, I still want flip, I just am unable to argue with rhickey about it :P |
| 15:19 | Kjellski | djork: Do you remember the bacteria thing? Maybe there is a much smarter way, but finally I´ve got it... |
| 15:19 | ordnungswidrig | hiredman: but then partial could be dropped too. Dear develier: "usage of partial is considered golfing" |
| 15:19 | djork | oh boy :) |
| 15:19 | ordnungswidrig | s/develier/developer/ |
| 15:19 | djork | Kjellski: still having fun with Clojure though? |
| 15:19 | djork | I have been doing Project Euler |
| 15:19 | djork | a few problems here and there |
| 15:19 | djork | will be firing up LWJGL soon |
| 15:19 | djork | real work gets in the way too often |
| 15:19 | Kjellski | djork : for sure... I´ll use that as my general purpose in the master studies... |
| 15:21 | djork | coolness |
| 15:21 | rhickey | ordnungswidrig: Haskell would balk at variable arity |
| 15:22 | Kjellski | djork: what is LWJGL ? And btw: http://pastebin.com/m351fa2d ... |
| 15:22 | Kjellski | djork : If you´ve got time to review my code and tell me it´s just shit... ^^ |
| 15:22 | djork | Lightweight Java Game Library |
| 15:23 | Kjellski | djork : something in the direction of PyGame? |
| 15:24 | ordnungswidrig | mixing destructurizing binding forms and simple ones in a single let can be confusing. lots brackets and unusual indenting |
| 15:26 | djork | Kjellski: it's lower level than that |
| 15:27 | djork | but yeah kind of |
| 15:27 | djork | in fact, I think it could be a great way to do multimedia apps |
| 15:27 | djork | games of course |
| 15:27 | Kjellski | djork : okay, I would try it for fun if it´s showable... |
| 15:28 | djork | it's someone else's project |
| 15:28 | djork | but a clojure wrapper might be in the pipeline from me |
| 15:30 | Kjellski | I´ve asked some time ago I think, but is someone arround that has a lazy-seq implementation of PI digits? |
| 15:31 | Chousuke | hm. |
| 15:32 | Chousuke | The idea of a very lazy seq just popped into my mind for some reason. |
| 15:33 | Chousuke | basically, it's so lazy that the computer refuses to do any works and the programmer has to add the items. |
| 15:33 | ordnungswidrig | why does slime-edit-definition doesn't work. Is it a known limitation of swank-clojure= |
| 15:33 | Chousuke | work* |
| 15:33 | ordnungswidrig | s/=/?/ |
| 15:34 | djork | Kjellski: destructuring will help your code a bit |
| 15:34 | djork | for instance, if you have a population count vector with the population by age in each slot of the vector... |
| 15:34 | djork | (defn day [[day-1 day-2 day-3 day-4]] [(+ day-1 day-2) day-1 day-2 day-3]) |
| 15:34 | djork | that replaces your live-day |
| 15:34 | djork | except it takes a vector |
| 15:35 | Chousuke | (defn day [{:keys day-1 day-2 day-3 day-4}] ...) |
| 15:35 | Chousuke | map destructuring! |
| 15:36 | Kjellski | Chousuke : huh? What would that produce? a vec with a map that contains only keys? |
| 15:37 | Chousuke | no, it's the argument list of the function. :) |
| 15:37 | chouser | (import 'java.util.concurrent.TimeUnit) |
| 15:37 | chouser | ,(import 'java.util.concurrent.TimeUnit) |
| 15:37 | clojurebot | java.util.concurrent.TimeUnit |
| 15:37 | twbray | Have a program that sends off a bunch of I/O intensive functions with send-off, they grind away and something reports a NPE with the helpful label (NO_SOURCE_FILE:0). What are some digging tools to find out what's blowing up? |
| 15:37 | chouser | ,(let [deref-timeout (fn [p t u & [f]] (if (.await (.d ((proxy-mappings p) "invoke")) t u) @p f))] (deref-timeout (promise) 2 TimeUnit/SECONDS :not-delivered)) |
| 15:37 | Chousuke | it takes a single map with the keys :day-1, :day-2 etc. and destructures them into the variables day-1, day-2 ... |
| 15:37 | clojurebot | :not-delivered |
| 15:37 | Kjellski | djork : Thanks a lot, that never came in my mind... |
| 15:38 | djork | this is quite a quick solution compared to building the actual populations :) |
| 15:39 | chouser | cemerick: I believe you've asked for that. |
| 15:39 | Kjellski | djork : It´s not that I don´t have a solution for that, but this will blow your heap, until it´s pretty memory intense to build up a vec that contains 1,000,000,000,000 items... |
| 15:40 | Kjellski | Chousuke : thanks for the explanation, I´ll try that version too. |
| 15:40 | cemerick | chouser: ah, the agent error handling stuff? |
| 15:40 | chouser | cemerick: no sorry, the deref-timeout. That one only works on 'promise' before the 'new' branch. |
| 15:40 | cemerick | oh, oh, right |
| 15:41 | chouser | probably 'await-promise' would be a better name |
| 15:41 | djork | ,((fn [[first second]] (println first) (println second)) ["foo" "bar"]) |
| 15:41 | clojurebot | foo bar |
| 15:41 | chouser | and of course nobody should use it because it depends on several internal details of promise. :-P |
| 15:41 | Chousuke | you could possibly build a lazy seq of the days. (defn foo [prev-day today] (lazy-seq (cons today (foo today (+ today prev-day))) |
| 15:42 | cemerick | chouser: timeouts aren't really a concern for me. My pet request would be an available? predicate for delays. |
| 15:42 | chouser | timeout of zero |
| 15:42 | chouser | hm, I think. I should check. |
| 15:42 | Chousuke | ,(letfn [(foo [prev-day today] (lazy-seq (cons today (foo today (+ prev-day today)))))] (take 5 (foo 0 1))) |
| 15:42 | clojurebot | (1 1 2 3 5) |
| 15:43 | cemerick | Super-easy to add, of course, just haven't gotten around to it. |
| 15:43 | Chousuke | ,(letfn [(foo [prev-day today] (lazy-seq (cons today (foo today (+ prev-day today)))))] (take 2 (partition 5 1 (foo 0 1)))) |
| 15:43 | clojurebot | ((1 1 2 3 5) (1 2 3 5 8)) |
| 15:43 | cemerick | chouser: the issue is, in certain cases, I don't want the delay to be realized at all. |
| 15:44 | Kjellski | Chousuke : *reading*, *thinking* |
| 15:44 | chouser | ohhh. yeah, that's different. |
| 15:44 | hiredman | if you deref the delay in a future you can check to see if the future is done, I believe |
| 15:45 | hiredman | http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html#isDone%28%29 |
| 15:45 | Chousuke | there was also a cleverer way to form the fibonacci sequence... |
| 15:46 | hiredman | a haskell way, if I recall |
| 15:49 | Chousuke | (let [fibos (concat [0 1] (map + fibos (drop 1 fibos))] (take 5 fibos)); something like this? |
| 15:49 | Chousuke | ,(let [fibos (concat [0 1] (map + fibos (drop 1 fibos))] (take 5 fibos));let's see :P |
| 15:49 | clojurebot | Unmatched delimiter: ] |
| 15:49 | Chousuke | gah. |
| 15:49 | Chousuke | ,(let [fibos (concat [0 1] (map + fibos (drop 1 fibos)))] (take 5 fibos)) |
| 15:49 | clojurebot | java.lang.Exception: Unable to resolve symbol: fibos in this context |
| 15:49 | Chousuke | meh. |
| 15:49 | hiredman | fibs = 0 : 1 : zipWith (+) fibs (tail fibs) |
| 15:52 | djork | hmm |
| 15:54 | chouser | ,(let [fibos (atom nil)] (reset! fibos (lazy-cat [0 1] (map + @fibos (rest @fibos)))) (take 10 @fibos)) |
| 15:54 | clojurebot | (0 1 1 2 3 5 8 13 21 34) |
| 15:55 | chouser | That's Chousuke's solution, poorly rendered to be clojurebot-compatible. |
| 15:55 | Chousuke | heh. |
| 15:55 | djork | ouch |
| 15:55 | Chousuke | lazy-cat still amuses me. |
| 15:56 | djork | lazy-cat is lazy |
| 15:56 | Chousuke | I can't help but think of felines. |
| 16:09 | djork | http://media.bigoo.ws/content/image/funny/funny_259.jpg |
| 16:10 | djork | as an easter-egg in the graphical version of a repl, lazy-cat should be replaced with a tiny version of that image |
| 16:15 | annealer | if somebody would help me, that would be fabulous. im trying to programatically call a macro. the name is in a string, like "GET". i would like to somehow call that macro. i cant figure it out. eval complains it cant find it in the current namespace |
| 16:16 | hiredman | :( |
| 16:16 | hiredman | why would you programatically call a macro? |
| 16:17 | annealer | that's a good question |
| 16:17 | annealer | so |
| 16:17 | djork | because you can't pass the value of a macro, I presume |
| 16:17 | annealer | the web framework compojure defines some handy macros |
| 16:17 | annealer | like GET, POST, PUT, DELETE |
| 16:17 | chouser | (defmacro foo [] "foo") (eval (read-string "(foo)")) ...works for me. |
| 16:17 | hiredman | annealer: I'm pretty sure it defines them as macros for a reason |
| 16:17 | annealer | i am new to clojure, so i'm more than happy to be convinced this is the Wrong Thing |
| 16:17 | chouser | oh. |
| 16:17 | chouser | This is the Wrong Thing. |
| 16:18 | chouser | :-) |
| 16:18 | hiredman | macros happen before runtime, and "programatically" calling stuff is certainlly a runtime thing |
| 16:18 | annealer | so this is bad mojo and i should not be doing it, essentially? |
| 16:18 | hiredman | so calling macro's programatically is a red flag |
| 16:18 | chouser | annealer: well, tell us what you're trying to do |
| 16:18 | arohner | annealer: you want to programmatically generate several routes? |
| 16:18 | annealer | arohner: precisely |
| 16:18 | annealer | i know i can do it with 'compile-route' |
| 16:18 | annealer | i was just wondering if using the macros was wrong or right |
| 16:18 | chouser | ah... you want to write a macro yourself then. |
| 16:18 | arohner | you can also specify your own regex |
| 16:19 | chouser | 'eval' is definitely not right in this case. |
| 16:19 | arohner | just (GET #"/") |
| 16:19 | annealer | arohner: im doing rails-style resource routing, essentially. so i wanted a call to "resources" to actually use those macros. so i guess i should make a resources macro? |
| 16:20 | annealer | or just use the compile-route function the macro uses under the scenes? |
| 16:20 | chouser | both those options sound more sensible than using 'eval' |
| 16:20 | annealer | (p.s. thanks for being the most helpful programming language irc channel i've stumbled into for a while) |
| 16:20 | annealer | aces |
| 16:20 | Licenser | hmm can someone help me what this: Exception in thread "main" java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.PersistentStructMap$Def means? |
| 16:20 | annealer | i'll go the non-hilariously-bad route then |
| 16:20 | chouser | annealer: :-) |
| 16:21 | Licenser | ah found it |
| 16:21 | arohner | in one case, I generated the regex |
| 16:21 | arohner | i.e. |
| 16:21 | arohner | (GET (my-regex-returning-fn) ...) |
| 16:22 | arohner | (defn my-regex-returning-fn [] (regex (str-join "|" "js" "swf" "css"))) |
| 16:22 | arohner | err (str-join "|" ["js "swf" "css"])) |
| 16:26 | arohner | I can paste the whole thing if you're interested |
| 16:27 | chouser | arohner: is that not working because GET doesn't evaluate the route form? |
| 16:27 | arohner | that was pseudo-code |
| 16:27 | arohner | my production one works |
| 16:33 | ordnungswidrig | how did the idion go to check for list containment using some? |
| 16:34 | arohner | ,(doc some) |
| 16:34 | clojurebot | "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)" |
| 16:34 | ordnungswidrig | thanks |
| 16:35 | chouser | ,(some #{:a} [:a :b]) |
| 16:35 | clojurebot | :a |
| 16:35 | djork | huh |
| 16:37 | lpetit | ,(some #{nil} [:a :b]) |
| 16:37 | clojurebot | nil |
| 16:37 | lpetit | ,(some #{nil} [nil :a]) |
| 16:37 | clojurebot | nil |
| 16:39 | chouser | ,(some nil? [nil :a]) |
| 16:39 | clojurebot | true |
| 16:39 | chouser | ,(some nil? [:a :b]) |
| 16:39 | clojurebot | nil |
| 16:40 | lpetit | ,(some #{false} [true true]) |
| 16:40 | clojurebot | nil |
| 16:40 | lpetit | ,(some #{false} [true false]) |
| 16:40 | clojurebot | nil |
| 16:41 | lpetit | one better has to know what is placed in the set |
| 16:41 | djork | wow seriously... NetBeans mpkg failed to install in OS X? |
| 16:41 | chouser | yes, collections that may contain false or nil have to be treated somewhat more carefully |
| 16:43 | djork | huh, I had to quit my repl |
| 16:43 | chouser | cddr`: reader shortcut for (meta ...) |
| 16:43 | cddr` | chouser: thanks |
| 16:44 | chouser | ,' ^foo |
| 16:44 | clojurebot | (clojure.core/meta foo) |
| 17:01 | patrkris | what is the easiest way to get a random element from a vector? |
| 17:01 | Kjellski | ,(apply str (partition 1 3 "123456789")) |
| 17:01 | clojurebot | "clojure.lang.LazySeq@50clojure.lang.LazySeq@53clojure.lang.LazySeq@56" |
| 17:01 | Kjellski | Sorry... |
| 17:02 | hiredman | ,(apply pr-str (partition 1 3 "123456789")) |
| 17:02 | clojurebot | "(\\1) (\\4) (\\7)" |
| 17:02 | hiredman | ,(apply str (map pr-str (partition 1 3 "123456789"))) |
| 17:02 | clojurebot | "(\\1)(\\4)(\\7)" |
| 17:02 | chouser | ,(clojure.contrib.seq-utils/rand-elt '(a b c d e)) |
| 17:02 | clojurebot | e |
| 17:03 | hiredman | (doc rend-elt) |
| 17:03 | clojurebot | Huh? |
| 17:03 | chouser | ,(clojure.contrib.seq-utils/rand-elt '(a b c d e)) |
| 17:03 | clojurebot | e |
| 17:03 | chouser | ,(clojure.contrib.seq-utils/rand-elt '(a b c d e)) |
| 17:03 | hiredman | (doc rand-elt) |
| 17:03 | clojurebot | c |
| 17:03 | clojurebot | "clojure.contrib.seq-utils/rand-elt;[[s]]; Return a random element of this seq" |
| 17:03 | hiredman | element |
| 17:03 | chouser | seq |
| 17:03 | hiredman | elt => element |
| 17:03 | chouser | ,(clojure.contrib.seq-utils/rand-elt {1 2 3 4 5 6}) |
| 17:03 | clojurebot | java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap |
| 17:03 | patrkris | t |
| 17:03 | patrkris | thanks |
| 17:04 | Kjellski | hiredman : how can I put the numbers itself into a str? |
| 17:04 | Kjellski | hiredman : without all the other stuff? |
| 17:05 | hiredman | ,(map first (partition 1 3 "123456789")) |
| 17:05 | clojurebot | (\1 \4 \7) |
| 17:05 | hiredman | ,(apply str (map first (partition 1 3 "123456789"))) |
| 17:05 | clojurebot | "147" |
| 17:05 | Kjellski | hiredman : ty |
| 17:05 | hiredman | I dunno if I would use partition for that |
| 17:05 | hiredman | but, I guess |
| 17:06 | chouser | ,(apply str (take-nth 3 "123456789")) |
| 17:06 | clojurebot | "147" |
| 17:09 | Kjellski | chouser : is that more efficient? or just sugar? |
| 17:10 | hiredman | should be more efficient |
| 17:11 | hiredman | partion cuts the seq up into a seq of seqs, and then you have to map first over each seq |
| 17:12 | chouser | less code and less processing -- what's not to like? :-) |
| 17:13 | Kjellski | hiredman: perfect. So I´ll use that... is there a oneliner to "spit" a string into a file? |
| 17:13 | chouser | when we have fully hyperlinked api docs, there should definitely be cross references between take-nth and partition. |
| 17:13 | Kjellski | I mean with no "extra-using" or so? |
| 17:14 | Kjellski | chouser : /signed |
| 17:14 | hiredman | ,(doc spit) |
| 17:14 | clojurebot | "clojure.contrib.duck-streams/spit;[[f content]]; Opposite of slurp. Opens f with writer, writes content, then closes f." |
| 17:15 | Kjellski | hiredman : I´m sometimes just banging my head against my table. But maybe, sometime in some future, my questions will take another stage... |
| 17:17 | hiredman | it will take a use of duck-streams to use spit |
| 17:17 | hiredman | ,(with-open [f (-> filename File. FileWriter.)] (.write f some-string)) |
| 17:17 | clojurebot | java.lang.IllegalArgumentException: Unable to resolve classname: FileWriter |
| 17:19 | djork | Kjellski: what are you trying to do there? |
| 17:20 | djork | (with the partition and string) |
| 17:20 | Kjellski | taking every 20000th digit of the 1500000th fib number... |
| 17:20 | Kjellski | @ djork |
| 17:20 | djork | hah wow |
| 17:21 | hiredman | yeah, you want take-nth |
| 17:21 | djork | is that a Project Euler problem? |
| 17:21 | Kjellski | djork : nope, hacker.org ... for me that´s more fun because it´s not _only_ math... |
| 17:21 | djork | yeah, interesting |
| 17:22 | Kjellski | djork : trying be learn more in practical usage... ^^ and this problem was solved much more fast than the bac thing... |
| 17:23 | Kjellski | djork : 1161269686625383 is the answer... |
| 17:23 | djork | heh don't give it away :) |
| 17:24 | Kjellski | djork: huh, sorry... just for prooving correct answers... if you don´t want to play the whole puzzles to that challenge... |
| 17:24 | Kjellski | djork : on hacker.org not all challenges are accessible... |
| 17:25 | djork | ah |
| 17:26 | djork | http://sixrevisions.com/resources/10-puzzle-websites-to-sharpen-your-programming-skills/ |
| 17:31 | Kjellski | Nice page, so far pretty good if someday my challenges are beaten on hacker.org... =) |
| 17:33 | ordnungswidrig | pushed my first project to github. ok, more the beginnings of a project :-) Please have a look at compojure-rest. I'd welcome feedback. |
| 17:34 | Kjellski | djork: Uhh... now, bigger fib says: take the log of the 150,000,000th fib number and round to two digits... |
| 17:34 | Kjellski | ordnungswidrig : link? |
| 17:35 | ordnungswidrig | http://github.com/ordnungswidrig/compojure-rest |
| 17:36 | Kjellski | thanks |
| 17:37 | ordnungswidrig | Kjellski: that fib challenge sounds tough |
| 17:39 | Kjellski | ordnungswidrig: I don´t think so at all... doesn´t that calculation go linear? So just more computation before going to log that? |
| 17:41 | djork | assuming you can take the log of a number that big in clojure |
| 17:41 | Kjellski | Uh, got me? |
| 17:41 | Kjellski | *grin* |
| 17:42 | ordnungswidrig | nope. |
| 17:42 | djork | ,(Math/log (read-string "1293871924879182379182739817294879871948723948719283759814739487239487918274987912734")) |
| 17:42 | clojurebot | 193.67478702654344 |
| 17:43 | ordnungswidrig | but the 150.000.000th fib will be a little longer ;-) |
| 17:43 | ordnungswidrig | I don't see how to chop the log on this one. |
| 17:44 | Kjellski | djork : actually the other one was 20000 times the number of digits I posted as the answer... ^^ |
| 17:44 | djork | oh awesome :) |
| 17:44 | ordnungswidrig | Kjellski: you actually feed the whole number to clojure? |
| 17:44 | Kjellski | ordnungswidrig : nope, I´m cheating here, using the great lazy-seq-fibo from stuarts book ... |
| 17:45 | Kjellski | ordnungswidrig : but just feeding it feels a lot more "cheating" for me... |
| 17:45 | ordnungswidrig | Kjellski: which creates a lazy seq of ? |
| 17:45 | Kjellski | ordnungswidrig : the fibonaccy sequence...? |
| 17:46 | djork | hmm this is kind of cool |
| 17:46 | ordnungswidrig | Kjellski: but so you actually calculated the 150.000.000th fib?! |
| 17:46 | djork | ,(BigInteger/probablePrime 128) |
| 17:46 | clojurebot | java.lang.IllegalArgumentException: No matching method: probablePrime |
| 17:46 | djork | huh |
| 17:46 | djork | oh |
| 17:47 | djork | ,(BigInteger/probablePrime 128 (Random.)) |
| 17:47 | clojurebot | java.lang.IllegalArgumentException: Unable to resolve classname: Random |
| 17:47 | djork | oh |
| 17:47 | Kjellski | ordnungswidrig : nope, I did that for the 1500,000th one... |
| 17:48 | djork | ,(BigInteger/probablePrime 128 (java.util.Random.)) |
| 17:48 | clojurebot | 283136236335513942374424665513338827589 |
| 17:48 | ordnungswidrig | Kjellski: that sounds more reasonable |
| 17:48 | djork | ,(BigInteger/probablePrime 128 (java.util.Random.)) |
| 17:48 | clojurebot | 247135970708632709525958798945080490857 |
| 17:48 | djork | verry interesting |
| 17:49 | Kjellski | djork : what is that doing there? |
| 17:49 | ordnungswidrig | Kjellski: there is a non-recursive expresion for the fibs one could use. |
| 17:49 | djork | ,(.nextProbablePrime (bigint 1234)) |
| 17:49 | clojurebot | 1237 |
| 17:49 | djork | ,(.nextProbablePrime (bigint 1237)) |
| 17:49 | clojurebot | 1249 |
| 17:50 | djork | hmm, interesting implications there |
| 17:50 | djork | saves me a lot of work :) |
| 17:50 | Kjellski | djork : what does that "probable" mean for real? |
| 17:50 | djork | dunno |
| 17:50 | chouser | "not divisible by 2" |
| 17:50 | Kjellski | *laughing* |
| 17:50 | djork | "The probability that the number returned by this method is composite does not exceed 2-100." |
| 17:50 | djork | 2^-100 |
| 17:51 | djork | so pretty probable |
| 17:51 | djork | not sure what method they are using |
| 17:51 | djork | but it would probably speed up creating lists of primes |
| 17:51 | djork | now who said the Java class library sucks :) |
| 17:51 | Kjellski | This is going to be a quote chouser ... can´t get over it... |
| 17:54 | Kjellski | chouser: http://bash.org/?907358 needs to be moderated... |
| 17:55 | chouser | wow. bash.org |
| 17:55 | ordnungswidrig | djork: gnu classpath uses rabin-miller |
| 17:59 | Kjellski | So, good night then... cya |
| 18:03 | ordnungswidrig | good night be me, too. |
| 18:14 | esj | guys, if I have sequence, and I want to 'modify' the last element, is it efficient/idiomatic to go: (conj (drop-last seq) new-element), or is there a better way ? |
| 18:16 | hiredman | :( |
| 18:17 | hiredman | thats not something a seq will be good at |
| 18:18 | esj | yeah, that's kinda why I brought it up |
| 18:20 | esj | I'm trying to do a cumulative sum of a sequence, with the twist that I want each the summed sequence to add up to a threshold, and then roll to the next element. IE, if my threshold is 10, I want the elements of the returned sequence to be the cumulative sum since the last element, until that reaches 10, then I want a new element. |
| 18:20 | esj | Ugh, that sounds ugly. |
| 18:21 | esj | its like, I'm packing boxes, and the first sequence contains elements with mass, and the second sequence is boxes, packed with those elements, such that no box weighs more than some threshold |
| 18:22 | esj | but growing the 'box' sequence from the first sequence is proving painful. |
| 18:42 | _ato | esj: should the numbers be less than n or the first value that is over 10? |
| 18:50 | _ato | actually.. I guess it won't work if the output should be less than 10 and theres an input greater than 10 |
| 18:50 | _ato | so lets assume the other way |
| 18:52 | esj | yeah, lets assume that for now |
| 18:53 | esj | its not super critical in the application, i'm more concerned about how I build this sequence sensibly |
| 18:54 | esj | at the moment I'm reducing along the first sequence, and either amending the last element of the 2nd sequence, or conjing to it, based on the total weight of the bax |
| 18:54 | esj | s/bax/box/ |
| 18:58 | _ato | http://gist.github.com/226530 |
| 18:58 | _ato | I just did it with recursion and lazy-seq, I couldn't think of a nice way to do it with higher-level functions |
| 18:59 | esj | *reading* |
| 19:01 | esj | yeah, I get it |
| 19:05 | esj | so, here's an equally daft question, but why, if it is efficient to add to the end |
| 19:05 | esj | of a vector (for arguments sake) is removing and the adding to it not ? |
| 19:06 | esj | or, is it because we're dealing with general sequences that we don't want to make such assumptions ? |
| 19:09 | Chousuke | some kind of a "partial reduce" could be useful. |
| 19:10 | _ato | err.. I don't get what you mean, it should be reasonably efficient, it's going to have to copy the whole last node though (clojure vectors are implemented as 32-way trees) |
| 19:10 | _ato | but you could get around that with transients |
| 19:11 | _ato | Chousuke: yeah, something like reduce-while, that performs a test and returns [reduced-value remaining-seq] when the test fails |
| 19:12 | bradford | when i eval exprs in a remore repl using contrib.server-socket, the text going to the output stream for the remore process can be valid exprs, or string repreentations fo java objects or exceptions. the latter can not be read with (read %). what is the best strategy for reading input from the strem from the remote repl? |
| 19:12 | esj | sadly everything I say is badly distorted by misunderstanding. What I mean is, my solution was to reduce the first sequence, and do the binding to the last element of the growing 'reduced' sequence with the (conj (drop-last seq) new), which was said to be bad ? Why so ? |
| 19:14 | Chousuke | drop-last of a sequence needs to walk the entire sequence. |
| 19:14 | Chousuke | so that it can find the end. |
| 19:14 | Chousuke | and drop it :P |
| 19:15 | _ato | so eg if your seq is really large, you might run out of memory |
| 19:15 | _ato | but with a vector it should be fine |
| 19:15 | Chousuke | a vector is not a sequence though. |
| 19:15 | Chousuke | (doc drop-last) |
| 19:15 | clojurebot | "([s] [n s]); Return a lazy sequence of all but the last n (default 1) items in coll" |
| 19:15 | Chousuke | ah, hm, it's lazy. never mind :) |
| 19:15 | _ato | ah true |
| 19:15 | _ato | hehe |
| 19:15 | Chousuke | butlast is the slow function. |
| 19:16 | Chousuke | (doc butlast) |
| 19:16 | clojurebot | "([coll]); Return a seq of all but the last item in coll, in linear time" |
| 19:17 | Chousuke | _ato: btw, instead of (if (nil? (seq s)) ...) I think it'd be more idiomatic to just use (if-not (seq s) ...) |
| 19:18 | _ato | Chousuke: ah yeah true |
| 19:18 | Chousuke | and (cons n nil) is probably better as (list n) |
| 19:18 | Chousuke | or just [n] |
| 19:19 | Chousuke | hmm |
| 19:19 | Chousuke | (cons 1 [2]) |
| 19:19 | Chousuke | ,(cons 1 [2]) |
| 19:19 | clojurebot | (1 2) |
| 19:19 | _ato | ,(next (cons 1 [2])) |
| 19:19 | clojurebot | (2) |
| 19:19 | esj | Chousuke: yikes, that makes in n! complex, nastiness :) |
| 19:20 | Chousuke | (doc cons) |
| 19:20 | clojurebot | "([x seq]); Returns a new seq where x is the first element and seq is the rest." |
| 19:20 | esj | so there is no way to kill the end of the sequence in O(1) ? |
| 19:20 | Chousuke | well, drop-last is lazy so you get the sequence in O(1) |
| 19:21 | Chousuke | but if you walk to the end it also needs to realise the n items you're dropping. |
| 19:21 | Chousuke | (otherwise it won't know the seq has ended) |
| 19:22 | esj | sorry, I misread you (its pretty late for me now) |
| 19:23 | Chousuke | but if you have a (drop-last 20000 some-source) where some-source has 40k items, and then only process the first 10000, it's going to realise only the first 30000 |
| 19:24 | Chousuke | though in that case just processing (take 10000 some-source) would be more efficient. |
| 19:24 | Chousuke | but I guess sometimes you might not know how much you need to process, but still want to make sure some stuff at the end is excluded... |
| 19:26 | _ato | esj: I think with the way you're using it, it should be fine. The main difference between your way and mine (if I'm understanding yours correctly) is mine is lazy and yours is eager. Either might be better depending on what you want to do with the result |
| 19:35 | esj | ok, here is what it looks like |
| 19:35 | esj | http://pastie.org/684209 |
| 19:36 | esj | i know i could avoid the '() by checking (empty? .) |
| 19:39 | _ato | I think the problem there is going to be (last product) |
| 19:40 | _ato | that's going to be O(length(product)) |
| 19:40 | Chousuke | esj: http://gist.github.com/226553 |
| 19:40 | esj | _ato: yeah, coz its going to have to walk the length of the growing sequence each time |
| 19:41 | Chousuke | that's probably not perfect though :P |
| 19:42 | esj | Chousuke: that's really nice ! |
| 19:42 | esj | I was led astray by insisting on using a reduce |
| 19:43 | _ato | Chousuke: neat idea |
| 19:43 | esj | much to learn... thanks for the help. |
| 19:44 | Chousuke | well, the condensator is basically reduce (it reduces to reduce!) if the predicate is always true |
| 19:44 | Chousuke | though it also needs to check if coll actually has any items left. |
| 19:46 | Chousuke | sleep for me. |
| 19:46 | Chousuke | good night. :) |
| 19:46 | esj | another good idea. good night ! |
| 20:21 | notallama | would parcomp be a better name for juxt? i noticed that the docstring says "name subject to change". |
| 21:36 | hiredman | http://gist.github.com/226651 |
| 21:36 | hiredman | gar |
| 21:36 | hiredman | http://gist.github.com/226651 <-- appegine + facebook app |
| 22:48 | djork | man, I feel like this is cheating |
| 22:48 | djork | (take 10 (fn [] (iterate #(.nextProbablePrime %) (bigint 3)))) |
| 22:48 | djork | ,(take 10 ((fn [] (iterate #(.nextProbablePrime %) (bigint 3))))) |
| 22:48 | clojurebot | (3 5 7 11 13 17 19 23 29 31) |
| 22:49 | djork | ,(nth ((fn [] (iterate #(.nextProbablePrime %) (bigint 1)))) 1000) |
| 22:49 | clojurebot | 7919 |
| 22:49 | hiredman | ~cheating |
| 22:49 | clojurebot | I don't understand. |
| 22:49 | hiredman | clojurebot: clojure? |
| 22:49 | clojurebot | clojure is the best way to learn java |
| 22:49 | hiredman | clojurebot: clojure? |
| 22:49 | clojurebot | clojure is not scheme |
| 22:49 | hiredman | :| |
| 22:49 | hiredman | clojurebot: clojure? |
| 22:49 | clojurebot | clojure is a language to use if you want to up your game |
| 22:50 | hiredman | clojurebot: clojure? |
| 22:50 | clojurebot | "[Clojure ...] feels like a general-purpose language beamed back from the near future." |
| 22:50 | hiredman | somewhere in there it says clojure is cheating |
| 22:50 | djork | hah |
| 22:51 | hiredman | clojurebot: clojure? |
| 22:51 | clojurebot | clojure > scheme |
| 22:51 | djork | clojure? |
| 22:51 | hiredman | clojurebot: clojure? |
| 22:51 | djork | oh |
| 22:51 | clojurebot | clojure is like life: you make trade-offs |
| 22:51 | djork | I trust you |
| 22:51 | hiredman | clojurebot: clojure? |
| 22:51 | clojurebot | clojure > scheme |
| 22:51 | hiredman | ok |
| 22:51 | hiredman | hmmm |
| 22:57 | solussd | is there an alternative to (get-in coll [...]) that returns nil instead of a null pointer exception if the index is out of range? |
| 22:58 | solussd | im mapping it to a bunch of indices |
| 23:00 | chouser | get-in doesn't throw NPE for me. |
| 23:03 | solussd | youre right- i'm derefing a nil returned by get-in |
| 23:03 | solussd | thanks |
| 23:04 | djork | what's the best way to get a Java null |
| 23:04 | solussd | is there a != in clojure? |
| 23:04 | chouser | nil is null |
| 23:04 | solussd | e.g. #(!= nill %) |
| 23:05 | notallama | not= |
| 23:05 | chouser | ,(not= nil 5) |
| 23:05 | clojurebot | true |
| 23:05 | chouser | ,(nil? nil) |
| 23:05 | clojurebot | true |
| 23:08 | chouser | ~deftype |
| 23:08 | clojurebot | deftype is see datatype |
| 23:09 | chouser | ~datatype |
| 23:09 | clojurebot | datatype is see datatypes |
| 23:09 | chouser | ~datatypes |
| 23:09 | clojurebot | http://www.assembla.com/wiki/show/clojure/Datatypes |
| 23:09 | chouser | clojurebot: thanks! have a botsnack |
| 23:09 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 23:09 | fatelang | ~.. |
| 23:10 | gilbertleung | hi |
| 23:11 | gilbertleung | i'm extending a class called "com.wowza.wms.module.ModuleBase" which has a protected static method called "getLogger" |
| 23:11 | chouser | gilbertleung: was it you that asked on the google group? |
| 23:12 | gilbertleung | yah |
| 23:12 | fatelang | Is it possible to .. inside a doto or otherwise call a method of a returned object? Something like (doto f (.. .method-of-f (method-of-returned-object args)) ...) |
| 23:13 | gilbertleung | to summarize, my question is: how can I call the parent's static method from a child instance? |
| 23:13 | chouser | gilbertleung: I'm not sure, but I think it may be impossible without writing some .java. |
| 23:13 | chouser | gilbertleung: did you try using gen-class's exposes-methods? |
| 23:14 | gilbertleung | chouser: nope, i didn't know there was such a thing |
| 23:14 | gilbertleung | chouser: lemme read up on in the docs |
| 23:14 | chouser | gilbertleung: well, it's worth a try, but I'm afraid it may only work on instance methods. |
| 23:15 | hiredman | chouser: he could use wallhack! |
| 23:15 | gilbertleung | hiredman: what's that? |
| 23:15 | chouser | gilbertleung: listen to hiredman |
| 23:16 | chouser | it's ugly but you've got to do what you've got to do. |
| 23:16 | hiredman | gilbertleung: lemme find some code |
| 23:16 | gilbertleung | hiredman: aite |
| 23:16 | chouser | fatelang: did you try that? seems like it might work. |
| 23:17 | hiredman | http://gist.github.com/226726 wallhack-method |
| 23:18 | hiredman | (wallhack-method some.class.Name :someMethod [Types Method Takes] nil arg1 arg2) |
| 23:18 | hiredman | nil is for a static method, the object instance for a non-static method |
| 23:22 | gilbertleung | hiredman: could you clarify what would be passed into [Types Method Takes] ? |
| 23:23 | fatelang | chouser: What I tried and it error is at http://paste.lisp.org/+1XAR. |
| 23:27 | arohner | are there built in function for doing map and filter on maps? |
| 23:27 | arohner | i.e. map/filter on the keys/values of a map? |
| 23:27 | arohner | I feel like I'm missing something for writing my own |
| 23:29 | tomoj | I wish we had those too |
| 23:30 | arohner | ok, I'm not crazy. I already have map-keys, map-values |
| 23:30 | arohner | I'm writing filter-keys right now |
| 23:30 | arohner | I'll write a patch |
| 23:30 | tomoj | as it is you can (into {} (for [[k v] the-map] ...)) |
| 23:30 | arohner | yeah, that's too verbose for me |
| 23:30 | tomoj | I don't think you can do anything much faster than that, realy |
| 23:31 | tomoj | unless the map function is the identity in most places |
| 23:31 | arohner | I'm not looking for speed, just less typing and more readability |
| 23:31 | tomoj | what does map-keys do when two keys in the original map get mapped to the same key in the result? |
| 23:32 | arohner | what do you want it to do? :-) |
| 23:32 | arohner | right now it does whatever (apply hash-map seq) does |
| 23:34 | tomoj | would be unpredictable if the original hash-map is unordered |
| 23:34 | tomoj | guess if you're going to map keys to the same thing you deserve what you get |
| 23:35 | arohner | yeah |
| 23:35 | arohner | don't do that :-) |
| 23:37 | gilbertleung | hiredman: anyways, thanks alot; i'll play round with it soon when my hands are not tied |
| 23:40 | arohner | hah: http://groups.google.com/group/clojure-dev/browse_thread/thread/4b20e40d83095c67# |
| 23:40 | hiredman | gilbertleung: it;s a vector of classes |
| 23:40 | hiredman | if the method takes a string it would be [String] |
| 23:42 | _ato | ,(clojure.contrib.generic.functor/fmap inc {:a 1, :b 2}) |
| 23:42 | clojurebot | {:a 2, :b 3} |
| 23:42 | gilbertleung | hiredman: great. Thanks alot! |
| 23:46 | _ato | arohner: before writing your patch, check out: http://groups.google.com/group/clojure-dev/browse_thread/thread/4b20e40d83095c67# |
| 23:47 | arohner | _ato: yeah, I just linked to it |
| 23:47 | arohner | I visited the dev group to post about writing my patch, and saw that |
| 23:47 | _ato | ah oops, missed that :) |
| 23:48 | arohner | not that it would really save me effort. I already have the fns written, because I need them now :-) |
| 23:48 | _ato | yeah, I meant more in the sense that there was some discussion going on about it |