2010-06-30
| 00:43 | technomancy | anyone know when the final reviewer notes for the latest Joy of Clojure draft is due? |
| 01:35 | scottj | Is there an abstraction for handling the case when you want branching behavior, but one branch is to do nothing (including not return nil)? Something like (defmacro bar [a] `(defn foo ,(when (even? a) a) [] ...)) when "when" can't return nil? You can write it roughly (defmacro bar [a] `(defn foo ,(let [tail []] (if (even? a) (cons a tail) tail)))) but I think it's kind of ugly as I want the branching to be cnfined to what's different, not inclu |
| 01:46 | tomoj | scottj: every expression returns something.. |
| 02:00 | scottj | tomoj: yeah, I thought maybe there might be a macro with a clever name that would abstract that away :) |
| 02:49 | jowag | what are the guidelines for using bang (!) in the fn name? I read somewhere that one should use it when it is not safe to use fn in the transaction, is that it? |
| 03:04 | Bahman | Hi all! |
| 03:28 | zmila | jowag - seems, the ! sign is for fns with mutations |
| 03:29 | Chousuke | io stuff usually isn't marked with a bang |
| 03:29 | Chousuke | I think it's for functions which *could* be functional but aren't. |
| 03:29 | Chousuke | eg. the operations on transients. |
| 03:40 | jowag | Yep, the io is what got me perplexed, why fns like slurp does not have a bang notation |
| 03:41 | Chousuke | you can mark io functions with the io! macro so they will throw an error if used in transactions |
| 03:42 | jowag | yes I use it, but I was uncertain about the fn naming guidelines |
| 03:42 | Chousuke | they don't really exist :) |
| 03:42 | Chousuke | anything goes as long as you're consistent. |
| 03:43 | jowag | I see :) |
| 03:46 | jowag | I think I'll go with something like "use ! notation for fn with side effects except io stuff, in that case just use io! macro inside those fns" |
| 04:02 | cais2002 | hi guys, is http://clojure.org/lazy the latest doc on laziness? |
| 04:04 | esj | Morning Good People |
| 04:04 | LauJensen | Good morning all |
| 04:04 | Bahman | Morning esj and LauJensen! |
| 04:05 | LauJensen | cais2002: Typically the stuff on clojure.org relates to the latest stable release, which feels like ages ago |
| 04:05 | cais2002 | good afernoon guys |
| 04:05 | LauJensen | cais2002: Streams didnt get into Clojure, Chunks did |
| 04:05 | cais2002 | am I supposed to get latest copy from github? |
| 04:06 | LauJensen | or via clojars, a snapshot |
| 04:09 | cais2002 | great, let me try it out, thanks |
| 04:13 | esj | Lau, cgrand: How did the clojure training go? |
| 04:26 | cgrand | esj: on the phone with Lau right now :-) |
| 04:26 | esj | planning round 2 I hope :) |
| 04:54 | LauJensen | esj: Thats right :) |
| 04:55 | bobo_ | same place? or too early to say perhaps |
| 04:56 | LauJensen | Yes, we havent zeroed in on a venue, so it might be close (ie Cologne), but it might be as far away as Berlin- All we know for certain is that its in Germany, early September. We are working rapidly on settling the last details |
| 04:56 | LauJensen | (although, picking a quality venue is always tricky. The one in Brussels was outstanding) |
| 05:00 | bobo_ | :-) |
| 05:01 | bobo_ | if only i could find any arguments to tell my employer to send me |
| 05:02 | LauJensen | I can give him a call if you want :) |
| 05:02 | bobo_ | :-) |
| 05:03 | bobo_ | there just isnt much clojure stuff for a consultant to take. |
| 05:04 | lpetit | bobo_: your employer may sometimes take some risks to be ahead of the concurrence. |
| 05:04 | lpetit | bobo_: and sending you for a 3-days course isn't such a great risk :) |
| 05:04 | bobo_ | true |
| 05:04 | bobo_ | well its money :-) |
| 05:05 | LauJensen | There might not be anything specifically labeled "Clojure", but knowing Clojure alone allows you to build better software, even if bound to another language. Secondly, even though it doesnt wear the Clojure label, many applications will benefit greatly from being implemented in Clojure. You'll learn about functional programming, concurrency etc, which are common themes nowadays |
| 05:05 | LauJensen | lpetit: concurrence = competition |
| 05:05 | bobo_ | yeh true |
| 05:05 | bobo_ | i can atleast give it a try :-) |
| 05:06 | LauJensen | bobo_: In return for a 25% administration fee, as well as a 10% greeting fee and finally a 15% drinks/dinner fee, I'm prepared to offer a 45% discount |
| 05:06 | bobo_ | early september is great timing atleast |
| 05:06 | bobo_ | lol |
| 05:07 | LauJensen | yea we hope most people are back from holidays |
| 05:09 | bobo_ | is the page for the last round gone? cant seem to find it |
| 05:09 | LauJensen | http://conj-labs.eu is still there, but registration is closed |
| 05:11 | LauJensen | I see the pictures under course/venue are actually still from Bruseels, but I'll update that once we find THE place :) |
| 05:32 | esj | LauJensen: after Brussels though, it can only be downhill..... at least in terms of beer ! |
| 05:35 | cgrand | esj: I recommend Moeder Lambic, they server great beers, http://www.moederlambic.eu/cellier/index.php/en/history/15-histoire/16-histoire :-) (fr, no english translation) |
| 05:37 | npoektop | hi! i need to do (apply some-macro first-ard '(rest-of-args)). I found apply-macro, but docs say "This is evil. Don't ever use it." Why? |
| 05:39 | cgrand | npoektop: because macros being functions is an impl detail |
| 05:40 | Chousuke | npoektop: if you need to do that, you're probably doing something weird |
| 05:40 | npoektop | is there a way to splice arglist to a macro? |
| 05:40 | cgrand | npoektop: usually you would prefer something like (macroexpand-1 `(some-macro ~first-arg ~@'(rest-of-args))) |
| 05:41 | cgrand | but like Chousuke sais if you need to manually macroexpand or "call" a macro you are probably doing something wrong |
| 05:41 | Chousuke | npoektop: from another macro you can generate your call to the other macro any way you want. |
| 05:42 | Chousuke | if you're trying to do it from a function then you're probably misusing macros |
| 05:42 | Chousuke | what are you trying to do? maybe there's a better way. |
| 05:43 | raek | macros are expanded at compile time |
| 05:43 | Chousuke | also if you're just trying to generate code based on the contents of a data structure then you don't need a macro at all |
| 05:43 | raek | their input is unevaluated code |
| 05:44 | Chousuke | functions can return clojure code too |
| 05:44 | raek | applying a macro doesn't make much sense, since then the arguments will already be evaluated |
| 05:44 | clojurebot | code-review is <rhickey> yikes |
| 05:47 | Chousuke | ,((fn [vec-of-fn-names] `(do ~@(for [fn-name vec-of-fn-names] (list fn-name :somearg)))) '[foo bar zonk]); like this |
| 05:47 | clojurebot | (do (foo :somearg) (bar :somearg) (zonk :somearg)) |
| 05:47 | Chousuke | and that you can pass to eval if you really need to, but eval too needs to be treated with suspicion :) |
| 05:51 | npoektop | i have this code: (defmodel ~collname (doall (map (fn [x#] (-> x# :name keyword)) conf#))). I'm trying to splice (doall (map...)) here. |
| 05:52 | Chousuke | hm |
| 05:52 | Chousuke | is that within a syntax-quote? |
| 05:53 | npoektop | I guess so: `(do ... (defmodel...)) |
| 05:53 | Chousuke | show the whole macro please |
| 05:53 | Chousuke | ~@(map (fn [x] ...)) ought to work though (no need for gensyms there since it's not part of the generated code) |
| 05:53 | clojurebot | maps are *AWESOME* |
| 05:54 | Chousuke | though I'm not sure about the conf# |
| 05:54 | npoektop | http://pastebin.com/UKSLSMhi |
| 05:54 | Chousuke | you can't splice in things that are part of the generated code, the stuff needs to be available when the macro is called |
| 05:55 | Chousuke | don't put closing parens on their own lines please ;( |
| 05:56 | npoektop | it's not my code. i do not like it too) |
| 05:57 | Chousuke | hm |
| 05:59 | Chousuke | do away with the let and just do (defmodel ~collname ~@(map (fn [x] (-> x :name keyword)) (process-columns collname-str columns)))) |
| 05:59 | cais2002 | guys, where can I find the definition of "reduce" ? |
| 05:59 | Chousuke | ~def reduce |
| 06:00 | Chousuke | npoektop: it looks like the macro has the usual confusion about syntax-quote, the macro parameters, unquoting and how it all actually works :) |
| 06:01 | Chousuke | a macro is a function of type anything -> clojure code |
| 06:02 | Chousuke | it just so happens that the result is also evaluated by the compiler |
| 06:03 | cais2002 | Chousuke: don't get it. but clojurebot does its job.. interesting |
| 06:03 | Chousuke | cais2002: that definition of reduce is rather more complicated than it needs to be, for performance reasons |
| 06:06 | Chousuke | an easy def of reduce is (defn red [f init coll] (if-not (seq coll) init (recur (f init (first coll)) (rest coll))))... it always requires the init value though. |
| 06:08 | cais2002 | why is it not found on http://richhickey.github.com/clojure/api-index.html |
| 06:09 | cais2002 | or am I looking at the wrong place for api reference? |
| 06:10 | npoektop | That assert is unneseccary here, right? (defmacro defmodel [modelname & attributes] (assert (seq? attributes)) ... ) |
| 06:17 | Chousuke | npoektop: right. |
| 06:18 | npoektop | thank you |
| 06:23 | Lajla | ja menee alas ja Chousuke:n päähän |
| 06:23 | Lajla | Nyt lajla on Chousuke:n päässä |
| 06:29 | Chousuke | :P |
| 06:44 | Lajla | Chousuke, on hyvää sun päässä |
| 06:45 | Lajla | Sun aivot on nätti ja hyvä. |
| 06:45 | Chousuke | Lajla: you should keep nonsense on -casual :P |
| 07:17 | npoektop | i have a macro with a construction inside: '(do ... (defmodel ...)). defmodel is a macro. How to skip (defmodel ...) when i do not need it? |
| 07:18 | npoektop | '(do ... (if condition (defmodel ...))) does not work. |
| 07:18 | jartur | Hi all. |
| 07:18 | jartur | Does anybody know if mmcgrana happens to be here sometimes? |
| 07:19 | lpetit | npoektop: you want some conditional code to execute in the macro, while constructing the code structure to be returned by the macro |
| 07:20 | lpetit | npoektop: so you need to escape from the "code template" : `(do ... ~@(when condition `(defmodel ...))) |
| 07:20 | npoektop | lpetit, thank you |
| 07:20 | npoektop | i'll try it |
| 07:20 | lpetit | ,`(do a (if true (defmodel)) b) |
| 07:20 | clojurebot | (do sandbox/a (if true (sandbox/defmodel)) sandbox/b) |
| 07:20 | lpetit | ,`(do a ~(if true `(defmodel)) b) |
| 07:20 | clojurebot | (do sandbox/a (sandbox/defmodel) sandbox/b) |
| 07:21 | lpetit | ,`(do a ~(if false `(defmodel)) b) |
| 07:21 | clojurebot | (do sandbox/a nil sandbox/b) |
| 07:21 | lpetit | ,`(do a ~@(if false `(defmodel)) b) |
| 07:21 | clojurebot | (do sandbox/a sandbox/b) |
| 07:21 | npoektop | cool |
| 07:21 | lpetit | ,`(do a ~@(if true `(defmodel)) b) |
| 07:21 | cais2002 | hi, for this one, why do we need the additional identify call: (.instanceMember Classname args*) ==> |
| 07:21 | clojurebot | (do sandbox/a sandbox/defmodel sandbox/b) |
| 07:21 | cais2002 | (. (identity Classname) instanceMember args*) |
| 07:21 | lpetit | ,`(do a ~@(if true `((defmodel))) b) |
| 07:21 | clojurebot | (do sandbox/a (sandbox/defmodel) sandbox/b) |
| 07:22 | lpetit | npoektop: there we are, if you want to avoid inserting a nil instead of defmodel when the condition is false, this form works: |
| 07:22 | lpetit | ,`(do a ~@(if true `((defmodel))) b) |
| 07:22 | clojurebot | (do sandbox/a (sandbox/defmodel) sandbox/b) |
| 07:22 | lpetit | ,`(do a ~@(if false `((defmodel))) b) |
| 07:22 | clojurebot | (do sandbox/a sandbox/b) |
| 07:22 | lpetit | npoektop: but if you don't care, then the following form is easier to understand: |
| 07:22 | lpetit | ,`(do a ~(if true `(defmodel)) b) |
| 07:22 | clojurebot | (do sandbox/a (sandbox/defmodel) sandbox/b) |
| 07:23 | lpetit | ,`(do a ~(if false `(defmodel)) b) |
| 07:23 | clojurebot | (do sandbox/a nil sandbox/b) |
| 07:24 | npoektop | lpetit, thank you very much! ) |
| 07:25 | lpetit | npoektop: np |
| 07:31 | thetafp | (+ 1 2) |
| 07:31 | clojurebot | 3 |
| 07:31 | jartur | so no mmcgrana here, aye? |
| 07:34 | cais2002 | (reduce + 1 (2 3)) |
| 07:35 | cais2002 | (reduce + 1 '(2 3)) |
| 07:35 | cais2002 | (+ 1 2) |
| 07:35 | clojurebot | 3 |
| 07:38 | Chousuke | that + thing is a special feature :P |
| 07:38 | Chousuke | you need to use ,(foo) if you want to eval clojure code |
| 07:38 | Chousuke | (+ 5 6 |
| 07:38 | Chousuke | (+ 5 6) |
| 07:38 | clojurebot | *suffusion of yellow* |
| 07:38 | Chousuke | like that :P |
| 07:39 | cais2002 | ,(+ 5 7) |
| 07:39 | clojurebot | 12 |
| 07:39 | cais2002 | ,(reduce + 1 '(2 3)) |
| 07:39 | clojurebot | 6 |
| 07:39 | cais2002 | ,(infinite loop) |
| 07:39 | clojurebot | java.lang.Exception: Unable to resolve symbol: infinite in this context |
| 07:40 | Chousuke | infinite loops will last 10 seconds |
| 07:46 | cais2002 | ok, that's what I thought would have happened |
| 07:47 | cais2002 | why does this not work? (macroexpand '((memfn charAt i) "ab" 1)) |
| 08:27 | jowag | ,(/ 1 0) |
| 08:27 | clojurebot | java.lang.ArithmeticException: Divide by zero |
| 09:01 | bartj | er, is it possible to issue bash commands from the REPL ? |
| 09:02 | LauJensen | bartj: using shell-out from contrib, yes |
| 09:02 | LauJensen | in Emacs there's also M-! |
| 09:07 | LauJensen | ,(use 'clojure.contrib.shell) |
| 09:07 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/shell__init.class or clojure/contrib/shell.clj on classpath: |
| 09:08 | LauJensen | well thats no fun |
| 09:08 | chouser | ,(require 'clojure.java.shell) |
| 09:08 | clojurebot | nil |
| 09:09 | LauJensen | same thing? |
| 09:09 | chouser | doubt it'll do you much good though. |
| 09:09 | chouser | ,(clojure.java.shell/sh "echo" "hello") |
| 09:09 | clojurebot | java.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute) |
| 09:10 | LauJensen | chouser: Is it the old contrib shell thats been moved? |
| 09:10 | bartj | and then do a "(echo hello)" ? |
| 09:10 | chouser | LauJensen: yes |
| 09:11 | LauJensen | chouser: Is there a list anywhere on which parts of contrib moved where? |
| 09:11 | LauJensen | bartj: No, that is the actual shell call |
| 09:11 | chouser | bartj: no, use the sh function from that namespace as I showed. The command to run and each of its args should be a separate arg to sh |
| 09:11 | chouser | hm, sh isn't really a good name |
| 09:11 | LauJensen | bartj: http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/shell.clj#L138 |
| 09:12 | chouser | should be shell/run or shell/launch or something. |
| 09:13 | bartj | gee, I don't see any output |
| 09:13 | bartj | ;(ls) |
| 09:16 | chouser | (sh "ls") |
| 09:18 | bartj | chouser: yay! thanks! |
| 09:28 | Licenser | cooookies |
| 09:35 | bartj | Licenser: for everyone ? |
| 09:36 | Licenser | of cause |
| 09:39 | LauJensen | Licenser: Just doesnt feel right without Raynes here to share the fun |
| 09:40 | Licenser | yea :( |
| 09:40 | Licenser | but well we can leave him some crumbs |
| 09:41 | LauJensen | Licenser: Hows your Clojure driven game coming along? |
| 09:42 | Licenser | LauJensen: not good, the team kind of backstabed me and left me alone with it - very frustrating experience |
| 09:42 | LauJensen | Oh |
| 09:45 | Licenser__ | So now i can keep chatting :) |
| 09:46 | LauJensen | Licenser__: There was this game some years ago called Freelancer, and later something that smelled like a Version 2 came out from another company, with another name, they were similar though. I would love to build an MMORPG like that in Clojure. It'll have to wait until I can clear a year out of the schedule though |
| 09:48 | Licenser__ | LauJensen: That would Be cool it sounds a bit like eve online so |
| 09:48 | LauJensen | Never played Eve online, but from what I've heard they would be completely different |
| 09:48 | bartj | LauJensen: this is the one - http://en.wikipedia.org/wiki/Freelancer_(video_game) |
| 09:48 | bartj | ? |
| 09:49 | LauJensen | http://www.gamespot.com/pc/sim/freelancer/index.html?tag=result%3Btitle%3B0 |
| 09:49 | Licenser__ | Never played it either but it sounded a bit like freelancer online :P so oddly enough you could look at the epic engine while not build with this kind of stuff in mind it could very well function l |
| 09:50 | Licenser__ | At least partially since it. Is turn based but speed should not be an issue it was made for battles witness a few thousand participants |
| 10:05 | TakeV | Why am I getting this error when I try to use the compile function? "java.io.FileNotFoundException: Could not locate clojure/examples/hello__init.class or clojure/examples/hello.clj on classpath: (NO_SOURCE_FILE:0)" |
| 10:15 | chouser | TakeV: most likely because your clj file is not on the classpath in the appropriate place |
| 10:16 | TakeV | chouser: I'm not using a clj file, just the REPL. I need a file? |
| 10:16 | chouser | (doc compile) |
| 10:16 | clojurebot | "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath." |
| 10:17 | chouser | yes, compile takes a lib name and finds the appropriate .clj file on disk, then writes out the appropriate .class file to go with it. |
| 10:18 | chouser | if you're not trying to get a .class file, you don't need 'compile' |
| 10:19 | TakeV | Yeah, trying to do ahead of time compilation. |
| 10:19 | TakeV | And I need to do (set! *compile-path* "/path/to/clj/file")? |
| 10:20 | chouser | no |
| 10:22 | pjstadig | you need "path/to/clj/file" to be in your classpath |
| 10:23 | chouser | AOT compilation can be a bit tricky to set up. I think there are good tutorials, though. |
| 10:24 | TakeV | chouser: Yeah, I'm reading them but they are not working. :\ |
| 10:25 | chouser | those would be the bad tutorials. :-) |
| 10:25 | LauJensen | haha |
| 10:25 | TakeV | http://clojure.org/compilation -- This one? |
| 10:25 | LauJensen | thats true. But on a new lein project just as an example. Start a repl, (set! *compile-path* "/classes") and compile, thats it |
| 11:20 | mtopolnik | what would be the idiomatic way to make a memoized defn? |
| 11:20 | mtopolnik | currently I have this: |
| 11:20 | mtopolnik | (defn- myfun [arg] ...) |
| 11:21 | mtopolnik | and then (def #^{:private true} myfun (memoize myfun)) |
| 11:23 | Chousuke | mtopolnik: that's pretty much it |
| 11:23 | Chousuke | mtopolnik: there's a defn-memoize or something in contrib to make that a bit neater though |
| 11:24 | mtopolnik | yes, i'm looking for just such a thing |
| 11:24 | mtopolnik | but it also needs to be private |
| 11:24 | Chousuke | that's not a problem |
| 11:24 | mtopolnik | of course, there isn't much work in defining it myself |
| 11:24 | AWizzArd | ,(doc defn-memo) |
| 11:24 | clojurebot | "clojure.contrib.def/defn-memo;[[fn-name & defn-stuff]]; Just like defn, but memoizes the function using clojure.core/memoize" |
| 11:24 | Chousuke | just add the metadata. |
| 11:24 | AWizzArd | I just defn-memo, easy to use. |
| 11:24 | mtopolnik | yeah, that'll do it |
| 11:25 | AWizzArd | mtopolnik: but of course, it is potentially able to introduce a "memory leak" into your app. |
| 11:25 | mtopolnik | sure, like any memoize |
| 11:25 | mtopolnik | but i've got that under control |
| 11:25 | AWizzArd | k |
| 11:25 | mtopolnik | i'm memoizing all the setter-functions for my java beans |
| 11:25 | mtopolnik | there won't be too many of those |
| 11:26 | mtopolnik | in the hundreds tops |
| 11:26 | mtopolnik | i guess a lambda doesn't use too much memory |
| 11:27 | AWizzArd | not much |
| 11:27 | Chousuke | mtopolnik: the problem isn't the number of the functions, it's the number of different arguments they get called with |
| 11:28 | mtopolnik | i wanted to say, my memoized function is a constructor for setter funtions |
| 11:28 | mtopolnik | so it will get called with only a couple hundred different arguments (property names) |
| 11:29 | mtopolnik | also, chouser warned me that it might make an even worse impact on memory (PermGen, specifically) if I don't memoize the lambdas but keep making new ones |
| 11:30 | hiredman | ,(doc resolve) |
| 11:30 | clojurebot | "([sym]); same as (ns-resolve *ns* symbol)" |
| 11:30 | hiredman | ,(ns-resolve (create-ns 'clojure.core) 'a) |
| 11:30 | clojurebot | nil |
| 12:08 | Fossi | ja |
| 12:30 | polypus | ~ping |
| 12:30 | clojurebot | PONG! |
| 12:46 | cais2002 | ~pong |
| 12:46 | clojurebot | Qinfengxiang! |
| 12:52 | _fogus_ | ,Q |
| 12:52 | clojurebot | java.lang.Exception: Unable to resolve symbol: Q in this context |
| 12:57 | polypus | are the hashcodes for datastructures generated at creation time or only when they are first needed by some equivalence test? |
| 12:58 | qbg | It seems to be usually by need |
| 13:02 | polypus | also, if i have a sorted set of some complex datastructure, and i am sorting on say the :id keys of those structures, which are integers, then hash codes do not need to be, and are not, calculated for the entire structure, but only for the keys, correct? |
| 13:33 | LauJensen | technomancy, hugod: M-. works great for the clj fns, but are there any way to dig into the java source as well ? |
| 13:34 | scottj | M-. works on any language if you use ctags |
| 13:34 | LauJensen | scottj: How do you get it to take you to one of the java files of Clojure.core? |
| 13:35 | hugod | LauJensen: specifically for core? |
| 13:36 | scottj | LauJensen, read emacs docs on ctags/etags |
| 13:36 | LauJensen | No not really, but its usually those functions I want to look up |
| 13:36 | LauJensen | @ hugod |
| 13:37 | technomancy | LauJensen: I don't think there's a good solution for that; seeing signatures via slime-inspector is the best I have managed. |
| 13:37 | scottj | short version: create TAGS file from source, load it, search it |
| 13:37 | technomancy | but if you really need it, yeah... ctags it is. |
| 13:37 | hugod | LauJensen scottj's suggestion seems the easiest - bind to a different key |
| 13:37 | LauJensen | Its odd that it takes a lot of work, since Eclipse does it out of the box, I didnt expect it to require any effort |
| 13:38 | technomancy | LauJensen: well, slime isn't really designed to work with Java =) |
| 13:38 | LauJensen | true |
| 13:38 | LauJensen | Alright, I'll look up ctags |
| 13:38 | LauJensen | thats scottj, hugod & technomancy :) |
| 13:38 | scottj | btw ctags is really useful for Clojure code as well since you don't have to have it loaded into slime (compilable, dependencies, etc) to browse/search it by tags |
| 13:39 | hugod | LauJensen: I use find . -name '*.java' | xargs etags --language=java |
| 13:39 | technomancy | scottj: right, but you have to build and constantly refresh the tags table |
| 13:39 | technomancy | seems like more work |
| 13:39 | LauJensen | hugod: oh ok, and just run that on the git repo? |
| 13:39 | hugod | LauJensen: at the root |
| 13:40 | hugod | of the repo |
| 13:40 | LauJensen | yea |
| 13:40 | scottj | technomancy: one command |
| 13:43 | LauJensen | technomancy: one love |
| 13:50 | shoover | scottj: do you run that in a file save hook or anything for constant updates? |
| 13:55 | LauJensen | hugod: Your shellcall works fine, so its seems odd to me that this doesnt: find . -name '*.java' -type f -exec etags.emacs --language=java '{}' \; |
| 13:56 | LauJensen | It simply returns a file thats about 1/4 of that of your call, yet a superficial inspection of the files found, looks similar for both calls |
| 14:00 | hugod | LauJensen: xargs is presumably calling etags once with all the files as arguments |
| 14:01 | hugod | LauJensen: I see etags has a -a argument |
| 14:03 | LauJensen | aha |
| 14:03 | LauJensen | hugod: Is there anyway I can move the TAGS file to ~/.emacs.d and reference it from my .emacs, or how do you integrate? |
| 14:04 | hugod | LauJensen: first time you call find-tag it asks for the TAG file |
| 14:05 | hugod | LauJensen: I use it across several projects, so don't load any tag file by default |
| 14:06 | LauJensen | ok, cool, thanks |
| 14:06 | clojurebot | namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 14:20 | bobo_ | hm, is there any "ok i installed the emacs-starter-kit now what" blog or similar? :-) |
| 14:20 | LauJensen | bobo_: To launch a repl, or to start coding? |
| 14:20 | bobo_ | no more, this is what it can do |
| 14:20 | LauJensen | ah - Sorry I dont know that kit very well |
| 14:21 | bhenry | bobo_ http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs |
| 14:21 | bhenry | if you haven't gotten the elpa stuff from esk yet |
| 14:23 | rhickey | Clojure now at: http://github.com/clojure |
| 14:25 | LauJensen | rhickey: fancy :) |
| 14:34 | polypus | most efficient way to remove N items from end of vector, getting vector back? |
| 14:35 | polypus | is it best to just pop multiple times? |
| 14:36 | hoeck | polypus: maybe that, or use subvec |
| 14:37 | polypus | hoeck: thanks, forgot about that one |
| 14:37 | hoeck | docs say its O(1) |
| 14:37 | polypus | that's what i need |
| 14:44 | technomancy | subvec won't allow elements in the original vector to get GC'd though, so watch out |
| 14:47 | polypus | technomancy: thanks for the heads up. |
| 15:08 | rhickey | pjstadig: fixed that problem from the other day: http://github.com/clojure/clojure/commit/0f4b6495347dc7d9601cc0907d5d08dd861bb3aa |
| 15:13 | LauJensen | rhickey: Its interesting to review the impact graph for Clojure. You're just slaving away on your lonesome all the way to 21 June 2009, when you dropped the stu bomb :) |
| 15:17 | pjstadig | rhickey: thanks...though I think that was actually a separate issue than I eventually realized was my problem |
| 15:17 | pjstadig | i think my problem ended up being that keywords are not GC'ed |
| 15:18 | polypus | forgive my ignorance, but what's the stu bomb? |
| 15:18 | Raynes | polypus: Stuart Halloway, I imagine. |
| 15:18 | polypus | but what's the bomb? |
| 15:18 | LauJensen | polypus: Yea Stuart, and the bomb was the 11500 lines he commited that day |
| 15:18 | Raynes | Tons of commits from Stu. |
| 15:18 | danlarkin | see kevin downey's patch to clojure-dev for more details on the keyword interning problem |
| 15:19 | polypus | ahh |
| 15:19 | danlarkin | unfortunately it's complicated :( |
| 15:20 | rhickey | pjstadig: yeah, keywords are not yet held by weak refs, they'll need a similar treatment in order to be tolerant of ongoing generation |
| 15:23 | danlarkin | I moved build.clojure.org to point to the new clojure github fyi |
| 15:34 | rhickey | danlarkin: cool |
| 15:35 | polypus | is into! planned for transients. what about peek on transient vectors? |
| 15:54 | wolfjb | where can I read more about clojure.test? I've just started learning clojure and have started my first project with lein, but running lein test gives an error 'Unable to resolve symbol in this context' |
| 15:55 | lancepantz | wolfjb: that's just an exception in either your source or your test |
| 15:56 | Raynes | wolfjb: http://java.ociweb.com/mark/clojure/article.html#Testing |
| 15:56 | wolfjb | Raynes: thanks |
| 15:58 | wolfjb | lancepantz: in myproject.core I have (defn add2 [x] (+ x 2)) and in myproject.core-test I have (deftest test-add2 (is (= (add2 2) 4))) but the unresolved symbol is add2 |
| 15:59 | lancepantz | wolfjb: you have to use myproject.core-test in your test |
| 15:59 | raek | (ns myproject.core-test (:use myproject.core)) |
| 15:59 | wolfjb | thanks |
| 16:00 | lancepantz | wolfjb: no prob, ask away |
| 16:00 | wolfjb | thanks! |
| 16:50 | replaca | rhickey: are you here? |
| 16:50 | rhickey | replaca: yes |
| 16:50 | replaca | the clojure org is now the official repo? |
| 16:51 | replaca | i see that you're pushing stuff there |
| 16:51 | rhickey | replaca: in the process, do you want me to change the hook? |
| 16:51 | replaca | yeah, the hook should be wherever you're pushing to |
| 16:51 | rhickey | replaca: I thought Stu was getting in touch with you to coordinate |
| 16:52 | dsop | hmm how to call the overwritten super class method in a gen-class? |
| 16:52 | replaca | also, I wanted to know where to push contrib changes and autodoc pages |
| 16:52 | replaca | rhickey: no, I hadn't heard from him yet |
| 16:52 | rhickey | yes, please to clojure now |
| 16:52 | replaca | ok. we'll have to update links on clojure.org |
| 16:53 | replaca | to point at the "new" autodoc |
| 16:53 | replaca | I'll get it building to there tonight (assuming github pages work with organizations) |
| 16:54 | rhickey | replaca: ok, hooks are on in the clojure repos |
| 16:55 | rhickey | replaca: let me know if you need any settings tweaked, I think you should have the privileges you need |
| 17:02 | chouser | so is the official git repo moving? was there an announcement I missed? |
| 17:03 | lpetit | what what ? :) |
| 17:04 | replaca | chouser: that seems to be it. Github has finally added an "organizations" feature that let's us put the repo in a place separate from the person "richhickey" while still letting him be BDFL |
| 17:05 | rhickey | chouser: yes, we are in the process of moving, will 'announce' when everything is in place. We're pushing to clojure from now on |
| 17:06 | chouser | ah, I see it. http://github.com/clojure/clojure but not quite ready yet? |
| 17:07 | rhickey | chouser: close, needs docs, downloads etc. hooks in place to assembla, all privileges in place |
| 17:07 | chouser | huh, didn't know I was a member. I wonder where I can see a list of the organizations I'm a member of. |
| 17:07 | chouser | rhickey: excellent. sounds good. |
| 17:14 | dsop | does someone know how to add an init function to defservice? |
| 17:14 | dsop | that is called during servlet initialization? |
| 17:19 | Raynes | It's a shame that all of those 956 watchers will have to watch the new repo. |
| 17:19 | Raynes | Organizations are confusing. |
| 17:19 | Raynes | :p |
| 17:43 | wolfjb | is there a mocking mechanism (like JMock or Mockito or similar) for clojure? |
| 17:44 | bhenry | chouser click "switch context" in the top(ish) right of the github home page to see all your orgs. |
| 17:47 | wolfjb | okay, found test-expect, but no doc? |
| 17:47 | Chousuke | Raynes: at least switching the url of a remote in git is trivial :P |
| 17:47 | Chousuke | Raynes: no need to reclone a repository |
| 17:50 | replaca | Chousuke: do I edit the file to do that or is there a git command? |
| 17:50 | Chousuke | git remote set-url remotename new-url |
| 17:50 | Chousuke | remotename should be origin in this case :) |
| 17:50 | replaca | Chousuke: thanks! |
| 17:51 | Chousuke | git's concept of remotes is excellent |
| 17:51 | replaca | Chousuke: yeah, git always seems to have a way to do what I want, it's just hard to figure out and keep track of :) |
| 17:52 | Chousuke | the original server is just given a default name, other than that, it's just like any other remote :P |
| 17:52 | technomancy | can also edit .git/config |
| 17:52 | Chousuke | I have two remotes in my local git repo |
| 17:52 | Chousuke | one for rhickey's repository, and one for my own clone |
| 17:52 | Chousuke | on github |
| 17:53 | Chousuke | haven't updated it in a while though :P |
| 17:57 | yacin | can you cast nil to something in clojure like you can cast null to an object in java? |
| 17:57 | yacin | like |
| 17:57 | DeusExPikachu | is this statement correct? "it is impossible to extend an object returned by reify" |
| 17:57 | yacin | (FastVector) null |
| 17:58 | yacin | i ask because in weka, to make a string attribute, you do: |
| 17:58 | yacin | new Attribute("att3", (FastVector) null) |
| 17:59 | DeusExPikachu | or better yet this statement "it is impossible to extend an object returned by reify to new protocols/interfaces" |
| 17:59 | yacin | i tried (cast FastVector nil) |
| 17:59 | yacin | but it doesn't seem to work properly |
| 18:00 | qbg | yacin: Is there another 2 argument constructor for Attribute? |
| 18:01 | Chousuke | DeusExPikachu: the class of a reified thing is anonymous so... yes? |
| 18:01 | DeusExPikachu | Chousuke: how does one extend the object then? |
| 18:01 | DeusExPikachu | as in the syntax required to do so |
| 18:01 | Chousuke | DeusExPikachu: though you could extend an interface that the reified object implements, thus "extending" the reified object too. |
| 18:01 | Chousuke | DeusExPikachu: you don't really extend protocols to objects. you do it to classes |
| 18:02 | yacin | qbg: there are a couple |
| 18:02 | qbg | Are you using 1.2? |
| 18:02 | yacin | nah, unfortunately not |
| 18:02 | qbg | 1.1? |
| 18:02 | yacin | yes |
| 18:02 | DeusExPikachu | Chousuke: like basically I know I can extend a type with extend-type, but dont' know how to do with something returned by reify as reify returns an object as you said |
| 18:03 | qbg | Try (Attribute. "att3" #^FastVector nil); that might work |
| 18:03 | Chousuke | DeusExPikachu: yeah, you can't |
| 18:03 | Chousuke | DeusExPikachu: you'd need to know the class of the reified object, but you don't |
| 18:03 | qbg | Actually not, because you can't put metadata on nil.. |
| 18:03 | DeusExPikachu | ok, so that's an important distinction between reify and defrecord then |
| 18:04 | Chousuke | DeusExPikachu: but as I said, if the reified object implements an extended-to interface or the protocol directly, then of course it works. |
| 18:04 | DeusExPikachu | Chousuke: hmm I'm not seeing the example in my head |
| 18:05 | Chousuke | DeusExPikachu: reified objects implement interfaces |
| 18:05 | Chousuke | DeusExPikachu: and protocols can be extended to interfaces |
| 18:05 | Chousuke | DeusExPikachu: 1) reify interface 2) extend protocol to interface 3) protocol methods work with aforementioned reified object |
| 18:06 | DeusExPikachu | that last part, protocls can be extended to interfaces, does that mean the protocol takes on new methods from interface? |
| 18:06 | Chousuke | no, it means that you provide an implementation of the protocol for objects of the interface |
| 18:07 | yacin | qbg: yeah =\ |
| 18:07 | Chousuke | DeusExPikachu: protocols *cover* different data types. thus extending means you extend the range of data types they work with |
| 18:08 | Chousuke | DeusExPikachu: it's a bit backwards from the usual "extending" in OO languages |
| 18:08 | DeusExPikachu | Chousuke: so extending a protocol to an interface implies that an interface is a datatype? |
| 18:08 | Chousuke | DeusExPikachu: not really |
| 18:09 | DeusExPikachu | btw, interface, thats java only right Chousuke? |
| 18:09 | Chousuke | yes. |
| 18:10 | qbg | yacin: Maybe try (let [#^FastVector x nil] (Attribute. "att3" x))? |
| 18:10 | DeusExPikachu | hmm I guess from within clojure, its not possible then |
| 18:10 | Chousuke | DeusExPikachu: you could have some protocol, say, MyFancyMapping with a method apply-to-all extended to the Collection interface. |
| 18:10 | Chousuke | DeusExPikachu: then all Collection classes would work with the protocol |
| 18:11 | yacin | qbg: awesome. works! |
| 18:11 | Chousuke | DeusExPikachu: extending can be done from Clojure |
| 18:11 | DeusExPikachu | oh so extending a protocol is like redefining the protocol as the union of the old protocol and the interface? |
| 18:12 | DeusExPikachu | *union of the methods |
| 18:12 | Chousuke | DeusExPikachu: no, the protocol doesn't gain new methods |
| 18:12 | yacin | yeah, seems pretty ridiculous to me |
| 18:12 | Chousuke | DeusExPikachu: it just gains new kinds of objects that the existing methods work on |
| 18:12 | DeusExPikachu | ok, so then I can't define new methods for a reified object then |
| 18:12 | yacin | but i'm adding support for strings in clj-ml |
| 18:13 | Chousuke | DeusExPikachu: you can't define java methods but you can make them work with protocols |
| 18:15 | DeusExPikachu | so lets say (def foo (reify ...)), and later how would I allow some other protocol to work with foo if I don't have the type for foo, only foo itself? |
| 18:17 | Chousuke | DeusExPikachu: You should know the interfaces foo reifies as they're the only way to actually use the object. |
| 18:17 | Chousuke | DeusExPikachu: and through those you can make it work with a protocol |
| 18:18 | Chousuke | DeusExPikachu: the actuall class of the object is unknown and can't be used, but then again that shouldn't be a problem |
| 18:18 | DeusExPikachu | so lets say foo implements bar-protocol, then I extend bar-protocol to some other types, that doesn't add methods to foo though right? |
| 18:18 | Chousuke | extending protocols doesn't add methods. ever. |
| 18:19 | DeusExPikachu | right, but that was my original question |
| 18:19 | DeusExPikachu | reiterated, is it possible to add methods to a object returned by reify |
| 18:19 | Chousuke | java methods? |
| 18:19 | Chousuke | no |
| 18:20 | DeusExPikachu | and the yes part is clojure methods? |
| 18:20 | Chousuke | but again, it's possible to make it work with new protocols even after it has been created, through extending the interfaces. but protocol functions aren't methods. |
| 18:21 | Chousuke | extending to the interfaces, even |
| 18:21 | Chousuke | need to be careful with the wording, it's confusing enough without me being sloppy :P |
| 18:21 | DeusExPikachu | Chousuke: np, just trying to get this figured out |
| 18:22 | Chousuke | it might be easier if you just forget about objects for a while and consider only types |
| 18:22 | DeusExPikachu | thats fine, reify returns an instance of a type |
| 18:22 | Chousuke | a protocol is a set of functions and a set of types that those functions work with |
| 18:22 | Chousuke | the set of types is extensible |
| 18:22 | Chousuke | that's all |
| 18:22 | DeusExPikachu | right |
| 18:23 | DeusExPikachu | so how would you make a new protocol extend to foo? |
| 18:23 | DeusExPikachu | and foo is : (def foo (reify ...)) |
| 18:23 | Chousuke | well you'd have to know an interface that foo implements |
| 18:24 | DeusExPikachu | foo implements bar-protocol |
| 18:24 | Chousuke | well then there's no need to extend because it's already in the set :P |
| 18:24 | Chousuke | but let's say it implements only a java interface instead |
| 18:24 | DeusExPikachu | ... but I want to extend to new protocols |
| 18:24 | Chousuke | ah, hmm |
| 18:25 | Chousuke | well since direct protocol-implementing is done via an interface, I guess you can treat bar-protocol as if it were an interface ;P |
| 18:26 | Chousuke | I'm not sure about the syntax right now but it goes something like (extend-type the.package.bar-protocol some-other-protocol (othermethod ...)) |
| 18:26 | DeusExPikachu | extend-type can accept a protocol as its arg? I thought it only accepts types |
| 18:27 | Chousuke | well that's taking advantage of the fact taht protocols are backed by an interface. |
| 18:27 | Chousuke | but hm, that won't work in the general case. |
| 18:28 | DeusExPikachu | ok well regardless, so you call extend-type on bar-protocol to extend to baz protocol I'm guessing? |
| 18:28 | Chousuke | yeah, that ought to work. though only for things that implenet bar-protocol directly. |
| 18:28 | Chousuke | implement |
| 18:29 | Chousuke | it's probably a bit fragile :/ |
| 18:29 | DeusExPikachu | so foo implements bar, and now bar is extended to baz, so does that mean baz methods/fns whatever you call it works on foo? |
| 18:30 | Chousuke | yes. |
| 18:30 | DeusExPikachu | ok, thats a new to me |
| 18:31 | DeusExPikachu | I didn't know you could extend bar to baz, you say its fragile though |
| 18:31 | Chousuke | but only if foo directly implements bar. if foo is extended to the bar protocol afterwards instead, it probably won't work. |
| 18:31 | Chousuke | DeusExPikachu: it takes advantage of an implementation detail |
| 18:32 | Chousuke | namely that when you generate a protocol, a matching interface is generated too |
| 18:32 | Chousuke | and it's automatically made part of the protocol |
| 18:32 | DeusExPikachu | btw, foo directly implements bar in this case though right? what I wouldn't be able to do if there was another protocol bee, and baz is later extended to bee, foo wouldn't get bee? |
| 18:32 | Chousuke | right. |
| 18:32 | DeusExPikachu | ok, think its clear now |
| 18:32 | DeusExPikachu | great help |
| 18:33 | DeusExPikachu | I think because it won't work in the general case, its better in my case to use defrecord instead of reify |
| 18:33 | DeusExPikachu | I'm guessing reify has some performance advantages though compared to defrecord? |
| 18:34 | Chousuke | the mechanism of extension is the same in either case, but defrecord generates a named class so you don't need to extend a protocol to it "indirectly" |
| 18:34 | Chousuke | but no, no real performance advantages I think |
| 18:34 | Chousuke | reify is mostly meant for one-off implementations of java interfaces. |
| 18:35 | DeusExPikachu | oh really, what about memory consumption despite how little, defrecord does more stuff behind the scences than reify right? |
| 18:35 | Chousuke | well, yeah |
| 18:35 | lpetit | hi guys. As with every new tool, there will be protocol / type / record abuse. How would you recommend the use (and not abuse) of these new features to newcomers ? |
| 18:35 | DeusExPikachu | kk, thanks Chousuke |
| 18:36 | Chousuke | lpetit: that's a broad question :P |
| 18:36 | lpetit | Chousuke: oh really ? :-) |
| 18:36 | Chousuke | lpetit: I don't think anyone except rhickey has a clear idea what constitutes use and abuse of those things, yet. |
| 18:36 | dnolen | lpetit: I probably wouldn't recommend them to newcomers. |
| 18:37 | lpetit | Chousuke: I'm just preparing myself for the new lengthy "noob" questions :-p |
| 18:37 | dnolen | lpetit: maybe defrecord if someone really wants a struct |
| 18:37 | Chousuke | lpetit: I suppose warning against hierarchies would be a good start. ie. tell newbies not to try to derive or inherit things :P |
| 18:38 | qbg | Well, protocols are a subset of multimethods in a sense, so it would be related to that. |
| 18:38 | lpetit | dnolen: and if someone knows in advance that he will just need single dispatch type-based polymorphism |
| 18:39 | dnolen | lpetit: but I still wouldn't recommend. You can get that with multimethods, and it encourages newcomers to explore a much more generic style of programming. |
| 18:40 | dnolen | maps + multimethods still the way to go at the beginning I think. |
| 18:40 | lpetit | dnolen, Chousuke: you wouldn't recommend them to newcomers, but when 1.2 will be out, you will (and newcomers will) see "protocols" "datatypes" written everywhere in twitter, facebook, blog posts, infoq, etc. . And they will think "I can do my OO stuff in clojure now, yeah !" :-) |
| 18:41 | Chousuke | lpetit: they'll be right and wrong at the same time? :D |
| 18:41 | lpetit | Chousuke: google group will not support the traffic jam concerning these explanations ! :) |
| 18:42 | lpetit | s/concerning/related to/ |
| 18:42 | sexpbot | Chousuke: google group will not support the traffic jam related to these explanations ! :) |
| 18:42 | qbg | Google groups will go into an infinite loop! |
| 18:43 | dnolen | lpetit: I don't think it hurts for newcomers to explore them, just as much as they'll explore macros - I think it's constructive to guide people to explore eslewhere. |
| 18:44 | lpetit | dnolen: you're right. |
| 18:44 | dnolen | I learned a lot by hearing people say early on to use maps over structs. eventually it sunk in. |
| 18:45 | Chousuke | part of that was that structs really weren't that much of an improvement over maps |
| 18:46 | Chousuke | records are entirely different however |
| 20:41 | defn | it is absolutely uncanny how much rich and phillip glass look alike |
| 20:51 | defn | http://graphics.musicme.com/wp/fr/2351/Philip_Glass_018.jpg http://pragprog.com/magazines/2009-07/images/clojure/RichHickey.jpg |
| 20:51 | LuminousMonkey | Woah! |
| 20:52 | LuminousMonkey | It is uncanny... |
| 20:52 | defn | heh...thought it was sort of interesting |
| 20:53 | LuminousMonkey | That means I should be listening to Koyaanisqatsi while programming Clojure? :) |
| 20:53 | defn | haha! |
| 20:53 | defn | Naqoyqatsi might be better |
| 20:54 | LuminousMonkey | Only have Koyaanisqatsi, I should get some others. |
| 20:54 | defn | glass has a pretty massive collection of operas and the like |
| 20:55 | defn | his most recent work is called the book of longing -- it's all solo cello |
| 20:55 | defn | very awesome work though |
| 20:55 | defn | recommended. |
| 20:55 | LuminousMonkey | Nice. I shall see what I can find. Thanks. |
| 20:56 | defn | actually i take that back |
| 20:56 | defn | book of longing is all based on leonard cohen poetry |
| 20:57 | defn | ah yes, here it is: songs and poems for solo cello - wendy sutter |
| 22:36 | yacin | can you modify metadata of variables created by let? |
| 22:37 | mikem | yacin: you can generate a new var which contains the metadata you need based on the one created with let |
| 22:38 | hiredman | variables? |
| 22:38 | hiredman | let doesn't make vars |
| 22:38 | yacin | i realize i'm not being precise with my terminology |
| 22:38 | mikem | hiredman: actually, what is the correct term for the thing let creates? |
| 22:38 | yacin | but i think my intent is pretty clear |
| 22:38 | hiredman | let doesn't create anything |
| 22:39 | mikem | a binding, maybe? |
| 22:39 | hiredman | but a binding is not a thing |
| 22:39 | hiredman | mikem: show me a reference to a binding |
| 22:40 | mikem | so if I have (let [x 1] (println x)) and I want to refer to the x passed to println, what would I call it? |
| 22:40 | hiredman | you don't |
| 22:40 | mikem | i mean, what would I call it in english, when trying to explain this code to someone for example :) |
| 22:40 | hiredman | let means replace the occurances of this thing with the value of evaluating this other thing |
| 22:40 | hiredman | x is a name |
| 22:41 | hiredman | or a local |
| 22:44 | yacin | well, i'm trying to make the weird java idiom of casting null easy in clojure |
| 22:44 | yacin | i can do it with: (let [#^classname x nil] x) |
| 22:46 | yacin | but i'd like something along the lines of (cast-null ClassName) |
| 22:56 | qbg | yacin: (defmacro cast-null [c] `(let [~(with-meta 'x {:tag c}) nil] ~'x)) |
| 22:58 | yacin | qbg: righteous, thanks |
| 23:03 | mudge | hello |
| 23:03 | mudge | celar |
| 23:03 | mudge | clear |
| 23:03 | mudge | i guess this doesn't work like a bash prompt |
| 23:03 | mudge | i'm a newbie to clojure |
| 23:03 | mudge | i was wondering if someone could help me with a simple thing |
| 23:03 | yacin | sure |
| 23:04 | mudge | i want to implement a java interface, one of the java interface methods returns void, so what is the way in clojure to write a function the returns void? |
| 23:04 | mudge | should the clojure function return nil ? |
| 23:05 | qbg | How are you implementing the java interface? |
| 23:06 | mudge | using :gen-class and :implements inside ns |
| 23:06 | mudge | then writing functions that start with "-" |
| 23:07 | qbg | Chances are that it will either just work, or you might have to play with :methods |
| 23:07 | mudge | okay |
| 23:07 | mudge | maybe i'll make my functions return nil |
| 23:07 | mudge | its kind of like void |
| 23:08 | qbg | Given that the docstring for gen-class says about :methods "Do not repeat superclass/interface signatures here.", it should just work I think. |
| 23:09 | mudge | yea, qbg, makes sense, thanks |
| 23:10 | mudge | wow, gen-class has a long doc string |
| 23:10 | mudge | qbg, you gave me the idea to read the doc strings of these things |
| 23:10 | mudge | that's even better than an answer to my question |
| 23:10 | mudge | thanks |
| 23:16 | arohner | mudge: just out of curiosity, why did you pick gen-class over the alternatives? |
| 23:19 | mudge | arohner, I didn't pick gen-class, i picked :gen-class inside ns. are there alternatives to this? |
| 23:19 | qbg | proxy |
| 23:20 | mudge | ah, i don't really understand proxy, is it better then using gen-class ? |
| 23:21 | arohner | mudge: depends on your needs. gen-class is useful if you need to start from a command line, or in some other cases where java code you don't control calls your class |
| 23:21 | qbg | If you don't need a named class, gen-class is probably overkill |
| 23:21 | qbg | For implementing an interface, proxy is usually more than fine. |
| 23:21 | mudge | ah, i do need to compile my code to a class so it can be called by Java code |
| 23:22 | mudge | so i will need a my class with a name right? |
| 23:22 | arohner | mudge: can you go into more detail? |
| 23:23 | mudge | i'm intending on writing some clojure code that uses Java classes and interfaces and that then generates java classes so that another java program can use them |
| 23:24 | mudge | i'm writing a 3rd part module for a Java application |
| 23:24 | mudge | party* |
| 23:24 | mudge | 3rd party* |
| 23:24 | arohner | ah, yeah, then gen-class is probably what you want |
| 23:24 | mudge | okay, cool |
| 23:25 | arohner | just making sure ;-). a lot of newbies aren't always aware of the options |
| 23:25 | mudge | thanks |
| 23:25 | qbg | There is a ton of stuff in Clojure, so it is easy to miss stuff |
| 23:25 | mudge | i bet |
| 23:26 | qbg | find-doc is your friend |
| 23:43 | arohner | WTH is c1337? |
| 23:44 | tomoj | would be nice if clojurebot could pull out the description from the pom, and if people wrote good descriptions |
| 23:44 | arohner | it looks like a hello world kind of project |
| 23:46 | hiredman | meh |
| 23:51 | itistoday | what's the difference between: (defmacro time2 [expr times] `(time (dotimes [_# ~times] ~@expr))) |
| 23:51 | itistoday | and (defmacro time2 [expr times] (time `(dotimes [_# ~times] ~@expr))) |
| 23:51 | qbg | The second one doesn't do what you want |
| 23:53 | itistoday | what does the second one do and why? |
| 23:53 | qbg | The second one times, at macroexpansion time, how long it takes `(dotimes [_# ~times] ~@expr) to execute |
| 23:53 | qbg | Which is very fast, as it is just constructing a list |
| 23:53 | itistoday | gotcha... |
| 23:53 | itistoday | ok thanks qbg, that's a good explanation! |
| 23:56 | qbg | Also, you want (defmacro time2 [expr times] `(time (dotimes [_# ~times] ~expr))) |
| 23:56 | itistoday | qbg: can you walk me through the steps? (or point me somewhere that lists them?) |
| 23:56 | qbg | itistoday: You mean how macros work? |
| 23:56 | itistoday | qbg: ok thanks, it worked |
| 23:56 | itistoday | qbg: yeah |
| 23:57 | qbg | A macro is just a function that returns some code |
| 23:57 | itistoday | i'm trying to guess based on what you said at what time the list is constructed, and when things are evaluated |
| 23:57 | qbg | When the macro call is compiled, the compiler runs the macro with its arguments, unevaluated, and substitutes its return value in its place. |
| 23:58 | itistoday | let's take this as an example: (defmacro time2 [expr times] (time `(dotimes [_# ~times] ~expr))) |
| 23:59 | qbg | Okay |
| 23:59 | itistoday | so, when i define that, the macro is not compiled yet, right? or is it? |
| 23:59 | qbg | The macro is compiled to a function, and {:macro true} is placed on time2's var's metadata |