#clojure logs

2008-10-19

00:00bitbcktah, you're right
00:00asbjxrn(filter #(< % 10) [ 1 11 2 14])
00:00bitbcktthe take is "taking" one ahead
00:00bitbcktbut... not returning?
00:00bitbcktas the filter is not returning anything past that boundary?
00:01asbjxrnIt keeps searching the sequence for the next number smaller than 10.
00:01asbjxrnWhich it will never find as the sequence is steadily increasing.
00:02bitbcktah, I see.
00:03duck1123oh well, I've solved the problem, and now I've learned something :)
00:04bitbcktduck1123: it's a good day.
00:12AWizzArdwhy does (. System.out.println "Hallo") produce an error?
00:17Chousertry: (.println System/out "Hallo")
00:19AWizzArdic
00:21AWizzArdis there already some kind of absolute value function in clj?
00:22Chouser(Math/abs x)
00:22Chouserso no, but it's easy to get to Java's.
00:22AWizzArdgreat
00:22AWizzArdwhy is it (.println System/out ...) but not (.abs Math)?
00:23Chouserstatic method vs. instance method
00:23Chouserout is a static field of the System class
00:23Chouserabs is a static method of the Math class. Thus System/out and Math/abs
00:24Chouserprintln is an instance method of the System/out object, thus (.println System/out)
00:25rottcodd_but it's still possible to do (. Math (abs -1)), is that bad style?
00:25Chouserthat's an older style. I think it's being phased out, but I'm not sure.
00:26ChouserAlso works: (. Math abs -10)
00:26AWizzArdso which is the newer one?
00:27AWizzArdbut (System/out/println "moo") ==> error
00:27Chousernewer: (Class/meth arg) for static and (.meth obj arg) for instance
00:27AWizzArdok, thanks
00:27Chouserright, println is an instance method, so don't try to use /
00:27asbjxrnI liked the (. style.
00:28asbjxrnOh, well.
00:28AWizzArdit's still there it seems
00:28asbjxrnBut if it's phased out...
00:30asbjxrnI kinda agree that too many ways to do stuff is bad, easier on the reader if there is one common way of doing things.
00:35AWizzArdcurrently the reader does not allow things like: (defn 3-or-more [guys] ...)
00:35AWizzArdsymbols may not begin with a number
00:36AWizzArdalso dots in symbols cause problems... one couldn't name range "from..to"
00:37AWizzArd(defn from..to [f t] (range f t))
00:46AWizzArdn8 n8
01:09duck1123I prefer the (. Class method) style
01:14anynhow do I do something like this in clojure: Log _log = new Log(ATalk.class);
01:14anyn?
01:14anynwhere ATalk.class is inside of the class definition for ATalk?
01:17Chouser(defn log (Log. ATalk)) perhaps?
01:18ChouserATalk.class in Java is to get the Class instance representing ATalk, right?
01:19anynright, but since most of the app logic that I'm recreating (for an exercise to learn) is inside of the class ATalk, I'm getting rid of the class and just doing all it's logic in the root namespace.. should I try to put it all in a function somehow?
01:21Chouserprobably not -- sound like you're on the right track.
01:23Chousersorry, that should be "def" not "defn" above.
01:24ChouserI don't suppose anyone knows of a way to set a public field on a Java instance?
01:24Chouseroh, (set!) does it. hm...
01:25anynI suppose I could, for each method that the java app uses the logging facility, do a (let [log (Log. thisFunctionName)] and do a new (.warn log "stuff happend") each time
01:27Chouseryou want a new instance of Log for each clojure fn?
01:28anynI suppose it'd have a slightly different effect. each fn would probably spit out a different log file (if I understand this logging facility correctly)
01:28anynWhereas, I guess this java class spits out one log file for the whole class
01:29anynno biggie, I'll probably just forgo the logging all together and print to the console
01:29anynChouser: I suppose you're a lisper moreso than a java person?
01:30Chouserno, more C++ and ruby.
01:30Chouserso I've had lots to learn. :-)
01:32Chousergotta go -- good luck!
01:32anyngah
01:32anynok, later
01:38anyntoanyone: So I'm trying to translate a java class to a clojure program. When a class has a bunch of class variables, would it be wise to put those variables in a map like {:myFile nil :myContact nil :myBirthday nil}. Then, have functions like (def doStuff [myFile] ((doInsideStuff) {:mybirthday newValue}))
01:39anynwhich returns a new map.. and then I can just merge the returned value into my map with a ref-set or something?
01:41anynI mean, (defn doStuf
01:50duck1123is there a way to get a sequence of the functions that are defined. (perhaps in a given ns)
01:59rottcodd_duck1123: yes http://clojure.org/namespaces
02:01duck1123thanks
02:03anynHow do you do a "while (true) { socket.accept }" in clojure?
02:04anynor just "while (true) {...}" for that matter
02:05rottcodd_loop and recur
02:08rottcodd_eg. (loop [] (do-stuff) (recur))
02:10anynah
02:12anynhmm, is there a "break" keyword to get out of a loop?
02:12rottcodd_put the recur in a conditional
02:13anyni see
02:15rottcodd_another way to approach your doStuff function would be to do (assoc myFile :my-birthday new-value)
02:15rottcodd_then you don't have to merge in the ref-set
02:15anyn(defn while [test do] (loop [test do] (if (not test) (recur test do))))?
02:16anynyea, you mean inside the function? and return the whole map?
02:16rottcodd_yes
02:16anynok
02:18rottcodd_also, you can look into struct-maps for better performance
02:43anyncan you implement java interfaces in clojure? and how would you create the required methods?
02:44scook0anyn: check out the "proxy" macro
02:45anynyea, I know about proxy, and have used it once or twice, but...
02:46anynI've used it for event listeners
02:48anynHere, I've got this large class that implements a "session" class, which requires certain methods.. I've done away with the larger class and broke the methods down into functions.. I'm guessing those functions will do their jobs, but they wont tie back as methods into the interface
02:52anynI guess I could create on function that proxies the session interface, then implements the respective methods, which in turn just point out to the other functions in my ns?
02:54H4nsanyn: did you look at the proxy macro?
02:59anynH4ns: yes. I'm only so so at reading the docs, but yea.
03:02H4nsanyn: i'm not sure if i understand your problem, but with proxy you can create a class that is used as a proxy so that java can call back into clojure functions
03:10anynH4ns: Yea, sorry.. It's just such a confusing class. The class implements "SessionListener" .. in a connect() method, it does _session.setSessionListener(this) .. in the run() method it has a "_session.sendMessage(..." in there. And then, further down, it implements the required methods. I've turned the connect() method (which had the 'this' reference) into defn myConnect .. and made session.setSessionListener(this) into (.setSessionListen
03:12anynso now the myConnect function has been registered as the listener for the "SessionListener" interface
03:13anyndo I have to add the proxy that implements the methods in the same function?
03:15anyner, to the same function? that registers with mySession?
03:15anynvery confusing
03:21anynseems like java methods usually translate to clojure functions (which are java classes) and a java class usually ends up being an entire clojure namespace (in terms of file size). So translating between the to isn't necessarily intuitive (for a newb).
03:23anynI guess I need to create some sessionProxy function that talks to the interface and delegates to the other functions.
03:52joha1any one using chimp with clojure here? Trying to assign F5 to EvalFile() in .vimrc, but vim can't find the chimp function. I've tried several variants of chimp:EvalFile() and so on, but no luck so far.
04:08Lau_of_DKMorning gents
04:35Lau_of_DKI might be lagging in my understanding of datastructures again, but if I have a list of lists, that I want to splice (?) so that I can work with the numbers individually, how to I go about this?
04:35Lau_of_DKLike, lets say I want to multiply all ints by 2, why doesnt this work
04:35Lau_of_DKuser=> (permutations [1 2])
04:35Lau_of_DK((1 2) (2 1))
04:35Lau_of_DKuser=> (map #(* % 2) (permutations [1 2]))
04:36Lau_of_DK...and more importantly, how do I fix
04:42Lau_of_DKand this is not what I need :)
04:42Lau_of_DKuser=> (map #(str %) (permutations [1 2]))
04:42Lau_of_DK("clojure.lang.PersistentList@8d94bf13" "clojure.lang.PersistentList@8d94bf53")
04:42kotarakLau_of_DK: you get (* (1 2) 2). Why should * know about lists?
04:44kotarak(map (fn [[x y]] (list (* x 2) (* y 2))) (permutations [1 2]))
04:44kotarakor: (map (fn [x] (map #(* % 2) x)) (permutations [1 2]))
04:48Lau_of_DKOh, thats a really clever way of doing it, didnt know about [[x y]] syntax
04:48Lau_of_DKthanks
04:48Lau_of_DKAnd kotorak, I was supposed to give you some feedback on that set/vector optimizing stuff we talked about right?
04:50kotarakYou could also use a zipper, which works for arbitrary nested lists:
04:50kotarak(loop [loc (seq-zip (permutations [1 2]))]
04:50kotarak (cond
04:50kotarak (end? loc) (root loc)
04:50kotarak (branch? loc) (recur (next loc))
04:50kotarak :else (do
04:50kotarak (edit loc * 2)
04:50kotarak (next loc))))
04:50kotarakLau_of_DK: yes. did you do some benchmark?
04:50Lau_of_DKyea, i'll show you my notes
04:50Lau_of_DKtest1: strings, fdigit
04:50Lau_of_DK(test-frac 500 1000): "Elapsed time: 75177.45724 msecs"
04:50Lau_of_DKtest2: set, w/o fdigit
04:50Lau_of_DK(test-frac 500 1000): "Elapsed time: 17426.179424 msecs"
04:50Lau_of_DKscore: Improved 430% from original
04:50Lau_of_DKtest3: set+vector, w/o fdigit
04:50Lau_of_DK(test-frac 500 1000): "Elapsed time: 2140.255575 msecs"
04:50Lau_of_DKscore: Improved 3512% from original 814% from test2
04:50H4nslisppaste8: url
04:50lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
04:51kotarakLau_of_DK: wow. :)
04:52Lau_of_DKyep, was a good tip :)
04:56Lau_of_DKokay, kotorak, it has to be flexible with the amount of args, lets say I have
04:56Lau_of_DK([ 1 2 3 4 ] [ 1 2 2 3]) and I want (1234 1223) to be my output
04:57Lau_of_DK(map (fn [[x]] (map #(Integer. (str %)) x)) (permutations [1 2 3]))
04:57Lau_of_DKshouldn't this do the trick ?
04:57Lau_of_DKit doesnt....
04:57Lau_of_DK:)
05:00kotarak(map #(Integer/parseInt (apply str %)) (permutations [1 2 3]))
05:00Lau_of_DKok, now holding fast unto the "teach a man how to fish" principle, how did you arrive at that ?
05:01kotarakOk. You want to concatenate the digits: (str 1 2 3 4) => "1234"
05:02kotarakYou get it in a list: (1 2 3 4) => (apply str (1 2 3 4)) => "1234"
05:02kotarakYou get it in a list of lists ((1 2 3 4) ...) and want a list of concats: (map ... ((1 2 3 4) ...)) => ("1234" ...)
05:03kotarakInsert Integer stuff at right point as necessary...
05:04kotarakStart with a small problem. build around your solution.
05:04Lau_of_DKOk, good tips - Im thinking your intuition is a little more fine tuned than mine, but I understand what youre saying
05:05Lau_of_DKbtw, that approach wrapped in a couple of filters solved euler-41 in about 1 second
05:05Lau_of_DKthanks for taking the time kotarak :)
05:05kotaraknp :)
05:05kotarakWhatever euler-41 is..
05:05Lau_of_DKhttp://projecteuler.net/index.php?section=problems&amp;id=41
05:08kotarakbtw. my zipper example above is actually broken....
05:09Lau_of_DKyou broke it?
05:16lisppaste8kotarak pasted "zipper multiplying all leafs with two" at http://paste.lisp.org/display/68799
05:16kotarakLau_of_DK: the correct version looks like this.
05:35Lau_of_DKI wish I could Lisp like that :)
05:36kotarakLike what?
05:37Lau_of_DKIts also SICP like, you can read it instantly, and it makes alot of sense, yet its hard to arrive at those solutions I think
05:39asbjxrnUh.. Swing class for popping up a message?
05:39kotarakYes. But when you are there, it a) so much fun and b) you ask yourself why didn't see it in the first place. One time I shrunk my code by around 8 screen pages, with the same functionality but much clearer. I asked myself afterwards, what I did in the first version.
05:39Lau_of_DKasbjxrn, JOptionPane
05:39Lau_of_DKhaha
05:39Lau_of_DKYes kotarak , I've been there
05:39asbjxrnThanks.
05:40Lau_of_DKYou can also compare my way of computing infinite fractions with Hoecks, thats about the same difference, and his is 4x faster
05:43kotarakBut in the end it's all about experience.
05:43Lau_of_DKAnd wits I think
05:43kotarakOur student worker only thinks on objects. "Uh.. We have to derive a class, blablabla"
05:44kotarakWhen I show him the clojure solution in three lines, he's totally surprised.
05:44kotarakIt's because he doesn't think that way.
05:45Lau_of_DKKinda how I felt after years of C and then later C#. When I switched to Linux I got into SBCL, which was a complete and utter mind-opener. Then when I was drowning in the frustrations of non-proprietary CL frameworks, I found Clojure :)
05:48asbjxrnFor me it was the library situation that drew me to Clojure, plus the cross-platformness of jvm.
05:48Lau_of_DKAnd not Lisp?
05:48asbjxrnI'm still more productive in CL.
05:49asbjxrn(Doesn't take much...)
05:49Lau_of_DKk
05:49asbjxrnFunny thing, I wanted to write a program that reads midi in from external devices.
05:51asbjxrnApparently midi in is not something java does all that well by itself. The most likely approach is to use midishare/portmidi which is the same libraries I used in CL. Midishare is even a spinoff of a CL project (Common Music) I think....
05:52Lau_of_DKSo its drawing you back in :)
05:54kotarakClojure excited me again about Lisp. I always preferred Scheme, because "it's a Lisp-1" or however it is called. But the 1000 implementations put me off. And Clojure has this library advantage. I just like it. :)
05:54asbjxrnNot really, I've also gotten rid of my PC, and I don't have lispworks for OS X.
05:57Lau_of_DKI never even dug into Scheme because I heard it was mostly a toy for University students :P
05:58kotarakI worked on an interpreter for it... But never got far. :|
06:02Lau_of_DKAn interpreter for Scheme ?
06:03kotarakYes.
06:03Lau_of_DKWritten in which language?
06:03kotarakC
06:03Lau_of_DK:)
06:03asbjxrnThere's your problem.
06:03Lau_of_DKWybiral wrote a Python interpreter in SBCL
06:04asbjxrnEveryone knows that scheme interpreteres are writtein in scheme.
06:04kotarakasbjxrn: This was more than ten years ago. I didn't know anything else. (Not to talk about language design... ) But it was fun. :)
06:14lisppaste8Lau_of_DK annotated #68789 with "How about this?" at http://paste.lisp.org/display/68789#2
06:38asbjxrnIs the namespace idiom still (in-ns 'foo) (clojure/refer 'clojure) ?
06:41hoeckasbjxrn: its currently (ns 'foo)
06:41hoeckoh, no, just (ns foo)
06:44asbjxrnThanks. That does seem to work.
06:47thomasleehi all
06:47hoeckhi
06:50thomasleeI'm messing around with gen-class, just trying to get my head around a few things ... a fundamental one that's got me a little stumped is how I would implement a setter in Clojure ... e.g. (defn MyClass-setFoo [this foo] (...))
06:51thomasleeand I guess a sub-question here would be how do I declare member data for an instance of MyClass ... would I *need* to? :P
06:55hoeckthomaslee: clojure discourages you to build mutable objects, but admits that its sometimes necessary
06:56kotarakthomaslee: you can only have one member, the state. Then you can do something like: (defn MyClass-init [x] [[]�(ref {:foo "default" :bar x})]) (defn MyClass-setFoo [this foo] (dosync (commute (. this state) :foo foo)))
06:56hoeckso you can pass a ref to genclass
06:57kotarak(commute assoc ....) actually
06:59thomasleehoeck: yeah, I know it's not encouraged but I'm interested to know how it would work for interop purposes :)
06:59thomasleekotarak: great, thanks very much
07:00hoeckthomaslee: yeah, sorry for the disclaimer there :)
07:01thomasleemeh. totally understand, even appreciate it. :)
07:02Lau_of_DKhoeck, I am most impress0red by your fraction. I think I actually understand it now
07:02Lau_of_DKAlthough - I dont get (at all) why it runs 4x faster than mine
07:05hoeckLau_of_DK: its the same algorithm, and its good news, it means lazy-seqs aren't that slow
07:06Lau_of_DKand you benched it against my final version which does range 500 - 1000 in about 2 secs
07:07hoeckthe one that uses vector and set and fdigit
07:07Lau_of_DKthats the one
07:07Lau_of_DKso yours does 500 fractions in that range in 0.5 secs?
07:09thomasleekotarak, so an equivalent getter would be something like (defn MyClass-getFoo [this] (get (deref (. this state)) :foo)) ?
07:10kotarakthomaslee: yes or just ((deref (. this state)) :foo), get is not strictly necessary
07:11thomasleekotarak, cheers!
07:16hoeckLau_of_DK: yes
07:17Lau_of_DKhoeck, my hat is off to you sir
07:20hoeckLau_of_DK: i'm not using any strings
07:21Lau_of_DKhoeck, no, the most impressive thing about your solution (from my pov) is that you totally escape all this conversion madness that I got myself into
07:22hoeckwhy did you do that this way? (converting integers to strings and back?)
07:23Lau_of_DKOnly way I knew how, because I was getting error messages in the REPL that I couldnt make head or tail from, so I knew that x->str->desired-type always works :P
07:26Lau_of_DKand also, because I hadnt found quot, which I can see you make good use of
07:27hoeckyeah, just inserted `quot' into your fraction-function, now you're 30% faster than me :)
07:27Lau_of_DKWeeeeeeeeeeeeeeeeeee
07:27Lau_of_DK:)
07:28Lau_of_DKHow do you like them apples Hoeck? You beat yourself at your own game
07:31Lau_of_DKhaha, Its improved 29251% from the original function
07:49thomasleekotarak: I'm seeing "No matching field found: state for class MyClass" ... is the state of an object always implicitly called "state" ? or am I doing it wrong? :P
07:50kotarakyou have to declare it in gen-class with :state. You can call it whatever you like.
07:50thomasleeah right, thanks
07:51thomasleethe documentation's a little screwy ... the :state option seems to be appended to the end of the documentation for :factory -- I missed it first time through.
07:52kotarakuse (doc gen-class) there it's not screwed.
07:52thomasleenice ... thanks for all the help
08:03thomasleesorry kotarak, one more thing: I'm getting a ClassCastException, presumably because setFoo is declared as returning void in :methods, but in actual fact is returning a non-void value due to the behavior of commute ... what's the most logical way to deal with that?
08:03thomasleeugh, "returning void" ... excuse the crap terminology
08:04kotarak(do (commute ...) nil) or declaring the setter to return Object, I think.
08:18thomasleekotarak: that seemed to do the trick. Also wound up having to use #(merge % {:foo foo}) in place of ":foo foo" for the setter call ... the value doesn't otherwise seem to be saved to the state
08:20kotarako.O no?
08:21thomasleenope ... not quite sure what was happening. Entirely probable I was doing something wrong, but the merge approach worked off the bat.
08:21thomasleeThe actual setter implementation looks like this: (dosync (commute (. this state) #(merge % {:cents cents}))) nil)
08:23kotarak(dosync (commute (. this state) assoc :foo foo)) does not work?
08:23thomasleeah I missed the assoc first time through
08:23thomasleeI'll give that a shot
08:24thomasleeyep, that works great
08:24thomasleesorry, I must've misread/misunderstood
08:24kotarakpfuu.. World saved again. ;)
08:24thomasleehaha ... bit more readable :)
08:25kotarakthomaslee: I miswrote initially.
08:26thomasleekotarak, ah I see now
08:27kotarakthomaslee: yeah, so I'm also kind of "guilty" if one wants to call it like that...
08:27thomasleekotarak: I'd still be scratching my head if it weren't for your help, so I'm not about to go laying blame ;)
08:43thomasleeis it possible to provide a name to defn dynamically in a macro? Something like `(defn (format-string "%s-%s" ~a ~b) (...)) ?
08:44thomaslees/format-string/format/
08:44kotarakyou do something like this: `(defn ~(symbol (str a "-" b)) ....)
08:50Pupeno-GHello.
08:51Pupeno-GSo, there are essentially two web frameworks for Clojure, Webjure and Compojure, right? Webjure seems to write a Java-style web application, but using Clojure and Compojure seems a more from-the-scratch approach; am I right?
08:52Pupeno-Gs/from-the-scratch/from-scratch/
08:56tWipdefine Java-style
08:57Pupeno-GtWip: with Servlets and other stuff I don't yet understand or know about.
08:58tWipI haven't checked compojure, but I made webjure work with servlets because that is the de-facto way Java web apps are deployed
08:58tWiptaking advantage of existing infastructure on app servers
08:59tWipyou don't need to write a single line of Java-code if you write a webjure app
09:02Pupeno-GI think I'd like to give webjure a try, but the last time I've tried to understand the Java Webapp world, I've read like 150 pages of Sun's Java EE manual or something like that without a single line of code... when I woke up I just went back to Django. Any recommendations on how to approach it?
09:03tWipThere is an installation page on the webjure wiki now, you could check that
09:04thomasleehttp://pastebin.com/d730b2d21 -- I'm seeing "Can't use qualified name as parameter: com.deskchecked.clojure.interop/this" ... what am I doing wrong here?
09:04tWipif you have maven installed, the process of getting the demos up and running is quite simple
09:05thomasleehttp://pastebin.com/db311b01 -- updated code with capitalize implementation and syntax highlighting
09:05Pupeno-GtWip: ok, that might be a good starting point. I'll just install maven, thankfully there's a package for my OS.
09:07thomasleeall that code is obviously in the namespace that's being complained about in the error message, but I'm curious as to why it's trying to bind "this" to that namespace.
09:07achim_p__ thomaslee: symbols inside syntax-quote automatically obtain ns prefixes
09:08achim_p__try a normal ' quote
09:10thomasleea normal quote where? in place of the backtick/syntax-quote?
09:13achim_p__no, just for the "thisses": "this" -> "~'this"
09:14achim_p__but it's probably better to use gensym to generate a unique symbol
09:15thomasleeah, brilliant - thanks very much
09:15achim_p__i.e. "this" -> "this#" (#-suffixes are a shorthand for gensym)
09:16thomasleeachim_p__, why's that? in case make-setter is invoked within another function declaring "this" ?
09:24achim_p__thomaslee: in your specific case, it doesn't matter, as far as i see - it's just a thing i accustomed to doing when writing macros, to avoid hard-to-debug name clash errors. plus, i find it easier to read than ~'anything
09:28thomasleeachim_p__, sure, understood. Thanks for the tip.
10:55anynLau_of_DK: I want to see this fraction code...
10:55Lau_of_DKhttp://paste.lisp.org/display/68739 <---3 versions
10:56Lau_of_DKAs they stand, #3 is the fastest
10:57AWizzArdhi
10:57Lau_of_DKHeya
11:02arbschthm, looks like lisppaste is down
11:02anynhmm. paste.lisp.org is having a hard time
11:02anynI concur
11:02anynthere it is
11:13anynthat's deep stuff
11:33Lau_of_DKuser=> (trunc [1030])
11:33Lau_of_DK["1030" "103" "10" "1" "" ["030" "30" "0" ""]]
11:33Lau_of_DKGents, how do I convert all these to Ints as concisely as possible?
11:35AWizzArdHow do I test for bar being not a collection, so, no string/list/map/vector/set? CL's (atom bar)
11:36duck1123(not (seq? bar)) maybe?
11:37AWizzArdno, seq? tests only for lists
11:37AWizzArd(not (seq? [1 2 3])) ==> true and (not (seq? '(1 2 3))) ==> false
11:38duck1123(nil? (rest bar))
11:39fyuryuyou can use derive for PersistentVector and others and then use isa?
11:40AWizzArdfyuryu: what do you mean?
11:40fyuryuAWizzArd: http://groups.google.com/group/clojure/browse_thread/thread/9cc9926de1bdb128
11:40AWizzArdI could also do something like (not-any? #(% bar) [seq? vector? string? map? set?]) ;-)
11:41fyuryuAWizzArd: because I don't think there is something like atom
11:42AWizzArdI think the same, at least by skimming through the api and boot.clj I didn't find it, and also no (col? bar)
11:43fyuryuAWizzArd: didn't know about not-any?, when did that happen?
11:44AWizzArdI don't know when it was added
11:44fyuryuAWizzArd: ok, not important ;-) just thinking to myself
11:47AWizzArdduck1123: (nil? (rest 5))
11:48duck1123yeah, I noticed that
11:58Chouserthere is (coll?)
11:58Chouserstring is not a Collection -- is that ok?
12:15fyuryuChouser: great, I was at the repl, but thought to myself:
12:15fyuryuChouser: "no, I bet there is no coll?" ane didn't evet try it
12:19AWizzArdthere is no col? yet
12:19AWizzArdwe should add it to the svn
12:19AWizzArdChouser: why is a string not a collection?
12:19fyuryucoll?
12:20AWizzArdIt surely is not a very generic one as it can only eat chars, but one can see it as a bag/collection full of them
12:20AWizzArdI personally like col? more fyuryu
12:21anynIf I'm converting a large java class into clojure (where, you know, most methods become functions) and said large class implements many interface methods, some of which are callbacks, with logic distributed throughout... what's the preferred way to manage that?
12:24anynit's weird. the class implements "SessionListener" and one method registers the class with a session with _session.setSessionListener(this); ... while other methods implement some session listener methods, like "messageReceived" .. so, when the implementation of an interface is spread across the whole class, how does one translate that?
12:26anynI can't proxy in every function, cause those various functions won't be recognized as the registered SessionListener in the session collection, right?
12:34anynbrb
12:45arbschtLau_of_DK: I presume you want to map Integer/parseInt to the strings, but how do you want to treat ""?
13:02duck1123has anyone here ever solved euler-12 in clojure? If so, do you know how long it took?
13:04StartsWithKhi
13:05StartsWithKwhat is the state of aot compiler?
13:20Lau_of_DKarbscht, I've fixed it, thanks
13:20Lau_of_DKthe trick was to avoid those ""'s
14:00ChouserStartsWithK: AOT compiler isn't ready yet, but I'm under the impression it's close.
14:02ChouserAWizzArd: collections can hold anything. If you want to treat a string like a seq, you may: (seq "foo")
14:06StartsWithKChouser: thanks
14:09Chouseranyn: you may need something like: (defn make-thing [] (let [somestate ...] (proxy [Listener1] (foo ..refer to somestate...)) (proxy [Listener2] (bar ..refer to somestate..)))
14:10AWizzArdChouser: I want to argue that a string is a collection.
14:11AWizzArdIt's a typed collection and can only contain chars, as opposed to generic/dynamic collections which can hold any objects.
14:12Chouserwell it may be a collection, but it's not a Collection.
14:12ChouserIt's a Java class, and so Java has set the rules for interacting with it.
14:18AWizzArdI am talking from the view of Clojure. Do you think one can't see it as a collection but instead as an atom?
14:19AWizzArdIt may be very well a Java String under the hood. But I would like to abstract that implementation detail away.
14:19duck1123wouldn't that mess up the ability to use a clojure string as a java string unmodified?
14:22AWizzArdI just mean that I see a string as a container datatype, and not something atomic like a number or character. Under the hood it's just zeros and ones, but I don't care. For me it's important that I know a string can contain a number of atomic objects, in this case: characters.
14:25lisppaste8Lau_of_DK pasted "Speed/Java-heap/Help" at http://paste.lisp.org/display/68822
14:25Lau_of_DKOkay, you old-school clojure-bred ninjas. Why does this fail so badly ?
14:28AWizzArdArgh, why putting the parameter list not in the line of (defn function [parameter here] ...)?
14:29Lau_of_DKbecause thats not 1337
14:29Lau_of_DKaccording to wikipedia :P
14:30AWizzArdI'm feeling ice cold now after I saw that ;-)
14:30duck1123does it bother anyone else that the doc-string goes before the param list?
14:30AWizzArdme :-)
14:30Lau_of_DKlook, you guys are missing the point, I wasnt asking for cosmetic tips here, I need this to compuete quicker and without blowing any heaps, any input on tht? :)
14:31AWizzArdbut Lau felt so free to put the parameter vector into the next line even when his functions had no docstring
14:32Lau_of_DKlol
14:32arbschtduck1123: it doesn't bother me. in fact, it makes sense, because a function can have multiple signatures
14:32duck1123I'm just used to elisp, where the order is reversed
14:33AWizzArdin common lisp it's also different
14:33AWizzArdarbscht: could you give an example of what you mean by multi signatures?
14:34AWizzArdyou mean like (defn str ...) in boot.cjl?
14:34AWizzArdor (defn concat ...) in boot.clj?
14:34kotarakAWizzArd: (defn foo ([x] :one) ([x y] :two)) (foo :x) => :one, (foo :x :y) => :two
14:35arbschtAWizzArd: yes, those are such examples
14:35AWizzArdokay, so destructuring functions.. yup, for those it makes sense, I agree
14:35kotarakNo. It's not destructuring. It's different arity.
14:36kotarak(defn foo [[x y]] ..) this is destructuring
14:36AWizzArdyes, you are right
14:36duck1123Lau_of_DK: sorry, my clojure isn't to the point yet where I'm even quite sure what that code is doing, let alone why it fails
14:38Lau_of_DKI know that the trunc isnt very pretty, but this is what it does
14:38Lau_of_DKuser=>(trunc [123])
14:38Lau_of_DK(123 23 3 21 1)
14:38Lau_of_DKor to put it another way
14:38Lau_of_DK123
14:38Lau_of_DK23
14:38Lau_of_DK3
14:38Lau_of_DK123
14:38Lau_of_DK12
14:38Lau_of_DK1
14:43hircusLau_of_DK: this for Project Euler? :)
14:43Lau_of_DKYes sir
14:43AWizzArdLau_of_DK: what do you expect trunc to be doing for (trunc [12345])?
14:44Lau_of_DK12345
14:44Lau_of_DK1234
14:44Lau_of_DK123
14:44Lau_of_DK12
14:44Lau_of_DK1
14:44Lau_of_DKand then from the other side as well
14:44Lau_of_DK2345
14:44Lau_of_DK345
14:44Lau_of_DK45
14:44Lau_of_DK5
14:45hircusnot familiar with Clojure's lazy sequences -- would filtering a lazy seq give a lazy seq or an eager one?
14:45Lau_of_DKWould still be lazy
14:45AWizzArdIs this part of the task? Or why do you test these strange things for being a prime?
14:45Lau_of_DKhttp://projecteuler.net/index.php?section=problems&amp;id=37
14:46hircusLau_of_DK: seems like you're better off eagerly computing primes up to a certain point
14:46Lau_of_DKI have no way of knowing what that point might be
14:47hircuswhen doing an earlier problem (sum of all primes < a million, IIRC) I found that Haskell's lazy prime number sieve became too slow
14:47Lau_of_DKk
14:47hircustrue. so I guess you can keep retrying as long as the number of primes you find is less than 11
14:48Lau_of_DKThats a good idea
14:48hircushaven't tried that problem yet, though. how many have you done?
14:48Lau_of_DKI need a quick reboot, then I'll get right on it
14:48Lau_of_DKI dont know, it blew the heap before I could see. The last number is 3797, and theres only 1 more known to man, I imagine its quite high
14:50duck1123hircus: if that was 10, I just did that last night ~10 sec done lazily
14:51achim_p__lisppaste8: url
14:51lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
14:53hircusduck1123: ah. I don't have the non-working Haskell code anymore though. but I might just not be writing it in the proper way; Haskell is tricky to write fast code in
14:54duck1123this is what I came up with: http://clojure-euler.wikispaces.com/Problem+10
14:54Chouserhm, I apparently abandoned projecteuler after problem 36
14:54duck1123I was trying problem 12, but it was taking forever
14:55duck1123never did find an answer, it was slowing down my computer too much
14:55lisppaste8achim_p pasted "???" at http://paste.lisp.org/display/68825
14:56achim_p__can anybody help explaining what's happening there? i just don't see it
14:56hircusduck1123: problem 12 took me quite fast in clojure
14:57hircusI used unchecked operations since the resulting numbers won't really get too big
14:57duck1123hircus: do you happen to have your code, I want to see what I was doing wrong
14:57hircusduck1123: sure. pastebin?
14:57duck1123that works
14:58lisppaste8hircus pasted "Euler #12" at http://paste.lisp.org/display/68826
14:59Lau_of_DKhircus, feel free to contribute: http://clojure-euler.wikispaces.com/
15:00achim_p__(= #{1 4} #{2 3}) ; => true - now it makes sense again!
15:00Lau_of_DKglad you worked it out achim_p__ , I was lost
15:01achim_p__mmh, they aren't exactly equal, are they?
15:01Lau_of_DKif you add them together they are
15:02achim_p__then we had to have (= 4 3), because 7 = 7
15:02Lau_of_DKif the comparison is just based on sum, then it makes sense
15:02Lau_of_DKtry {10 2} {8 4}
15:02achim_p__why should a comparison be based on a sum?
15:02Lau_of_DKbug maybe? :)
15:02hircusLau_of_DK: cool, will do
15:03hircusfound another Clojure Euler project at Google Code but the code there was atrocious
15:04hircuswhoever ran it reimplemented things like even? and did the world's slowest exponentiation function
15:05Lau_of_DKWell, things can also be improved upon, so its probably a good idea just to consolidate on wikispaces
15:06hircusyup, I agree that a Wiki is actually a good place for things like this
15:06Lau_of_DKI think the "Optimal toolkit" will be sweet. Specially if people are diligent in bencmarking their stuff
15:06hircusshould we rename the problems to all have three digit numbers, so that they sort properly?
15:06Lau_of_DKGood idea
15:07Lau_of_DKI dont know who owns it, I think it was started by achim_p, so I cant really decide anything, but it sounds good
15:07achim_p__can anybody reproduce this equality?
15:07bitbcktachim_p__: came late to the game. which?
15:07hircusLau_of_DK: ok, just applied
15:07Lau_of_DKachim_p__, I'd love to help, but Im still waiting for my filter to return
15:07achim_p__(= #{1 4} #{2 3}) ; => true
15:08AWizzArd(= #{-100 -50} #{-210 60}) ==> also true :-)
15:08hircusachim_p__: same here
15:08bitbcktnope, false here
15:08hircusbitbckt: which Clojure build are you on?
15:08achim_p__bitbckt: which revision?
15:08bitbcktI'm on the 9/16
15:08bitbcktjust about to say, lol
15:08hircusI'm on an SVN checkout from a few days ago. looks like new bug
15:09achim_p__okay, thanks for your feedback!
15:09bitbcktof course.
15:10hircusLau_of_DK: using Python, the 11th number you're looking for is under 1 million :)
15:10bitbcktgit bisect to the rescue...
15:11Lau_of_DKhircus, I cant except anything coming from Python, sorry
15:13hircusLau_of_DK: hehe. well, I can port the code to Clojure real quick
15:13Lau_of_DKPlease do so
15:17achim_p__http://www.bitbucket.org/shoover/clojure-mirror/changeset/9a6760cf79b9/#chg-src/jvm/clojure/lang/APersistentSet.java
15:17achim_p__might be this change that breaks it
15:18Lau_of_DKConsidered posting it to the Google group so Rich could have a look ?
15:18bitbcktachim_p__: 49a1829 looks like the first bad commit
15:18bitbcktr1052 in the SVN repo
15:19bitbcktfrom the comments: unified equality and hashCode semantics for sets/maps/lists with java.util
15:19Lau_of_DKhircus, I have a working clojure solution now,
15:20bitbcktheh... you found it first
15:20bitbcktdamnit ;-)
15:20achim_p__bitbckt: :) thanks! you used git bisect?
15:20bitbcktyessir
15:20bitbcktI didn't script it, since there were so few commits... it goes slower
15:21Lau_of_DKbitbckt, want me to get you that violin?
15:21bitbckthehe
15:21Lau_of_DK:)
15:23achim_p__bitbckt: i don't really know git, but the bisect feature looks very cool
15:23bitbcktachim_p__: it works wonders
15:24bitbcktachim_p__: ... darcs and hg have it, too
15:27achim_p__ok, then i'll stick with hg. i'm slowly getting used to it. bzr was probably my favourite, in ease-of-use terms, but the only free hosting service was launchpad, which is a complete catastrophy in ease-of-use-terms :)
15:30AWizzArdachim_p__: do you think it could have to do ith the hash?
15:30hircusLau_of_DK: ugh, turning an integer to a string in Clojure could be made a bit easier
15:31ChouserI think it's a typo.
15:31hircusLau_of_DK: ah nevermind, misread something
15:31bitbcktachim_p__: you don't need validation from me, but I like hg, too. I use both on-and-off nearly everyday.
15:36Lau_of_DKChouser, did you catch cgrand's update on his blog?
15:37ChouserLau_of_DK: heh, nope.
15:38lisppaste8hircus pasted "stack problem computing primes" at http://paste.lisp.org/display/68828
15:39hircusany idea what's going on here? (not the Clojury way to do things, but it really should not fail, no?)
15:39Chouserachim_p__: nice catch -- I think I spotted the typo.
16:02PupenoCan webjure be used with Glassfish instead of Jetty?
16:03achim_p__Chouser: cool, thanks for tracking it down!
16:08sohailI may have missed this in the reference, but what does #^ mean?
16:09sohailah, nevermind. It's in the reader section
16:09sohailpretty f'in cool man
16:12AWizzArdIn principle a Clojure developer does not need the java jdk (installed), right? The jre is enough?
16:14Lau_of_DKYes
16:17AWizzArdAnd do we know what version of the jre is needed? Is 1.5.0_04 enough?
16:18Lau_of_DKI think so
16:18Lau_of_DKI remember trying, I think it succeded
16:19arohnerI'm running 1.5.0_16 here
16:19bitbcktJRE 1.5.0_16 works
16:19bitbcktheh
16:19AWizzArdgood
16:26sohailjust checking my understanding. If there is no singleton empty-list value, each empty-list value will return nil when asked to iterate, which is almost the same thing right?
16:29arohnerisn't there a function to flatten a vector? i.e. [ [1 2] [3 4]] -> [1 2 3 4]
16:29AWizzArd(= () ()) ==> true and (identical? () ()) ==> true
16:30sohailAWizzArd, what are you showing there?
16:31arbschtarohner: (mapcat identity [[1 2] [3 4]]) => [1 2 3 4]
16:33Chouseror (apply concat [[1 2] [3 4]])
16:33Chousersohail: yes -- calling seq on any empty collection returns nil
16:34arohnerthanks!
16:34sohailthat doesn't really flatten nested lists
16:34Chouserarohner: there's also something in clojure.contrib if you want arbitrary depth flattening
16:34sohailerr vectors
16:34sohailah
16:37AWizzArdsohail: it seems there is a singleton empty list
16:39sohailAWizzArd, I think the reason is that immutable structures define = as value comparison, not identity
16:40sohailoh wait you did identical?
16:40sohaildoes that use .equals or java == ?
16:41sohailReference comparison. Returns true if x is the same object as y, false otherwise.
16:41sohailk!
16:41AWizzArdI don't know java, but it is like Common Lisps eq
16:42AWizzArdit makes sense that there exists exactly one empty list
16:43sohailwhat is (rest '(1)) supposed to give you?
16:43arohnerI *think* that clojure lists share structure whenever possible
16:44arohnerso the empty list is just a particular instance of lists sharing structure
16:44sohailhas anyone tried to write a GUI using clojure?
16:44AWizzArdin Clojure I would suppose it should not give me anything, so nil would be cool
16:45arbschtmany have
16:45sohailarbscht, have any examples?
16:45AWizzArdsohail: hehe, this one maybe: http://clojure.org/jvm_hosted
16:45sohailAWizzArd, ya I saw *that*
16:45sohailI meant a real one :-)
16:46sohailis enclojure written in clojure?
16:46sohail"enclojure is written predominately in Clojure."
16:46arbschtthere are snippets here http://groups.google.com/group/clojure/browse_thread/thread/22e4696550b6c4fa
16:47arbschtthis is a little game in Swing http://blog.jalat.com/2008/10/game-clojure-version.html
16:48sohailhang on. you can do interactive GUI development? cool...
16:48AWizzArdThe guy for that game should have made it available as webstart or applet also
16:48arbschtI wrote a tiny implementation of Snake on Swing http://www.plt1.com/1070/even-smaller-snake/
16:49AWizzArdsohail: yes, you can change your gui from within clojure while your program is running
16:49AWizzArdarbscht: where is the binary for that? ;-)
16:49AWizzArdyou could make it available by a mouse click
16:49sohailhmm, it killed the REPL when I hit ALT-F4
16:50arbschtdepends on the default close operation of the frame
16:59lisppaste8achim pasted "lazy powerset enumeration" at http://paste.lisp.org/display/68832
16:59achim_p__anybody in for a game of clojure pingpong? ;) my first lazy seq - no doubt there is a better way
17:00achim_p__weird indentation
17:03hircusachim_p__: ping pong?
17:05achim_p__ah, it was golf, not ping pong (http://clj-me.blogspot.com/) - they're pretty close, white ball etc.
17:09Lau_of_DKlol
17:09Lau_of_DKetc?
17:11achim_p__clubs
17:12Lau_of_DKif somebody has the time, would you mind writing clomacs ?
17:22hircusClomacs would be really neat. probably more feasible than the Scheme port of Emacs :)
17:24AWizzArdsuns java sdk in debians/ubunts package list is called openjdk?
17:24arbschtsun-java6-jdk or sun-java5-jdk
17:25AWizzArduh, is their java different from the openjdk stuff?
17:26arbschtit's non-free
17:45Lau_of_DKhttp://clojure-euler.wikispaces.com/ <-- Counting 17 solutions now, everybody feel free to contribute
18:08hircussilly question, but how do I use the closure.set functions?
18:11jaohi. is M-. (find-source-location) supposed to work in slime for clojure?
18:13AWizzArdhircus: apply them on arguments
18:13sohailhow do you use multimethods with structs?
18:13hircusAWizzArd: I can't get them imported, that's the problem
18:13arohnerhircus: (use 'clojure.set)
18:14sohailit isn't obvious to me how to make (defstruct rectangle ...) use :shape as the dispatch function
18:14hircusarohner: aha. thanks
18:15arohnerhircus: also look at (doc require)
18:17sohailanyone know how to convert the multiple dispatch example to use structs?
18:18AWizzArdcan you be more specific?
18:18sohailAWizzArd, the one here: http://clojure.org/multimethods
18:18sohailI can't see how to set the :Shape key to always return :Circle or :Rectangle via defstruct
18:21AWizzArdthe keyword itself can be used as a function
18:21AWizzArd(defmulti blah count)
18:21sohailI know
18:22AWizzArdthis means that whenever blah is called it's arguments will be applied to count
18:22AWizzArd(blah something) will become: (count something)
18:22AWizzArdthis yields a result
18:22AWizzArd(defmethod blah 3 [arg] "hallo")
18:22AWizzArdand now you can say: (blah [10 20 30]) ==> "hallo"
18:22sohailbut how would I define the rectangle struct so that rectangle always returns :Rectangle for that function?
18:23AWizzArdbecause (count [10 20 30]) yields 3
18:23sohailif I have my own make-rectangle, I can return {:Shape :Rectangle ... }
18:23AWizzArdyes
18:23sohailand so (:Shape (make-rectangle ...)) => :Rectangle
18:23AWizzArdand it must have an even number of elements
18:23sohailbut how do I use defstruct to do that?
18:24AWizzArd(defstruct foo :name :age)
18:24sohailand..
18:24AWizzArdand now you can have a (def x (struct foo "Carl" 29))
18:24AWizzArd(:age x) ==> 29
18:24sohailI got that
18:24sohailbut I don't want the user to have to set :Shape, I want it to have a default value
18:25StartsWithK(defstruct rectange :Shape :x :y :w :h)
18:25AWizzArdnow lets dispatch on the age
18:25arbschtyou cannot set a default value when you define a struct. it's not a class
18:25sohailoh, are there classes too?
18:25arbschtno :)
18:25AWizzArdyou have something much better
18:25AWizzArdPaul Graham said already long time ago: functional programming + macros outperforms OOP
18:26sohailyeah don't worry, I get it
18:26sohailwhere is CLOJS ? :-)
18:26sohailor is it CJOS
18:26AWizzArdCLOS
18:26arbschtthere are ad-hoc hierarchies which, admittedly, I'm not fully familiar with
18:26arbschtsee isa and derive
18:28sohailok, I guess I'll look at it later
18:28AWizzArdWhen you create one million hash table objects that all share their keys and only differ in value, then you waste some memore. defstruct, as I understand it, enables you to create these one mio instances and they all share the keys (= the struct fields).
18:29sohailok, that's fine
18:29AWizzArddo you feel now better about this example from the clojure site?
18:29sohailbut I don't understand how I would implement any sane sort of multimethod based API without some support for default values
18:29sohailno
18:29AWizzArdlet's make it 100% clear, but you need to tell exactly what is unclear
18:30sohailI mean, as long as the user can do: (struct rectangle :Shape :Circle ...) things can go pear-shaped
18:30sohailhttp://clojure.org/multimethods
18:30AWizzArdit has 16 lines... which of those are still puzzeling?
18:31AWizzArdit = the example on that site you just posted
18:31sohailconvert that to using structs... without the factory functions, the user can accidentally type (struct rectangle :Shape :Circle ...)
18:32sohailok I gtg just now
18:32sohailbbl
18:37AWizzArdsohail: as I understand it you can't do this example with structs. If you have a (defstruct rect :wd :ht) and say (def x (struct rect 10 20)) then there is no way to find out that x is a rect. If you want to keep this info then you would need to do something like: (def x (conj {:Shape :Rect } (struct rect 10 20))) and never forget to conjunct these things whenever you create a rect.
18:44StartsWithKAWizzArd: But then :Shape key will not be shared
18:45AWizzArdStartsWithK: as I see the example from the Clojure site :Shape won't be shared anyway.
18:46StartsWithKAWizzArd: but example is not using struct
18:46AWizzArdright, so it can't share the key information.
18:47AWizzArdthe example from Rich does not make use of the data structure "Structured Map"
18:48AWizzArda struct is a table where you can have any number of lines where the columns have headlines (= "fields" of the struct)
18:49StartsWithKbut is example how to use multimetods, nothing more, it's minimaln in that way
18:49AWizzArdyes, he uses multimethods, but I think sohail is trained in oop thinking and tries to find out how this example would look like if Rich had used structs.
18:50StartsWithKwhen you want to use struct, and you know :Shape key will use in every struct you create, then you should put it inside struct itself
18:50StartsWithKwill be used*
18:50AWizzArdStartsWithK: this would still be a leaky abstraction, as you would every time you create a rect have to say (struct Shape :rect 10 20)
18:52StartsWithKbut you will get key shaing, struct have any other advantages
18:52StartsWithKsharing*
18:52StartsWithKi don't see how not sharing :Shape is more or less of leaky abstraction
18:53AWizzArdbecause you need to explicitly give the same argument whenever you create a rect
18:53AWizzArdthe example on the page shows how you only have to specific width and height
18:56StartsWithK(defn rect [wd ht] {:Shape :Rect :wd wd :ht ht})
18:56AWizzArdyes
18:56StartsWithKit gives :Shape every time you create rectangle
18:56nicknullis there a database lib shipping with clojure?
18:56StartsWithKand not only width and height
18:56StartsWithKnicknull: there is sql lib in clojure-contrib
18:56AWizzArdnicknull: yes, the one from Java
18:57AWizzArdStartsWithK: yes, this is right, and it is exactly what I said.
18:57nicknulllol
18:57StartsWithKnicknull: http://sourceforge.net/projects/clojure-contrib
18:57AWizzArdIt is just not a struct
18:57StartsWithKAWizzArd: you sad " the example on the page shows how you only have to specific width and height"
18:57AWizzArdit is a hash map
18:58nicknullty Clojure really is cool. so many alternative langs lack practicality
18:58StartsWithKand you have to specify :Shape to
18:58AWizzArdyes, and you have.. the function you posted takes 2 arguments, not 3
18:58StartsWithKbut that is a factory function
18:58AWizzArdno, :Shape is always set to a symbol
18:58AWizzArdright
18:58AWizzArdand there is no defstruct in the example, so, no structured map, but a hash map instead
18:58StartsWithKso, you will have a factory function for your rectangle struct too
18:59AWizzArd(defstruct rect :hd :wd)
18:59StartsWithKonly differance is your keys will get shared
18:59StartsWithKthere is nothing more struct will do for you
18:59AWizzArd(struct rect 10 20) ==> {:ht 10 :wt 20}
18:59AWizzArdand not {:Shape :rect :ht 10 :wt 20}
19:00StartsWithKbut if you want to dispach on shape type you will have to have :Shape key in there
19:00AWizzArdabsolutely
19:00AWizzArdand this is why I said to sohail that he can not use defstruct here
19:00nicknullbut clojure got it all
19:00StartsWithKwhy not?
19:00AWizzArdshow me how StartsWithK
19:01AWizzArdMaybe I don't understand this mechanism well enough
19:01AWizzArdI would like to see how you do it as sohail asked for
19:02AWizzArddo the same example as in http://clojure.org/multimethods but you must not have factory functions
19:02StartsWithK(defstruct rectangle-struct :Shape :w :h) (defn rectangle [w h] (struct :Rect w h)) (defmulti area :Shape)
19:02StartsWithK(defmethod :Rect ...)
19:02AWizzArdsohail explicitly disallowed functions..
19:02AWizzArdyou may not use defn
19:02StartsWithKhow you mean no factory function
19:02StartsWithKthat makes no sense
19:02AWizzArdhe wanted it
19:03AWizzArdand I answered that this way this example can't be don
19:03AWizzArddone
19:03StartsWithKyes, i was reading it
19:03AWizzArdof course it makes no sense, but this was what he asked for
19:04rukubitesHello, I am a common lisp programmer and I use Slime extensively. I am looking into using Clojure for an upcoming project, and I have clojure and swank-clojure installed. Unfortunately slime-eval-print-last-expression (C-j in *slime-scratch*) is failing, I think because it uses asynchronous evaluation. Is this a known issue or a regression? Is it fixable?
19:04AWizzArdand this means that if you have a (defstruct Rect :Shape :w :h) then you must always provide an argument for the :Shape key
19:04StartsWithKbut, this is what i sad is wrong: (def x (conj {:Shape :Rect } (struct rect 10 20)))
19:04StartsWithKbecouse you don't get :Shape key sharing
19:05AWizzArdno StartsWithK, I explained a few lines before that the struct rect looks like this: (defstruct rect :w :h). As you see, no :shape key there.
19:06rukubitesI really want to be able to adapt my workflow for working with clojure, and I use C-j all the time.
19:07AWizzArdStartsWithK: sohail was thinking in OOP terms. If Clojures struct where really a struct then saying (defstruct Rect :h :w) would be fine, because (struct rect 10 20) would yield an object on which you could do something like: (is-rect? (struct rect 10 20)) ==> true
19:08StartsWithKYou sad: " If you want to keep this info then you would need to do something like: (def x (conj {:Shape :Rect } (struct rect 10 20))) and never forget to conjunct these things whenever you create a rect."
19:09AWizzArdyes, of course
19:09StartsWithKand i sad: But then :Shape key will not be shared
19:09AWizzArdand i agree
19:09AWizzArdshared in the sense of StructMaps (the datatype)
19:10AWizzArdand I also say: as this example stands on the website, there also is no sharing
19:10rukubitesAnyone?
19:11AWizzArdrect always returns a fresh Map, but not a StructMap
19:12AWizzArd:Shape :Rect is shared in the sense of being a key/value pair in that Map. But it is not shared in the sense of a StructMap, where the keys don't consume memory, but only the values.
19:12AWizzArdrukubites: for me slime+Clojure works fine. But I never used your key combination, so I can't say anything about it
19:13rukubitesAWizzArd: if it is convenient, can you test to see if it works? I downloaded all the code fresh today, and if it works, that would indicate a regression.
19:14AWizzArdwhat do I have to do?
19:17rukubitesM-x slime-scratch , then in the buffer type (+ 1 1) and press C-j after the last bracket.
19:17rukubitesC-x C-e after the bracket works correctly.
19:17AWizzArdit says: "Evaluation aborted." after I pressed C-j
19:18rukubitesYes. Normally it inserts a newline and writes out "2" below the form.
19:18rukubitesThank you.
19:18rukubitesI will email the list.
19:18AWizzArdI see
19:19rukubitesIt is the way I standardly develop, in a buffer. I don't really like using the REPL directly.
19:19AWizzArdI see, I never used slime-scratch
19:19AWizzArdalways do CL on the relp, since many years :-)
19:20arbschtit appears swank:eval-and-grab-output is unimplemented by swank-clojure
19:22rukubitesAhhh. I am not a slime/swank programmer per-se, do you know whether it is unimplemented because it is "hard" or because it is just "not done yet" ?
19:23AWizzArdno idea
19:23rukubitesAWizzard: I like using scratch pads because it is easier to morph exploratory code into working functions.
19:23arbschtrukubites: I would say "not done yet"
19:24rukubitesarbscht: That is promising. *heh* I could make it my "hello world" in Clojure.
19:26rukubitesLooking at the allegro implementation it doesn't look too hard.
19:35rukubitesarbscht: I am not sure you are right. The function swank:eval-and-grab-output is implemented in swank.lisp, not in one of the implementation-dependent files.
19:35rukubitesBut then, I guess a lot more would be done in swank-clojure.
19:35rukubites(than if it was a CL implemantation.)
19:47arbschtrukubites: swank-clojure does not use swank.lisp. slime's implementation-specific arrangement only applies to CL
19:58rukubitesarbscht: Yes, I came to that conclusion too, you're right, of course.
20:13anynWhat is "AOT"?
20:14anynahead of time, got it
20:15anynand it's purpose for clojure?
20:15anynI'm guessing that would allow clojure to work on the android platform, right?
20:16Chouseranyn: AOT compilation would allow you to produce .class files, rather than just a running program, from .clj files.
20:16Chouseranyn: right, android
20:16anynright, deploy to jvm without the clojure.jar
20:16anynright?
20:16Chouseralso, delivering a clojure app with no Compiler or ASM libs.
20:16anynright
20:17Chouserwell, you'd still need the runtime classes from clojure.jar. The data structures and such.
20:17anynwhich would be pretty sweet
20:17Chouserbut it'd still be fair bit smaller than the current clojure.jar, which may help for mobile phones and such
20:17anyndoes the jre come with a jit compiler anyway?
20:18anynjre comes with hotspot, doesn't it
20:18Chouseralso clojure currently uses a custom classloader whch can cause some deployment difficulties in some contexts, like applets.
20:18anynooooh
20:18anynassimilation is key
20:18Chouseranyn: I think so, but that's to compile java bytecode to native instructions, right? we'd still want that. :-)
20:19anynoooh
20:26AWizzArdshouldn't we be able to get Clojure programs running on mobile phones today?
20:44pjb3Is it documented somewhere how you use clojure contrib?
20:45pjb3I assume you just download, make the jar, add it to your claspath
20:45anynAWizzArd: yea, but the android has a stack-based jre... all code has to be precompiled to bytecode
20:46anyni mean 'jvm'
20:48anynnot sure if javaME is compatible.. android is j2StandardEdition
20:48Chouseryou don't need to make a jar
20:49Chouserjust svn-get clojure contrib and add clojure-contrib/src/ to your Java classpath
20:57pjb3then how do you load it once it's on your classpath?
20:57pjb3require?
20:59arohnerpjb3: yes, require or use
20:59arohnerpjb3: (use 'clojure.contrib.sql)
21:00pjb3arohner: thanks
21:21Chouserpjb3: best is to use the ns macro, like (ns pjb3 (:require [clojure.contrib.sql :as sql]))
21:21pjb3Chouser: so what does that mean?
21:22pjb3I would call pjb3/whatever
21:22pjb3if whatever is a function in clojure.contrib.sql
21:23Chouserdo that at the top of your file (or whenever in the repl) and you can call sql functions list (sql/with-connection ...)
21:23Chousers/list/like/
21:24pjb3what's the purpose of (ns pjb3 ?
21:24Chouserat the repl I usually say (ns user ...)
21:24Chouserthat's your own namespace, so new thing you define go there and won't conflict with anybody else's.
21:25pjb3why not do (require [clojure.contrib.sql :as sql])
21:25Chouserthat's okay, though you have to quote the vector
21:26Chouserif you're putting it in a file, though, using a single ns call at the top is idiomatic.
21:27pjb3sure, because that defines and sets the namespace, right?
21:33Chouseryep
22:04AWizzArdHow are lists implemented in Clojure? Can concat add in constant time to the end of a list?
22:04arohnerI think conj adds in constant time to the beginning
22:04ChouserAWizzArd: how would that be possible without mutation?
22:06AWizzArdRich explained he used these crazy data structures that allow magic things. One can cons and conj stuff to huge sequences and Clojure does not need to make a full copy.
22:07Chouser:-) ok, good point.
22:07arohnerright, so if I have the list a -> b -> c, you can make d -> a -> b -> c without modifying the original list
22:08AWizzArdarohner: it is unfortunately a bit more complex... all other vars that have a reference to that list must not see my change.
22:08ChouserI'm pretty sure the PersistentList is just a plain ol' singly-linked list. So no, concat would be linear time on one of the lists.
22:08arohnerbut if you want a -> b -> c -> d, you now have to modify the c cell
22:08ChouserAWizzArd: nope, arohner's right.
22:09duck1123don't vectors add to the end of the list though
22:09arohnerduck1123: yes, vectors do
22:09arohneras a singlely linked list, 'a' has no idea that 'd' is pointing at it
22:09AWizzArdright, I agree
22:10Chouseranybody that had a ref to "a" keeps that, while anybody that added "d" (or anything else) sees their own addition plus the old list.
22:10AWizzArdbut I don't know *if* it is a plain old linked list
22:10ChouserI'm pretty sure it is.
22:10AWizzArdIf that is true and we have a list with, say, 2gb of data then consing 1 byte in front of it will result in a copying session of the 2 gigs.
22:11AWizzArdmaybe Rich was talking about hash tables then, where he implemented this magic stuff
22:11arohnerPersistentList(IPersistentMap meta, Object _first, IPersistentList _rest, int _count){
22:11arohner super(meta);
22:11arohner this._first = _first;
22:11arohner this._rest = _rest;
22:11arohner this._count = _count;
22:11arohner}
22:11Chouserno, consing 1 byte on the front copies nothing. Trying to add something on the tail would require a full copy.
22:11AWizzArdChouser: yes, that's what I meant
22:12ChouserAWizzArd: oh, sorry, I get head/tail mixed up pretty often.
22:12ChouserSo yes, if you want to cons one thing on the right-hand side, use a PersistentVector, where there's magic to keep it cheap.
22:12AWizzArdfrom this video it sounded as if he can add stuff to a map (= hash table) and need not to copy it if other vars have a reference to it
22:12duck1123what if you do something with lazy-cons, would that avoid making copies?
22:13duck1123or is that all the same if you're putting it on the end
22:13AWizzArdAnd he was talking about having no cons cells anymore. So I thought lists are implemented in some other datastructure that will not always need to be copied.
22:14arohnerI think that meant that the "cons interface" is abstracted away
22:14Chouserduck1123: no, you're onto something there. lazy-cat for example.
22:14arohneras a user, you deal with lists, vectors etc, not cons cells
22:15AWizzArdright
22:15AWizzArdhe probably just meant this abstract thinking about what lists are
22:15Chouserlists are cheap to add to one end, vector to add to the other.
22:15arohnerand as we pointed out earlier, when you use lists efficiently, they don't have to always be copied
22:15AWizzArdfrom the posted code it looks though that it just is a linked list
22:15Chouservectors allow "changes" anywhere in the middle, as do maps.
22:16AWizzArdChouser: but how can that be done without copying?
22:16ChouserAWizzArd: for vectors and hash-maps?
22:16AWizzArdfor vectors
22:17AWizzArdadding something anywhere would need a fresh copy
22:17AWizzArdof the full vector, no?
22:17Chouservectors are not linked lists, they're a sort of tree, and when you make a "change", only a single path thru the tree needs to be copied, so much cheaper than copying the whole thing.
22:18AWizzArdokay, so not one-dimensional arrays?
22:18Chouserno, they're clever, magic little critters, not an array.
22:18AWizzArdthis of course costs more for accessing elements
22:19Chouseryes, but still practically constant time
22:19AWizzArdSo we have no arrays in Clojure?
22:19Chouseryou can access Java arrays if you really want to.
22:19AWizzArdand those are "real arrays" then I guess?
22:19AWizzArdOr has sun also banned them? ;-)
22:20Chouseryep. mutable, fixed length (I think), constant-time read and write, Arrays.
22:21AWizzArdBack in the 80ies we did not have all this stylish tree stuff on the C64. Plain arrays were cutting edge.
22:21Chouser:-)
22:21AWizzArdwhat kind of tree is it that Clojure uses under the hood for vectors?
22:22Chouservectors and hashes have a similar implementation. There are a couple screencasts on "data structures" that I think contain some details.
22:23Chouserwatch those and read the code, and you'll be all set.
22:23AWizzArdokay, that was the video I didn't see so far
22:23ChouserPorting them to another language is optional, but very helpful.
22:23Chouser:-)
22:23AWizzArdlong discussion, and I am all the time talking about lists with usually +/- 5 elements *g*
22:24AWizzArdI should not care much if I have to reverse it or add to the end
22:24Chouser:-) yep. Vectors of < 32 elements just copy the whole thing on any change.
22:24Chousernice fast blit, I would assume.
22:25Chouserdon't use reverse though, just use a vector. they work great.
22:25AWizzArdI need a list at the end - it's code that I generate
22:26Chousera seq over the vector's not good enough?
22:27AWizzArdBut is it not the same to reverse a list vs reverse a vector and then seq it?
22:29Chousersince conj'ing onto a vector puts things in the opposite order, you probably won't need to reverse it at all.
22:30Chouserthe seq on it still walks the right direction though.
22:31Chouser(reverse (apply conj '() (range 5)))
22:31Chouser(seq (apply conj [] (range 5)))
22:32Chouserboth produce (0 1 2 3 4), but the first creates a list and then copies tho whole thing (via reverse)
22:32AWizzArdin principle seq and reverse should have +/- the same efficiency... we need to run through the whole collection anyway
22:33AWizzArd(into [] (range 5))
22:33Chouserreverse keeps the whole copy in memory, seq does not.
22:34Chouserwhen you're talking about 5 or 10 items, the efficiency differences don't matter much. But using list and reverse is not idiomatic when vector would work.
22:35AWizzArdalthough consing up a list should be more efficient in general than inserting into a tree
22:36AWizzArdotherwise we could do everything with a vector and always seq it in the end, if we really need a list
22:38AWizzArdand one thing that sounds really strange is this: http://clojure.org/data_structures#toc53
22:39AWizzArd"nth also works for Java arrays, and, in O(n) time, for sequences."
22:39AWizzArdnevermind, I misread that *sigh*
22:47rukubitesSomewhere above you guys implied that you can't compile clojure to .class files. I thought Clojure was further along than that. :-(
22:49Chouserwhy do you want .class files?
22:50arohnerrukubites: rhickey is currently working on compiling to .class files
22:50AWizzArdyou should ask yourself if you really need .class files in the coming few months... if this is critical then Clojure is not yet for you
22:51AWizzArdbut if you think that your life does not depend on it, then you shouldn't worry, as this will come
22:52rukubitesChouser: so I can write in Clojure and users of my software don't care that the source code is clojure.
22:53rukubitesI actually did some reasonably major work with ABCL to try to get something like that happening.
22:53Chouserthey have no need to care. You can put everything you need into a .jar and deploy it.
22:53rukubitesLibraries...
22:53Chouseryou mean to provide a library, or to use one?
22:53rukubitesProvide, of course.
22:54Chouseryou can use gen-class to provide a .class file that turns around and calls clojure fns for all methods (and constructor, etc.)
22:56rukubitesI guess that may well be good enough. I guess the same issue exists with Common Lisp, the only flavour that can compile down to a .so/.dll library is theoretically ECL.
22:57Chouserrhickey has already demonstrated producing .class files is possible, but he's still working out all the details. It'll come, and gen-class features will probably be rolled into it.
22:58rukubitesChouser, that does sound cool. :-)
23:00Chouserone of the nice things about gen-class (compared to regular java) is that you get clojure features on your class -- swap out method implementations at runtime and transaction aware object state changes.
23:15AWizzArdChouser: woohoo, I have currying ready :-)
23:35sohailAWizzArd, you there?
23:35AWizzArdyes
23:35sohailok so I saw the discussion
23:35sohailabout :Shape + struct
23:36AWizzArdthis discussion that followed was mostly for this other guy, as he didn't understand the difference between maps and structure maps
23:36sohailI see
23:36AWizzArdBut is this example as it is written on the website 100% clear?
23:37sohailyes definitely
23:37sohailI was just trying to map the example to CLOS
23:37sohailbut it seems the two don't quite map
23:37sohailwhich is unfortunate
23:38AWizzArdlet's see
23:38AWizzArdI think you can do it very much the same in clos
23:39rukubitesI have a question that might be meaningless, but I'll give it a shot: Why make a distinction between let and with-local-vars?
23:40AWizzArdrukubites: Add (binding ...) to the discussion as well :-)
23:40sohailwell for CLOS, I would have done (defclass shape ()) (defclass rectangle (shape) (<slot-defns>)) (defmethod area ((r rectangle)) ... )
23:40AWizzArdsohail: looks good
23:40sohailand then (make-instance 'rectangle :width w :height h)
23:40rukubitesNo I understand binding, I think. binding locally sets what in CL would be a special variable.
23:41sohailbut for clojure, seems I gotta do the equivalent of (make-instance 'rectangle :width w :height h :metaclass (find-class 'rectangle)) (I made up everything after :height)
23:41AWizzArdrukubites: what is the difference between let and binding? Replace binding in this example with let: http://clojure.org/vars#toc1
23:41walterslet is lexical, binding is dynamic
23:41rukubitesI wasn't asking about binding...
23:42rukubitesI was asking about with-local-vars.
23:42rukubitesIs it that let interns variables?
23:42AWizzArdrukubites: but _I_ am asking about binding
23:42sohailjust seems to me that clojure doesn't exactly have an object system
23:42sohailwhich is fine, I just need to get used to it
23:42AWizzArdsohail: that's correct. No OOP - it's a lucky day!
23:42rukubitesAWizzArd: Wow you hijacked my question nicely then:
23:42AWizzArd;-)
23:43sohailit's lucky as long as I don't write more or make code more buggy, but in this case, it seems I do
23:43sohailI think clojure will eventually end up having an object system layered over it
23:44AWizzArdsohail: you can build an object system anytime yourself..
23:44AWizzArdyou could implement clos in Clojure if you wanted
23:44sohailAWizzArd, ya... except it'll be slow as hell!
23:44AWizzArdI just see nothing which would be made easier by having an object system
23:44AWizzArdwe want to go away from that (oop that is)
23:46AWizzArdwalters: so if I shadow bindings with let then those variables will not change globally for the thread in which the let is running in, but with binding this would be the case?
23:46sohailAWizzArd, maybe
23:46sohailI just don't see how making the usage of multiple-dispatch MORE buggy helps though
23:46arbschtI've missed CLOS little in the time I've used clojure, but I don't try to write CL in clojure
23:46sohailarbscht, that's what I was looking for
23:47rukubitesCLOS can be quite evil. People tend to use it when they should be using generic tools and passed functions.
23:48AWizzArdsohail: in what aspect did Clojure make the use of multiple dispatch more buggy?
23:48rukubitesI prefer polymorphism by passing functions as parameters.
23:48sohailAWizzArd, the example I gave earlier
23:48sohailsomeone could just do {:Shape :Circle :width w :height w}
23:48sohailit doesn't help that clojure says nothing
23:48rukubitesThe above is a map?
23:48AWizzArdyes
23:48sohailthat's the multiple dispatch example, yeah
23:49AWizzArdbut what is the problem with it?
23:49sohaila circle doesn't have a width and a height?
23:49rukubitesYes it does
23:49sohailuh.
23:49sohailwhat?
23:50sohailin the example it sure didn't
23:50arbschtnot if it's defined otherwise, say by radius. that's an arbitrary coincidence
23:50arbschtright
23:50sohailyeah I mean seriously, talk about missing the forest
23:50rukubitesSOrry, I was talking about circles, not the example. n/m.
23:51AWizzArdsohail: so you complain that someone could just build up his own map, without using the constructor functions provided and then call circle methods for things that are not really circles?
23:51sohailand iirc, an ellipse is defined using eccentricity
23:51sohailAWizzArd, pretty much, yeah
23:51AWizzArdthis would give a run time error but could in principle be caught by the compiler
23:51sohailnot really complaining, but pointing out
23:52arbschthow can the compiler be sure? generalized multimethods don't just dispatch on 'type'
23:52AWizzArdwell, sohail knew it
23:53AWizzArdso there exists a way to reason about code and come to this conclusion.. a compiler could in principle do anything a human can also know about code
23:53sohailarbscht, I guess what I am saying is totally separate from multi methods
23:53sohaili.e., I still have to get used to it ;-)
23:54sohailI mean to be honest, I use dictionaries quite liberally in Python but I find it quite annoying if it is done all over the place.
23:55AWizzArdsohail: you complain that there exists ways to cause runtime errors
23:55AWizzArdthis is well possible in Clojure, CL and Python
23:55sohailI point out that it doesn't need to be so seat-of-your-pants!
23:55rukubitesI think that if objects are really just maps with no higher-level structures, they will be open to abuse. But this is (a) lisp, not a baby language.
23:56AWizzArdhave fun
23:56sohailI'm kidding
23:56sohailgeez
23:56rukubites:-D
23:56arbschtI'm not convinced that encoding rules around your objects in functions is necessarily more prone to bugs
23:56AWizzArdwell, it's a legitimit descision to not code in Clojure
23:57sohailall you need is some real smug weenies in here and your transformation to a lisp is complete
23:57sohail(again, kidding)
23:57sohailarbscht, you mean less prone?
23:57sohailor do you mean manually doing it in every function that manipulates said objects?
23:57sohails/manipulates/uses/
23:57arbschtsohail: no, more prone. (defn rect ..) versus default values in CL-style struct
23:58rukubites*heh* a colleague of mine runs the blog smug lisp weenie.
23:58sohailrukubites, tilton?
23:58AWizzArdis (format ..) the best way to make a string out of a symbol?
23:58rukubitesYep
23:58sohailarbscht, sure, but that is how CL started isn't it
23:59sohaili.e., defstruct generated a bunch of functions
23:59sohailthen people were like, "wtf this is silly" -> CLOS