#clojure logs

2010-06-30

00:43technomancyanyone know when the final reviewer notes for the latest Joy of Clojure draft is due?
01:35scottjIs 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:46tomojscottj: every expression returns something..
02:00scottjtomoj: yeah, I thought maybe there might be a macro with a clever name that would abstract that away :)
02:49jowagwhat 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:04BahmanHi all!
03:28zmilajowag - seems, the ! sign is for fns with mutations
03:29Chousukeio stuff usually isn't marked with a bang
03:29ChousukeI think it's for functions which *could* be functional but aren't.
03:29Chousukeeg. the operations on transients.
03:40jowagYep, the io is what got me perplexed, why fns like slurp does not have a bang notation
03:41Chousukeyou can mark io functions with the io! macro so they will throw an error if used in transactions
03:42jowagyes I use it, but I was uncertain about the fn naming guidelines
03:42Chousukethey don't really exist :)
03:42Chousukeanything goes as long as you're consistent.
03:43jowagI see :)
03:46jowagI 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:02cais2002hi guys, is http://clojure.org/lazy the latest doc on laziness?
04:04esjMorning Good People
04:04LauJensenGood morning all
04:04BahmanMorning esj and LauJensen!
04:05LauJensencais2002: Typically the stuff on clojure.org relates to the latest stable release, which feels like ages ago
04:05cais2002good afernoon guys
04:05LauJensencais2002: Streams didnt get into Clojure, Chunks did
04:05cais2002am I supposed to get latest copy from github?
04:06LauJensenor via clojars, a snapshot
04:09cais2002great, let me try it out, thanks
04:13esjLau, cgrand: How did the clojure training go?
04:26cgrandesj: on the phone with Lau right now :-)
04:26esjplanning round 2 I hope :)
04:54LauJensenesj: Thats right :)
04:55bobo_same place? or too early to say perhaps
04:56LauJensenYes, 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:56LauJensen(although, picking a quality venue is always tricky. The one in Brussels was outstanding)
05:00bobo_:-)
05:01bobo_if only i could find any arguments to tell my employer to send me
05:02LauJensenI can give him a call if you want :)
05:02bobo_:-)
05:03bobo_there just isnt much clojure stuff for a consultant to take.
05:04lpetitbobo_: your employer may sometimes take some risks to be ahead of the concurrence.
05:04lpetitbobo_: and sending you for a 3-days course isn't such a great risk :)
05:04bobo_true
05:04bobo_well its money :-)
05:05LauJensenThere 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:05LauJensenlpetit: concurrence = competition
05:05bobo_yeh true
05:05bobo_i can atleast give it a try :-)
05:06LauJensenbobo_: 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:06bobo_early september is great timing atleast
05:06bobo_lol
05:07LauJensenyea we hope most people are back from holidays
05:09bobo_is the page for the last round gone? cant seem to find it
05:09LauJensenhttp://conj-labs.eu is still there, but registration is closed
05:11LauJensenI see the pictures under course/venue are actually still from Bruseels, but I'll update that once we find THE place :)
05:32esjLauJensen: after Brussels though, it can only be downhill..... at least in terms of beer !
05:35cgrandesj: 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:37npoektophi! 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:39cgrandnpoektop: because macros being functions is an impl detail
05:40Chousukenpoektop: if you need to do that, you're probably doing something weird
05:40npoektopis there a way to splice arglist to a macro?
05:40cgrandnpoektop: usually you would prefer something like (macroexpand-1 `(some-macro ~first-arg ~@'(rest-of-args)))
05:41cgrandbut like Chousuke sais if you need to manually macroexpand or "call" a macro you are probably doing something wrong
05:41Chousukenpoektop: from another macro you can generate your call to the other macro any way you want.
05:42Chousukeif you're trying to do it from a function then you're probably misusing macros
05:42Chousukewhat are you trying to do? maybe there's a better way.
05:43raekmacros are expanded at compile time
05:43Chousukealso 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:43raektheir input is unevaluated code
05:44Chousukefunctions can return clojure code too
05:44raekapplying a macro doesn't make much sense, since then the arguments will already be evaluated
05:44clojurebotcode-review is <rhickey> yikes
05:47Chousuke,((fn [vec-of-fn-names] `(do ~@(for [fn-name vec-of-fn-names] (list fn-name :somearg)))) '[foo bar zonk]); like this
05:47clojurebot(do (foo :somearg) (bar :somearg) (zonk :somearg))
05:47Chousukeand that you can pass to eval if you really need to, but eval too needs to be treated with suspicion :)
05:51npoektopi have this code: (defmodel ~collname (doall (map (fn [x#] (-> x# :name keyword)) conf#))). I'm trying to splice (doall (map...)) here.
05:52Chousukehm
05:52Chousukeis that within a syntax-quote?
05:53npoektopI guess so: `(do ... (defmodel...))
05:53Chousukeshow the whole macro please
05:53Chousuke~@(map (fn [x] ...)) ought to work though (no need for gensyms there since it's not part of the generated code)
05:53clojurebotmaps are *AWESOME*
05:54Chousukethough I'm not sure about the conf#
05:54npoektophttp://pastebin.com/UKSLSMhi
05:54Chousukeyou can't splice in things that are part of the generated code, the stuff needs to be available when the macro is called
05:55Chousukedon't put closing parens on their own lines please ;(
05:56npoektopit's not my code. i do not like it too)
05:57Chousukehm
05:59Chousukedo away with the let and just do (defmodel ~collname ~@(map (fn [x] (-> x :name keyword)) (process-columns collname-str columns))))
05:59cais2002guys, where can I find the definition of "reduce" ?
05:59Chousuke~def reduce
06:00Chousukenpoektop: it looks like the macro has the usual confusion about syntax-quote, the macro parameters, unquoting and how it all actually works :)
06:01Chousukea macro is a function of type anything -> clojure code
06:02Chousukeit just so happens that the result is also evaluated by the compiler
06:03cais2002Chousuke: don't get it. but clojurebot does its job.. interesting
06:03Chousukecais2002: that definition of reduce is rather more complicated than it needs to be, for performance reasons
06:06Chousukean 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:08cais2002why is it not found on http://richhickey.github.com/clojure/api-index.html
06:09cais2002or am I looking at the wrong place for api reference?
06:10npoektopThat assert is unneseccary here, right? (defmacro defmodel [modelname & attributes] (assert (seq? attributes)) ... )
06:17Chousukenpoektop: right.
06:18npoektopthank you
06:23Lajlaja menee alas ja Chousuke:n päähän
06:23LajlaNyt lajla on Chousuke:n päässä
06:29Chousuke:P
06:44LajlaChousuke, on hyvää sun päässä
06:45LajlaSun aivot on nätti ja hyvä.
06:45ChousukeLajla: you should keep nonsense on -casual :P
07:17npoektopi have a macro with a construction inside: '(do ... (defmodel ...)). defmodel is a macro. How to skip (defmodel ...) when i do not need it?
07:18npoektop'(do ... (if condition (defmodel ...))) does not work.
07:18jarturHi all.
07:18jarturDoes anybody know if mmcgrana happens to be here sometimes?
07:19lpetitnpoektop: you want some conditional code to execute in the macro, while constructing the code structure to be returned by the macro
07:20lpetitnpoektop: so you need to escape from the "code template" : `(do ... ~@(when condition `(defmodel ...)))
07:20npoektoplpetit, thank you
07:20npoektopi'll try it
07:20lpetit,`(do a (if true (defmodel)) b)
07:20clojurebot(do sandbox/a (if true (sandbox/defmodel)) sandbox/b)
07:20lpetit,`(do a ~(if true `(defmodel)) b)
07:20clojurebot(do sandbox/a (sandbox/defmodel) sandbox/b)
07:21lpetit,`(do a ~(if false `(defmodel)) b)
07:21clojurebot(do sandbox/a nil sandbox/b)
07:21lpetit,`(do a ~@(if false `(defmodel)) b)
07:21clojurebot(do sandbox/a sandbox/b)
07:21npoektopcool
07:21lpetit,`(do a ~@(if true `(defmodel)) b)
07:21cais2002hi, for this one, why do we need the additional identify call: (.instanceMember Classname args*) ==>
07:21clojurebot(do sandbox/a sandbox/defmodel sandbox/b)
07:21cais2002(. (identity Classname) instanceMember args*)
07:21lpetit,`(do a ~@(if true `((defmodel))) b)
07:21clojurebot(do sandbox/a (sandbox/defmodel) sandbox/b)
07:22lpetitnpoektop: there we are, if you want to avoid inserting a nil instead of defmodel when the condition is false, this form works:
07:22lpetit,`(do a ~@(if true `((defmodel))) b)
07:22clojurebot(do sandbox/a (sandbox/defmodel) sandbox/b)
07:22lpetit,`(do a ~@(if false `((defmodel))) b)
07:22clojurebot(do sandbox/a sandbox/b)
07:22lpetitnpoektop: but if you don't care, then the following form is easier to understand:
07:22lpetit,`(do a ~(if true `(defmodel)) b)
07:22clojurebot(do sandbox/a (sandbox/defmodel) sandbox/b)
07:23lpetit,`(do a ~(if false `(defmodel)) b)
07:23clojurebot(do sandbox/a nil sandbox/b)
07:24npoektoplpetit, thank you very much! )
07:25lpetitnpoektop: np
07:31thetafp(+ 1 2)
07:31clojurebot3
07:31jarturso no mmcgrana here, aye?
07:34cais2002(reduce + 1 (2 3))
07:35cais2002(reduce + 1 '(2 3))
07:35cais2002(+ 1 2)
07:35clojurebot3
07:38Chousukethat + thing is a special feature :P
07:38Chousukeyou need to use ,(foo) if you want to eval clojure code
07:38Chousuke(+ 5 6
07:38Chousuke(+ 5 6)
07:38clojurebot*suffusion of yellow*
07:38Chousukelike that :P
07:39cais2002,(+ 5 7)
07:39clojurebot12
07:39cais2002,(reduce + 1 '(2 3))
07:39clojurebot6
07:39cais2002,(infinite loop)
07:39clojurebotjava.lang.Exception: Unable to resolve symbol: infinite in this context
07:40Chousukeinfinite loops will last 10 seconds
07:46cais2002ok, that's what I thought would have happened
07:47cais2002why does this not work? (macroexpand '((memfn charAt i) "ab" 1))
08:27jowag,(/ 1 0)
08:27clojurebotjava.lang.ArithmeticException: Divide by zero
09:01bartjer, is it possible to issue bash commands from the REPL ?
09:02LauJensenbartj: using shell-out from contrib, yes
09:02LauJensenin Emacs there's also M-!
09:07LauJensen,(use 'clojure.contrib.shell)
09:07clojurebotjava.io.FileNotFoundException: Could not locate clojure/contrib/shell__init.class or clojure/contrib/shell.clj on classpath:
09:08LauJensenwell thats no fun
09:08chouser,(require 'clojure.java.shell)
09:08clojurebotnil
09:09LauJensensame thing?
09:09chouserdoubt it'll do you much good though.
09:09chouser,(clojure.java.shell/sh "echo" "hello")
09:09clojurebotjava.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)
09:10LauJensenchouser: Is it the old contrib shell thats been moved?
09:10bartjand then do a "(echo hello)" ?
09:10chouserLauJensen: yes
09:11LauJensenchouser: Is there a list anywhere on which parts of contrib moved where?
09:11LauJensenbartj: No, that is the actual shell call
09:11chouserbartj: 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:11chouserhm, sh isn't really a good name
09:11LauJensenbartj: http://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/shell.clj#L138
09:12chousershould be shell/run or shell/launch or something.
09:13bartjgee, I don't see any output
09:13bartj;(ls)
09:16chouser(sh "ls")
09:18bartjchouser: yay! thanks!
09:28Licensercooookies
09:35bartjLicenser: for everyone ?
09:36Licenserof cause
09:39LauJensenLicenser: Just doesnt feel right without Raynes here to share the fun
09:40Licenseryea :(
09:40Licenserbut well we can leave him some crumbs
09:41LauJensenLicenser: Hows your Clojure driven game coming along?
09:42LicenserLauJensen: not good, the team kind of backstabed me and left me alone with it - very frustrating experience
09:42LauJensenOh
09:45Licenser__So now i can keep chatting :)
09:46LauJensenLicenser__: 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:48Licenser__LauJensen: That would Be cool it sounds a bit like eve online so
09:48LauJensenNever played Eve online, but from what I've heard they would be completely different
09:48bartjLauJensen: this is the one - http://en.wikipedia.org/wiki/Freelancer_(video_game)
09:48bartj?
09:49LauJensenhttp://www.gamespot.com/pc/sim/freelancer/index.html?tag=result%3Btitle%3B0
09:49Licenser__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:50Licenser__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:05TakeVWhy 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:15chouserTakeV: most likely because your clj file is not on the classpath in the appropriate place
10:16TakeVchouser: I'm not using a clj file, just the REPL. I need a file?
10:16chouser(doc compile)
10:16clojurebot"([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:17chouseryes, 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:18chouserif you're not trying to get a .class file, you don't need 'compile'
10:19TakeVYeah, trying to do ahead of time compilation.
10:19TakeVAnd I need to do (set! *compile-path* "/path/to/clj/file")?
10:20chouserno
10:22pjstadigyou need "path/to/clj/file" to be in your classpath
10:23chouserAOT compilation can be a bit tricky to set up. I think there are good tutorials, though.
10:24TakeVchouser: Yeah, I'm reading them but they are not working. :\
10:25chouserthose would be the bad tutorials. :-)
10:25LauJensenhaha
10:25TakeVhttp://clojure.org/compilation -- This one?
10:25LauJensenthats true. But on a new lein project just as an example. Start a repl, (set! *compile-path* "/classes") and compile, thats it
11:20mtopolnikwhat would be the idiomatic way to make a memoized defn?
11:20mtopolnikcurrently I have this:
11:20mtopolnik(defn- myfun [arg] ...)
11:21mtopolnikand then (def #^{:private true} myfun (memoize myfun))
11:23Chousukemtopolnik: that's pretty much it
11:23Chousukemtopolnik: there's a defn-memoize or something in contrib to make that a bit neater though
11:24mtopolnikyes, i'm looking for just such a thing
11:24mtopolnikbut it also needs to be private
11:24Chousukethat's not a problem
11:24mtopolnikof course, there isn't much work in defining it myself
11:24AWizzArd,(doc defn-memo)
11:24clojurebot"clojure.contrib.def/defn-memo;[[fn-name & defn-stuff]]; Just like defn, but memoizes the function using clojure.core/memoize"
11:24Chousukejust add the metadata.
11:24AWizzArdI just defn-memo, easy to use.
11:24mtopolnikyeah, that'll do it
11:25AWizzArdmtopolnik: but of course, it is potentially able to introduce a "memory leak" into your app.
11:25mtopolniksure, like any memoize
11:25mtopolnikbut i've got that under control
11:25AWizzArdk
11:25mtopolniki'm memoizing all the setter-functions for my java beans
11:25mtopolnikthere won't be too many of those
11:26mtopolnikin the hundreds tops
11:26mtopolniki guess a lambda doesn't use too much memory
11:27AWizzArdnot much
11:27Chousukemtopolnik: the problem isn't the number of the functions, it's the number of different arguments they get called with
11:28mtopolniki wanted to say, my memoized function is a constructor for setter funtions
11:28mtopolnikso it will get called with only a couple hundred different arguments (property names)
11:29mtopolnikalso, 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:30hiredman,(doc resolve)
11:30clojurebot"([sym]); same as (ns-resolve *ns* symbol)"
11:30hiredman,(ns-resolve (create-ns 'clojure.core) 'a)
11:30clojurebotnil
12:08Fossija
12:30polypus~ping
12:30clojurebotPONG!
12:46cais2002~pong
12:46clojurebotQinfengxiang!
12:52_fogus_,Q
12:52clojurebotjava.lang.Exception: Unable to resolve symbol: Q in this context
12:57polypusare the hashcodes for datastructures generated at creation time or only when they are first needed by some equivalence test?
12:58qbgIt seems to be usually by need
13:02polypusalso, 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:33LauJensentechnomancy, hugod: M-. works great for the clj fns, but are there any way to dig into the java source as well ?
13:34scottjM-. works on any language if you use ctags
13:34LauJensenscottj: How do you get it to take you to one of the java files of Clojure.core?
13:35hugodLauJensen: specifically for core?
13:36scottjLauJensen, read emacs docs on ctags/etags
13:36LauJensenNo not really, but its usually those functions I want to look up
13:36LauJensen@ hugod
13:37technomancyLauJensen: I don't think there's a good solution for that; seeing signatures via slime-inspector is the best I have managed.
13:37scottjshort version: create TAGS file from source, load it, search it
13:37technomancybut if you really need it, yeah... ctags it is.
13:37hugodLauJensen scottj's suggestion seems the easiest - bind to a different key
13:37LauJensenIts 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:38technomancyLauJensen: well, slime isn't really designed to work with Java =)
13:38LauJensentrue
13:38LauJensenAlright, I'll look up ctags
13:38LauJensenthats scottj, hugod & technomancy :)
13:38scottjbtw 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:39hugodLauJensen: I use find . -name '*.java' | xargs etags --language=java
13:39technomancyscottj: right, but you have to build and constantly refresh the tags table
13:39technomancyseems like more work
13:39LauJensenhugod: oh ok, and just run that on the git repo?
13:39hugodLauJensen: at the root
13:40hugodof the repo
13:40LauJensenyea
13:40scottjtechnomancy: one command
13:43LauJensentechnomancy: one love
13:50shooverscottj: do you run that in a file save hook or anything for constant updates?
13:55LauJensenhugod: Your shellcall works fine, so its seems odd to me that this doesnt: find . -name '*.java' -type f -exec etags.emacs --language=java '{}' \;
13:56LauJensenIt 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:00hugodLauJensen: xargs is presumably calling etags once with all the files as arguments
14:01hugodLauJensen: I see etags has a -a argument
14:03LauJensenaha
14:03LauJensenhugod: Is there anyway I can move the TAGS file to ~/.emacs.d and reference it from my .emacs, or how do you integrate?
14:04hugodLauJensen: first time you call find-tag it asks for the TAG file
14:05hugodLauJensen: I use it across several projects, so don't load any tag file by default
14:06LauJensenok, cool, thanks
14:06clojurebotnamespaces 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:20bobo_hm, is there any "ok i installed the emacs-starter-kit now what" blog or similar? :-)
14:20LauJensenbobo_: To launch a repl, or to start coding?
14:20bobo_no more, this is what it can do
14:20LauJensenah - Sorry I dont know that kit very well
14:21bhenrybobo_ http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs
14:21bhenryif you haven't gotten the elpa stuff from esk yet
14:23rhickeyClojure now at: http://github.com/clojure
14:25LauJensenrhickey: fancy :)
14:34polypusmost efficient way to remove N items from end of vector, getting vector back?
14:35polypusis it best to just pop multiple times?
14:36hoeckpolypus: maybe that, or use subvec
14:37polypushoeck: thanks, forgot about that one
14:37hoeckdocs say its O(1)
14:37polypusthat's what i need
14:44technomancysubvec won't allow elements in the original vector to get GC'd though, so watch out
14:47polypustechnomancy: thanks for the heads up.
15:08rhickeypjstadig: fixed that problem from the other day: http://github.com/clojure/clojure/commit/0f4b6495347dc7d9601cc0907d5d08dd861bb3aa
15:13LauJensenrhickey: 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:17pjstadigrhickey: thanks...though I think that was actually a separate issue than I eventually realized was my problem
15:17pjstadigi think my problem ended up being that keywords are not GC'ed
15:18polypusforgive my ignorance, but what's the stu bomb?
15:18Raynespolypus: Stuart Halloway, I imagine.
15:18polypusbut what's the bomb?
15:18LauJensenpolypus: Yea Stuart, and the bomb was the 11500 lines he commited that day
15:18RaynesTons of commits from Stu.
15:18danlarkinsee kevin downey's patch to clojure-dev for more details on the keyword interning problem
15:19polypusahh
15:19danlarkinunfortunately it's complicated :(
15:20rhickeypjstadig: yeah, keywords are not yet held by weak refs, they'll need a similar treatment in order to be tolerant of ongoing generation
15:23danlarkinI moved build.clojure.org to point to the new clojure github fyi
15:34rhickeydanlarkin: cool
15:35polypusis into! planned for transients. what about peek on transient vectors?
15:54wolfjbwhere 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:55lancepantzwolfjb: that's just an exception in either your source or your test
15:56Rayneswolfjb: http://java.ociweb.com/mark/clojure/article.html#Testing
15:56wolfjbRaynes: thanks
15:58wolfjblancepantz: 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:59lancepantzwolfjb: you have to use myproject.core-test in your test
15:59raek(ns myproject.core-test (:use myproject.core))
15:59wolfjbthanks
16:00lancepantzwolfjb: no prob, ask away
16:00wolfjbthanks!
16:50replacarhickey: are you here?
16:50rhickeyreplaca: yes
16:50replacathe clojure org is now the official repo?
16:51replacai see that you're pushing stuff there
16:51rhickeyreplaca: in the process, do you want me to change the hook?
16:51replacayeah, the hook should be wherever you're pushing to
16:51rhickeyreplaca: I thought Stu was getting in touch with you to coordinate
16:52dsophmm how to call the overwritten super class method in a gen-class?
16:52replacaalso, I wanted to know where to push contrib changes and autodoc pages
16:52replacarhickey: no, I hadn't heard from him yet
16:52rhickeyyes, please to clojure now
16:52replacaok. we'll have to update links on clojure.org
16:53replacato point at the "new" autodoc
16:53replacaI'll get it building to there tonight (assuming github pages work with organizations)
16:54rhickeyreplaca: ok, hooks are on in the clojure repos
16:55rhickeyreplaca: let me know if you need any settings tweaked, I think you should have the privileges you need
17:02chouserso is the official git repo moving? was there an announcement I missed?
17:03lpetitwhat what ? :)
17:04replacachouser: 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:05rhickeychouser: yes, we are in the process of moving, will 'announce' when everything is in place. We're pushing to clojure from now on
17:06chouserah, I see it. http://github.com/clojure/clojure but not quite ready yet?
17:07rhickeychouser: close, needs docs, downloads etc. hooks in place to assembla, all privileges in place
17:07chouserhuh, didn't know I was a member. I wonder where I can see a list of the organizations I'm a member of.
17:07chouserrhickey: excellent. sounds good.
17:14dsopdoes someone know how to add an init function to defservice?
17:14dsopthat is called during servlet initialization?
17:19RaynesIt's a shame that all of those 956 watchers will have to watch the new repo.
17:19RaynesOrganizations are confusing.
17:19Raynes:p
17:43wolfjbis there a mocking mechanism (like JMock or Mockito or similar) for clojure?
17:44bhenrychouser click "switch context" in the top(ish) right of the github home page to see all your orgs.
17:47wolfjbokay, found test-expect, but no doc?
17:47ChousukeRaynes: at least switching the url of a remote in git is trivial :P
17:47ChousukeRaynes: no need to reclone a repository
17:50replacaChousuke: do I edit the file to do that or is there a git command?
17:50Chousukegit remote set-url remotename new-url
17:50Chousukeremotename should be origin in this case :)
17:50replacaChousuke: thanks!
17:51Chousukegit's concept of remotes is excellent
17:51replacaChousuke: 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:52Chousukethe original server is just given a default name, other than that, it's just like any other remote :P
17:52technomancycan also edit .git/config
17:52ChousukeI have two remotes in my local git repo
17:52Chousukeone for rhickey's repository, and one for my own clone
17:52Chousukeon github
17:53Chousukehaven't updated it in a while though :P
17:57yacincan you cast nil to something in clojure like you can cast null to an object in java?
17:57yacinlike
17:57DeusExPikachuis this statement correct? "it is impossible to extend an object returned by reify"
17:57yacin(FastVector) null
17:58yacini ask because in weka, to make a string attribute, you do:
17:58yacinnew Attribute("att3", (FastVector) null)
17:59DeusExPikachuor better yet this statement "it is impossible to extend an object returned by reify to new protocols/interfaces"
17:59yacini tried (cast FastVector nil)
17:59yacinbut it doesn't seem to work properly
18:00qbgyacin: Is there another 2 argument constructor for Attribute?
18:01ChousukeDeusExPikachu: the class of a reified thing is anonymous so... yes?
18:01DeusExPikachuChousuke: how does one extend the object then?
18:01DeusExPikachuas in the syntax required to do so
18:01ChousukeDeusExPikachu: though you could extend an interface that the reified object implements, thus "extending" the reified object too.
18:01ChousukeDeusExPikachu: you don't really extend protocols to objects. you do it to classes
18:02yacinqbg: there are a couple
18:02qbgAre you using 1.2?
18:02yacinnah, unfortunately not
18:02qbg1.1?
18:02yacinyes
18:02DeusExPikachuChousuke: 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:03qbgTry (Attribute. "att3" #^FastVector nil); that might work
18:03ChousukeDeusExPikachu: yeah, you can't
18:03ChousukeDeusExPikachu: you'd need to know the class of the reified object, but you don't
18:03qbgActually not, because you can't put metadata on nil..
18:03DeusExPikachuok, so that's an important distinction between reify and defrecord then
18:04ChousukeDeusExPikachu: but as I said, if the reified object implements an extended-to interface or the protocol directly, then of course it works.
18:04DeusExPikachuChousuke: hmm I'm not seeing the example in my head
18:05ChousukeDeusExPikachu: reified objects implement interfaces
18:05ChousukeDeusExPikachu: and protocols can be extended to interfaces
18:05ChousukeDeusExPikachu: 1) reify interface 2) extend protocol to interface 3) protocol methods work with aforementioned reified object
18:06DeusExPikachuthat last part, protocls can be extended to interfaces, does that mean the protocol takes on new methods from interface?
18:06Chousukeno, it means that you provide an implementation of the protocol for objects of the interface
18:07yacinqbg: yeah =\
18:07ChousukeDeusExPikachu: protocols *cover* different data types. thus extending means you extend the range of data types they work with
18:08ChousukeDeusExPikachu: it's a bit backwards from the usual "extending" in OO languages
18:08DeusExPikachuChousuke: so extending a protocol to an interface implies that an interface is a datatype?
18:08ChousukeDeusExPikachu: not really
18:09DeusExPikachubtw, interface, thats java only right Chousuke?
18:09Chousukeyes.
18:10qbgyacin: Maybe try (let [#^FastVector x nil] (Attribute. "att3" x))?
18:10DeusExPikachuhmm I guess from within clojure, its not possible then
18:10ChousukeDeusExPikachu: you could have some protocol, say, MyFancyMapping with a method apply-to-all extended to the Collection interface.
18:10ChousukeDeusExPikachu: then all Collection classes would work with the protocol
18:11yacinqbg: awesome. works!
18:11ChousukeDeusExPikachu: extending can be done from Clojure
18:11DeusExPikachuoh so extending a protocol is like redefining the protocol as the union of the old protocol and the interface?
18:12DeusExPikachu*union of the methods
18:12ChousukeDeusExPikachu: no, the protocol doesn't gain new methods
18:12yacinyeah, seems pretty ridiculous to me
18:12ChousukeDeusExPikachu: it just gains new kinds of objects that the existing methods work on
18:12DeusExPikachuok, so then I can't define new methods for a reified object then
18:12yacinbut i'm adding support for strings in clj-ml
18:13ChousukeDeusExPikachu: you can't define java methods but you can make them work with protocols
18:15DeusExPikachuso 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:17ChousukeDeusExPikachu: You should know the interfaces foo reifies as they're the only way to actually use the object.
18:17ChousukeDeusExPikachu: and through those you can make it work with a protocol
18:18ChousukeDeusExPikachu: the actuall class of the object is unknown and can't be used, but then again that shouldn't be a problem
18:18DeusExPikachuso 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:18Chousukeextending protocols doesn't add methods. ever.
18:19DeusExPikachuright, but that was my original question
18:19DeusExPikachureiterated, is it possible to add methods to a object returned by reify
18:19Chousukejava methods?
18:19Chousukeno
18:20DeusExPikachuand the yes part is clojure methods?
18:20Chousukebut 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:21Chousukeextending to the interfaces, even
18:21Chousukeneed to be careful with the wording, it's confusing enough without me being sloppy :P
18:21DeusExPikachuChousuke: np, just trying to get this figured out
18:22Chousukeit might be easier if you just forget about objects for a while and consider only types
18:22DeusExPikachuthats fine, reify returns an instance of a type
18:22Chousukea protocol is a set of functions and a set of types that those functions work with
18:22Chousukethe set of types is extensible
18:22Chousukethat's all
18:22DeusExPikachuright
18:23DeusExPikachuso how would you make a new protocol extend to foo?
18:23DeusExPikachuand foo is : (def foo (reify ...))
18:23Chousukewell you'd have to know an interface that foo implements
18:24DeusExPikachufoo implements bar-protocol
18:24Chousukewell then there's no need to extend because it's already in the set :P
18:24Chousukebut let's say it implements only a java interface instead
18:24DeusExPikachu... but I want to extend to new protocols
18:24Chousukeah, hmm
18:25Chousukewell since direct protocol-implementing is done via an interface, I guess you can treat bar-protocol as if it were an interface ;P
18:26ChousukeI'm not sure about the syntax right now but it goes something like (extend-type the.package.bar-protocol some-other-protocol (othermethod ...))
18:26DeusExPikachuextend-type can accept a protocol as its arg? I thought it only accepts types
18:27Chousukewell that's taking advantage of the fact taht protocols are backed by an interface.
18:27Chousukebut hm, that won't work in the general case.
18:28DeusExPikachuok well regardless, so you call extend-type on bar-protocol to extend to baz protocol I'm guessing?
18:28Chousukeyeah, that ought to work. though only for things that implenet bar-protocol directly.
18:28Chousukeimplement
18:29Chousukeit's probably a bit fragile :/
18:29DeusExPikachuso 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:30Chousukeyes.
18:30DeusExPikachuok, thats a new to me
18:31DeusExPikachuI didn't know you could extend bar to baz, you say its fragile though
18:31Chousukebut only if foo directly implements bar. if foo is extended to the bar protocol afterwards instead, it probably won't work.
18:31ChousukeDeusExPikachu: it takes advantage of an implementation detail
18:32Chousukenamely that when you generate a protocol, a matching interface is generated too
18:32Chousukeand it's automatically made part of the protocol
18:32DeusExPikachubtw, 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:32Chousukeright.
18:32DeusExPikachuok, think its clear now
18:32DeusExPikachugreat help
18:33DeusExPikachuI think because it won't work in the general case, its better in my case to use defrecord instead of reify
18:33DeusExPikachuI'm guessing reify has some performance advantages though compared to defrecord?
18:34Chousukethe 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:34Chousukebut no, no real performance advantages I think
18:34Chousukereify is mostly meant for one-off implementations of java interfaces.
18:35DeusExPikachuoh really, what about memory consumption despite how little, defrecord does more stuff behind the scences than reify right?
18:35Chousukewell, yeah
18:35lpetithi 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:35DeusExPikachukk, thanks Chousuke
18:36Chousukelpetit: that's a broad question :P
18:36lpetitChousuke: oh really ? :-)
18:36Chousukelpetit: I don't think anyone except rhickey has a clear idea what constitutes use and abuse of those things, yet.
18:36dnolenlpetit: I probably wouldn't recommend them to newcomers.
18:37lpetitChousuke: I'm just preparing myself for the new lengthy "noob" questions :-p
18:37dnolenlpetit: maybe defrecord if someone really wants a struct
18:37Chousukelpetit: I suppose warning against hierarchies would be a good start. ie. tell newbies not to try to derive or inherit things :P
18:38qbgWell, protocols are a subset of multimethods in a sense, so it would be related to that.
18:38lpetitdnolen: and if someone knows in advance that he will just need single dispatch type-based polymorphism
18:39dnolenlpetit: 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:40dnolenmaps + multimethods still the way to go at the beginning I think.
18:40lpetitdnolen, 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:41Chousukelpetit: they'll be right and wrong at the same time? :D
18:41lpetitChousuke: google group will not support the traffic jam concerning these explanations ! :)
18:42lpetits/concerning/related to/
18:42sexpbotChousuke: google group will not support the traffic jam related to these explanations ! :)
18:42qbgGoogle groups will go into an infinite loop!
18:43dnolenlpetit: 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:44lpetitdnolen: you're right.
18:44dnolenI learned a lot by hearing people say early on to use maps over structs. eventually it sunk in.
18:45Chousukepart of that was that structs really weren't that much of an improvement over maps
18:46Chousukerecords are entirely different however
20:41defnit is absolutely uncanny how much rich and phillip glass look alike
20:51defnhttp://graphics.musicme.com/wp/fr/2351/Philip_Glass_018.jpg http://pragprog.com/magazines/2009-07/images/clojure/RichHickey.jpg
20:51LuminousMonkeyWoah!
20:52LuminousMonkeyIt is uncanny...
20:52defnheh...thought it was sort of interesting
20:53LuminousMonkeyThat means I should be listening to Koyaanisqatsi while programming Clojure? :)
20:53defnhaha!
20:53defnNaqoyqatsi might be better
20:54LuminousMonkeyOnly have Koyaanisqatsi, I should get some others.
20:54defnglass has a pretty massive collection of operas and the like
20:55defnhis most recent work is called the book of longing -- it's all solo cello
20:55defnvery awesome work though
20:55defnrecommended.
20:55LuminousMonkeyNice. I shall see what I can find. Thanks.
20:56defnactually i take that back
20:56defnbook of longing is all based on leonard cohen poetry
20:57defnah yes, here it is: songs and poems for solo cello - wendy sutter
22:36yacincan you modify metadata of variables created by let?
22:37mikemyacin: you can generate a new var which contains the metadata you need based on the one created with let
22:38hiredmanvariables?
22:38hiredmanlet doesn't make vars
22:38yacini realize i'm not being precise with my terminology
22:38mikemhiredman: actually, what is the correct term for the thing let creates?
22:38yacinbut i think my intent is pretty clear
22:38hiredmanlet doesn't create anything
22:39mikema binding, maybe?
22:39hiredmanbut a binding is not a thing
22:39hiredmanmikem: show me a reference to a binding
22:40mikemso 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:40hiredmanyou don't
22:40mikemi mean, what would I call it in english, when trying to explain this code to someone for example :)
22:40hiredmanlet means replace the occurances of this thing with the value of evaluating this other thing
22:40hiredmanx is a name
22:41hiredmanor a local
22:44yacinwell, i'm trying to make the weird java idiom of casting null easy in clojure
22:44yacini can do it with: (let [#^classname x nil] x)
22:46yacinbut i'd like something along the lines of (cast-null ClassName)
22:56qbgyacin: (defmacro cast-null [c] `(let [~(with-meta 'x {:tag c}) nil] ~'x))
22:58yacinqbg: righteous, thanks
23:03mudgehello
23:03mudgecelar
23:03mudgeclear
23:03mudgei guess this doesn't work like a bash prompt
23:03mudgei'm a newbie to clojure
23:03mudgei was wondering if someone could help me with a simple thing
23:03yacinsure
23:04mudgei 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:04mudgeshould the clojure function return nil ?
23:05qbgHow are you implementing the java interface?
23:06mudgeusing :gen-class and :implements inside ns
23:06mudgethen writing functions that start with "-"
23:07qbgChances are that it will either just work, or you might have to play with :methods
23:07mudgeokay
23:07mudgemaybe i'll make my functions return nil
23:07mudgeits kind of like void
23:08qbgGiven that the docstring for gen-class says about :methods "Do not repeat superclass/interface signatures here.", it should just work I think.
23:09mudgeyea, qbg, makes sense, thanks
23:10mudgewow, gen-class has a long doc string
23:10mudgeqbg, you gave me the idea to read the doc strings of these things
23:10mudgethat's even better than an answer to my question
23:10mudgethanks
23:16arohnermudge: just out of curiosity, why did you pick gen-class over the alternatives?
23:19mudgearohner, I didn't pick gen-class, i picked :gen-class inside ns. are there alternatives to this?
23:19qbgproxy
23:20mudgeah, i don't really understand proxy, is it better then using gen-class ?
23:21arohnermudge: 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:21qbgIf you don't need a named class, gen-class is probably overkill
23:21qbgFor implementing an interface, proxy is usually more than fine.
23:21mudgeah, i do need to compile my code to a class so it can be called by Java code
23:22mudgeso i will need a my class with a name right?
23:22arohnermudge: can you go into more detail?
23:23mudgei'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:24mudgei'm writing a 3rd part module for a Java application
23:24mudgeparty*
23:24mudge3rd party*
23:24arohnerah, yeah, then gen-class is probably what you want
23:24mudgeokay, cool
23:25arohnerjust making sure ;-). a lot of newbies aren't always aware of the options
23:25mudgethanks
23:25qbgThere is a ton of stuff in Clojure, so it is easy to miss stuff
23:25mudgei bet
23:26qbgfind-doc is your friend
23:43arohnerWTH is c1337?
23:44tomojwould be nice if clojurebot could pull out the description from the pom, and if people wrote good descriptions
23:44arohnerit looks like a hello world kind of project
23:46hiredmanmeh
23:51itistodaywhat's the difference between: (defmacro time2 [expr times] `(time (dotimes [_# ~times] ~@expr)))
23:51itistodayand (defmacro time2 [expr times] (time `(dotimes [_# ~times] ~@expr)))
23:51qbgThe second one doesn't do what you want
23:53itistodaywhat does the second one do and why?
23:53qbgThe second one times, at macroexpansion time, how long it takes `(dotimes [_# ~times] ~@expr) to execute
23:53qbgWhich is very fast, as it is just constructing a list
23:53itistodaygotcha...
23:53itistodayok thanks qbg, that's a good explanation!
23:56qbgAlso, you want (defmacro time2 [expr times] `(time (dotimes [_# ~times] ~expr)))
23:56itistodayqbg: can you walk me through the steps? (or point me somewhere that lists them?)
23:56qbgitistoday: You mean how macros work?
23:56itistodayqbg: ok thanks, it worked
23:56itistodayqbg: yeah
23:57qbgA macro is just a function that returns some code
23:57itistodayi'm trying to guess based on what you said at what time the list is constructed, and when things are evaluated
23:57qbgWhen the macro call is compiled, the compiler runs the macro with its arguments, unevaluated, and substitutes its return value in its place.
23:58itistodaylet's take this as an example: (defmacro time2 [expr times] (time `(dotimes [_# ~times] ~expr)))
23:59qbgOkay
23:59itistodayso, when i define that, the macro is not compiled yet, right? or is it?
23:59qbgThe macro is compiled to a function, and {:macro true} is placed on time2's var's metadata