#clojure log - Nov 16 2009

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:06 solussd: Just finished my highlfe implementation in clojure, if anyone's interested in some late night REPL fun: http://www.solussd.com/?p=118

0:08 tomoj: solussd: what are you using to highlight clojure code?

0:09 solussd: "SyntaxHighlighter Evolved" for wordpress. It isn't perfect, but you can easily edit the "brushes" for a language's syntax

0:10 tomoj: thanks

0:10 just installed wordpress for the first time the other day

0:13 solussd: I I found the clojure syntax highlighter brush here: http://travis-whitton.blogspot.com/2009/06/syntaxhighlighter-for-clojure.html Turn it into a javascript file called shBrushClojure.js. You'll have to make some small modifications to the syntaxhighlighter evolved plugin to tell it where to find it.

0:13 tomoj: for now I am just going to embed gists I think

0:14 solussd: You can make the plugin changes directly from the wordpress 'admin' screens (click the modify link next to the plugin).

0:14 ok- If you do decide to install the plugin, you can do it right from wordpress's admin screens using the plugin installer.

0:18 duncanm: technomancy: i just installed slime via elpa, and i'm getting a FileNotFoundException

0:18 technomancy: is there something i'm missing? java.io.FileNotFoundException: Could not locate swank/swank__init.class or swank/swank.clj on classpath: (NO_SOURCE_FILE:0)

0:19 defn: why is (if test then else?)

0:19 not in the api documentation on clojure.org?

0:20 arbscht: duncanm: did you add (clojure-slime-config ...) to your init file as instructed?

0:21 somnium: defn: http://clojure.org/special_forms#toc2

0:22 duncanm: I installed a few hours ago, had to clean out .clojure and then it installed everything. though swank-clojure-project looks for the swank-jar in lib

0:24 defn: somnium: i know about that page -- but the special forms are completely missing from the API link

0:24 which seems wrong to me, but *shrug*

0:24 I know there's the direction to read special forms, but I don't see why you wouldn't include them in the larger list of api documentation

0:25 duncanm: arbscht: where are the instructions?

0:26 arbscht: duncanm: at the end of the clojure-install procedure

0:26 somnium: arbscht: I think that configuration step isn't necessary with the just released version

0:26 clojure-install says its deprecated now when I tried to run it

0:26 arbscht: oh?

0:26 I see

0:26 somnium: new version just up on elpa

0:27 duncanm: somnium: that's nice

0:29 maravillas: solussd: i added a comment recently regarding that clojure brush

0:29 need to tweak a couple of the regexes to highlight keywords properly

0:30 solussd: maravillas- cool, do you have the tweak? I'll try it now. :)

0:30 maravillas: and unfortunately the tool's getKeywords method doesn't provide a way to specify "keyword" boundaries

0:31 { regex: /:[a-z][A-Za-z0-9_\-]*/g, ...

0:31 only difference is the \- in the pattern

0:36 solussd: thanks

0:36 maravillas: no problem

0:36 _ato: ,:+-*/.<>=!?$%_&~^:@

0:36 clojurebot: :+-*/.<>=!?$

0:36 maravillas: heh

0:36 well then

0:36 guess there's more work to do

0:36 _ato: ,:+-*/.<>=!?$_&~^:@

0:36 clojurebot: :+-*/.<>=!?$_&

0:36 _ato: ,:+-*/.<>=!?$_&^:

0:36 clojurebot: :+-*/.<>=!?$_&

0:37 _ato: hehe

0:37 maravillas: ah yes, looks like the question mark at least is applicable to you, solussd :)

0:38 solussd: I love being able to use a question mark and exclamation points.

0:39 even better, I like using dashes in symbol names. this-is-much-more-readable thanTryingToReadStupidCamelCase

0:39 maravillas: of course they seem to be valid, but i wonder how often people use anything other than alphanumerics and dashes in keywords?

0:39 solussd: ... and hitting the shift key is for suckers..

0:40 question marks are good for predicates

0:40 e.g. (if alive? (something) (something-else))

0:40 _ato: like {:alive? true, :name "Rupert"}

0:40 maravillas: sure, but i mean keywords

0:40 _ato: ha, we picked the same example

0:41 maravillas: well, i'll concede question marks, i guess

0:41 duncanm: maravillas: having ! in identifiers is common in other lisps too

0:42 things like initialize!

0:42 maravillas: i mean only keywords

0:42 duncanm: ruby copied that into its libraries, afaik

0:42 maravillas: why does it matter anyhow?

0:42 maravillas: it doesn't

0:42 i'm just curious :)

0:43 duncanm: in CLOS, i think there's a style of using <Point> to notate a class

0:43 $foo is often used to refer to fluid variables

0:43 maravillas: no, i get all that

0:43 i mean specifically clojure keywords

0:43 meaning, for example, :initialize!

0:44 solussd: I use :alive? in my highlife program. :)

0:44 _ato: I could see :+ :< :& etc being used in the context of something like {:operation :+}

0:45 duncanm: on a separate topic, i thought it might be cool to extend the literal syntax, so that there're literals for URLs and Paths (coming in JDK7)

0:45 maravillas: ah yes, good point

0:47 what were you considering?

0:48 duncanm: ah, "The read table is currently not accessible to user programs." -- so no user-defined reader macros for now ;-P

0:48 * maravillas nods

0:48 duncanm: having |/home/duncan/foo| ought to be pretty handy

0:49 or maybe #|/foo/bar|

0:49 i work on Windows during the day, so having support for DOS-style paths would be great

0:49 #|C:\Program Files|

0:50 jkkramer: anyone know if it's possible yet to get a value from a transient hash set without specifying a key? e.g. something like (nth (transient #{1 2 3}) 0) => 1 ?

0:51 chouser: [most] urls are already valid symbols

0:51 'http://foo.bar.baz/bing/bang.html

0:51 ,'http://foo.bar.baz/bing/bang.html

0:51 clojurebot: http://foo.bar.baz/bing/bang.html

0:52 duncanm: chouser: i don't get your point

0:53 maybe it's not worthwhile to add more literal syntax, (File. "/foo/bar") is not *that* much longer

0:53 chouser: well -- what were you going to use literal syntax for URLs to do?

0:53 _ato: jkkramer: you can't, you'll have to call persistent on it

0:53 jkkramer: :(

0:54 there's a commit saying TransientHashSet was implemented, but seems like only conj! and disj! work, not get or nth. those work for TransientVector

0:56 duncanm: chouser: i've been using clojure to write a lot of shell-script like programs, and esp. having to reverse my \s into /s has been kinda annoying

0:56 tomoj: what do you expect nth to do on sets?

0:56 _ato: mmm, HashSets are HashMaps underneath and TransientHashMap doesn't support nth either

0:56 duncanm: twbray: did you restart your phone? maybe you need to soft reboot it

0:57 twbray: duncanm: several times

0:57 chouser: duncanm: \ is already reversed. / is the right way to separate paths. ;-)

0:57 _ato: ah yeah nth doesn't work on a set at all

0:57 duncanm: twbray: did you jsut turn it on and off? or did you do the red button + home key thing?

0:58 jkkramer: i actually just want to get an arbitrary value from a persistent set, doesn't matter which one. i just don't want to have to specify the key

0:58 twbray: duncanm: Had to do that a couple times as part of the upgrade process. could do it again. Searching, maybe a known problem :(

0:58 jkkramer: was groping around for something like first or nth or something

0:58 duncanm: oh

0:59 twbray: i have a G1 from T-Mobile, the update worked for me fine, sorry.

0:59 twbray: duncanm: Yeah, problem seems specific to the Ion AKA Google I/O devie

1:46 mikem: hi, what's the clojure way to execute a series of functions in order? in common-lisp the prog form is used for that

1:48 hoeck1: mikem: do

1:48 ,(do 'foo 'bar)

1:48 clojurebot: bar

1:48 mikem: hoeck1: ah, great, thanks

1:49 hoeck1: mikem: np :)

2:51 hiredman: ,(apply conj (ring-buffer 10 [] 0) (range 1000))

2:51 clojurebot: #<sandbox$ring_buffer$reify__3709 [990 991 992 993 994 995 996 997 998 999 989]>

3:58 mikem: is (assoc a (count a) "item"), where a is a vector, the best way to append an item to the end of a vector?

3:58 hiredman: use conj

3:58 mikem: by "append" i mean "return a new vector that's the same as a with item appended" of course

3:58 hiredman: ah yes, conj. Thanks

4:46 Licenser: morning everyone

4:51 AWizzArd: Moin Licenser

4:52 Licenser: How are things going in the clojure worlds?

4:52 yason_: Licenser: almost purely functional, thank you for asking

4:53 Licenser: glad to hear that :)

5:23 I've a macro that encalpsulates a ssh session and allows to run commands and stuff on a remote host, what is the more ideomatic name for ti with-session or do-session, it kind of both makes sense to me. Do since it has side effects and with since it kind of is a with-open block in my eyes

5:24 _ato: I'd call it with-session

5:25 Licenser: thanks that was what I went with in the first place too

5:25 _ato: do-stuff tends to make me think of doto, doseq, dotimes etc. Things that change the code structure

5:27 Chousuke: generally do is used to imply that the thing is used for side-effects.

5:28 presumably running commands over ssh is rather side-effecty, but with-session is idiomatic for a macro that creates a context.

6:35 Drakeson: how can I interrupt a slime repl? C-c C-c does not seem to work.

6:36 _ato: C-c C-b

6:36 doesn't always work though

6:40 Licenser: sorry for the delay and thanks for the input I'll stay with with-session then

6:43 hmm exec, scp-put, scp-get something else that might be important?

6:51 _ato: Licenser: do you support directory copies (ie the "D" scp command) with scp-put? if not, that might be something useful if you're making a general clojure ssh library

6:54 Licenser: good idea

6:54 lets figure out how that works :P

7:19 hrm jsch sems not tu support that :/

7:19 _ato: wait... jsch has builtin scp support? gah.. I did it myself

7:20 AWizzArd: rhickey: in the last but one example at http://www.assembla.com/wiki/show/clojure/Protocols it could also be 'AMultiProtocol' vs without 'Multi'

7:21 _ato: Licenser: http://blogs.sun.com/janp/entry/how_the_scp_protocol_works

7:26 Licenser: _ato: it has a very neat sftp support

7:26 not scp directly

7:28 _ato: ah right

7:30 Licenser: scp looks very ugly and I didn't liked it so I used sftp, I stumbled about the same stuff you linked me to - I found it way too complicated

7:30 then again a good scp library for clojoure would be cool I guess

7:30 since sftp does not seem to copy directories :/

7:32 _ato: there must be a way to do it somehow as the sftp command supports it

7:33 maybe JSch just doesn't implement it :/

7:33 oh well :)

7:33 Licenser: _ato: might not be implemented in jsch,

7:33 well or ti does but does not document it :P with couldn't be surprising

8:31 hmm apply does not work with special forms? o.O

8:33 chouser: Licenser: I don't see how it could. what are you trying to do?

8:35 Licenser: just tried to use (apply . object method arglist)

8:36 chouser: ah, yes.

8:36 Licenser: which isn't working too well :P

8:36 chouser: "method" is not evaluated so that's just not going to work. If you know the method name at compile time, you have an excuse to write a macro.

8:37 Licenser: then again I am horrible with amcros

8:37 method is not something to be evaluated I know the method name

8:38 https://gist.github.com/a6e903ef4c7998d82d34 <- that is what I'm trying to do :P mostly at least

8:39 yason: Licenser: would memfn help?

8:40 chouser: that's a lot of code for a macro.

8:40 memfn hardly ever helps -- you can just use #(something) instead

8:40 Licenser: hmm chouser I think you're right

8:43 chouser: it's a macro so you can capture 'session ?

8:45 Licenser: (with-session "user" "pass" "host" 22 (do-sftp (:put "D:/test/1.txt" "/tmp") (:get "/tmp/1.txt" "D:/")))

8:45 _ato: Licenser: might be better to use a binding instead and just use a regular function for do-sftp

8:46 oh wait... you want a list

8:46 Licenser: so a) I can fetch session and b) to not have to pass nice () stuff instead of ugly '() stuff

8:46 _ato: hmm

8:47 chouser: would you find [:get "/tmp/1.txt" "D:/"] acceptable?

8:47 Licenser: hmm it kind of is not as nice as ()

8:48 * Licenser came up with https://gist.github.com/a6e903ef4c7998d82d34 as compromise

8:49 chouser: ok, so I'd recommend your do-sftp macro just repackage your args -- capture 'session if you want and convert your (:put ...) to [:put ...], and then pass it all to a function to do the real work.

8:49 ah. like that!

8:49 :-)

8:49 Licenser: ^^

8:49 briliant minds think alike, and sometimes even I get teh same idea if it's obviouse enough .P

8:49 chouser: though you could probably move even more things into the fn

8:50 Licenser: *nods* the open and close likely

8:50 or connect and disconnect

8:50 ohpauleez: I'm new to Clojure but not to Lisp in general. What does the hash after a symbol do?

8:50 chouser: ohpauleez: auto-gensym

8:50 Licenser: it generates a id'ed symbol for macros

