2009-11-16
| 00: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 |
| 00:08 | tomoj | solussd: what are you using to highlight clojure code? |
| 00:09 | solussd | "SyntaxHighlighter Evolved" for wordpress. It isn't perfect, but you can easily edit the "brushes" for a language's syntax |
| 00:10 | tomoj | thanks |
| 00:10 | tomoj | just installed wordpress for the first time the other day |
| 00: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. |
| 00:13 | tomoj | for now I am just going to embed gists I think |
| 00:14 | solussd | You can make the plugin changes directly from the wordpress 'admin' screens (click the modify link next to the plugin). |
| 00:14 | solussd | ok- If you do decide to install the plugin, you can do it right from wordpress's admin screens using the plugin installer. |
| 00:18 | duncanm | technomancy: i just installed slime via elpa, and i'm getting a FileNotFoundException |
| 00:18 | duncanm | 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) |
| 00:19 | defn | why is (if test then else?) |
| 00:19 | defn | not in the api documentation on clojure.org? |
| 00:20 | arbscht | duncanm: did you add (clojure-slime-config ...) to your init file as instructed? |
| 00:21 | somnium | defn: http://clojure.org/special_forms#toc2 |
| 00:22 | somnium | 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 |
| 00:24 | defn | somnium: i know about that page -- but the special forms are completely missing from the API link |
| 00:24 | defn | which seems wrong to me, but *shrug* |
| 00:24 | defn | 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 |
| 00:25 | duncanm | arbscht: where are the instructions? |
| 00:26 | arbscht | duncanm: at the end of the clojure-install procedure |
| 00:26 | somnium | arbscht: I think that configuration step isn't necessary with the just released version |
| 00:26 | somnium | clojure-install says its deprecated now when I tried to run it |
| 00:26 | arbscht | oh? |
| 00:26 | arbscht | I see |
| 00:26 | somnium | new version just up on elpa |
| 00:27 | duncanm | somnium: that's nice |
| 00:29 | maravillas | solussd: i added a comment recently regarding that clojure brush |
| 00:29 | maravillas | need to tweak a couple of the regexes to highlight keywords properly |
| 00:30 | solussd | maravillas- cool, do you have the tweak? I'll try it now. :) |
| 00:30 | maravillas | and unfortunately the tool's getKeywords method doesn't provide a way to specify "keyword" boundaries |
| 00:31 | maravillas | { regex: /:[a-z][A-Za-z0-9_\-]*/g, ... |
| 00:31 | maravillas | only difference is the \- in the pattern |
| 00:36 | solussd | thanks |
| 00:36 | maravillas | no problem |
| 00:36 | _ato | ,:+-*/.<>=!?$%_&~^:@ |
| 00:36 | clojurebot | :+-*/.<>=!?$ |
| 00:36 | maravillas | heh |
| 00:36 | maravillas | well then |
| 00:36 | maravillas | guess there's more work to do |
| 00:36 | _ato | ,:+-*/.<>=!?$_&~^:@ |
| 00:36 | clojurebot | :+-*/.<>=!?$_& |
| 00:36 | _ato | ,:+-*/.<>=!?$_&^: |
| 00:36 | clojurebot | :+-*/.<>=!?$_& |
| 00:37 | _ato | hehe |
| 00:37 | maravillas | ah yes, looks like the question mark at least is applicable to you, solussd :) |
| 00:38 | solussd | I love being able to use a question mark and exclamation points. |
| 00:39 | solussd | even better, I like using dashes in symbol names. this-is-much-more-readable thanTryingToReadStupidCamelCase |
| 00:39 | maravillas | of course they seem to be valid, but i wonder how often people use anything other than alphanumerics and dashes in keywords? |
| 00:39 | solussd | ... and hitting the shift key is for suckers.. |
| 00:40 | solussd | question marks are good for predicates |
| 00:40 | solussd | e.g. (if alive? (something) (something-else)) |
| 00:40 | _ato | like {:alive? true, :name "Rupert"} |
| 00:40 | maravillas | sure, but i mean keywords |
| 00:40 | _ato | ha, we picked the same example |
| 00:41 | maravillas | well, i'll concede question marks, i guess |
| 00:41 | duncanm | maravillas: having ! in identifiers is common in other lisps too |
| 00:42 | duncanm | things like initialize! |
| 00:42 | maravillas | i mean only keywords |
| 00:42 | duncanm | ruby copied that into its libraries, afaik |
| 00:42 | duncanm | maravillas: why does it matter anyhow? |
| 00:42 | maravillas | it doesn't |
| 00:42 | maravillas | i'm just curious :) |
| 00:43 | duncanm | in CLOS, i think there's a style of using <Point> to notate a class |
| 00:43 | duncanm | $foo is often used to refer to fluid variables |
| 00:43 | maravillas | no, i get all that |
| 00:43 | maravillas | i mean specifically clojure keywords |
| 00:43 | maravillas | meaning, for example, :initialize! |
| 00:44 | solussd | I use :alive? in my highlife program. :) |
| 00:44 | _ato | I could see :+ :< :& etc being used in the context of something like {:operation :+} |
| 00: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) |
| 00:45 | maravillas | ah yes, good point |
| 00:47 | maravillas | what were you considering? |
| 00:48 | duncanm | ah, "The read table is currently not accessible to user programs." -- so no user-defined reader macros for now ;-P |
| 00:48 | duncanm | having |/home/duncan/foo| ought to be pretty handy |
| 00:49 | duncanm | or maybe #|/foo/bar| |
| 00:49 | duncanm | i work on Windows during the day, so having support for DOS-style paths would be great |
| 00:49 | duncanm | #|C:\Program Files| |
| 00: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 ? |
| 00:51 | chouser | [most] urls are already valid symbols |
| 00:51 | chouser | 'http://foo.bar.baz/bing/bang.html |
| 00:51 | chouser | ,'http://foo.bar.baz/bing/bang.html |
| 00:51 | clojurebot | http://foo.bar.baz/bing/bang.html |
| 00:52 | duncanm | chouser: i don't get your point |
| 00:53 | duncanm | maybe it's not worthwhile to add more literal syntax, (File. "/foo/bar") is not *that* much longer |
| 00:53 | chouser | well -- what were you going to use literal syntax for URLs to do? |
| 00:53 | _ato | jkkramer: you can't, you'll have to call persistent on it |
| 00:53 | jkkramer | :( |
| 00:54 | jkkramer | there's a commit saying TransientHashSet was implemented, but seems like only conj! and disj! work, not get or nth. those work for TransientVector |
| 00: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 |
| 00:56 | tomoj | what do you expect nth to do on sets? |
| 00:56 | _ato | mmm, HashSets are HashMaps underneath and TransientHashMap doesn't support nth either |
| 00:56 | duncanm | twbray: did you restart your phone? maybe you need to soft reboot it |
| 00:57 | twbray | duncanm: several times |
| 00:57 | chouser | duncanm: \ is already reversed. / is the right way to separate paths. ;-) |
| 00:57 | _ato | ah yeah nth doesn't work on a set at all |
| 00:57 | duncanm | twbray: did you jsut turn it on and off? or did you do the red button + home key thing? |
| 00: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 |
| 00: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 :( |
| 00:58 | jkkramer | was groping around for something like first or nth or something |
| 00:58 | duncanm | oh |
| 00:59 | duncanm | twbray: i have a G1 from T-Mobile, the update worked for me fine, sorry. |
| 00:59 | twbray | duncanm: Yeah, problem seems specific to the Ion AKA Google I/O devie |
| 01: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 |
| 01:48 | hoeck1 | mikem: do |
| 01:48 | hoeck1 | ,(do 'foo 'bar) |
| 01:48 | clojurebot | bar |
| 01:48 | mikem | hoeck1: ah, great, thanks |
| 01:49 | hoeck1 | mikem: np :) |
| 02:51 | hiredman | ,(apply conj (ring-buffer 10 [] 0) (range 1000)) |
| 02:51 | clojurebot | #<sandbox$ring_buffer$reify__3709 [990 991 992 993 994 995 996 997 998 999 989]> |
| 03: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? |
| 03:58 | hiredman | use conj |
| 03:58 | mikem | by "append" i mean "return a new vector that's the same as a with item appended" of course |
| 03:58 | mikem | hiredman: ah yes, conj. Thanks |
| 04:46 | Licenser | morning everyone |
| 04:51 | AWizzArd | Moin Licenser |
| 04:52 | Licenser | How are things going in the clojure worlds? |
| 04:52 | yason_ | Licenser: almost purely functional, thank you for asking |
| 04:53 | Licenser | glad to hear that :) |
| 05:23 | Licenser | 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 |
| 05:24 | _ato | I'd call it with-session |
| 05:25 | Licenser | thanks that was what I went with in the first place too |
| 05:25 | _ato | do-stuff tends to make me think of doto, doseq, dotimes etc. Things that change the code structure |
| 05:27 | Chousuke | generally do is used to imply that the thing is used for side-effects. |
| 05:28 | Chousuke | presumably running commands over ssh is rather side-effecty, but with-session is idiomatic for a macro that creates a context. |
| 06:35 | Drakeson | how can I interrupt a slime repl? C-c C-c does not seem to work. |
| 06:36 | _ato | C-c C-b |
| 06:36 | _ato | doesn't always work though |
| 06:40 | Licenser | sorry for the delay and thanks for the input I'll stay with with-session then |
| 06:43 | Licenser | hmm exec, scp-put, scp-get something else that might be important? |
| 06: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 |
| 06:54 | Licenser | good idea |
| 06:54 | Licenser | lets figure out how that works :P |
| 07:19 | Licenser | hrm jsch sems not tu support that :/ |
| 07:19 | _ato | wait... jsch has builtin scp support? gah.. I did it myself |
| 07: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' |
| 07:21 | _ato | Licenser: http://blogs.sun.com/janp/entry/how_the_scp_protocol_works |
| 07:26 | Licenser | _ato: it has a very neat sftp support |
| 07:26 | Licenser | not scp directly |
| 07:28 | _ato | ah right |
| 07: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 |
| 07:30 | Licenser | then again a good scp library for clojoure would be cool I guess |
| 07:30 | Licenser | since sftp does not seem to copy directories :/ |
| 07:32 | _ato | there must be a way to do it somehow as the sftp command supports it |
| 07:33 | _ato | maybe JSch just doesn't implement it :/ |
| 07:33 | _ato | oh well :) |
| 07:33 | Licenser | _ato: might not be implemented in jsch, |
| 07:33 | Licenser | well or ti does but does not document it :P with couldn't be surprising |
| 08:31 | Licenser | hmm apply does not work with special forms? o.O |
| 08:33 | chouser | Licenser: I don't see how it could. what are you trying to do? |
| 08:35 | Licenser | just tried to use (apply . object method arglist) |
| 08:36 | chouser | ah, yes. |
| 08:36 | Licenser | which isn't working too well :P |
| 08: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. |
| 08:37 | Licenser | then again I am horrible with amcros |
| 08:37 | Licenser | method is not something to be evaluated I know the method name |
| 08:38 | Licenser | https://gist.github.com/a6e903ef4c7998d82d34 <- that is what I'm trying to do :P mostly at least |
| 08:39 | yason | Licenser: would memfn help? |
| 08:40 | chouser | that's a lot of code for a macro. |
| 08:40 | chouser | memfn hardly ever helps -- you can just use #(something) instead |
| 08:40 | Licenser | hmm chouser I think you're right |
| 08:43 | chouser | it's a macro so you can capture 'session ? |
| 08:45 | Licenser | (with-session "user" "pass" "host" 22 (do-sftp (:put "D:/test/1.txt" "/tmp") (:get "/tmp/1.txt" "D:/"))) |
| 08:45 | _ato | Licenser: might be better to use a binding instead and just use a regular function for do-sftp |
| 08:46 | _ato | oh wait... you want a list |
| 08:46 | Licenser | so a) I can fetch session and b) to not have to pass nice () stuff instead of ugly '() stuff |
| 08:46 | _ato | hmm |
| 08:47 | chouser | would you find [:get "/tmp/1.txt" "D:/"] acceptable? |
| 08:47 | Licenser | hmm it kind of is not as nice as () |
| 08: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. |
| 08:49 | chouser | ah. like that! |
| 08:49 | chouser | :-) |
| 08:49 | Licenser | ^^ |
| 08:49 | Licenser | briliant minds think alike, and sometimes even I get teh same idea if it's obviouse enough .P |
| 08:49 | chouser | though you could probably move even more things into the fn |
| 08:50 | Licenser | *nods* the open and close likely |
| 08:50 | Licenser | or connect and disconnect |
| 08:50 | ohpauleez | I'm new to Clojure but not to Lisp in general. What does the hash after a symbol do? |
| 08:50 | chouser | ohpauleez: auto-gensym |
| 08:50 | Licenser | it generates a id'ed symbol for macros |
| 08:50 | ohpauleez | ahhh cool |
| 08:50 | ohpauleez | thank you both |
| 08:52 | Licenser | hey I'm glad if I once can help and don't just ask all the time :P |
| 08:52 | chouser | Licenser: note the way you've got it there, you can only pass in literal strings for your (:get ...) args. |
| 08: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 |
| 08:53 | Licenser | ^^ |
| 08:54 | Licenser | I see, you're right again chouser that is bad'ish |
| 08:54 | Licenser | hmm bindings kind of broke stuff soo |
| 08:55 | _ato | Licenser: https://gist.github.com/989fbc3b6972c145d1a3 |
| 08:55 | _ato | I'd do something more like that |
| 08:55 | _ato | so you can put ifs and stuff in the body |
| 08:55 | _ato | but that might not be what you're going for |
| 08:56 | Licenser | _ato: actually it pretty much is, so I wanted to remove the sftp prefixes from the stuff |
| 09:00 | Licenser | _ato: so I like how you do that with binding |
| 09: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 |
| 09:10 | rhickey_ | http://paste.lisp.org/display/90495 |
| 09:10 | rhickey_ | I think I want something like this for when defs are being explicitly provided^^ |
| 09:11 | chouser | can you do extend more than once on the same type without overwriting? |
| 09:14 | Licenser | _ato: mind if I pick up from that idea? |
| 09:15 | _ato | sure go for it |
| 09:17 | Licenser | thanks |
| 09:19 | rhickey_ | chouser: separate extends?, yes, only overwrite same protocol/type combo |
| 09:19 | rhickey_ | big part of protocols is independent extension |
| 09:19 | chouser | ah, of course. |
| 09:20 | rhickey_ | fred write P, ethel writes T, lucy extends T to P |
| 09:20 | chouser | ok, so you could mix extend-type with extend if one of the protocols needed merge but the others didn't |
| 09:20 | rhickey_ | right |
| 09:20 | rhickey_ | I just see a lot of impls being explicit and inline, where the map stuff is just in the way |
| 09:21 | rhickey_ | also the type hint could come from the type up top and not be repeated |
| 09:24 | rhickey_ | anyone want to take a crack at those? |
| 09:27 | chouser | if you don't mind waiting a couple days, I bet someone on the dev group would like to get involved. |
| 09:28 | _ato | that reminds me |
| 09:28 | _ato | rhickey_: don't suppose you've received my CA yet? |
| 09:28 | ohpauleez | Are the protocols in clojure similar to that of ObjC? |
| 09:29 | ohpauleez | nvm: http://www.assembla.com/wiki/show/clojure/Protocols |
| 09: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) |
| 09:29 | _ato | ah ok, thanks |
| 09:30 | _ato | sent it on the 6th so it'll probably be there next time you check |
| 09:30 | _ato | no worries :) |
| 09:32 | rhickey_ | ohpauleez: they differ in significant ways - ObjC is duck-typed, and protocols map to class methods |
| 09:33 | rhickey_ | Clojure protocol functions are not methods of the classes that extend the protocol |
| 09:33 | rhickey_ | you do not indicate support of a protocol in the definition of the extending class |
| 09:33 | rhickey_ | they are not duck-typed |
| 09:33 | ohpauleez | they're generic, which opens up a lot of cool possibilities |
| 09:33 | ohpauleez | I'm reading that wiki page now |
| 09:34 | ohpauleez | ps: I'm Paul, I worked on the JVM backend for PyPy |
| 09:34 | rhickey_ | cool |
| 09:34 | ohpauleez | I'm migrating here, catching up, and digging in |
| 09:35 | chouser | ohpauleez: I've got some functional-flavoured kool-aid here if you'd like a sip. |
| 09:36 | ohpauleez | I tend to do more functional-esque styles in Python than OO stuff, and really enjoy Common Lisp |
| 09:37 | ohpauleez | 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 | the-kenny | 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 | chouser | oh, 'last' works? |
| 10:54 | chouser | hmph |
| 10:54 | the-kenny | Yes |
| 10:54 | the-kenny | AS does nth |
| 10:57 | the-kenny | 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 | the-kenny | chouser: hm strage, emacs has hidden the stacktrace.. bad emacs, bad! |
| 10:59 | the-kenny | Somewhere in the regex-api |
| 11:01 | the-kenny | hm strange, I can't imagine how lazyness could cause such an error |
| 11:03 | the-kenny | hm.. I think it would help to force the evaluation of the json before I add it to the queue, right? |
| 11:04 | the-kenny | ..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 | the-kenny | (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 | AWizzArd | 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 | AWizzArd | 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 | arohner | I'm getting java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V |
| 11:21 | arohner | at swank.util$flet__9.<init>(util.clj:5) |
| 11:23 | the-kenny | oh strange |
| 11:23 | the-kenny | chouser: (nth 23 @my-agent) throws now too. |
| 11:23 | the-kenny | Looks like the 23th element is broken |
| 11:24 | the-kenny | 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 | stuartsierra | 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 | rhickey_ | (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 | chouser | 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 | chouser | 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 | chouser | 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 | rhickey_ | 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 | rhickey_ | else if(o instanceof String) return ((String) o).length(); |
| 11:42 | rhickey_ | becomes |
| 11:42 | rhickey_ | (extend-class String Countable (cnt [s] (.length s))) |
| 11:43 | rhickey_ | but with extend-protocol, a bunch of these could be grouped together: |
| 11:43 | rhickey_ | (extend-protocol Countable |
| 11:43 | rhickey_ | 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 | chouser | Having said that, I don't know that extend-protocol would make that particularly worse. |
| 11:45 | rhickey_ | this seems pretty snazzy: |
| 11:45 | rhickey_ | (extend-protocol Countable |
| 11:45 | rhickey_ | clojure.lang.Counted (cnt [c] (.count c)) |
| 11:45 | rhickey_ | String (cnt [s] (.length s)) |
| 11:45 | rhickey_ | java.util.Map (cnt [c] (.size c)) |
| 11:45 | rhickey_ | 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 | ohpauleez | I just ran into that this past weekend actually |
| 11:47 | rhickey_ | (extend-class clojure.lang.Counted Countable (cnt [c] (.count c))) |
| 11:47 | rhickey_ | (extend-class String Countable (cnt [s] (.length s))) |
| 11:47 | rhickey_ | (extend-type nil Countable (cnt [_] 0)) |
| 11:47 | rhickey_ | (extend-class java.util.Collection Countable (cnt [c] (.size c))) |
| 11:47 | rhickey_ | (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 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | just experimenting with the perf of a protocol versus the RT methods |
| 11:57 | rhickey_ | 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 | chouser | cons dispatches on the wrong arg |
| 11:58 | rhickey_ | yeah, I didn't invent cons :) |
| 11:59 | chouser | hehe |
| 11:59 | chouser | 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 | chouser | sorry! |
| 11:59 | chouser | maybe cons can be (defn cons [x c] (cons-left c x)) |
| 12:00 | chouser | 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 | chouser | for simple things like cons, the solution is simple. |
| 12:03 | chouser | 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 | arohner | 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 | hiredman | 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 | stuartsierra | 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 | wavis | 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 | rhickey_ | b) have manual dispatch using conditionals |
| 12:48 | rhickey_ | a protocol implementation will get wired into a call site, and even sites that change do caching |
| 12:48 | rhickey_ | 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 | rhickey_ | (extend-class clojure.lang.ISeq S (s [x] (.seq x))) |
| 12:51 | rhickey_ | (def #^clojure.lang.ISeq sq (seq [1 2 3])) |
| 12:51 | rhickey_ | (time (dotimes [_ 100000000] (seq sq))) |
| 12:52 | rhickey_ | user=> "Elapsed time: 916.738 msecs" |
| 12:52 | rhickey_ | (time (dotimes [_ 100000000] (s sq))) |
| 12:52 | rhickey_ | user=> "Elapsed time: 619.931 msecs" |
| 13:44 | pjstadig | ~suddenly |
| 13:44 | clojurebot | CLABANGO! |
| 13:44 | pjstadig | hehe |
| 13:44 | pjstadig | still works |
| 13:44 | danlarkin | demons have been summoned |
| 13:45 | danlarkin | or should I say daemons have |
| 13:45 | danlarkin | 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 | polypus | 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 | danlarkin | (= (type (make-byte-array) (type v)) is lame |
| 14:09 | danlarkin | oops, mismatched parens there, but you get the idea |
| 14:11 | AWizzArd | rhickey: can one extend Arrays of "long" with a protocol? |
| 14:11 | AWizzArd | 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 | ohpauleez | 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 | ohpauleez | 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 | rhickey_ | ,(some #{4} '[2, 4, 1, 3, 5, 6, etc] ) |
| 14:26 | clojurebot | 4 |
| 14:26 | ohpauleez | Ah, that's awesome too |
| 14:27 | ohpauleez | thanks hiredman |
| 14:27 | rhickey_ | not only awesome, but correct, the contains? thing isn't |
| 14:27 | rhickey_ | ,(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 | rhickey_ | ,(.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 | rhickey | ArrayList of Foos, no, generic types are not reified |
| 14:45 | rhickey | 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 | chouser | 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 | krumholt_ | 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 | rhickey | 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 | chouser | kanak: though someone did build a CL-style multiple return value lib on top of thread-local bindings |
| 15:33 | chouser | 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 | rhickey | 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 | chouser | oh, nope. old 'when' form |
| 15:37 | chouser | 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 | arohner | 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 | arohner | 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 | hiredman | or something |
| 15:44 | hiredman | 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 | dakrone | without loading the entire thing into memory |
| 15:46 | hiredman | dakrone: yes |
| 15:46 | hiredman | 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 | dakrone | 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 | rhickey | 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 | rhickey | chouser: it always required an interface for Java, and always will. So, there will be matching interfaces if only for that purpose |
| 15:51 | rhickey | even with :on that was still the case |
| 15:52 | rhickey | 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 | rhickey | 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 | chouser | 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 | rhickey | 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 | hiredman | 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 | rhickey | 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 | dnolen | 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 | AWizzArd | 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 | qed | 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 | qed | (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 | qed | 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 | johnmn3 | 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 | johnmn3 | I'm sure people are running the new branch on emacs.. are there any caveats? |
| 17:24 | johnmn3 | 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 | johnmn3 | 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 | KirinDave | Like if I wanted to segment a task (say fetching urls) into groups and threading them out |
| 17:35 | KirinDave | 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 | KirinDave | and then sending to all of them. |
| 17:38 | KirinDave | 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 | hiredman | 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 | hiredman | 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 | KirinDave | 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 | KirinDave | hiredman: That's cool and I didn't know about pmap, so thank you. |
| 17:43 | KirinDave | hiredman: But if I wanted to say, ensure at most 4 simultaneous connections? |
| 17:43 | hiredman | ah |
| 17:43 | hiredman | well |
| 17:43 | technomancy | unslot your extra cores from the die |
| 17:43 | KirinDave | Lol |
| 17:43 | hiredman | you can use agents |
| 17:44 | hiredman | 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 | KirinDave | To do stuff like that. |
| 17:45 | hiredman | well |
| 17:45 | hiredman | you know, why not make an agetn per url |
| 17:45 | hiredman | agent |
| 17:45 | hiredman | (like your example did) |
| 17:45 | KirinDave | (take 4 ...), wait on them |
| 17:45 | KirinDave | and then continue? |
| 17:45 | hiredman | I mean, agents are already backed by threadpools |
| 17:46 | hiredman | KirinDave: nah, do it the wya you were doing it |
| 17:46 | KirinDave | (map agent (partition width urls-to-fetch)) |
| 17:46 | KirinDave | Okay |
| 17:47 | KirinDave | Would it be unreasonable to desire that you could link agents to a specific threadpool |
| 17:47 | KirinDave | 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 | AWizzArd | "would thought" ==> "would think" |
| 17:52 | AWizzArd | 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 | AWizzArd | strange |
| 17:53 | hiredman | (dotimes [i 100000000] (inc %)) doesn't actually run |
| 17:53 | AWizzArd | yes, it was i instead of % |
| 17:53 | AWizzArd | but in the map i replaced the i with the % so that i can use the #() reader macro vs. (fn [_] ...) |
| 18:00 | AWizzArd | 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 | Chousuke | 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 | hiredman | 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 | Chousuke | (the size of the chunk) |
| 18:10 | hiredman | Chousuke: still troubling for people expect map to be lazy |
| 18:10 | hiredman | 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 | Chousuke | 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 | Chousuke | 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 | hiredman | 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 | Chousuke | 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 | hiredman | 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 | arohner_ | :-) |
| 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 | michaeljaaka | 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 | michaeljaaka | Error occurred during initialization of VM |
| 18:16 | michaeljaaka | java.lang.Error: Properties init: Could not determine current working directory. |
| 18:16 | michaeljaaka | at java.lang.System.initProperties(Native Method) |
| 18:16 | michaeljaaka | 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 | hiredman | 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 | Chousuke | hiredman: so it's fine to alter. |
| 18:18 | hiredman | ~google pastebin |
| 18:18 | clojurebot | First, out of 151000 results is: |
| 18:18 | clojurebot | pastebin - collaborative debugging tool |
| 18:18 | clojurebot | 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 | Chousuke | hiredman: what happens is that some silly programs may become a bit slower. |
| 18:19 | Chousuke | 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 | michaeljaaka | 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 | _ato | 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 | michaeljaaka | it works too |
| 18:21 | hiredman | map is no longer lazy then |
| 18:21 | Chousuke | it is |
| 18:21 | Chousuke | just less lazy than it was before. |
| 18:21 | Chousuke | 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 | Chousuke | ,(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 | Chousuke | 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 | Chousuke | compute* |
| 18:27 | Chousuke | 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 | AWizzArd | 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 | AWizzArd | 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 | hiredman | er |
| 18:31 | hiredman | a chunked seq |
| 18:32 | hiredman | 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 | AWizzArd | 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 | AWizzArd | (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 | Chousuke | 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 | Chousuke | because those are "eager" data structures. except for range I guess. |
| 18:38 | hiredman | Chousuke: but the result is not eager! |
| 18:38 | hiredman | 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 | hiredman | 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 | Chousuke | 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 | clojurebot | 012345678910111213141516171819202122232425262728293031 |
| 18:41 | AWizzArd | Chousuke: so what would be bad about having it fully lazy then? |
| 18:41 | AWizzArd | 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 | dreish | 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 | AWizzArd | 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 | Chousuke | 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 | Chousuke | 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 | Chousuke | AWizzArd: it's still lazy. only 32 times less than the fully lazy one. |
| 18:46 | Chousuke | 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 | dreish | 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 | Chousuke | everyone else can just enjoy a faster map |
| 18:49 | Chousuke | 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 | AWizzArd | 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 | Chousuke | 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 | dreish | 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 | dreish | 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 | dreish | 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 | Chousuke | 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 | dreish | 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 | rhickey_ | 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 | dreish | 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 | dreish | 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 | dreish | 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 | rhickey_ | 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 | AWizzArd | ,(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 | hiredman | 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 | hiredman | 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 | dreish | 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 | michaeljaaka | 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 | AWizzArd | 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 | AWizzArd | 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 | AWizzArd | 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 | michaeljaaka | _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 | _ato | 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 | AWizzArd | ,(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 | hiredman | 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 | AWizzArd | 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 | _ato | 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 | _ato | where f is that function |
| 19:24 | _ato | ? |
| 19:24 | _ato | 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 | qed | something seems broken.. |
| 19:30 | _ato | oh right |
| 19:30 | _ato | that's because if returns 1 |
| 19:30 | _ato | not results |
| 19:30 | qed | ahhhh |
| 19:31 | qed | 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 | dnolen | analogous to |
| 19:43 | rhickey_ | deftype can do a particular subset of things - deriving and defining the methods of interfaces |
| 19:43 | rhickey_ | it can't derive from classes, can't define members not in the interfaces |
| 19:44 | rhickey_ | 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 | michaeljaaka | I have (fn[o] (. o message "Hello") ) |
| 19:57 | michaeljaaka | wchich returns function |
| 19:57 | michaeljaaka | Now I want the same with #() macro |
| 19:57 | michaeljaaka | (#(println %1 "Hello")) |
| 19:57 | michaeljaaka | doesn't work because it want to be evaluated |
| 19:58 | michaeljaaka | I want a reference to that function just like with fn[o] had |
| 19:58 | michaeljaaka | (fn[o] println o "Hello" ) |
| 19:58 | michaeljaaka | should be |
| 19:58 | michaeljaaka | 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 | arohner_ | * Implements a fast vector class without synchronized |
| 20:01 | arohner_ | * methods. Replaces java.util.Vector. (Synchronized methods tend to |
| 20:01 | arohner_ | * be slow.) |
| 20:01 | arohner_ | 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 | qed | a vector |
| 20:05 | arohner_ | qed: I wrote a little utility function to do it |
| 20:05 | arohner_ | 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 | lisppaste8 | arohner pasted "untitled" at http://paste.lisp.org/display/90537 |
| 20:07 | tomoj | if it's just numbers |
| 20:07 | tomoj | ,(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 | arohner_ | 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 | tomoj | the &more fn for max just reduces on the rest |
| 20:10 | arohner_ | ~def apply |
| 20:10 | arohner_ | 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 | Chousuke | ,(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 | clojurebot | "Elapsed time: 109.589 msecs" |
| 20:11 | Chousuke | ,(let [a (vec (range 100000))] (time (reduce max a))) |
| 20:11 | clojurebot | 99999 |
| 20:11 | clojurebot | "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 | clojurebot | "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 | clojurebot | "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 | Chousuke | ,(let [a (list* (range 100000))] (time (reduce max a))) |
| 20:13 | clojurebot | 99999 |
| 20:13 | clojurebot | "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 | michaeljaaka | http://pastebin.com/d6d2f2670 |
| 20:16 | michaeljaaka | I want to define something like this |
| 20:16 | michaeljaaka | but I get |
| 20:16 | michaeljaaka | http://pastebin.com/d4a04b69a |
| 20:17 | Chousuke | arohner_: it's chunked. :) |
| 20:17 | arohner_ | Chousuke: ah, right |
| 20:17 | arohner_ | 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 | Chousuke | 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 | Chousuke | michaeljaaka: anyway, the iface argument passed to proxy is not evaluated |
| 20:22 | Chousuke | ie. it's just a symbol |
| 20:22 | Chousuke | 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 | qed | 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 | qed | it's a good thing project euler stipulates the "if it takes less than 1 minute it's an okay solution" |
| 20:30 | qed | 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 | arohner_ | ngoc: I would grep through the src |
| 20:35 | arohner_ | 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 | arohner_ | ~def root-resource |
| 20:38 | arohner_ | 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 | qed | 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 | _ato | 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 | arohner_ | ,(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 | arohner_ | 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 | rlb | Anyway, just wanted to make sure there wasn't something obvious I was overlooking. |
| 20:45 | rlb | (This is just a toy anyway -- managing a powermate, and looking for double-clicks... |
| 20:45 | rlb | ) |
| 20:46 | arohner_ | rlb: IIRC, there's a java lib for interacting with unix somewhere |
| 20:47 | arohner_ | hrm. looks like there's a bunch of them |
| 20:47 | arohner_ | 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 | michaeljaaka | I have http://pastebin.com/d1e94de3c |
| 20:55 | michaeljaaka | 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 | michaeljaaka | 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 | weissj | 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 | weissj | or maybe i'll just put a counter in the key :) |
| 21:08 | michaeljaaka | what is wrong with that? |
| 21:08 | michaeljaaka | (import 'java.util.HashMap) |
| 21:08 | michaeljaaka | (def a (memfn put )) |
| 21:08 | michaeljaaka | (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 | rhickey_ | memfn predates #() |
| 21:14 | weissj | how does one create a comparator to use with sorted-map-by? proxy? |
| 21:15 | weissj | 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 | chouser | plain ol clojure fns are Comparators. :-) |
| 21:16 | weissj | chouser: oh, never occurred tome |
| 21:16 | weissj | 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 | _ato | 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 | _ato | michaeljaaka: what's the problem that needs fixing? |
| 21:32 | _ato | 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 | _ato | hang on a tick |
| 21:36 | _ato | michaeljaaka: http://gist.github.com/236571 |
| 21:36 | _ato | let me know if you don't see why that worked |
| 21:39 | michaeljaaka | _ato: works great!!! |
| 21:39 | michaeljaaka | _ato: thanks a lot! exactly that I needed |
| 21:40 | michaeljaaka | _ato: these macros are very powerful |
| 21:41 | michaeljaaka | _ato: I see why it works |
| 21:41 | michaeljaaka | _ato: you may only explain why quote for (message "Hello") is not needed |
| 21:41 | _ato | ah |
| 21:42 | _ato | because arguments to macros aren't evaluated, so they don't need to be quoted |
| 21:42 | michaeljaaka | ok :) |
| 21:42 | michaeljaaka | and what about @ what that mean? |
| 21:43 | michaeljaaka | &args in macrodef and in its body i can see ~@args |
| 21:43 | _ato | ah, ~@ is different to @ |
| 21:43 | _ato | ~@ means splicing unquote |
| 21:43 | clojurebot | Gabh mo leithscéal? |
| 21:43 | _ato | so |
| 21:44 | _ato | suppose v is [1 2 3] |
| 21:44 | _ato | then `(foo ~v) => (foo [1 2 3]) |
| 21:44 | _ato | while `(foo ~@v) => (foo 1 2 3) |
| 21:44 | michaeljaaka | I see |
| 21:44 | michaeljaaka | super |
| 21:44 | michaeljaaka | :D |
| 21:45 | michaeljaaka | 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 | michaeljaaka | I know that instead of second ther eshould be rest |
| 21:50 | _ato | should do |
| 21:50 | _ato | 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 | qed | 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 | arohner_ | 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 | arohner_ | well then, the docs are out of date |
| 21:59 | arohner_ | :-) |
| 22:01 | qed | how does clojure.org do its syntax hilighting? |
| 22:01 | qed | 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 | qed | really? |
| 22:02 | qed | what browser are you using? |
| 22:02 | arohner_ | chrome on OSX |
| 22:02 | arohner_ | though it says the page has been loading since I linked it |
| 22:02 | qed | hm weird |
| 22:02 | qed | 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 | qed | 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 | qed | 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 | qed | or just lists and vectors? |
| 22:38 | ohpauleez | You can also use .contains |
| 22:38 | ohpauleez | some will return the first true value it finds |
| 22:38 | ohpauleez | (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 | ohpauleez | (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 | leafw | it's quite bizarre, wehn it comes to write java classes that use its internals. |
| 22:42 | leafw | 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 | leafw | best luck :) |
| 22:43 | arohner_ | thanks :-) |
| 23:03 | qed | wow |
| 23:04 | qed | i think i actually learned some clojure today |
| 23:04 | qed | lol -- it took me quite a while to understand that whole loop/recur form for different situations |
| 23:05 | qed | kind of embaressing really |
| 23:05 | ohpauleez | but once you get it, it makes total sense |
| 23:05 | ohpauleez | congrats on the progress |
| 23:06 | qed | thanks man -- it's a good community we have here |
| 23:06 | qed | 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 | qed | 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 | qed | 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 | technomancy | 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 | qed | technomancy: yeah, no doubt |
| 23:11 | qed | 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 | qed | 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 | technomancy | 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 | qed | "if you wanan talk, come over and code a little bit" |
| 23:13 | qed | we all basically do it already |
| 23:13 | qed | people using pastie left and right |
| 23:14 | qed | explaining concepts to eachother, sharing ideas |
| 23:14 | qed | 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 | qed | </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 | arohner_ | 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 | qed | 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 | qed | _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 | qed | than just sitting in irc reading contextually isolated lines of information |
| 23:19 | qed | 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 | djork | 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 | qed | 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 | qed | 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: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 | jkkramer | yes |
| 23:36 | jkkramer | the slime repl works as expected |
| 23:37 | _ato | I dunno then :/ |
| 23:37 | _ato | 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 | Draggor | They're all in the same package |
| 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 | technomancy | 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: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 | technomancy | *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 | technomancy | 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 | jkkramer | M-x slime works |
| 23:53 | technomancy | jkkramer: maybe turn on M-x ido-mode and see if the problem persists |
| 23:53 | technomancy | 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 | jkkramer | what's ido-mode, btw? |
| 23:54 | technomancy | jkkramer: ido ist awesome |
| 23:55 | technomancy | it's like magic press-fewer-keys mode |
| 23:55 | hiredman | Draggor: just (func1 some-arg)? |
| 23:55 | hiredman | 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 |