#clojure logs

2009-08-09

00:51alphaeusWhat's the idiomatic way for saying give me the item in coll that maximizes function f?
00:53_mst,(apply max-key #(* % %) [-10 1 2 3 4 5])
00:53clojurebot-10
00:54alphaeusthanks _mst
00:54alphaeuswhy key in max-key?
00:56_mstI know common lisp uses the term "key" for a function that gets applied to a value before a comparison is made. Not sure if clojure adopted it from there
01:01mark_the_piratedoes anybody know why I can't get threads to print to the emacs+slime repl st. out?
01:03alphaeusmark_the_pirate: do they print to *inferior-lisp* buffer?
01:03mark_the_pirateyes
01:07alphaeusmark_the_pirate: maybe M-x slime-redirect-inferior-output
01:08mark_the_piratealphaeus, that works. thanks.
01:09alphaeusde nada
01:44bradbeveridgeI'm trying to build a simple swing app & I'm having problems with the mixing of functional and imperative. For example, I want to control where something is on a custom JPanel with a slider, but all the ways I've tried to connect the slider to the variable feel bad. What is the idiomatic way to do that kind of thing?
01:53mebaran151what import statement would be forward compatible for test-is?
01:54mebaran151right now, when I use the latest clojure contrib require test-is from contrib doesn't work
01:54mebaran151is there anyway to specify to use either clojure.test or clojure.contrib.test-is, whichever is available?
02:12tomojI need to have a big structmap in mememory at all times, but I also need it to be persistent. suggestions?
02:15alphaeusWhen you memoize a function that has a recur, when it recurs will it consult the cache for those recur arguments?
02:16hiredman~def memoize
02:17hiredmanmo
02:17hiredmanman
02:17hiredmanwhy did I even get the source
02:17hiredmanmemoize wraps the function in another function
02:19carki think it will not check the cach on recur
02:19carkcache
02:20hiredmanit cannot
02:20carkit might be possible to write a with-memoize-loop macro
02:21hiredmanthe recur takes place in the function that is wrapped by the funtion that memoize creates
02:27mebaran151can you catch a StackOverflowException?
02:28lisppaste8alphaeus pasted "memoize with recur" at http://paste.lisp.org/display/85081
02:29carkwaitwaitwait
02:29alphaeuscark: hiredman: in that paste I have some code that appears to me to be sped up using memoize with recur
02:29carkit isn't
02:29carkyou're memoizing another function
02:30cark(memoize collatz-length)
02:30carkinstead of function1
02:30kotarakI think one cannot memoize recur. Only real recursive calls.
02:30alphaeusoh sorry, I was trying to simplify the code. same result if that were to say memoize function1
02:31hiredmanwell
02:31kotarakSince recur is not a recursive call.
02:31hiredmanI can appear to make coins disapear
02:31hiredmanbut they don't
02:32Fossiyou do? :o
02:34hiredmanalphaeus: I don't know what the actual reason for the apparent speed up is, but I can tell you, based on knowledge of the recur mechanism and the source of the memoize function, that recur does not participate in "memoized" calls
02:35alphaeushiredman: ok, that's what I thought from looking at the source, I just couldn't think of another explanation for the 4x speedup
02:36hiredmanjit?
02:37alphaeusI don't think so because if I swap them and run the memoized version first it is still 4x faster.
02:42alphaeushttp://www.fatvat.co.uk/2009/05/levenshtein-distance-in-clojure-ii.html
02:42alphaeusbottom of the third paragraph there sure seems to imply that recur uses memoize
02:44kotarakThis is not recur. This is a real recursive call.
02:45hiredmanI am telling you, any website url you paste, no matter what it implies, recur cannot interact with the memoize mechanism as implemented by the memoize function
02:45hiredman_bottomline_
02:52bradbeveridgehiredman: what do you mean by "cannot interact"?
02:52hiredmanbradbeveridge: recur exists within a function
02:53hiredmanmemoize just wraps the function in another function
02:53bradbeveridgeyes - recur is basically a goto to a loop or function point
02:53hiredmanthat first function is still there, and recur will recur to that function
02:53bradbeveridgeoh, you're saying that previous results of recur cannot be memoized naievely?
02:53kotarakand hence cannot work with memoize (as it is now), because the function is not called again.
02:54bradbeveridgewhen you memoize a function, it is only replaced once
02:54hiredmanbradbeveridge: I am saying when you recur, it does not go back through the memoize logic
02:54hiredmanit recurs to the first function frame
02:56bradbeveridgeyes. If you want recur to work in a memoized fashion, you'd need to do the caching yourself
06:33maaclHas anyone seen examples of calling Jython functions from Clojure?
07:57Fossidamn
07:57Fossii'm sick of these release cycles
07:59Fossii really wonder how hard it would be to make a compiler to .dex
08:04Fossibeing register based makes it a little funky
08:55andyfingerhutRich, I recently re-listened to your "Clojure for Lisp Programmers" talk from the Boston Lisp meeting, and there were several questions regarding transactions and agents involving what could go wrong if transactions were not pure functions, etc. I was wondering how useful you thought it might be if there were a function that could (at least in some cases, perhaps common ones) determine whether a function was pure or not. Yo
08:56andyfingerhutShoot, that was way longer than it looked while I was thinking it :-)
09:15Chousukethe io! macro can be used to make a block of code throw an exception if run inside a transaction
09:16Fossiwhich would mean that you would have to flag it before it's being called in one
09:16Fossiwhich is the unlikely case, or not?
09:16Fossii mean, it could be considered good style to wrap everything in io!
09:16Chousukewell, you could use it inside a function
09:17Chousukeand then trying to use that function in a transaction would cause an error
09:17Fossiyeah, but then i have to know beforehand that it will be tried
09:17Fossiwhich i think is unlikely
09:17Chousukehm? :/
09:17Chousuketried?
09:18Fossiso i guess i should wrap all sideeffects with io!, to be sure nobody calls them in one
09:18Fossis/one/a transaction
09:18Chousukewell, usually you should keep side-effects in their own functions anyway.
09:18clojurebotfunctions are maps
09:18Chousukeseparate from pure functions.
09:20andyfingerhutBut I'm wondering -- if someone never used io! in their code, how tricky can it be to detect whether the function is pure or not, with an algorithm, not with a person reading over it?
09:21ChousukeI think it
09:21Chousuke...it's not possible
09:21andyfingerhutI'm guessing it cannot be decided in general, but what are the tricky cases?
09:21Fossicalling into java would be a sideeffect i guess?
09:21Chousukeanything that calls java, or functions not explicitly marked as pure.
09:22Chousukeor anything called in an environment with dynamically rebound variables
09:22andyfingerhutI agree, calling into Java would be a bit of a tarpit, unless you also wrote a program to decide whether Java methods were pure or not. What would be next most tricky after Java calls?
09:23Chousukeyou could do (binding [+ evil-+] ...) and "break" pure functions.
09:26andyfingerhutHmmm. I'm missing something. Why doesn't this exhibit your evil-+ behavior? (binding [+ (fn [x y] (- x y))] (+ 4 2)) evaluates to 6 in my REPL. I guess it is because the second + is really clojure.core/+ ?
09:28Chousukehmm
09:28andyfingerhutYep, that must be it. (binding [my-fun1 evil-my-fun1] ...) does override an earlier (my-fun1 ...) in the same namespace.
09:28Chousuke,(binding [+ -] (+ 4 2))
09:28clojurebot6
09:28Chousuke,(binding [+ -] (#'+ 4 2))
09:28clojurebot2
09:29Chousuke,(binding [+ -] (#(+ 4 2)))
09:29clojurebot6
09:29Chousukehm
09:29Chousuke,(binding [clojure.core/+ -] (+ 4 2))
09:29clojurebot6
09:29Chousukepuzzling
09:30Chousuke,(let [foo #(+ %1 %2)] (binding [clojure.core/+ -] (foo 4 2)))
09:30clojurebot6
09:30andyfingerhutBut for user-defined functions, it is easy to rebind, so that can make it a more global program property to decide whether a particular function x that calls another function y is pure or not. It is if y is pure, but the tricky part is knowing what the definition of y is at the time of the call.
09:30Chousukeah
09:31Chousukeinlining!
09:31Chousuke,(binding [+ -] (+ 4 2 3))
09:31clojurebot-1
09:32Fossiheh. extra confusing ;D
09:33Fossi,(binding [+ -] [(+ 4 2 3) (+ 4 2)])
09:33clojurebot[-1 6]
09:33ChousukeI wonder if that's a bug or just a gotcha :P
09:33Fossithat would be terrible hard to find out ;D
09:34andyfingerhutOK, let's back off from that for a second, and ask whether we can make a program that takes the text of one function foo, and perhaps give an answer like "foo is pure, if the functions bar and baz, called within foo, are pure"
09:34Fossiif you really don't like your collegues you write that somewhere up the chain
09:36andyfingerhutbut it doesn't necessarily try to determine what the bindings of bar and baz are, although in the absence of dynamic bindings, a programmer could run the same program on the source code of bar and baz, and so on, until they got a warm fuzzy feeling :)
09:40andyfingerhutI'm not trying to be frustrating here -- I'm recording the tricky cases as we go. I just want to peel the onion a little and see what the next tricky cases might be.
09:41Chousukeis there an easy case? :)
09:43andyfingerhutWell, I think I can say that if none of +, -, *, / etc are rebound, then a function with args [x y z] that only calls those functions and uses values x, y, and z is pure. Generalize to other known pure functions besides +, -, *, /
09:44andyfingerhutI think I can throw in uses of let, loop/recur, cond, if, when, and a few other things like that for good measure.
09:45andyfingerhutThere should be plenty of useful functions one can write that are straightforward to see for a human, and for a program to automatically decide, are pure.
09:45Chousukehmm
09:46Chousukeit probably helps if you macroexpand the function first, too :)
09:46andyfingerhutdefinitely
09:46andyfingerhutFor which we've got clojure.contrib.macro-utils
09:47andyfingerhutThat gets the number of special forms down to a more manageable number.
09:48Chousukethough, higher order functions will still be a problem :/
09:49Chousukeyou'd have to know which parameters are functions.
09:50andyfingerhutWell, map is pure if the function you pass to it is pure. That is similar to saying that (defn my-plus [x y] (+ x y)) is pure as long as + hasn't been rebound to something non-pure.
09:50andyfingerhuti.e. it is a "conditional guarantee".
09:51andyfingerhutGiven that can be violated with sufficiently tricky uses of binding, I'm willing to think of the output of such a function as hints for a developer, rather than something that makes guarantees on its own.
09:51Fossitime to hack away at the dalvik dexer with clojure, making it more parallel ;D
09:51clojurebot"[Clojure ...] feels like a general-purpose language beamed back from the near future."
09:56andyfingerhutI guess exceptions are not exactly pure, and some things that are "normally pure" like nth can throw exceptions
09:59Chousukeandyfingerhut: functions that throw exceptions are pure as long as the outcome depends only on the parameters.
10:00Chousukeit's just undefined for certain values, like division by zero.
10:01andyfingerhutSure. I guess if I'm willing to "document" gaping holes like "pure if bar and baz haven't been dynamically rebound", then tossing in "may throw an exception rather than return a value normally" is fine, too.
10:12pdoNewbie question: anybody doing anything with complex numbers in Clojure?
10:20pdoI'm new to Clojure and am wondering if there are any libraries available for complex arithmetic? I have some common lisp code I want to translate to Clojure.
10:22Fossimight be in contrib
10:22Fossihttp://code.google.com/p/clojure-contrib/wiki/ComplexNumbersApiDoc seems pretty unfinished
10:23pdoThanks Fossi, will take a look.
10:24Fossihttp://www.mail-archive.com/clojure@googlegroups.com/msg11037.html seems to be the 'announcement'
12:06AWizzArdLet's say I have a Java method foo which takes a clojure function object f and wants to calls it, and then returning the return value of (f). How should the Java code look like?
12:06AWizzArdpublic Object foo(clojure.lang.Function x) { return RT.call(x); } or something like that?
12:06AWizzArdI am looking especially for the call hook, the method which will do the call
12:07AWizzArd(defn foo [function] (function)) is the equivalent in Clojure.
12:10leafwAWizzArd: since all fn are objects and implement Callable, then return x.call() (without arguments) should be what you want.
12:11AWizzArdi only guessed that "call" is the right name
12:11AWizzArdokay, so I will try that
12:12AWizzArdfunny :)
12:12AWizzArdthx leafw
12:12leafwyou're welcome.
12:14leafwAWizzArd: http://clojure.org/special_forms#fn provides some extended info. It says, among other things, that you can use x.invoke(arg1, arg2); if you need to.
12:20AWizzArdOh thanks, this is good
12:24AWizzArdleafw: I am writing a Clojure lib which will make a Java lib usable, and that Java lib takes strings that can also include Java code which will be executed.
12:25AWizzArdAs I don't want to have my Clojure users write Java but Clojure instead, I will need a mechanism to call that Clojure code.
12:48leafwAWizzArd: reading
12:49leafwAWizzArd: so you want a clojure user to programmatically pass a String containing clojure code to a java program that then will execute the clojure code?
12:49leafwit's doable: you need a PushBackLineReader and just parse it, like the old clojure.lang.Repl class used to do (see a few revisons back, before it was emptied.)
13:20AWizzArdI think i have even fewer requirements. Having my users use a macro which will do all the magic under the hood will be fine.
13:20AWizzArdI will let you know in some days/weeks, depending on how much time I have to progress with the project.
16:20ataggartAnyone else occasionally overcome with joy when writing in clojure?
16:21hiredmanI have a high tolerance for joy
16:22ataggartit might be the large run and coke I have next to me
16:22ataggart*sum
16:22ataggart*rum
16:26Raynesataggart: I think it's the Clojure.
16:26ataggartheh, concurrent use of both is ideal
16:28Fossi1synchronous? asynchronous?
16:28Fossi1organized?
16:30mark_the_piratedoes anybody know of a good way to kill an infinitely looping script in the slime+emacs repl without having to restart emacs?
16:31mark_the_piratekilling the slime buffer i start the loop in doesn't seem to work
16:34ataggartFossi1: Right now its synchronous; if I had a straw I could make the process asynchronous.
16:34Fossi1ataggart: you need an agent
16:34ataggartagreed, alas my gf is out of town
16:44ataggartis it improper (or is there a better idiom) to use an agent to perform logging even if the agent holds no useful state? The only reason I'm using agents is so that logging behave correctly within a tx
16:47Fossi1logging is a side effect, so why not?
16:48ataggartyep, the rub is I have to pass it an action function that will ignore the first arg
16:48ataggartso it looks bit messy
16:49Fossi1dunno, i'm not the crack really
16:49Fossi1off to bed. n8.
17:08hiredman~the mosth horrible thing?
17:08clojurebotI don't understand.
17:08hiredman~the most horrible thing?
17:08clojurebotmost horrible thing is http://tinyurl.com/b65o8e
17:14ataggartn: awesome
17:14ataggarthiredman: awesome
17:15alrex021I have a (let [guest (session :login)]) ... how do I assign a value to guest if :login is nil in session, within the same block?
17:21hiredmanalrex021: you can give a default value
17:21hiredman(session :login default-value)
17:22hiredmanor (:login session default-value)
17:22alrex021ahh, I c
17:22hiredmanor (get session :login default-value)
17:22alrex021so session being a map...it is also a func that takes default val
17:23hiredmanoh
17:23hiredmanI just sort of assumed session was a map
17:23hiredmanit is, right?
17:23alrex021yup it is
17:24alrex021as far as I know...:) ...I am trying to use compojure .... with-session
17:24d2dchatHow would you get a random item from a vector?
17:25alrex021so I am trying to check if session has a :login key.....if not, do session-assoc to associate :login with current session
17:26alrex021it works...but my control flow not looking right yet
17:26hiredman,([1 2 3 4] (rand-int 3))
17:26clojurebot2
17:26hiredman,([1 2 3 4] (rand-int 3))
17:26clojurebot3
17:26hiredmanalrex021: you can use if-let
17:26alrex021;hiredman
17:27alrex021hiredman: I just came across that macro a sec a go...cool thx
17:28d2dchathiredman: thx! Although it never hit 4
17:28d2dchatafter 20 tries
17:28d2dchatlol
17:28hiredman,(rand-int)
17:28clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$rand-int
17:28hiredmaner
17:28hiredman,(doc rand-int)
17:28clojurebot"([n]); Returns a random integer between 0 (inclusive) and n (exclusive)."
17:28d2dchatright, does the vector index start at 0?
17:28hiredmanof course
17:28d2dchatTry seeign if you ever get 4
17:30hiredmanyou won't with rand-int of 3
17:30d2dchatso rand-int 4 then?
17:31hiredmand2dchat: what do you think?
17:34d2dchat(def my-vector [1 2 3 4])
17:34d2dchat(my-vector (rand-int (count my-vector)))
17:35d2dchatseems to work :)
18:10alrex021could someone pls explain how I go about using the if-let
18:11alrex021I am looking at the clojure api, but don't understand how to use this macro
18:14hiredman,(if-let [a false] a :not-a)
18:14clojurebot:not-a
18:14hiredman,(if-let [a nil] a :not-a)
18:14clojurebot:not-a
18:15hiredman,(if-let [a (+ 1 2)] a :not-a)
18:15clojurebot3
18:24alrex021hiredman: http://clojure.pastebin.com/m18c956bf
18:24alrex021line 3 is my problem
18:24alrex021the guest-account generates a guest account
18:25alrex021but I also need to bind that result form that function to session-assoc
18:26alrex021so something like: (let [guest (session :login (session-assoc :login (guest-account)))] ... however session-assoc doesn't return the value...so I have to run session-assoc and return result from guest-account
18:27alrex021so my code in pastebin is running but session never has :login, because session-assoc is not called...I need to somehow added like above code
18:27alrex021I'm have tried about 100 different ways so far :(
19:29osaundersI'm confused. Is Clojure object-oriented? How do I create an object?
19:34Chousukeosaunders: clojure is not very object oriented.
19:34Chousukeosaunders: it has access to the java facilities, but Java OO is not really idiomatic clojure.
19:38Chousukeosaunders: usually, you just write functions that take in certain kinds of data structures and output other kinds of data structures. the exact class is not relevant.
19:39Chousukeosaunders: many clojure core functions work on "sequences" and there are many things that can work as a sequence.
20:38Anniepoo,(doc vector)
20:38clojurebot"([] [& args]); Creates a new vector containing the args."
20:38Anniepoohow am I to read the arg list of that?
20:39hiredmanAnniepoo: it meens vector is a multifn, one definition takes no args, one takes a variable number of args
20:39Anniepooah, ok, thanks
20:54Anniepoohmm... using my first multimethod, and wondering if I should be
20:55Anniepoomy code preps data to be transmitted to another system, so I need at some points to be talking to it in
20:55Anniepoothe other system's (typed) language (LSL, if you're wondering)
20:55AnniepooI have some 'type hint' functions that add metadata saying how to encode as LSL
20:56Anniepoo(defn lsl-int [x] #^{:lsltype TYPE_INTEGER} (int x))
20:58Anniepoonow I have some method (in this case, serialize) and want tohave it do the right thing will all these various types
20:59Anniepoo[1]sorry, bailed
21:06mellingI just tried this on a Mac on got "No such namespace: Double" --- http://clojure.org/jvm_hosted
21:07mellingJava 1.6
21:08arbschtwhat version of clojure are you using?
21:09melling1.0
21:10arbschtyou might want to try a newer build
21:11mellingthat was the latest from clojure.org
21:11mellingneed to check out src?
21:12arbschtyes, http://github.com/richhickey/clojure/tree/master
21:12mellingk. thx.
21:14arbschthm, just tried and it works for me with clojure 1.0 on java 1.6
21:16mellingon mac?
21:16arbschtno, GNU/Linux
21:16mellinglet me check out on my linux box.
21:16arbschthow are you loading and running the example?
21:22mellingworks on my Fedora 9 system.
21:22mellingjava -cp clojure.jar foo.clj
21:23mellingclojure.lang.Repl
21:23mellingforgot that.
21:24mellingmaybe i have my Java 1.6 CLASSPATH whacked on my mac?
21:24arbschtseems likely
21:41LauJensenGood night gents
21:59LauJensenNoones having a good night?
22:00arbschtit isn't night time yet :)
22:00LauJensenoh - its 04:01 here
22:05Anniepooclojurebot paste
22:06Anniepoodarn, how do you address a message to the clojurebot?
22:06arbschtclojurebot: paste
22:06clojurebotlisppaste8, url
22:06lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
22:07Anniepoothanks
22:07Anniepooclojurebot: paste
22:07clojurebotlisppaste8, url
22:07lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
22:08lisppaste8Anniepoo pasted "untitled" at http://paste.lisp.org/display/85106
22:08LauJensenAnniepoo: Why always "untitled" ?
22:08Anniepooam I doing a bad thing naming files like this?
22:09Anniepoowhat good would a name do? nobody on earth will be interested in this in 5 minutes
22:10Anniepoomy question is "am I doing a bad thing naming files like this?"
22:10LauJensenI sometimes review the list to find interesting pastes. I have to check everyone named "untitled"
22:10Anniepoomy repl's obviously looking for a java-compatible filename
22:10Anniepooah, sorry, good reason not to
22:10Anniepoothen I'll start naming them
22:10AnniepooI usually set the expiration
22:11Anniepooas well
22:11LauJensenThanks. Regarding the name there is a java convention about using - in namespaces and _ in files. Or perhaps the other way around. You can check out contrib for examples, like lazy-seq
22:12Anniepoook, so if my namespace is foo-utils it should be in a file called foo_utils.clj
22:12Anniepoo8cD we are happy to comply
22:12Anniepoomight be why my repl seems so broken
22:13LauJensenIt might be like that, I think you should check out lazy-seq in contrib, its more reliable than my faulty memory. For the same reason I never use anything but alphaNumeric in my naming :)
22:13Anniepooyes, I was leery of - in names when I first saw it.
22:14Anniepooand there are no spaces in my directory names that *I* put there
22:19Anniepooeven more puzzling, namespace edu.uh.test.testUploadDialog is in test-upload-dialog and works fine
22:20LauJensenThe worst part about Lisp is Java :)
22:20LauJensenAre you using this from a .jar file or classes or what?
22:20Anniepooinside IntelliJ
22:21Anniepoothe source is supposedly on the classpath
22:21LauJensenOh, then Im totally blank. I stick with Emacs and SLIME, and even with that cocktail SLIME can sometimes obscure the issue
22:22Anniepooanyway, it looks like my problems not the underscores anyway.
22:22LauJensenok
22:22LauJensenAre you sure, that you dont want to import it instead of using it?
22:23LauJensen(import '(edu.uh.hhp.sl.automation.primbot builder-bot-language)) ?
22:23Anniepoono, it's a clojure file
22:23AnniepooI shouldn't import it
22:23LauJensenoh ok
22:24AnniepooI think I'm about to give up my beloved IntelliJ and use emacs for this stuff
22:25Anniepoothanks for the help
22:26AnniepooI'm gonna take a break.
23:31baetis-flycan you provide different doc strings depending on the number of args to a function?
23:31LauJensenI dont know, but if you have the need I think you need to reconsider your design
23:32LauJensenNo you cant
23:32hiredmanbaetis-fly: no, you don't look up docs via name+arg list you look them via the name
23:32baetis-flymany thanks.
23:34baetis-flyi just seemed to recall (doc something) providing different strings after the different argument lists. my mistake.