8:50 ohpauleez: ahhh cool

8:50 thank you both

8:52 Licenser: hey I'm glad if I once can help and don't just ask all the time :P

8:52 chouser: Licenser: note the way you've got it there, you can only pass in literal strings for your (:get ...) args.

8:53 ohpauleez: :) I understand the feeling. I remembered seeing it here (http://en.wikibooks.org/wiki/Learning_Clojure#Macros) but forgot when I was looking at your code

8:53 Licenser: ^^

8:54 I see, you're right again chouser that is bad'ish

8:54 hmm bindings kind of broke stuff soo

8:55 _ato: Licenser: https://gist.github.com/989fbc3b6972c145d1a3

8:55 I'd do something more like that

8:55 so you can put ifs and stuff in the body

8:55 but that might not be what you're going for

8:56 Licenser: _ato: actually it pretty much is, so I wanted to remove the sftp prefixes from the stuff

9:00 _ato: so I like how you do that with binding

9:01 _ato: yeah, means you can use functions instead of macros, and the calling code can also use functions without having to worry about passing the myserious invisible session and sftp symbols around

9:10 rhickey_: http://paste.lisp.org/display/90495

9:10 I think I want something like this for when defs are being explicitly provided^^

9:11 chouser: can you do extend more than once on the same type without overwriting?

9:14 Licenser: _ato: mind if I pick up from that idea?

9:15 _ato: sure go for it

9:17 Licenser: thanks

9:19 rhickey_: chouser: separate extends?, yes, only overwrite same protocol/type combo

9:19 big part of protocols is independent extension

9:19 chouser: ah, of course.

9:20 rhickey_: fred write P, ethel writes T, lucy extends T to P

9:20 chouser: ok, so you could mix extend-type with extend if one of the protocols needed merge but the others didn't

9:20 rhickey_: right

9:20 I just see a lot of impls being explicit and inline, where the map stuff is just in the way

9:21 also the type hint could come from the type up top and not be repeated

9:24 anyone want to take a crack at those?

9:27 chouser: if you don't mind waiting a couple days, I bet someone on the dev group would like to get involved.

9:28 _ato: that reminds me

9:28 rhickey_: don't suppose you've received my CA yet?

9:28 ohpauleez: Are the protocols in clojure similar to that of ObjC?

9:29 nvm: http://www.assembla.com/wiki/show/clojure/Protocols

9:29 rhickey_: _ato: all people with CAs are listed on the contributors page, if you are not there I haven't gotten it (note I only check the box every week or so)

9:29 _ato: ah ok, thanks

9:30 sent it on the 6th so it'll probably be there next time you check

9:30 no worries :)

9:32 rhickey_: ohpauleez: they differ in significant ways - ObjC is duck-typed, and protocols map to class methods

9:33 Clojure protocol functions are not methods of the classes that extend the protocol

9:33 you do not indicate support of a protocol in the definition of the extending class

9:33 they are not duck-typed

9:33 ohpauleez: they're generic, which opens up a lot of cool possibilities

9:33 I'm reading that wiki page now

9:34 ps: I'm Paul, I worked on the JVM backend for PyPy

9:34 rhickey_: cool

9:34 ohpauleez: I'm migrating here, catching up, and digging in

9:35 chouser: ohpauleez: I've got some functional-flavoured kool-aid here if you'd like a sip.

9:36 * ohpauleez hands a gallon container over

9:36 ohpauleez: I tend to do more functional-esque styles in Python than OO stuff, and really enjoy Common Lisp

9:37 clojure has answered many of my issues with common lisp, it's an ideal middle ground for me

10:53 the-kenny: What can cause (take 24 @my-agent) to fail with a NullPointerException when (take 23 @my-agent) works? (last works too, as does nth)

10:54 I think something very strange is happening here... The code worked for some hours now, but suddenly I get this NPE.

10:54 chouser: my-agent could be a lazy seq that errors when it tries to compute the 24th item

10:54 oh, 'last' works?

10:54 hmph

10:54 the-kenny: Yes

10:54 AS does nth

10:57 I use this agent as a simple queue were elements get added from a thread pool.

10:57 chouser: the stack trace doesn't point you anywhere?

10:57 the-kenny: The add-method is just a simple (if (> (count state *limit*) (commit-to-couchdb) (cons state json))

10:59 chouser: hm strage, emacs has hidden the stacktrace.. bad emacs, bad!

10:59 Somewhere in the regex-api

11:01 hm strange, I can't imagine how lazyness could cause such an error

11:03 hm.. I think it would help to force the evaluation of the json before I add it to the queue, right?

11:04 ..maybe evaluation is the wrong word.

11:04 chouser: yeah, if you're reading from a file or stream into a lazy seq and then passing that off to another thread, there's definitely more timing complexity there than you probably want to deal with.

11:05 the-kenny: hm.. ok. It's just strange that this happens after hours and not before.

11:06 (Sorry, my english isn't very good :)

11:06 chouser: your english is fine. yeah, I can't tell you what's wrong without more details.

11:07 the-kenny: I read from a stream (http), parse this as json, pass some parts of the json to some functions to extract new data, collect this data into a new json struct, add this to the queue and push the queue to couchdb :)

11:10 AWizzArd: What foo do I need to have (= ::x (foo (deftype x []))) ==> true ?

11:10 So, how do I go from a Var to a keyword, including the namespace?

11:13 chouser: you really want to process the return value of deftype, not the return value of (x ...) ?

11:13 stuartsierra: (defn foo [var] (let [m (meta var)] (symbol (name (:name m)) (name (ns-name (:ns m))))))

11:13 Licenser: geez stupid questio, how to :use :only within a ns?

11:14 stuartsierra: Licenser: (ns ... (:use [foo :only (one two three)]))

11:15 Licenser: woooh thanks stuartsierra i think I treid every other combination form m[ and (

11:15 AWizzArd: chouser: yes, I would like to know if/how I can go from a var to a Namespace-Keyword.

11:18 and maybe other than (keyword (subs (str #'user) 2)) :-)

11:19 chouser: stuartsierra gave the right answer, at least until we can talk rhickey into having Vars implement Named

11:21 arohner: Is swank known to work on the deftype/defprotocol branch?

11:21 I'm getting java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V

11:21 at swank.util$flet__9.<init>(util.clj:5)

11:23 the-kenny: oh strange

11:23 chouser: (nth 23 @my-agent) throws now too.

11:23 Looks like the 23th element is broken

11:24 Is there something like a reverse-take?

11:24 stuartsierra: arohner: I got the same error

11:25 arohner: great, mvn compile against swank downloads its own clojure.jar, rather than trying to build against my branch

11:26 chouser: (doc take-last)

11:26 clojurebot: "([n coll]); Returns a seq of the last n items in coll. Depending on the type of coll may be no better than linear time. For vectors, see also subvec."

11:26 the-kenny: Thanks :) The 23th element is definately broken.

11:29 rhickey_: extend-type and extend-class are up

11:31 stuartsierra: arohner: You can build your own Clojure JAR and install it with Maven

11:31 arohner: stuartsierra: how do I do that? Build the jar and then copy it to...?

11:32 stuartsierra: Get the Clojure sources, checkout the new branch, and run "mvn install"

11:32 In the Clojure source dir

11:32 rhickey_: would extend-protocol be too confusing? when you want to provide several impls of the same protocol in one shot

11:33 (extend-protocol P AType (foo ...) (bar ...) BType (foo ...) (bar ...) AClass (foo ...) (bar ...) ...)

11:33 chouser: hmph. my extend-type is just now working.

11:33 I have no self-control.

11:33 rhickey_: if only I knew you were trying it

11:33 chouser: or I you

11:34 rhickey_: right

11:34 chouser: oh well, your is better

11:34 http://paste.lisp.org/display/90495#1

11:35 rhickey_: I ended up bailing on the keyword-izing, for two reasons, one, it can get confusing when you need to use the keyword and not, and two, extend-type can now work on classes or nil too

11:35 chouser: ok.

11:36 keywordizing qualified vs. unqualified symbols required surprising work

11:36 rhickey_: iirc in CLOS I was confused about when to quote clasnames

11:36 AWizzArd: Why do Vars have a .ns with some content and a .sym whose namespace is nil?

11:36 arohner: stuartsierra: my new clojure claims it is 1.1-alpha, but swank-clojure builds against clojure-1.0.0. should I rename the jar, or do something else?

11:37 rhickey_: chouser: there really isn't a good rationale for how to 'resolve' to a keyword, as the user might or might not have pulled in the name otherwise

11:37 arohner: nm, I see the dependency line in the pom

11:37 stuartsierra: arohner: change the version in the swank-clojure POM to match your new Clojure build

11:37 rhickey_: chouser: what do you think of extend-protocol idea ^^ ?

11:38 flips protocol/type

11:40 chouser: to let you compose in roughly the groupings that core.clj does today

11:42 rhickey_: yeah, just looking t replacing things like RT.count

11:42 else if(o instanceof String) return ((String) o).length();

11:42 becomes

11:42 (extend-class String Countable (cnt [s] (.length s)))

11:43 but with extend-protocol, a bunch of these could be grouped together:

11:43 (extend-protocol Countable

11:43 String (cnt [s] (.length s)))

11:44 chouser: I think it's probably quite reasonable. It's just that protocols vs types are still a bit slippery for me.

11:44 Having said that, I don't know that extend-protocol would make that particularly worse.

11:45 rhickey_: this seems pretty snazzy:

11:45 (extend-protocol Countable

11:45 clojure.lang.Counted (cnt [c] (.count c))

11:45 String (cnt [s] (.length s))

11:45 java.util.Map (cnt [c] (.size c))

11:45 nil (cnt [_] 0))

11:46 chouser: yeah, can't really argue with that

11:46 AWizzArd: Otherwise many "extend"s would be needed?

11:46 chouser: esp. since the alternative would be to say "extend foo Countable" a lot

11:47 ohpauleez: fwiw, I totally favor that (rhickey)

11:47 I just ran into that this past weekend actually

11:47 rhickey_: (extend-class clojure.lang.Counted Countable (cnt [c] (.count c)))

11:47 (extend-class String Countable (cnt [s] (.length s)))

11:47 (extend-type nil Countable (cnt [_] 0))

11:47 (extend-class java.util.Collection Countable (cnt [c] (.size c)))

11:47 (extend-class java.util.Map Countable (cnt [c] (.size c)))

11:47 chouser: String #(.length %) ?

11:48 wavis: if i pass a seq into a method, and that argument is referenced once, is the head of the seq retained until the end of the method despite not being used?

11:48 rhickey_: chouser: not in these macros, at least not if they auto-type hint

11:49 one problem with extend-protocol would be determining when it could type hint, since it could be a mix of extended types/classes/nil

11:50 chouser: types would use keywords right?

11:54 rhickey_: chouser: yes, actually not so bad, extend-protocol probably a simple macro on top of extend-type/class

11:55 another problem with #(.length %) is there's no place for the fn name, which must be present as the protocol might have multiple fns

11:56 chouser: oh, right, it's actually String (count [s] (.length s))

11:56 rhickey_: yup

11:56 chouser: you were using cnt because it's not cinc quite yet, and count is something else

11:56 rhickey_: right

11:57 just experimenting with the perf of a protocol versus the RT methods

11:57 so far, faster

11:57 chouser: beautiful

11:57 rhickey_: and of course, much better in that they are extensible

11:57 chouser: I'll have to spend some time eventually figuring out what I'm doing wrong with the finger trees.

11:58 cons dispatches on the wrong arg

11:58 rhickey_: yeah, I didn't invent cons :)

11:59 chouser: hehe

11:59 finger trees want to differentiate between cons and conj

11:59 rhickey_: but things like that are just a matter of a fn on a protocol fn

11:59 chouser: maybe cons can be (defn cons [x c] (consLeft c x))

11:59 sorry!

11:59 maybe cons can be (defn cons [x c] (cons-left c x))

12:00 oh, that's what you just said.

12:01 Chousuke: I keep wanting to rewrite the reader on top of protocols and deftype all the time but other things keep me too busy to do that ;(

12:01 rhickey_: right, the protocol might not be the ultimate end-user api

12:02 chouser: gah. wth is this thing trying to use fcase.clj

12:03 rhickey_: chouser: allowing for other-than-first arg would add a lot of complexity and reduce flexibility, so I opted out

12:03 chouser: no, not at all worth it.

12:03 for simple things like cons, the solution is simple.

12:03 for complex things, multimethods are right there

12:19 arohner: stuartsierra: I fixed that java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V by rebuilding clojure-contrib

12:19 I also had to clean clojure-contrib before it would build happily

12:20 hiredman: that exception, as far as I can tell, always means you need to rebuild contrib

12:20 I don't recall ever seeing it any other time

12:21 arohner: hiredman: where were you an hour ago? :-)

12:28 rhickey_: extend-protocol is up

12:36 AWizzArd: thx

12:39 wavis: how do I process a large coll within a method without retaining the head?

12:39 stuartsierra: rhickey_: really, protocol methods are faster than RT? Awesome. I assumed they would be slightly slower.

12:40 So this means any new type can implement conj/count/first/rest/..., with the same performance as built-in types?

12:41 arohner: ,(doc dorun)

12:41 clojurebot: "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."

12:41 wavis: arohner: doesn't work. the head of the coll is retained until the end of the method

12:43 i made it work by creating a once-accessible IDeref that sets its value to null after the first access. but that's messy.

12:43 stuartsierra: wavis: you can iterate over a large collection safely with loop/recur

12:44 hiredman: or iterate?

12:45 wavis: stuartsierra: I haven't tried that, but isn't it essentially the same solution as dorun? I'll open a loop in the mehtod, but the head of the coll will stick around until the end. maybe I need to do something other than use large collections.

12:45 hiredman: wavis: are you sure dorun is hanging on to the head?

12:46 wavis: dorun isn't, but because i pass the collection into the method as an arg, the arg is.

12:46 arohner: ~def dorun

12:46 rhickey_: stuartsierra: yes, that's the idea

12:46 arohner: looks like the head is only present in the first iteration

12:47 rhickey_: once count/first/rest become protocols

12:47 hiredman: wavis: args are cleared on tail calls

12:47 stuartsierra: rhickey_: awesome

12:47 rhickey_: the RT methods a) still have to be wrapped in Clojure fns

12:47 b) have manual dispatch using conditionals

12:48 a protocol implementation will get wired into a call site, and even sites that change do caching

12:48 so most of the time there is no lookup

12:49 stuartsierra: Ah, yes. That's how polymorphism is supposed to work. :)

12:50 wavis: hiredman: right. so i need to compose two methods, one which processes the coll, and hands off to the second step in the process where the head is not retained. OK gracias

12:51 rhickey_: (defprotocol S (s [x]))

12:51 (extend-class clojure.lang.ISeq S (s [x] (.seq x)))

12:51 (def #^clojure.lang.ISeq sq (seq [1 2 3]))

12:51 (time (dotimes [_ 100000000] (seq sq)))

12:52 user=> "Elapsed time: 916.738 msecs"

12:52 (time (dotimes [_ 100000000] (s sq)))

12:52 user=> "Elapsed time: 619.931 msecs"

13:44 pjstadig: ~suddenly

13:44 clojurebot: CLABANGO!

13:44 pjstadig: hehe

13:44 still works

13:44 danlarkin: demons have been summoned

13:45 or should I say daemons have

13:45 ha!

13:50 polypus: is there a map function which preserves the data-structure type?

13:51 technomancy: polypus: I usually use reduce for that

13:51 polypus: (map #(str % "!") ['a 'b 'c]) -> [a! b! c!] not a seq

13:52 ok thx, just checking

13:58 djpowell: wrap it in (into (empty s)

14:08 danlarkin: what's the best way to check if a symbol is bound to a byte array?

14:09 (= (type (make-byte-array) (type v)) is lame

14:09 oops, mismatched parens there, but you get the idea

14:11 AWizzArd: rhickey: can one extend Arrays of "long" with a protocol?

14:11 Or ArrayList of Foos?

14:20 mrSpec: Hello

14:24 ohpauleez: is there an easy way to do something like python's "in" as a predicate? ex: if 4 in [2, 4, 1, 3, 5, 6, etc] returns true if 4 is in the collection

14:25 I was looking through the cookbook and special forms, but I'm not coming up with anything

14:25 piccolino: (contains? [2 4 1 3] 4)

14:25 ohpauleez: also looked in seq-utils in contrib

14:25 ahh, thank you

14:25 hiredman: be sure to read the docstring for contains?

14:26 rhickey_: (some #{4} '[2, 4, 1, 3, 5, 6, etc] )

14:26 ,(some #{4} '[2, 4, 1, 3, 5, 6, etc] )

14:26 clojurebot: 4

14:26 ohpauleez: Ah, that's awesome too

14:27 thanks hiredman

14:27 rhickey_: not only awesome, but correct, the contains? thing isn't

14:27 ,(contains? [2 4 1 3] 4)

14:27 clojurebot: false

14:28 piccolino: Yeah. That's what I get for guessing a function name.

14:28 rhickey_: contains? tests associative things for their keys, which for arrays is their indices

14:29 ohpauleez: I just read the doc and realized that

14:29 rhickey_: Java's Collection.contains is available, however

14:29 ,(.contains [2 4 1 3] 4)

14:29 clojurebot: true

14:29 hiredman: reading docs is good

14:31 ohpauleez: yeah I just couldn't find the common idiomatic approach, thanks guys

14:44 rhickey: AWizzArd: arrays of long, yes, if a bit icky (Class/forName "[J")

14:44 ArrayList of Foos, no, generic types are not reified

14:45 but ArrayList, yes

15:17 krumholt_: hi i am reading on the clojure.org page about vars and the global environment. i am not a native english speaker so maybe i don't get the meaning but what does this mean? "Bindings created with binding can be assigned to, which provides a means for nested contexts to communicate with code before it the call stack." Is it possible there is a word missing?

15:18 kanak: krumholt_: "before _it_ in the call stack" maybe?

15:19 hiredman: on

15:19 chouser: right. "before it on the call stack"

15:20 it's a scary little feature, fortunately very rarely used.

15:20 krumholt_: ok

15:20 chouser: in fact, I think I've only seen it used in Compiler.java

15:20 kanak: isn't binding somewhat like special variables?

15:21 krumholt_: i used binding to get a thread local version of a global variable. just wanted to read up on it and didn't understand the sentence

15:22 chouser: getting a thread local of a global var is good and common

15:22 dnolen: kanak: yes

15:22 krumholt_: ok

15:22 good thanks :)

15:23 chouser: changing it on a deeper part of the call stack in order to communicate up the call stack is unusual, too-clever, and a bit scary.

15:24 rhickey: I never got around to wrapping that in a Sow/Reap thing like Mathematica has

15:25 http://reference.wolfram.com/mathematica/tutorial/CollectingExpressionsDuringEvaluation.html

15:25 chouser: does that make it less scary? reaping doesn't *sound* less scary.

15:26 rhickey: heh

15:28 lisppaste8: Chouser pasted "using binding to pass extra return values" at http://paste.lisp.org/display/90515

15:29 chouser: hm! possibly less scary.

15:31 kanak: what would the disadvantages of having a CL-style multiple return values be?

15:32 tomoj: java?

15:32 chouser: kanak: clojure fn calls could no longer be simply java method calls (and vice-versa)

15:33 kanak: though someone did build a CL-style multiple return value lib on top of thread-local bindings

15:33 ages ago

15:33 rhickey: early Clojure prototypes had it

15:34 notallama: how do you get a specific branch with git? (i'm trying to download new)

15:34 kanak: chouser: thanks for the reply.

15:35 chouser: http://paste.lisp.org/display/68919 -- jochu, 1 year, 3 weeks ago

15:35 rhickey: but yes, you can't manipulate the real stack using JVM bytecode the way you'd want, so you end up with thread locals, and making it transparent to use either one or more than one of the returns (the key CL feature vs just returning tuples) makes all calls less efficient

15:35 so it's out

15:35 arohner: notallama: git checkout <branchname>

15:36 chouser: huh. I bet that code all still works. not too shabby.

15:37 oh, nope. old 'when' form

15:37 bah, nm. that didn't change. :-P

15:37 notallama: arohner: i get "error: pathspec 'new' did not match any file(s) known to git."

15:38 arohner: notallama: git branch -a to see the list of branches

15:38 you'll probably want git branch -t origin/new

15:40 dakrone: is there a contrib function similar to duck stream's read-lines, but for reading a # of bytes?

15:40 arohner: notallama: that sets up a local branch to track the remote branch, so you can stay up to date with it

15:42 notallama: arohner: i have no idea what that means. got it working well enough for my needs, though. thanks!

15:43 arohner: notallama: this describes tracking in more detail, if you're interested

15:43 http://book.git-scm.com/4_tracking_branches.html

15:43 hiredman: (comp first (juxt first #(.read (second %) (first %)) (juxt (comp (partial make-array Byte/TYPE) first) second) list)

15:43 or something

15:44 dakrone: I don't know, but if you are dealing with an inputstream it is pretty trivial to use the .read method directly

15:45 dnolen: people who are up the deftype, defprotocol work - is declaring a protocol the same as writing and loading a Java interface except you can do it dynamically at runtime?

15:46 dakrone: hiredman: doesn't read-lines returns it as a lazy-seq? I was trying to do a pmap over a giant file in 8192-byte sized chucks, would .read work for that?

15:46 without loading the entire thing into memory

15:46 hiredman: dakrone: yes

15:46 it would be slightly more complicated

15:46 chouser: dnolen: there are several important differences, but that'll do as a sort of rough-cut of the general category of functionaly protocol provides.

15:47 dakrone: hiredman: okay, I'll try using .read directly

15:47 thanks

15:47 hiredman: you would use repeatedly

15:47 chouser: rhickey: is there a story now for consuming protocol-related things in Java?

15:47 hiredman: and a thunk that calls .read

15:49 dnolen: chouser: k good to know.

15:49 rhickey: chouser: same story, just tell them to implement an interface, on the Clojure side (extend ThatInterface TheProtocol)

15:50 or now, (extend-class TheInterface ...)

15:50 chouser: I meant the other way around -- if IPersistentCollection is just a protocol, how does Java use one?

15:50 rhickey: the extend-* are definitely handy

15:51 chouser: it always required an interface for Java, and always will. So, there will be matching interfaces if only for that purpose

15:51 even with :on that was still the case

15:52 but, and this is true today as well, any interface for which extend is already written is an ok way to connect to the protocol

15:52 e.g. things that are Java collections and Iterables will work, because the protocols will be extended to them anyway

15:53 chouser: hm, I think I get it. With :on I was imagining there'd often be a protocol that with just the same methods as the interface.

15:53 but there's no point in that, you can just extend the interface instead of the protocol

15:53 rhickey: chouser: that may still be, but still 2 things

15:54 a protocol isn't a thing in Java type terms, so not something you could derive from

15:54 chouser: right, I get that.

15:54 rhickey: I have one more idea for :on that might yield some additional advantage to having it, at some implementation complexity cost TBD

15:55 dnolen: rhickey: so why would you use extend-protocol? (sorry still trying to understand, just saw that you added that)

15:55 spuz: What's the correct syntax for the load-file function? When I try (load-file "sub/dir/file.clj") I get "No such namespace: sub/dir"

15:56 hiredman: ,(doc load-file)

15:56 clojurebot: "([name]); Sequentially read and evaluate the set of forms contained in the file."

15:56 hiredman: :|

15:56 spuz: needs a file://

15:56 rhickey: when you want to write the implementation of a single protocol for several types all at once, reduces repetition

15:56 dnolen: ^^

15:56 hiredman: spuz: I think

15:56 chouser: dnolen: it just lets you group your implementation fns differently: http://clojure-log.n01se.net/date/2009-11-16.html#11:42c

15:56 hiredman: actually

15:57 spuz: hiredman: really? Hmm I'm sure I've used it with the direct file name in the past. Maybe it has to be on the class path?

15:57 chouser: I've used load-file with a plain path string not on the classpath

15:58 lisppaste8: rhickey pasted "doc extend-protocol" at http://paste.lisp.org/display/90517

15:58 chouser: spuz: you're suring there's nothing wrong in the file itself, some reference to "sub/dir"?

15:58 dnolen: rhickey: so that instead of multiple deftype with an interface plus method implementations?

15:58 I suppose I'm confused by the fact you can provide method implementations in deftype and other ways.

15:58 chouser: yes, try to ignore deftype method definitions

15:59 spuz: chouser: yes, but perhaps my cwd is not the same as the path I launched clojure from...

15:59 dnolen: chouser: as in that's not something that should generally be done?

15:59 chouser: dnolen: they're just there to confuse you (and to solve interop issues)

15:59 rhickey: dnolen: methods and protocol functions are completely different things, it's easiest to learn about the latter if you ignore the former

15:59 dnolen: chouser: it definitely worked :)

15:59 spuz: chouser: eh, actually, it's working now, no idea why it wasn't earlier...

16:01 dnolen: rhickey: so deftype with fields + protocols is the better way to think about things.

16:01 rhickey: dnolen: that's the pure protocol way, yes

16:01 AWizzArd: Nice video of Guy Steele, talking about functional programming and parallelism: http://vimeo.com/6624203

16:02 fits well to rhickeys talk about time management, which was recently uploaded

16:02 hiredman: gah, I still don't understand how github can be so broken with firefox

16:02 dnolen: rhickey: chouser: thx much for the clarifications. I think I'm beginning to understand.

16:07 fyuryu: anyone got the clojur-maven-plugin + clojure:swank goal working on Windows?

16:51 qed: http://pastie.org/private/cxw8cedwaate4y4lmj7y8a

16:52 what's wrong with this picture?

16:54 hiredman: no docstring?

16:54 qed: hehe, is there anything wrong with the general form of it?

16:54 (step n) returns n/2 if its even , and 3n+1 if odd

16:55 lenst: it never halts

16:55 qed: im trying to make a vector starting at n = let's say 100, and have it conj onto the vector for each step

16:55 hiredman: qed: I imagine it loops forever because you never change n

16:55 qed: oh rigt

16:55 right*

16:57 _mst: and even then you've only gone from "will never halt" to "might never halt" ;)

16:57 ohpauleez: haha

16:57 qed: lol

16:57 hiredman: _mst: :)

16:57 qed: nevermind

17:20 johnmn3: hello

17:21 I was reading the tutorial at riddel.us. I was wondering if there are tutorials for using the new branch

17:22 duncanm: la la la

17:23 Chousuke: johnmn3: I don't think there are tutorials but the assembla wiki pages contain the current documentation :P

17:24 johnmn3: yea, I've been checking that out.

17:24 I'm sure people are running the new branch on emacs.. are there any caveats?

17:24 or is it as simple as replacing the jar?

17:26 arohner_: johnmn3: I had to rebuild clojure-contrib and swank to get things to work on the new branch

17:26 Chousuke: you may need to recompile contrib/swank/whatever

17:27 johnmn3: hmm. ok. There's a new build of contrib on the build site.

17:27 which, I believe was said to be compatible with new

17:34 stuartsierra: johnmn3: you still have to rebuild contrib/swank with the new branch of clojure for it all to work, I think

17:35 KirinDave: Hey folks. is there a concurrency guide for clojure?

17:35 Like if I wanted to segment a task (say fetching urls) into groups and threading them out

17:35 is that just a job for agents?

17:36 johnmn3: stuartsierra: ok. Thanks.

17:36 the-kenny: KirinDave: I've managed to do this with a ThreadPool from java for the processing and an agent for collecting the results.

17:36 KirinDave: the-kenny: Yeah I could use the underlying java threading primitives

17:36 hiredman: ,(doc pmap)

17:36 clojurebot: "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead."

17:36 AWizzArd: Contrib json module says: (json-str {200 [1 2 3], 401 [0 0 8]}) ==> "{\"200\":[1,2,3],\"401\":[0,0,8]}" - is this really allowed? Aren't {} objects in JS and need named fields as their keys?

17:37 hiredman: AWizzArd: looks valid to me

17:37 KirinDave: hiredman: How do I know how "wide" that operation is going to be? Do I have any way of knowing or controlling that?

17:38 AWizzArd: hiredman: oki

17:38 KirinDave: Like I could imagine for a width N operation saying (partition N (map agent urls-to-fetch))

17:38 and then sending to all of them.

17:38 But then I wouldn't really know how many underlying threads are in the threadpool that agent purports to use.

17:38 hiredman: :(

17:39 KirinDave: depends

17:40 KirinDave: hiredman: Please do go on :)

17:40 AWizzArd: hiredman: yes, you are right, the rfc says it's ok

17:40 hiredman: if you send via send the agent's action is run on a threadpool bounded by 1 or 2 plus the number of cores

17:40 KirinDave: Oh so it is based of the number of cores?

17:40 hiredman: if you use send-off the threadpool is unbounded

17:40 KirinDave: So I can assume the number is going to be reasonable?

17:40 hiredman: KirinDave: just use pmap

17:41 seriously

17:41 KirinDave: So pmap and then force?

17:41 hiredman: or not, as you please

17:41 KirinDave: Well, if the job is fetching URLs :)

17:42 I've gotta confess this is so murky to me. I've been spoiled by erlang's fire-and-forget concurrency.

17:42 technomancy: pmap will attempt to stay ahead of the consumer IIRC

17:42 hiredman: KirinDave: pmap is fire and forget

17:42 KirinDave: technomancy: So it claims in the documentation.

17:42 hiredman: That's cool and I didn't know about pmap, so thank you.

17:43 hiredman: But if I wanted to say, ensure at most 4 simultaneous connections?

17:43 hiredman: ah

17:43 well

17:43 technomancy: unslot your extra cores from the die

17:43 KirinDave: Lol

17:43 hiredman: you can use agents

17:44 I guess you could use them in the manner you suggested

17:44 KirinDave: Is it frowned upon?

17:44 hiredman: I am more partial to something like (cycle (take 4 (repeatedly #(agent nil))))

17:44 technomancy: KirinDave: you could make a version of pmap that accepts a concurrency-count as an argument; it's a simple enough function to just copy

17:44 KirinDave: I've seen examples where people just go (map agent (range 5))

17:45 To do stuff like that.

17:45 hiredman: well

17:45 you know, why not make an agetn per url

17:45 agent

17:45 (like your example did)

17:45 KirinDave: (take 4 ...), wait on them

17:45 and then continue?

17:45 hiredman: I mean, agents are already backed by threadpools

17:46 KirinDave: nah, do it the wya you were doing it

17:46 KirinDave: (map agent (partition width urls-to-fetch))

17:46 Okay

17:47 Would it be unreasonable to desire that you could link agents to a specific threadpool

17:47 If you wanted to make a more dynamic behavior change in flight?

17:49 hiredman: (map fetch (map agent urls))

17:50 AWizzArd: á propos map.. (dotimes [i 100000000] (inc %)) takes one second to run on my system. (def x (map #(do (dotimes [i 100000000] (inc %)) %) (range 10))) immediately returns, as expected. But why does (time (nth x 2)) take 10 seconds, and not only 3? And when I then want to print x in the repl it returns immediately. I would thought that only then all 10 runs be done.

17:50 "would thought" ==> "would think"

17:52 When I replace map with pmap then it also immediately returns, but i see how my both cores are burning for around 5 seconds. Seems that pmap very much stays ahead.

17:52 strange

17:53 hiredman: (dotimes [i 100000000] (inc %)) doesn't actually run

17:53 AWizzArd: yes, it was i instead of %

17:53 but in the map i replaced the i with the % so that i can use the #() reader macro vs. (fn [_] ...)

18:00 hiredman: can you reproduce that? I don't understand it so far :-)

18:03 krumholt_: ,(let [+ -] (+ 1 1))

18:03 clojurebot: 0

18:03 krumholt_: ,(binding [+ -] (+ 1 1))

18:03 clojurebot: 2

18:03 hiredman: krumholt_: + is inlined

18:03 krumholt_: can someone explain the difference?

18:04 hiredman: AWizzArd: try (def x (map #(do (dotimes [i 100000000] (inc %)) (println %) %) (range 10))) with nth

18:05 krumholt_: hiredman, so the compiler optimizes the call to + ? in binding but not in let ?

18:05 Chousuke: krumholt_: the thing is, in the binding form the + refers to the var #'+, but in the let form it's just a local

18:06 krumholt_: ah ok thanks

18:06 Chousuke: krumholt_: and because the compiler inlines + for two arguments, the binding fails to work.

18:06 krumholt_: i get it thanks a lot

18:06 Chousuke: ,(binding [+ -] (+ 1 2 3)); no inlining

18:06 clojurebot: -4

18:06 krumholt_: bad compiler :)

18:07 Chousuke: the clojure compiler has next to no smarts

18:07 well, besides "big" optimisations I guess.

18:07 hiredman: ,(nth (map pr (range 10)) 2)

18:07 clojurebot: 0123456789

18:07 Chousuke: but any details are left to the JVM.

18:07 hiredman: that is rather tourbling

18:08 troubling

18:08 duncanm: hiredman: yeah, that's no good

18:08 Chousuke: I think that's because range is chunked

18:08 AWizzArd: hiredman: yes, it printed all

18:09 duncanm: hiredman: on my machine, running Clojure 1.0, i get user> (nth (map pr (range 10)) 2)

18:09 hiredman: I see

18:09 duncanm: 012nil

18:09 hiredman: duncanm: yes

18:09 Chousuke: ,(nth (map pr (range 64)) 2)

18:09 clojurebot: 012345678910111213141516171819202122232425262728293031

18:09 Chousuke: note, first 32 items only :)

18:09 (the size of the chunk)

18:10 hiredman: Chousuke: still troubling for people expect map to be lazy

18:10 expecting

18:10 AWizzArd: i didn't know that

18:10 Chousuke: moral of the story: laziness is not a guarantee, and you should keep it away from side-effects

18:10 AWizzArd: i thought that map is indeed very lazy

18:10 hiredman: Chousuke: what?

18:11 Chousuke: AWizzArd: it depends on the data structure.

18:11 hiredman: more like someone changed the semantics of map

18:11 Chousuke: hiredman: it hasn't changed.

18:11 hiredman: Chousuke: not directly

18:11 Chousuke: hiredman: there was never a guarantee that it only evaluates things one-by-one :)

18:11 hiredman: Chousuke: bull

18:12 Chousuke: hiredman: where does it say that in the docs?

18:12 it only specifies a lazy seq.

18:12 AWizzArd: i would think that i tried this in the past and did not see this behaviour

18:12 Chousuke: AWizzArd: it's an optimisation

18:12 AWizzArd: for example, it makes no sense to map things one-by-one over a vector.

18:12 hiredman: Chousuke: no it isn't

18:12 Chousuke: yes it is.

18:12 hiredman: it changes the semantics of the code

18:13 AWizzArd: but is this new behaviour?

18:13 Chousuke: hiredman: no it doesn't, if it's purely functional :)

18:13 hiredman: Chousuke: so?

18:13 Chousuke: AWizzArd: it's existed since chunked sequences.

18:13 hiredman: clojure has never been purely functional

18:13 Chousuke: hiredman: you're not supposed to use lazy sequences for side-effects :P

18:13 hiredman: it means you might end up running more computations then you want to

18:14 even if you are purely functional

18:14 AWizzArd: i think lazyness is the optimization... *not* doing stuff

18:14 Chousuke: which is an optimisation in some cases.

18:14 for example. reducing or mapping over a vector is much faster thanks to chunking.

18:14 AWizzArd: if my f in (map f coll) is expensive, say, 20 minutes runtime, then I am happy if I only need to calculate 3 and not 19

18:14 hiredman: (nth (map some-calculation (range 10)) i)

18:15 where some-calculation is a pure function and i is a number determined somehow

18:15 Chousuke: yes.

18:15 hiredman: suddenly your code is slower because it is doing more

18:15 Chousuke: it'll calculate all 10

18:15 arohner_: hiredman: it could be worse. In scheme, they don't even specify that map evaluates in order

18:15 :-)

18:15 Chousuke: that very probably won't matter.

18:15 AWizzArd: would be nice to have a lmap, which really is lazy

18:16 michaeljaaka: Hi

18:16 AWizzArd: and plmap

18:16 michaeljaaka: I'm tring to run my app

18:16 I have some functions in clj

18:16 Chousuke: ,(nth (map pr (seq (range 10))) 2)

18:16 arohner_: AWizzArd: you mean, guarantees one-at-a-time evaluation?

18:16 clojurebot: 0123456789

18:16 Chousuke: hmm

18:16 michaeljaaka: and I want to call one of them to start

18:16 AWizzArd: arohner_: yes

18:16 michaeljaaka: java -cp MyClojureProject.jar:lib/clojure-1.0.0.jar:lib/clojure-contrib-1.0.0.jar:lib/DistributedCommunication.jar:lib/JRuceCommons.jar clojure.main -e "(require 'com.yourcompany.receiver)(com.yourcompany.receiver/runr)"

18:16 Error occurred during initialization of VM

18:16 java.lang.Error: Properties init: Could not determine current working directory.

18:16 at java.lang.System.initProperties(Native Method)

18:16 at java.lang.System.initializeSystemClass(System.java:1087)

18:16 arohner_: AWizzArd: how do you tell the difference?

18:16 AWizzArd: for plmap it would be okay to stay ahead of the consumer, but it does not necessarily mean to be eager

18:16 Chousuke: hiredman: but seriously, this thing *is* an optimisation. you can ask rhickey :)

18:16 michaeljaaka: what is wrong with that?

18:17 hiredman: Chousuke: I understand that chunked seqs are supposed to be an optimization

18:17 michaeljaaka: what is wrong is a failure to use a pastebin

18:17 AWizzArd: arohner_: the difference is that for a f with a runtime of 20 minutes (second (map f (range 19))) would not run 40 minutes, but over 6 hours

18:17 hiredman: Chousuke: but this completely alters the behaviour of map

18:18 michaeljaaka: pastebin?

18:18 Chousuke: hiredman: behaviour which was never specified :P

18:18 hiredman: so it's fine to alter.

18:18 hiredman: ~google pastebin

18:18 clojurebot: First, out of 151000 results is:

18:18 pastebin - collaborative debugging tool

18:18 http://pastebin.com/

18:18 michaeljaaka: ok

18:18 hiredman: Chousuke: it's not fine

18:18 Chousuke: AWizzArd: in weird cases like those you'd ensure the seq is not chunked.

18:19 hiredman: when people have programs that rely on the old behaviour that break

18:19 Chousuke: hiredman: sure it is. at least in this case.

18:19 hiredman: what happens is that some silly programs may become a bit slower.

18:19 hiredman: while most get a lot faster.

18:19 hiredman:

18:19 _ato: michaeljaaka: might be a filesystem permissions problem. what directory are you running it from?

18:19 michaeljaaka: http://pastebin.com/m656eaf9f

18:20 I'm running it from my home directory

18:20 Chousuke: hiredman: the thing is, supporting the old behaviour would require not having chunked seqs.

18:20 AWizzArd: i think a new map construct could be used to work as map currently does, while the old map would automatically ensure that its colls are not chunks then

18:20 Chousuke: hiredman: that's not an okay tradeoff :)

18:20 _ato: hmm odd then

18:20 michaeljaaka: does the clojure repl work if you run it without all the other jars?

18:20 hiredman: Chousuke: not for people who relied on the lazy behaviour of map

18:21 michaeljaaka: yes

18:21 it works too

18:21 hiredman: map is no longer lazy then

18:21 Chousuke: it is

18:21 just less lazy than it was before.

18:21 for SOME seqs.

18:21 _ato: michaeljaaka: I guess one of those jars is messing up java's system properties then

18:21 michaeljaaka: because the first jar has meta-info ith set classpath to all others jars in libs

18:21 AWizzArd: ,(chunked-seq? (range 10))

18:21 clojurebot: false

18:21 Chousuke: hmm. that should be true.

18:21 hiredman: the whole move to the lazier branch was to avoid this kind of non-lazy behaviour

18:22 Chousuke: (nth (map pr (iterate inc 1)) 2)

18:22 ,(nth (map pr (iterate inc 1)) 2)

18:22 clojurebot: 123

18:22 Chousuke: hiredman: but sometimes laziness is less performant.

18:22 michaeljaaka: hmmm I will try to make dummy example project to see if it works

18:23 AWizzArd: ,(chunked-seq? (iterate inc 10))

18:23 clojurebot: false

18:23 hiredman: Chousuke: sure, but this negates http://clojure.org/lazier

18:23 Chousuke: hiredman: negates? how?

18:23 notallama: so i have 4 functions that work on fns, and they work fine. i get all sorts of errors if i instead define a protocall with those 4 functions, and extend IFn with the same bodies. am i doing it wrong, or is it broken? http://paste.lisp.org/display/90530

18:24 Chousuke: hiredman: full laziness is still possible.

18:24 hiredman: but for some seqs, map is not fully lazy because it makes no sense.

18:24 hiredman: Chousuke: why doesn't it make sense?

18:25 AWizzArd: i also have to admit that i find this unexpected...

18:25 Chousuke: hiredman: either because the data is already there. or the overhead of laziness is too high.

18:26 hiredman: Chousuke: sure, the data is already there for the range, but not the map

18:26 michaeljaaka: hmmm, It works for dummy project ;(

18:26 Chousuke: hiredman: yes, but that really doesn't matter.

18:26 hiredman: it does!

18:27 AWizzArd: Chousuke: so, how do i make (first (map #(pr % ",") (range 100))) really lazy?

18:27 Chousuke: hiredman: if your operation is so expensive you can't afford to computer it ahead by at most 32 items, you should use pmap or some other model altogether :P

18:27 compute*

18:27 at most 31, even.

18:28 AWizzArd: Chousuke: but even pmap will let my 32 core machine burn on all cores for 20 minutes then

18:28 i just wanted the first 2 elements, and only knew this at runtime

18:28 Chousuke: an easy way to unchunk a seq is to concat an empty list to it

18:28 hiredman:

18:29 AWizzArd: this won't work for (range 10) tho, as this isn't even a chunked seq..

18:29 Chousuke: but seriously, any concerns you are having are purely theoretical

18:29 hiredman: ,(nth (rest (concat () (map pr (range 10)))) 2)

18:29 clojurebot: 0123456789

18:29 hiredman: :|

18:29 michaeljaaka: _ato: I know what it was

18:29 AWizzArd: so, how can this be really lazy?

18:30 hiredman: Chousuke: any assurances you've given have been purely theoretical

18:30 Chousuke: hiredman: has anyone actually been bit by this?

18:30 michaeljaaka: _ato: I'm using enclojure, I rebuilded the project and the Terminal has just lost the dist directory because it was deleted by netbeans

18:30 Chousuke: hiredman: this has been the default behaviour for who knows for how long already :P

18:30 hiredman: Chousuke: AWizzArd just was

18:30 AWizzArd: perhaps some more people were hit and just didn't find out yet

18:30 michaeljaaka: _ato: the new one was created but terminal had still old reference

18:30 _ato: michaeljaaka: ah right. :)

18:31 michaeljaaka: _ato: solution, exit and enter again

18:31 hiredman: it means I have to reexamine everything

18:31 AWizzArd: Chousuke: I didn't notice it for quite a long time and was totally convinced that it will really be lazy

18:31 michaeljaaka: _ato: thanks anyway!

18:31 AWizzArd: with pmap okay, this will consume a bit more

18:31 but map is fully lazy - i thought

18:31 hiredman: clojurebot's input fuzzer takes a long time to run, perhaps somewhere something is returning a lazy seq

18:31 er

18:31 a chunked seq

18:32 so it is doing more work than it needs to

18:32 AWizzArd: would be great if i could count on the lazyness, even if that reduces the runtime speed in some cases

18:33 and, if there is a way to make map guaranteed work lazy, then map could ensure that it will always work like this, and we simply get a new-map

18:33 (def new-map map) ... (defn map .. really lazy ...)

18:34 Chousuke: either way, I don't see this as a big enough problem to be worth fixing :P

18:35 AWizzArd: so, do you have then a way how to make map work guaranteed lazy?

18:35 Chousuke: I thought the concat trick worked but hmm

18:35 dreish: Just use the pre-chunks implementation.

18:36 AWizzArd: ,(set-mode map :pre-chunked)

18:36 clojurebot: java.lang.Exception: Unable to resolve symbol: set-mode in this context

18:36 Chousuke: ,(nth (map pr [1 2 3 4]) 2)

18:36 clojurebot: 1234

18:36 Chousuke: ,(nth (map pr (concat () [1 2 3 4])) 2)

18:36 clojurebot: 1234

18:36 Chousuke: hmm. :/

18:37 AWizzArd: so, map is mostly eager, but can in some cases be lazy

18:37 Chousuke: it's not mostly eager

18:37 it's mostly lazy, but can in some cases be eager :)

18:38 hiredman: and you will never know when it will do which

18:38 Chousuke: the eager cases so far are vectors, maps, sets and ranges

18:38 because those are "eager" data structures. except for range I guess.

18:38 hiredman: Chousuke: but the result is not eager!

18:38 or should not be

18:38 AWizzArd: ,(first (filter (comp #(= % 3) pr) (range 100)))

18:38 clojurebot: 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899

18:39 AWizzArd: *sigh*

18:39 hiredman: I might know all the values in a vector

18:39 but that doesn't mean I want them eagerly mapped!

18:39 Chousuke: hiredman: but in the overwhelming majority of cases that doesn't matter :/

18:39 it's not fully eager either. only 32 items at once.

18:39 _ato: AWizzArd: err... that pr returns nil causing the filter to run through the whole range

18:40 AWizzArd: ,(first (filter #(do (pr %) (= % 3)) (range 100)))

18:40 clojurebot: 3

18:40 012345678910111213141516171819202122232425262728293031

18:41 AWizzArd: Chousuke: so what would be bad about having it fully lazy then?

18:41 if people care about performance then there is always pmap

18:41 Chousuke: AWizzArd: it would not be as performant due to the overhead.

18:42 dreish: pmap isn't generally faster.

18:42 Chousuke: AWizzArd: pmap is even less performant.

18:42 AWizzArd: if f is not something like + then pmap will be more performant

18:42 dreish: AWizzArd: Really, just git checkout 14316ae2110a or whatever, look at the source of map at the time, call it map1, and go on with your life.

18:42 It's really not that big a deal.

18:42 AWizzArd: but if f is so cheap, why then care about pure lazyness?

18:42 Chousuke: AWizzArd: yes. and chunked seqs are more performant if the f IS +

18:43 hiredman: AWizzArd: I think the issue is when f is not cheap

18:43 Chousuke: AWizzArd: laziness has a per-item overhead. chunked laziness cuts that overhead down to 1/32

18:43 AWizzArd: if f is not cheap then pmap is great

18:43 if f is cheap it's still fast enough when map is fully lazy

18:43 Chousuke: no it's not if f is really cheap :)

18:43 if you're mapping lots of cheap operation the laziness overhead accumulates really quickly.

18:44 hiredman: but pmap still does extra work

18:44 Chousuke: operations*

18:44 hiredman: Chousuke: then lets make some strict versions of the sequence functions

18:44 AWizzArd: and what about this vmap or whatever it is called in the PAR branch?

18:44 hiredman: instead of this hybrid nonsense

18:45 Chousuke: AWizzArd: that automatically parallelises itself, taking advantage of a vector's underlying structure. it's fully strict.

18:45 hiredman: but that wouldn't be nice at all :)

18:45 AWizzArd: Chousuke: so, map can be fully lazy, and those people who want to map + can use vmap?

18:45 Chousuke: AWizzArd: but chunked map is not eager.

18:46 AWizzArd: it's still lazy. only 32 times less than the fully lazy one.

18:46 in SOME cases.

18:47 hiredman: Chousuke: it would be nicer than suddenly realizing that map is doing 32 times more work than you thought it was

18:47 dreish: AWizzArd: I think people want to use map the way it is.

18:47 Here's the old one: http://github.com/richhickey/clojure/blob/a9cb831fe714966e225a5297ef844513fe4a373a/src/clj/clojure/core.clj

18:47 AWizzArd: dreish: I am not sure, I think most people would like map to be lazy.

18:47 dreish: It is lazy.

18:47 Chousuke: hiredman: except due to laziness overhead, doing "32 times the work" will in many cases be cheaper than being fully lazy.

18:48 dreish: We've really got to stop doing this.

18:48 _ato: heh, it's a pity some magic can't measure the time the first element takes and if it's expensive compared to laziness overhead decide to not eagerly do the rest. But the timing would probably be expensive itself

18:48 AWizzArd: map could be lazy again, and on the homepage one could have a link to git, so that people who want the chunked map can check it out, name it map1 and be happy with it.

18:48 hiredman: Chousuke: but not all the cases, and there is no way to tell

18:49 Chousuke: if those 32 items are killing your performace you can mod your algorithm suitably :P

18:49 everyone else can just enjoy a faster map

18:49 and reduce.

18:49 AWizzArd: and this is not possible if map would be fully lazy?

18:49 Chousuke: AWizzArd: no, because laziness has overhead.

18:49 AWizzArd: modifying the algorithm?

18:49 i see

18:50 hiredman: Chousuke: or you can have a map and a map*, and depending if you want a lazy map or not you can pick

18:50 AWizzArd: why then stick with 32?

18:50 Chousuke: the purpose of the chunking optimisations was to allow people to use map even for cheap operations, where normal laziness overhead would kill performance and you'd have to write a loop.

18:50 AWizzArd: maybe map can do 65536 chunks in one step?

18:50 Chousuke: AWizzArd: because vectors are internally chunks of 32 items and it's a good number.

18:50 AWizzArd: why 32 and not 1, or 2 or 64 or 768?

18:51 Chousuke: as I said above: vectors :P

18:51 and I guess other clojure data structures too

18:52 hiredman: clojurebot: map?

18:52 clojurebot: map is *LAZY*

18:52 Chousuke: they're internally chunked and processing them a chunk at a time is a *lot* faster than thunking each item to achieve full laziness.

18:52 hiredman: clojurebot: forget map is *LAZY*

18:52 Chousuke: that will have to be fixed I guess :)

18:52 clojurebot: I forgot map is *LAZY*

18:52 AWizzArd: :(

18:52 Chousuke: clojurebot: map is lazy

18:52 clojurebot: 'Sea, mhuise.

18:52 dreish: AWizzArd: Seriously, are you having an actual problem with this, or just "if my f were expensive"?

18:52 hiredman: clojurebot: forget map is lazy

18:52 clojurebot: I forgot map is lazy

18:53 hiredman: clojurebot: map is <reply>map and the other sequence functions used to be lazy, but with the advent of chunked sequences, may or may not be lazy, consult your local ouija board

18:53 clojurebot: Ik begrijp

18:53 AWizzArd: dreish: I worry because I don't know if I have an actual problem with it.

18:54 dreish: AWizzArd: Well, that's a difficult problem to solve.

18:54 It's a lot easier to solve an actual problem in actual code than it is to solve the problem of being dissatisfied that rhickey chose one thing and not the other.

18:55 But as I keep pointing out, the old code is still out there, and still fine. You could defn map1 and use it in your projects.

18:55 Maybe it should be part of the core, or contrib at least. I don't know.

18:55 Chousuke: 2009-05-25 16:17 "rhickey: reduce+filter+map - 4x faster chunked" :P

18:55 that's when they were still in their own branch

18:55 rhickey_: I someone having an actual problem with map?

18:55 hiredman: Chousuke: I bet they would be even "faster" if we removed all laziness

18:55 rhickey_: is?

18:56 hiredman: so lets do that

18:56 AWizzArd: 2009-11-17 00:55 "AWizzArd: reduce+filter+map - 32x less lazy" :P

18:56 dreish: AWizzArd: How are you to know that non-chunked map wouldn't cause you actual performance problems? It most likely would, and those would be the more subtle ones because they would involve lots of little cases scattered all over the place instead of an expensive fn that would stick out in profiling.

18:56 Chousuke: hiredman: you can use a loop

18:56 AWizzArd: dreish: yes, can probably be solved somehow, it is just a new source of uncertainity

18:56 hiredman: Chousuke: you can use a loop, since you are willing to give up laziness

18:56 dreish: AWizzArd: Well, get out there and write some code and find out!

18:57 rhickey_: hiredman: no they wouldn't. The overhead for laziness was less than 10%, now 1/32 of that. You are unlikely to see any benefit and will find a ton of costs as you recalculate things or fully realize intermediate results

18:57 AWizzArd: dreish: i have a big enough code base

18:57 dreish: So why not profile it then?

18:57 Or benchmark it? Try it with chunks, and then without.

18:57 AWizzArd: dreish: how to try it without chunks?

18:58 rhickey_: map on a non-chunked seq is non-chunked

18:58 i.e. same as always

18:58 dreish: I'm sure there's a more elegant way, but I would copy and paste the relevant functions in core from the URL above.

18:58 notallama: protocols are supposed to be the same as multimethod dispatch with (fn [a & as] (class a)) as the dispatch function, yes?

18:58 AWizzArd: ,(chunked-seq? (range 10))

18:58 clojurebot: false

18:58 hiredman: rhickey_: sure, but now (nth x 2) maps f over the 0 to the 31st thing, instead of just 0 to 2

18:58 rhickey_: notallama: no, they don't use the hierarchy system

18:59 _ato: ,(chunked-seq? (seq (range 10)))

18:59 clojurebot: true

18:59 dreish: rhickey_: Is there an easy way to convert a chunked seq to a non-chunked seq? Something like (unchunk s)?

18:59 rhickey_: hiredman: there may be a need for a seq-1 which will dribble even chunked seqs as non-chunked when that matters

18:59 AWizzArd: ,(first (map pr (range 100)))

18:59 rhickey_: so, I am looking for use cases

18:59 clojurebot: 012345678910111213141516171819202122232425262728293031

18:59 AWizzArd: ,(first (map pr (seq (range 100))))

18:59 clojurebot: 012345678910111213141516171819202122232425262728293031

18:59 rhickey_: not theoretical problems

18:59 AWizzArd: _ato: didn't help :(

19:00 dreish: So far it's just vague worries, not even theoretical problems.

19:00 But I would think there might be cases where a well-placed seq-1 could help.

19:00 rhickey_: In thinking about this, I came to the conclusion that all we need is a seq1

19:00 AWizzArd: it's scary that something that you thought is guaranteed lazy suddenly isn't

19:00 rhickey_: anything following it would be non-chunked

19:01 dreish: AWizzArd: Why is that scary if you're writing function programs/

19:01 functional

19:02 hiredman: functional or not, it still burns cpu to run a pure function

19:02 dreish: And it burns CPU to cons atom by atom instead of chunk by chunk.

19:02 Prove that one is better than the other.

19:02 AWizzArd: well, with pmap i would expect this to happen, to some extent

19:03 rhickey_: yes, the main argument for laziness is to avoid fully realizing intermediate results

19:04 since the infrastructure of all lazy fns is still the same, its simply a matter of feeding then non-chunked seqs when you care - they are still fully lazy in that case

19:04 hiredman: dreish: sure, just map fib over a range, suddenly it takes a whole lot longer to complete

19:04 AWizzArd: rhickey_: it seems that (range 10) is not chunked

19:04 ,(chunked-seq? (range 10))

19:04 clojurebot: false

19:04 Chousuke: I guess a seq1 function would really solve this neatly. you could get full laziness when you really do care about it.

19:04 rhickey_: ah, fib, so, we are not talking about real programs ...

19:04 dreish: hiredman: So few of my programs involve mapping fib, though.

19:04 Chousuke: AWizzArd: the reason is it's not a seq :)

19:04 hiredman: rhickey_: pardon me

19:05 rhickey_: dreish asked for proof that one is better than the other

19:05 Chousuke: AWizzArd: as _ato pointed above.

19:05 dreish: In the GENERAL case.

19:05 hiredman: fib just happens to be an easy proof

19:05 rhickey_: I really do care about this, and would like to hear peoples real experiences with chunked seqs

19:05 AWizzArd: Chousuke: but *both* (range 10) and (seq (range 10)) let map behave in the same way, see above.

19:05 Chousuke: AWizzArd: because map calls seq

19:05 dreish: hiredman: As in, point to a big, real application and show how it performs with and without chunks.

19:05 michaeljaaka: _ato: how to get output from println, right now when I run scripts as standalone apps I can only get ouput via logger

19:06 AWizzArd: dreish: if this is not easy, how can one then know that the current implementation is better?

19:06 hiredman: dreish: do you have such proof?

19:06 I have tons of calls to map everywhere

19:06 dreish: No, I don't, I just think it's absurd to burn up this much time yakking about it.

19:06 If it's a real problem, show why it is.

19:06 _ato: michaeljaaka: err... println should just be going to stdout in a script unless you've redirected it

19:06 AWizzArd: Would it not take some full analyzes of real apps to see if the current map performs better?

19:06 hiredman: so do I have to hunt down ever call to see if there are chunked-seqs anywhere?

19:07 dreish: This is driving me nuts. I'm getting dinner.

19:07 Chousuke: hiredman: if we get this seq1 function you'd just need to add those to places where you really care about full laziness.

19:07 hiredman: Chousuke: sure

19:07 Chousuke: hiredman: which won't be most uses of map :P

19:08 rhickey_: hiredman: as I said, if after trying with chunked seqs you have problems, bring them up and we'll work out solutions

19:08 michaeljaaka: hmmm, when I type in script (println "Hello World") I can see it on output

19:09 but when I do that in a callback method of proxy object

19:09 rhickey_: chunked seqs have been in master for a while, and I haven't gotten any complaints

19:09 Chousuke: though seq1 looks ugly ;/ seq* would be neater, but I guess the 1 is kind of hinting at its purpose.

19:09 michaeljaaka: I can't see any output

19:10 _ato: michaeljaaka: strange. how about with (.println System/out "hello") in your callback?

19:10 AWizzArd: rhickey_: it is just that some people (like me) expect filter and map to be fully lazy. When doing Genetic Programming one could try to find the first f for which a good fitness value is found. Those f's could be running for days each.

19:11 If now someone is convinced that filter will stop immediately as soon a certain fitness value is met will wonder why is program was runing several many hours (or weeks).

19:11 Now that I am aware about that I would not use find-first anymore

19:11 rhickey_: AWizzArd: I understand the theoretical argument

19:11 AWizzArd: it is totally practical

19:12 only by accident i stumbled upon this

19:12 rhickey_: only if you have no way to control that

19:12 michaeljaaka: _ato: nothing is showing

19:12 _ato: dorun helped

19:12 AWizzArd: now i will use loop instead, but if i didn't find this out tonight I would probably have used find-first

19:12 michaeljaaka: _ato: dorun ( println "Hello there")

19:13 _ato: michaeljaaka: huh... I don't know what would cause that :/

19:13 rhickey_: AWizzArd: but switching your structure is completely unnecessary. filter and find-first are fully lazy when given a non-chunked seq, so all you need are the tools to give them one

19:13 AWizzArd: yes

19:14 qed: i think im getting dumber by the day -- i cannot figure out how to use loop... (loop [n (+ n 1)]

19:14 notallama: my stuff works with regular functions and multimethods, but not protocols. (extending clojure.lang.AFn). as far as i can tell, it should be the same, but i'm getting "Wrong number of args passed to: arrow$eval--114$fn--147$G--103".

19:14 _ato: qed: you need to use recur with loop

19:15 qed: something like (loop [n n] (recur (inc n)))

19:16 AWizzArd: rhickey_: it seems that map is making some non-chunked seqs chunked.

19:16 rhickey_: AWizzArd: it can't do that

19:17 qed: _ato: yeah, i have my clojure book out, ill figure it out, but thanks

19:17 AWizzArd: [10 20 30] is a non-chunked seq

19:17 ,(first (map pr [10 20 30])) ; will print 10

19:17 hiredman: that is a vector

19:17 clojurebot: 102030

19:17 hiredman: not a seq

19:17 and vectors produce chunked seqs, I believe

19:17 _ato: ,(chunked-seq? (seq [10 20 30]))

19:17 clojurebot: true

19:18 _ato: ,(seq? [1 2 3])

19:18 clojurebot: false

19:18 _ato: a vector is seqable (it can be turned into a seq) it's not a seq itself

19:18 AWizzArd: well, then my understanding of chunked-seq? is wrong

19:19 so, how do i make a seq (but non-chunked) out of a vector?

19:20 rhickey_: AWizzArd: that's what seq1 would be for

19:20 AWizzArd: ok, i understand

19:20 qed: (defn step-seq [result n] (if (= n 1) 1 (recur (conj result n) (step n)))) -- im trying to make (step n) the new value that the loop takes as it's input

19:22 _ato: qed: that code works for me if I define step as 'dec' and call with say n = 10

19:22 qed: what's the problem?

19:23 qed: wont dec just decrement 10..9..8..7, etc? I want to call a function on the new value of step n, every time i go through the loop

19:24 _ato: (defn step-seq [result n] (if (= n 1) 1 (recur (conj result (f n)) (step n)))) ?

19:24 where f is that function

19:24 ?

19:24 or you want to do it to the result of step n, in which case just let-bind the result of (step n)

19:29 qed: _ato: I just get 1 as my return

19:29 something seems broken..

19:30 _ato: oh right

19:30 that's because if returns 1

19:30 not results

19:30 qed: ahhhh

19:31 sweet -- thanks _ato

19:38 lisppaste8: rhickey pasted "seq1" at http://paste.lisp.org/display/90536

19:42 dnolen: rhickey: this example brings up another question, so it's now possible to write something analogous Java classes using pure Clojure (i.e. the more confusing bits about deftype & protocols :) ?

19:42 analogous to

19:43 rhickey_: deftype can do a particular subset of things - deriving and defining the methods of interfaces

19:43 it can't derive from classes, can't define members not in the interfaces

19:44 if that subset works for you (and it should in most non-interop scenarios), then use deftype, otherwise there is still gen-class

19:44 dnolen: rhickey_: ah, I got burned by that. Tried to derive from an interface and I had some of my own dummy fields.

19:47 rhickey_: you get fields a b c from (deftype Foo [a b c])

19:56 qed: (defn count-and-track [result n] (loop [cnt n size (count (step-seq [] n))] (if (= n 1) result (recur (conj result size) (dec cnt)))))

19:57 michaeljaaka: hi

19:57 I have (fn[o] (. o message "Hello") )

19:57 wchich returns function

19:57 Now I want the same with #() macro

19:57 (#(println %1 "Hello"))

19:57 doesn't work because it want to be evaluated

19:58 I want a reference to that function just like with fn[o] had

19:58 (fn[o] println o "Hello" )

19:58 should be

19:58 but what about # ?

19:59 dnolen: ,(do #(println "Hello"))

19:59 clojurebot: #<sandbox$eval__3860$fn__3862 sandbox$eval__3860$fn__3862@2a9403>

19:59 dnolen: michaeljaaka: just remove the surrounding parens

20:00 michaeljaaka: dnolen: thanks!!! :)

20:00 dnolen: np

20:01 arohner_: sigh. really:

20:01 * Implements a fast vector class without synchronized

20:01 * methods. Replaces java.util.Vector. (Synchronized methods tend to

20:01 * be slow.)

20:01 from the WEKA source

20:04 qed: best way to find the maximum value in an array?

20:04 maravillas: (ArrayList?)

20:04 qed: err sorry

20:04 a vector

20:05 arohner_: qed: I wrote a little utility function to do it

20:05 using reduce

20:06 qed: hmmm, how would you do that?

20:06 arohner_: lisppaste8: url

20:06 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

20:06 arohner pasted "untitled" at http://paste.lisp.org/display/90537

20:07 tomoj: if it's just numbers

20:07 ,(reduce max [1 2 3 4 5])

20:07 clojurebot: 5

20:07 qed: oh man, im getting dumber and dumber as the day goes on

20:08 arohner_: wow that's a lot prettier

20:08 find-max is some of my earliest clojure

20:09 tomoj: (apply max ..) works too but is slower, I wonder why

20:09 Chousuke: hm

20:09 arohner_: tomoj: apply is usually slower than the alternative

20:09 tomoj: yeah, but why?

20:09 the &more fn for max just reduces on the rest

20:10 arohner_: ~def apply

20:10 you have an extra var deref + a copy of the arguments

20:11 Chousuke: ,(let [a (vec (range 100000))] (time apply max a))

20:11 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: core$time

20:11 Chousuke: ...

20:11 ,(let [a (vec (range 100000))] (time (apply max a))=

20:11 clojurebot: EOF while reading

20:11 Chousuke: ,(let [a (vec (range 100000))] (time (apply max a)))

20:11 clojurebot: 99999

20:11 "Elapsed time: 109.589 msecs"

20:11 Chousuke: ,(let [a (vec (range 100000))] (time (reduce max a)))

20:11 clojurebot: 99999

20:11 "Elapsed time: 11.49 msecs"

20:12 Chousuke: ,(let [a (vec (range 100000))] (time (apply max a))) ; wonder if that was a fluke

20:12 clojurebot: 99999

20:12 "Elapsed time: 9.841 msecs"

20:12 arohner_: hah, we're warming up clojurebot's JVM

20:12 tomoj: it's consistently slower for me on (range 1000000)

20:13 Chousuke: ,(let [a (list* (range 100000))] (time (apply max a))); hum

20:13 clojurebot: 99999

20:13 "Elapsed time: 22.222 msecs"

20:13 Chousuke: ,(let [a (list* (range 100000))] (time (apply reduce a)))

20:13 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$reduce

20:13 Chousuke: ...

20:13 ,(let [a (list* (range 100000))] (time (reduce max a)))

20:13 clojurebot: 99999

20:13 "Elapsed time: 34.151 msecs"

20:14 tomoj: ~def spread

20:14 Chousuke: in any case, reducing over a vector should be faster than over a list

20:14 arohner_: on my box, they each take about 3 ms, with the reduce version about .1 ms faster on average

20:14 Chousuke: I guess the size is too small :P

20:15 tomoj: apply spreads the rest of the arg which looks linear

20:15 arohner_: Chousuke: why should reducing over a vector be faster?

20:15 michaeljaaka: hi

20:16 http://pastebin.com/d6d2f2670

20:16 I want to define something like this

20:16 but I get

20:16 http://pastebin.com/d4a04b69a

20:17 Chousuke: arohner_: it's chunked. :)

20:17 arohner_: Chousuke: ah, right

20:17 I was thinking in complexity, not implementation

20:18 Chousuke: hm, this is problematic :(

20:19 ngoc: Hi, where can I look for information about meta programming in Clojure? For example, how to list all functions inside a namespace?

20:19 Chousuke: I can't even construct a list of million items in my repl without running out of heap

20:19 building a vector is okay though.

20:19 _ato: ngoc: have a look at: http://richhickey.github.com/clojure-contrib/ns-utils-api.html

20:20 michaeljaaka: how to make that iface is visible in whole function body

20:20 _ato: ngoc: as well as: http://clojure.org/namespaces

20:21 Chousuke: michaeljaaka: you should use a bit more spaces :P

20:21 michaeljaaka: anyway, the iface argument passed to proxy is not evaluated

20:22 ie. it's just a symbol

20:22 in short: you can't do that. You need a macro :)

20:22 michaeljaaka: ugh

20:22 arohner_: michaeljaaka: you can write a macro that will do that though

20:22 ngoc: Thanks, is there a function to convert x_y_z.clj to x-y-z?

20:22 qed: why doesnt max-key work on a {}?

20:23 Chousuke: in general if you define new named things you should use a macro.

20:24 _ato: ,(apply max-key key {1 :a, 3 :b, 2 :c})

20:24 clojurebot: [3 :b]

20:24 Chousuke: (defmacro receiver [name iface mapping] `(new EchoReceiver ~name (init-proxy (proxy [~iface] []) ~mapping))) should do. though I can't quite tell what use an empty proxy is.

20:24 _ato: oh you mean on an empty map?

20:24 qed: what goes is max-key if you have to tell it how large the largest key should be?

20:24 nevermind

20:27 ngoc: I mean is there a function to convert a file name "x_y_z.clj" to a namespace name "x-y-z"?

20:29 qed: wow my code is ugly

20:30 it's a good thing project euler stipulates the "if it takes less than 1 minute it's an okay solution"

20:30 because otherwise id fail

20:31 _ato: ngoc: not as far as I know, but it's easy to do youself, just replace _ with - and chop off te .clj

20:32 arohner_: well obviously there's one somewhere, because the compiler uses it

20:32 _ato: oh and change / to .

20:32 arohner_: whether it's accessible to users is a different question

20:35 ngoc: I would grep through the src

20:35 try looking for the error clojure throws when the file doesn't match the namespace

20:35 _ato: ,(clojure.lang.RT/munge "a-b-c!")

20:35 clojurebot: java.lang.IllegalArgumentException: No matching method: munge

20:36 _ato: ,(clojure.lang.Compiler/munge "a-b-c!")

20:36 clojurebot: "a_b_c_BANG_"

20:36 _ato: hmm

20:37 dnolen: erg *** slime

20:37 arohner_: aha!

20:37 ~def root-resource

20:38 currently marked private, but at least you can copy it

20:39 _ato: ,(@#'clojure.core/root-resource 'baz.foo-bar)

20:39 clojurebot: "/baz/foo_bar"

20:40 qed: Could someone take a look at my code and see if they can optimize it? http://devinwalters.com/posts/21

20:40 my result runs very slow

20:40 _ato: I think ngic wanted the other way around, but yeah, it is just replace _ with - and / with .

20:40 s/ngic/ngoc/

20:41 rlb: Any suggestions regarding the best "clojure" way to handle input from /dev/input/event? with a timeout? I can already read the events via a DataInputStream, but I'd like to abstract it as a stream of events where you can ask for the next event with a timeout. I could probably work something out with send-off and await-for...

20:42 arohner_: rlb: you could make a lazy seq, or use futures

20:42 ,(doc future)

20:42 clojurebot: "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block."

20:42 rlb: arohner_: will that work with a hardware blocking call?

20:42 _ato: rlb: if I remember correctly java's IO library is broken, you can't use read with a timeout on a file, you have to poll :(

20:42 rlb: i.e. (.read stream) may block indefinitely.

20:42 _ato: it's really annoying

20:42 arohner_: oh,wow

20:42 was not aware of that

20:42 rlb: arohner_: I was assuming that via send-off I could just let a thread handle getting the next event.

20:43 michaeljaaka: ,(doc let)

20:43 clojurebot: "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein."

20:43 arohner_: futures run in the background

20:43 _ato: you can do it on sockets using nio selectors but I couldn't figure out a way to do it with files

20:43 arohner_: they use the agent pool

20:43 Chousuke: isn't that why they're working on NIO2 :/

20:43 rlb: arohner_: send-off doesn't use the pool, right?

20:43 arohner_: that sounds right, but I'm not 100% certain

20:44 rlb: (though I may do that differently -- I'm not that keen on launching a thread for each event -- may just have a thread that fills a queue...)

20:44 Anyway, just wanted to make sure there wasn't something obvious I was overlooking.

20:45 (This is just a toy anyway -- managing a powermate, and looking for double-clicks...

20:45 )

20:46 arohner_: rlb: IIRC, there's a java lib for interacting with unix somewhere

20:47 hrm. looks like there's a bunch of them

20:47 anyways, there are several libs out there for making java & posix play nicer

20:47 ngoc: _ato: thanks a lot

20:47 arohner_: that might help

20:51 weissj: anyone know how i can make an ordered map so that items stay in the order they're added?

20:52 rhickey_: weissj: Clojure doesn't come with a data structure with those properties

20:52 chouser: weissj: use a sorted-map and include a globally incrementing counter in the key?

20:53 qed: anyone here know if there's a plugin or something out there that will let me do easy clojure syntax hilighting in rails?

20:53 chouser: I guess finger trees ought to be able to do that.

20:54 rhickey_: chouser: that depends on the meaning of "stay in the order they're added"

20:54 weissj: what are finger trees

20:55 chouser: weissj: they don't exist.

20:55 weissj: i'm not too concerned about keys that are added more than once going to the end of the list vs staying in place

20:55 michaeljaaka: hi, I have another challange

20:55 I have http://pastebin.com/d1e94de3c

20:55 I want to modify code so use would look like this

20:56 funkenblatt: i guess in a functional language, the idea of "order of insertion" isn't supposed to matter

20:56 michaeljaaka: http://pastebin.com/d4d1f7a3c

20:56 I know that there is a memfn

20:56 weissj: chouser: java has LinkedHashMap, is there any way to make that the backing store for a map?

20:56 jensli: weissj, maybe you could create a java LinkedHashMap,

20:57 michaeljaaka: which do what I want but don't know exactly how to use it

20:57 jensli: Oh, you alleady knew about that one.

20:58 weissj: yeah, that's sort of what i'm trying to reproduce here. i have a map of tests to test results, i want the order the tests are run to be preserved

20:58 there's lots of ways to do this, but i'm trying to stick with built-in stuff as much as possible

20:58 srader: what about array-map?

20:59 weissj: ,(doc array-map)

20:59 clojurebot: "([] [& keyvals]); Constructs an array-map."

20:59 weissj: not very helpful doc :)

21:00 rhickey_: http://clojure.org/data_structures describes ArrayMaps

21:02 weissj: rhickey_ ok I suppose what i'm using is a "very small map", probably never more than a few hundred items. linear lookup is probably not going to be noticably slow

21:03 or maybe i'll just put a counter in the key :)

21:08 michaeljaaka: what is wrong with that?

21:08 (import 'java.util.HashMap)

21:08 (def a (memfn put ))

21:08 (a (java.util.HashMap.) "32")

21:11 rhickey_: (def a (memfn put k v))

21:11 michaeljaaka: ok, that is HashMap, thanks

21:11 _ato: ,(macroexpand-1 '(memfn put k v))

21:11 clojurebot: (clojure.core/fn [target__5709__auto__ k v] (. target__5709__auto__ (put k v)))

21:12 rhickey_: #(.put ht k v) more idiomatic than memfn

21:12 memfn predates #()

21:14 weissj: how does one create a comparator to use with sorted-map-by? proxy?

21:15 or is it just a plain ol function? i am not sure if it's wanting a java Comparator or what

21:15 chouser: weissj: just return a positive, negative, or zero

21:15 plain ol clojure fns are Comparators. :-)

21:16 weissj: chouser: oh, never occurred tome

21:16 i guess they might as well be.

21:16 chouser: ,(instance? java.util.Comparator #())

21:16 clojurebot: true

21:17 weissj: a fn that doesn't take 2 argsdoesnt' seem like a comparator, but why not eh

21:17 chouser: weissj: yeah, not very useful.

21:17 _ato: ,(.compare #() 1 2)

21:17 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--3955$fn

21:18 _ato: ,(.compare #(- %1 %2) 1 2)

21:18 clojurebot: -1

21:18 _ato: hm :)

21:26 michaeljaaka: any idea how to fix that macro ? http://pastebin.com/d6be08903

21:30 _ato: put parens around dorun

21:30 actually.. wait.. what's the dorun even for?

21:31 michaeljaaka: it can be skiped

21:31 _ato: oh does EchoSender.message() return a lazyseq

21:32 michaeljaaka: what's the problem that needs fixing?

21:32 oh I ssee

21:32 michaeljaaka: this '(message "Hello World") must be expandend in macro to (. o message "Hello World")

21:33 _ato: you need to move some tildes

21:33 hang on a tick

21:36 michaeljaaka: http://gist.github.com/236571

21:36 let me know if you don't see why that worked

21:39 michaeljaaka: _ato: works great!!!

21:39 _ato: thanks a lot! exactly that I needed

21:40 _ato: these macros are very powerful

21:41 _ato: I see why it works

21:41 _ato: you may only explain why quote for (message "Hello") is not needed

21:41 _ato: ah

21:42 because arguments to macros aren't evaluated, so they don't need to be quoted

21:42 michaeljaaka: ok :)

21:42 and what about @ what that mean?

21:43 &args in macrodef and in its body i can see ~@args

21:43 _ato: ah, ~@ is different to @

21:43 ~@ means splicing unquote

21:43 clojurebot: Gabh mo leithscéal?

21:43 _ato: so

21:44 suppose v is [1 2 3]

21:44 then `(foo ~v) => (foo [1 2 3])

21:44 while `(foo ~@v) => (foo 1 2 3)

21:44 michaeljaaka: I see

21:44 super

21:44 :D

21:45 ok, for today it is enough, thanks again everyone!

21:45 _ato: so yeah you could do: (. o# ~@ufun) instead of (. o# ~(first ufun) ~(second ufun))

21:46 michaeljaaka: I'm using IRC, google groups for the first time to learn new things, and your community is answome

21:47 _ato: :)

21:47 michaeljaaka: _ato: will it work even for method with many arguments?

21:48 I know that instead of second ther eshould be rest

21:50 _ato: should do

21:50 should expand to (. o f a b c)

21:52 michaeljaaka: ok, thanks again and bye!

21:53 qed: I have some slowwww code I'd like to improve. Would anyone mind taking a look at : http://pastie.org/private/k530tmjmfozxvarkzriehw and possibly giving me some suggestions?

21:53 Right now it runs in about 30sec, but that seems really meh, to me -- without changing my approach completely, how could I improve performance?

21:58 arohner_: qed: you could use transients

21:58 qed: arohner_: wuzzat?

21:58 arohner_: http://clojure.org/transients

21:58 nm, maps aren't supported yet

21:59 chouser: ,(transient {})

21:59 clojurebot: #<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@1d0fe80>

21:59 qed: ah, interesting

21:59 arohner_: oh that's right, cgrand fixed them

21:59 well then, the docs are out of date

21:59 :-)

22:01 qed: how does clojure.org do its syntax hilighting?

22:01 im looking for a good way to do syntax hilighting in rails

22:01 arohner_: where do you see syntax highlighting on clojure.org?

22:01 qed: cgrand's code is be-ay-yootiful

22:01 chouser: clojure.org uses javascript something

22:02 qed: arohner_: on the transient page you linked?

22:02 arohner_: huh, I don't

22:02 qed: not even under example?

22:02 really?

22:02 what browser are you using?

22:02 arohner_: chrome on OSX

22:02 though it says the page has been loading since I linked it

22:02 qed: hm weird

22:02 im using safari

22:02 arohner_: chrome and my internet connection are flaky sometimes

22:03 qed: maybe ill just write up a clojure theme for one of the existing hilighting enginers

22:03 engines

22:33 arohner_: is there existing support for making a seq out of a java.util.Enumeration?

22:33 chouser: (doc enumeration-seq)

22:33 clojurebot: "([e]); Returns a seq on a java.util.Enumeration"

22:33 arohner_: chouser: thanks!

22:37 qed: i have some big list of integers, and i have an integer that may or may not be in the list

22:37 what is the fastest way to find out if the integer i have in my hand is inside the list?

22:37 arohner_: ,(some #{3} [1 2 3 4 5])

22:37 clojurebot: 3

22:37 qed: arohner_: nice! thanks man

22:37 arohner_: ,(some #{10} [1 2 3 4 5])

22:37 clojurebot: nil

22:38 qed: that works on lists and vectors and maps?

22:38 or just lists and vectors?

22:38 ohpauleez: You can also use .contains

22:38 some will return the first true value it finds

22:38 (just asked this today!)

22:38 qed: :)

22:39 ohpauleez: contains? will work on keys and indexes

22:39 arohner_: chouser: do you know why seq supports iterable, but not enumeration?

22:39 ohpauleez: (contains? [1 2 3 4 5] 5) => false

22:39 (some #{5} [1 2 3 4 5]) => 5

22:40 chouser: arohner_: I'd have to dig a bit -- I believe seq used to support enumaration but that there was some kind of issue with it, so it was backed off to a separate function.

22:40 leafw: arohner_: enumeration? as in java.util.Enumeration? That is an outdated iterator type with poor semantics.

22:40 arohner_: leafw: yes, I'm aware it sucks. I'm forced to use it for inter-op :-(

22:41 leafw: arohner_: old libs ...

22:41 arohner_: WEKA still uses it in current versions

22:41 leafw: I've been using weka recently

22:41 it's quite bizarre, wehn it comes to write java classes that use its internals.

22:42 lots of statics and stateful procedural constructs.

22:42 arohner_: yeah, It's not fun

22:42 leafw: I isolated the damage in a single class file.

22:42 best luck :)

22:43 arohner_: thanks :-)

23:03 qed: wow

23:04 i think i actually learned some clojure today

23:04 lol -- it took me quite a while to understand that whole loop/recur form for different situations

23:05 kind of embaressing really

23:05 ohpauleez: but once you get it, it makes total sense

23:05 congrats on the progress

23:06 qed: thanks man -- it's a good community we have here

23:06 lots of eager minds

23:06 ohpauleez: I started working on project to port some of SQLAlchemy's features over to a new project build on contrib.sql and clj-crud

23:06 qed: cool!

23:07 ohpauleez: built**

23:07 qed: i haven't 100% decided on what i'd like to build in clojure

23:07 once there is support for protocols, i was thinking about building sort of a collaborative coding platform

23:08 technomancy: qed: the Emacs implementation for Google Wave uses Clojure on the server-side

23:08 qed: think Github meets irc, meets pair programming in a shared buffer

23:08 technomancy: damn you technomancy !

23:08 technomancy: mwahaaha

23:08 qed: always one step ahead of me phil

23:08 technomancy: well it's not finished yet

23:08 still a chance to help out! =)

23:09 ohpauleez: haha, that's awesome

23:09 qed: technomancy: i know you have the basics going on there, but do you see what i was driving at?

23:09 ohpauleez: The other project I had was to create some sort of sandbox

23:09 qed: like you login to github, and you can edit code, in real time, with other committers, on the spot

23:10 technomancy: qed: so a shared buffer but with controls exposed for committing; viewing history, etc?

23:10 ohpauleez: qed: screen + emacs?

23:10 qed: ohpauleez: yeah like that, technomancy yes

23:10 technomancy: I've been thinking of adding that kind of functionality to rudel: http://rudel.sf.net

23:10 qed: just imagine pair programming in irc, like as a fixture of irc

23:10 ohpauleez: rock

23:11 technomancy: qed: that's a big problem though; making an editor that isn't painfully restricted is a huge task in and of itself without even considering the server-side

23:11 qed: like i have my irc window up right now, but what if my drawer was a context-based text buffer, that showed people coding while i was talking in irc

23:11 technomancy: yeah, no doubt

23:11 it's still a great idea though

23:12 technomancy: there is textjure, but I have no idea how complete that is or even if it would be any good as a general-purpose editor

23:12 qed: rudel really has me psyched to do some coding with other people -- i was it wasnt so formal though

23:12 it'd be nice to just drop in on some project, and say "hi, im just going to watch, and might consider adding a few lines"

23:12 technomancy: that's a very interesting idea

23:12 from a social angle

23:12 qed: yeah, i feel like it would really facilitate the development of some projects

23:12 technomancy: a collaborative-by-default project.

23:12 qed: like "hey dude, im hanging out over in "some obscure repo" right now"

23:13 "if you wanan talk, come over and code a little bit"

23:13 we all basically do it already

23:13 people using pastie left and right

23:14 explaining concepts to eachother, sharing ideas

23:14 one of the most annoying parts of reading other people's code is that you weren't there, but you could conceivably sit down and watch a project from the sidelines, and know how it all fits together"

23:15 </rant>

23:15 technomancy: you could set up a headless Emacs session with Rudel to subscribe to all buffers on a server and auto-save and auto-commit on an interval to get a persistent session going on.

23:15 arohner_: qed: I suspect you wouldn't get that from watching rhickey code

23:16 honestly, I suspect part of the reason clojure has terrible error messages is that rhickey makes so few mistakes he doesn't notice them

23:16 technomancy: hah! that explains everything.

23:17 qed: the real reason the error messages are so bad is that they

23:17 they're actually a cruel joke about error messages

23:18 _ato: I like it, would be interesting

23:18 qed: i didnt want to finish that thought, but when you accidentally hit enter, you're screwed

23:18 _ato: i checked out technomancy's rudel the other night, and then you got me on ethaedit, and i really felt like i got way more out of that

23:19 than just sitting in irc reading contextually isolated lines of information

23:19 you learn faster in that environment

23:21 djork: I have found the horrible stack traces and errors to be pretty easy to cope with after a little time

23:21 null reference my eye

23:22 qed: also, when you think about it, one major problem with irc is that you cannot easily discern many people's lines at once, so there is all of this hate for "flooding", like > 3 lines and you're "flooding"

23:22 all that does is make people less apt to praticipate, or if they do, they go through pastie, which is contextually separate from the discussion, which is a totally uneeded context switch

23:22 im rambling, aren't i?

23:23 _ato: hehe, frankly if Clojure's error messages just said "You suck!" with a line number they'd work about as effectively as they do now a lot of the time.. maybe even more so as you wouldn't have to go hunting through the nested exceptions to find the line number that actually matters :p

23:23 technomancy: qed: I feel that way whenever I use an IRC client that doesn't color nicknames

23:24 qed: i use uncolored nicknames in irssi :X

23:24 technomancy: _ato: maybe that will be an option in swank-clojure 2.0 =)

23:24 leafw: clj contrib had a nice error reporting system, but I can't find anymore. It removed all the non-relevant parts of the stack trace and formated the rest nicely.

23:28 * qed documents some error messages

23:35 jkkramer: i'm attempting to use clojure-mode's M-x swank-clojure-project and when it asks me for the project root, it doesn't do anything when i press return. this is in Aquamacs. M-x slime works fine. any ideas?

23:35 _ato: jkkramer: do you have all the jars you need (including clojure.jar) in project/lib ?

23:35 jkkramer: i should say, when i press return, it actually prints a newline rather than doing anything

23:36 yes

23:36 the slime repl works as expected

23:37 _ato: I dunno then :/

23:37 anything in the *Messages* buffer?

23:38 technomancy: jkkramer: known bug with an older version; try updating

23:39 jkkramer: i thought i did, to 1.6...hmm

23:39 qed: how do you get the fancy slime startup?

23:39 technomancy: or enabling ido-mode; even better

23:39 jkkramer: oh, do i need to rerun clojure-install?

23:39 technomancy: jkkramer: the best way to install is through elpa: http://tromey.com/elpa/install.html

23:40 qed: ah yes, (setq slime-startup-animation on)

23:45 slyrus: jkkramer: bah. you shouldn't need some fancy auto-installer just to get slime up and running. but you do need to be aware that swank-clojure doesn't work with slime's HEAD.

23:45 Draggor: I have a file with a bunch of declare statements, yet when I load later files that would use vars/functions that are declared, clojure claims they are unbound. Why is that?

23:45 They're all in the same package

23:45 * slyrus is a control freak and likes others to keep their dirty mitts off his .emacs (and source code repos for that matter)

23:45 Draggor: err, namespace

23:45 jkkramer: i installed clojure-mode 1.5 through elpa a while back. i tried to upgrade to 1.6 but now i think my setup is fubar'd. is there an easy way to clear clojure stuff out and start fresh?

23:46 technomancy: don't resist elpa; it's going to be part of emacs 24

23:46 jkkramer: just -rm -rf .emacs.d/elpa/clojure*

23:46 slyrus: just because it will be part of it doesn't mean I have to use it...

23:47 technomancy: ok, but I don't have to support you then. =)

23:47 * slyrus never liked asdf-install either, FWIW

23:48 slyrus: fair enough. but when something is legitimately (huh?) broken don't say "use the elpa version" either and we'll have a deal.

23:48 arohner_: Draggor: circular loads?

23:48 technomancy: dear

23:48 *deal

23:49 Draggor: arohner_: nope, one clj file that loads the others

23:49 technomancy: I just can't merge the latest swank-clojure to master without breaking clojure-install since the latter works off master

23:49 lack of foresight

23:49 hiredman: Draggor: declared how?

23:50 lgas: is there an equivalent of the partition function that will not drop any odd remaining values? e.g. (partition 2 [1 2 3]) returns ((1 2)) but I would like ((1 2) (3))?

23:50 hiredman: lisppaste8: url?

23:50 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

23:50 slyrus: technomancy: you lost me there. are you saying you have a swank-clojure that works with the current SLIME head?

23:50 technomancy: no, but it fixes the problem jkkramer saw

23:52 Draggor: hiredman: I have three declares with a list of names afterwards in a file

23:53 jkkramer: ok, cleared out everything and reinstalled 1.6 clojure-mode and swank-clojure. still seeing the return printing when i do M-x swank-clojure-project

23:53 M-x slime works

23:53 technomancy: jkkramer: maybe turn on M-x ido-mode and see if the problem persists

23:53 if it does it's something else that I haven't seen before

23:53 hiredman: Draggor: and how are you using the declared names?

23:54 Draggor: hiredman: function calls and variables. (declare func1) in the declare file. Then in another, later loaded file I might have a form (func1 some-arg)

23:54 jkkramer: awesome, that worked. thanks!

23:54 what's ido-mode, btw?

23:54 technomancy: jkkramer: ido ist awesome

23:55 it's like magic press-fewer-keys mode

23:55 hiredman: Draggor: just (func1 some-arg)?

23:55 because that's not going to work

23:55 jkkramer: sounds good

23:56 technomancy: "i[nteractively] do [things]"

23:56 _ato: jkkramer: it does fuzzy searching on find-file and buffer switching and such

23:56 technomancy: http://www.vimeo.com/1013263

23:56 hiredman: (func1 some-arg) is going to try and get the function in the var named func1

23:57 jkkramer: thanks for your work on clojure-mode, technomancy. makes it easier for folks like me that want to focus on coding and less on messing with tools

23:57 hiredman: and declare just creates an empty var, if I recall

23:57 Draggor: hiredman: Also trying to use it in a map: {"func1", func1}

23:57 technomancy: jkkramer: glad it's helpful.

23:57 jkkramer: will check that vid out

23:58 technomancy: jkkramer: were you seeing RET-inserts-newline behaviour in elpa's version of swank-clojure? that's odd.

23:58 hiredman: Draggor: unless you have the name inside a function body (the value of the var won't be looked up until you execute the function) then declare is not going to help you

23:58 technomancy: or was it just clojure-mode that you got from elpa?

23:58 cataska: the vid is made by the author of Programming Clojure

23:59 jkkramer: after clearing things out, i marked clojure-mode and swank-clojure for elpa installation

23:59 Draggor: hiredman: Ahh, so could I cheat and just have my map definition in a closure that gets executed upon load?

23:59 technomancy: jkkramer: I'm guessing an old version of swank-clojure may have stuck around; perhaps it was loading out of ~/src/swank-clojure?

23:59 hiredman: Draggor: still not going to help, unless the things you are declare are actually defined before you execute the fn

Logging service provided by n01se.net