#clojure logs

2009-01-09

00:31danlarkinOh man I'm totally in the clojure zone right now
01:13durkais there an easy way to have a long .. form, but just bail out early and return nil if something in the chain returns nil?
01:15vogelrndurka: the only thing I can think of (although that isn't saying much) is to make a variation on the .. macro
01:18durkai might do that
01:21durkai just wrapped the call to .. in a try and caught NullPointerExceptions
01:22hiredmanheh
01:22hiredman"maybe" be damned
01:23durkaeh?
01:23hiredman"try" or "andand" or whatever they are calling it these days
01:24hiredmanhttp://andand.rubyforge.org/
01:24durkais bitbucket down?
01:25PuzzlerI've been thinking again about "amb". Is it possible to implement amb without continuations? Does anyone here even know what I'm talking about :) ?
01:25vogelrnI do not :P
01:26hiredmansounds slightly familiar
01:27Puzzlerhttp://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-15.html
01:27durkabitbucket responds to ping but i think apache crashed...
01:27durkacan someone confirm or is my computer acting up?
01:28PuzzlerIt's a very useful tool for writing search programs with backtracking.
01:28PuzzlerIt's also one of those things that's commonly used to show off something you can write in Lisp/Scheme that's hard to write in other languages.
01:32hiredmaninteresting
01:41vogelrnPuzzler: it looks like it's possible, but more complicated. Isn't it basically just a depth first traversal of the options?
01:42hiredmanno
01:42vogelrnoh?
01:43Puzzlervogelrn: It's related, but the way (amb) jumps back and retries the last choice point with a different option makes it tricky to implement.
01:43hiredmanwithout contiuations I dunno how you could do it
01:43PuzzlerHow do you break out? By raising an error? That doesn't quite work. How do you capture the remaining computation?
01:45PuzzlerI think it might be possible to implement a variation that obeys a certain kind of scoping. Not quite the same, but maybe just as useful for the common case.
01:45hiredmanmaybe you could do it with some kind of abstraction over (try (catch))
01:46durkaandle
01:46durkafail
01:46hiredmanclojurebot: just a little bit?
01:46clojurebot1
01:47durkaclojurebot: how 'bout a zero bit?
01:47clojurebot1
01:47PuzzlerIt's hard to figure out how to make something like this work: (defn pick-a-digt [] (amb 0 1 2 3 4 5 6 7 8 9))
01:48hiredmanclojurebot: amb is http://gd.tuwien.ac.at/languages/scheme/tutorial-dsitaram/t-y-scheme-Z-H-15.html
01:48clojurebot'Sea, mhuise.
01:48PuzzlerIt's easier to imagine a form that works like let: (amb [x (range 10)] (if (< x 8) (amb-fail) x)))
01:49hiredmanyes
01:49PuzzlerMy 9 ) turned into a emoticon 9)
01:49Puzzler8)
01:49PuzzlerI mean 8 )
01:51hiredman(amb-fail) could just throw an exception
01:52PuzzlerRight, and that might work for the one that works like a let form. But in the first case, imagine amb is a macro that tries to catch an amb-fail exception. In that block of code, there is no exception. The exception will be thrown somewhere completely different that isn't scoped as part of this code.
01:53hiredmanyeah
01:53hiredmanI know
01:54PuzzlerWhat interests me the most about this problem is that if I can implement amb, I'd like to see if I can leverage Clojure's agent system to create a new variant that explores various branches on different threads. I think it could be a very cool way to do search.
01:54hiredmanman
01:54hiredmanmy fingers are itching now
01:55hiredmanhmmm, and vim has stopped working
01:56vogelrnit might just be that I'm tired, but I'm still having trouble seeing how it isn't equivalent to depth-first search on a tree
01:58vogelrnyou go down a branch, and if you encounter failure, you backtrack to the last place you had another option
01:59PuzzlerThe order in which the various choices are searched is equivalent to a depth-first search. But the way in which you express the choice points, and the rejection of choices, in your code, is very flexible, making it a pleasant way to code such things.
02:00PuzzlerFor example, at the REPL, I can say something like (def a (amb 1 2 3)). As I work with a, for now it will be 1. Later, I can just type (amb) at the prompt, and it will automatically go back and redo everything I've done as if earlier I had defined a to be 2.
02:02durkathat sounds really hard to do without a continuation
02:03Puzzleri wonder if maybe there's a way to take advantage of the transaction system to record a "choice point". But transactions don't really nest; inner transactions are essentially a no-op.
02:03PuzzlerSo no way to create a hierarchy of choice points with that technique.
02:05vogelrnwould it be correct to say that amb is taking advantage of continuations as an implicit tree structure?
02:08PuzzlerI think it's usually implemented where each time you do amb, it takes a continuation and stores it on a stack. When amb fails, it pops the most recent continuation off the stack and resumes with another choice. So it's the combination of the stack and the continuations that gives you the tree structure.
02:09durkai mean, at the REPL you're looping so even if you throw something like an exception there's nothing to unwind
02:09vogelrnok, just making sure I understood
02:11vogelrnthe way I see it you would either have to use an explicit tree structure or find another language feature capable of expressing it implicitly, neither of which seems very palatable :P
02:12PuzzlerI think the let version might be doable though. I'll have to think more about it. Anyway, I've gotta run. Good chatting with y'all!
02:13vogelrnwhatever it is it's going to be very hackish
02:13vogelrnyou too, I'm out as well
02:14durkaapparently i have 19,947 unique classes on my classpath
02:29durkathat was incorrect, a bug excluded clojure.jar
02:29durkathere are 25,814 classes
02:30durkaGorilla=> (lookup "Ref")
02:30durka["com.sun.xml.internal.bind.v2.model.core.Ref" "com.sun.xml.internal.bind.v2.runtime.reflect.opt.Ref" "com.sun.xml.internal.xsom.impl.Ref" "java.sql.Ref" "sun.misc.Ref" "clojure.lang.Ref"]
02:30hiredman,(identity *ns*)
02:30clojurebot#<Namespace sandbox>
02:30hiredman,(amb [v (range 1 8)] (if (not= 8 v) (throw (Exception. "not an eight")) v))
02:30clojurebot8
02:33durka,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w (throw (Exception. "not equal"))))))
02:33clojurebotjava.lang.Exception: Too few arguments to if
02:33durkawhoopa
02:33hiredmanlisppaste8: url?
02:33lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
02:33durka,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w) (throw (Exception. "not equal")))))
02:33clojurebotnil
02:34hiredmanhmmm
02:34hiredmannot a very clean macro
02:34durka,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w) (throw (Exception. "not equal")) v)))
02:34clojurebot#<core$range__3485 clojure.core$range__3485@141e00a>
02:35durkaer
02:35hiredmannesting is a no go
02:36lisppaste8hiredman pasted "amb, embaressing attempt 1" at http://paste.lisp.org/display/73311
03:01hiredman,(amb [v (range 1 8)] (amb [w (range 7 0 -1)] (if (not= v w) (throw (Exception. "not equal")) v)))
03:01clojurebot1
03:01lisppaste8hiredman annotated #73311 with "try #2" at http://paste.lisp.org/display/73311#1
08:19jpcooperhello
08:19jpcooperdoes anyone know about getting Clojure running with j2me?
08:20jpcooperI'm interested in writing programmes for my mobile phone
09:10ole3hello i like to specialize methods on types, this works for strings as in the example on the homepage, but i can not specialize on keywords. Is it posible to specialise a function on keywords?
09:11rhickeyole3: sure
09:11rhickeyyou want to say (foo :fred ...) and have that do something different from (foo :ethel ...) ?
09:12ole3nope
09:12rhickeythen what?
09:12ole3i want to say (foo string ...) to be different from (foo :keyword)
09:12ole3I get an exeption: No method for dispatch value
09:13rhickeyyou've done (defmulti foo class)?
09:13ole3yes
09:13ole3(defmethod foo keyword [k] ...)
09:13rhickey(then defmethod foo clojure.lang.Keyword [k] ...)
09:13ole3;)
09:14ole3thank you!
09:14kotarakole3: (class :foo) helps in such a case to find at the correct dispatch value...
09:15ole3i see!
09:40leafwsimple problem, hard solution: suppose I have a vector or list [a b c d e] and now I want to take d and put it after a: [a d b c e]. What is the proper, easy way to do so?
09:42AWizzArdTo my knowledge Clojure does not yet offer a function to do this. Even no vdelete and vinsert are availble. So you will manually have to remove and insert that element.
09:43leafwAWizzArd: then I have to implement my own vdelete and vinsert ..
09:43AWizzArdleafw: or make it a hashmap with numbers as keys
09:43leafwAWizzArd: can't. I need to keep a list with no gaps in the numeric keys.
09:43AWizzArd{0 a 1 b 2 c 3 d 4 e}
09:43leafwi.e. inserting one new element would mean shifting all keys
09:44leafwor adding a floating point key
09:44leafwits a list of objects to be painted in stack order, because they overlap.
09:44gnuvince_leafw: how would you make the function call?
09:45AWizzArdleafw: (apply hash-map (interleave (range (count your-vector)) your-vector))
09:45leafwI would pass the element to shift, plus a numeric shift value: -1, -2, 6, etc. relative to its current position. If it goes beyond first or last, then make it first or last respectively.
09:45AWizzArdthen you can use assoc and dissoc
09:48leafwthere must be an easier way. Keeping a hash map would mean dissoc first, assoc with a floating point key, sort by keys, get vals, make new vector, interleave with range, make new hash map ...
09:48leafwthat reads is overly complicated.
09:48hiredman(doc sorted-map)
09:48clojurebotkeyval => key val Returns a new sorted map with supplied mappings.; arglists ([& keyvals])
09:49gnuvince_leafw: have you considered alternative ways to accomplish the higher level task you want to do?
09:50leafwgnuvince_: I confess I used to do this with an array, where positions are swapped easily.
09:50leafwgnuvince_: but resizing arrays is a pain
09:51leafwhiredman: the sorted map doesn't solve much, still need floating point keys, which may become unmanageable.
09:51leafwI know I can solve this, I am just exploring how could one solve it easily and elegantly
09:51gnuvince_leafw: cause it looks like there's no easy solution for this
09:51hiredmanleafw: after you munge the map, you can turn it back into a vector
09:51hiredmanand loose the keys
09:52gnuvince_And although I have no proof of that, my gut tells me that the implementation would be rather inefficient
09:52leafwhiredman: true. Then make it again .. every time
09:52hiredman*shrug*
09:52leafwwith cons cells one should be able to do it
09:52AWizzArdleafw: you could use a doubly linked list
09:52hiredmanhow many objects are you painting?
09:53AWizzArdThere you could move elements around pretty efficient. But random access is not so fast as in vectors of course.
09:53leafwhiredman: from 0 to thousands
09:54AWizzArdmaybe java.util.LinkedList can help
09:54leafwAWizzArd: need to learn more about doubly linked lists
09:55leafwAWizzArd: would need to protect it in a private ref in any case ... could work
09:55AWizzArdleafw: http://java.sun.com/javase/6/docs/api/java/util/package-summary.html or specifically http://java.sun.com/javase/6/docs/api/java/util/LinkedList.html
09:56leafwAWizzArd: I know the java collections rather well, thanks :)
09:56lisppaste8jdz pasted "the put one thing after the other thing" at http://paste.lisp.org/display/73321
09:56leafwI was looking for a trivial solution in clojure
09:56AWizzArdleafw: does not exist yet
09:56leafwAWizzArd: one can only hope.
09:56achim_phmm, is there a data structure that provides constant-time indexed access and fast inserts/deletes? none that i knew of.
09:57leafwachim_p: a doubly linked list, I guess. Removing is just remerging the prev with the next elements in the chain.
09:58AWizzArdthe constant-time indexed access is not available with doubly linked lists
09:58achim_pleafw: lists have linear time access ...
09:58leafwachim_p: true
10:03lisppaste8jdz annotated #73321 with "a terminating version" at http://paste.lisp.org/display/73321#1
10:04leafwjdz: commendable, but I can't use it. Thanks in any case.
10:04jdzleafw: you can't use it because?
10:06leafwjdz: because the first time I described the problem improperly. Then I explained: I would pass the element to shift, plus a numeric shift value: -1, -2, 6, etc. relative to its current position. If it goes beyond first or last, then make it first or last respectively.
10:07jdzleafw: seems like a trivial change to the function to me
10:29lisppaste8jdz annotated #73321 with "oh those lazy young programmers" at http://paste.lisp.org/display/73321#2
10:31jdzi think i'll rather go do some projecteuler.net puzzles
10:39Carkhum this doesn't work anymore : (.showMessageDialog JOptionPane parent (if (nil? message) "null" message))
10:40Carkit says that JOptionPane has no showMessageDialog method
10:40Carki guess because it's a static method
10:40rhickey.method is for instance methods only
10:40Carkwhat would be the correct syntax now ?
10:40jdztry .JOptionPane/showMessageDialog?
10:41Carkah that makes sense
10:43Lau_of_DKIts (javax.swing.JOptionPane/showMessagedialog nil "Message")
10:43Carkyep that works, thanks all
10:45Lau_of_DKnpz
11:32knaprhow hard would it be to port Clojure to another platform? or create its own VM ?
11:34rhickeyChouser's ported a lot of it to JavaScript
11:34RaynesHawt.
11:34vsthesquaresthat's nice
11:34knaprbut bascially a lot of it is portbale right? the /src stuff. it is the java stuff that needs to be rewritten
11:34rzezeskirhickey, didn't you initially implement Clojure on both the JVM and .Net simultaneously, but then dropped the .Net impl because of time?
11:35knaprnot that I want to Java interop is super. just asking
11:35rhickeyrzezeski: yes
11:35Raynesrhickey: I totally want your autograph :p
11:36vsthesquaresbut why would you want to make yet another VM? there's enough duplication in effort going on as it is
11:37knapr^^ as i said
11:37knaprjust wondering
11:38rzezeskiNot that I care for it to be implemented on another VM, but it could help for adoption in certain situations (say a .Net only shop)
11:38knaprbut wouldnt they just choose F# ?
11:39knaprim getting into datamining more and more, generally heavy computational tasks and it looks like C++ is kind of needed a lot.
11:39knaprthen
11:39rzezeskimaybe, maybe not, but they may have no choice if Clojure is only on the JVM
11:39vsthesquaresmaybe we'll see a IronClojure one day ;)
11:40RaynesThey wouldn't use F# because F# is a horrible mess.
11:40Raynes:|
11:42cooldude127hey is there a way to declare function arguments to be type `int'?
11:42rzezeskiMost any language is a horrible mess with a big enough microscope
11:42cooldude127as opposed to the boxed Integer
11:42rhickeycooldude127: no
11:43knaprcooldude: i think you can annotate inside a function to spped up though, not the same thing though obv
11:43cooldude127knapr: how do you mean?
11:43cooldude127optimization is the goal here
11:44cooldude127rhickey: is this because the difference between primitives and objects would require too much special code?
11:44rhickeycooldude127: but if you need to use them as such in a tight loop inside the fn, you can re-let them with type coercions: (defn foo [x y] (let [ (int x) y (int y)] ...))
11:45rhickeysorry (let [x (int x)...
11:45cooldude127oh
11:45rhickeycooldude127: yes, fns have a uniform object-based interface
11:45rhickeyIFn
11:46cooldude127should i be fooled by the fact that at the repl, (class (int 5)) gives java.lang.Integer
11:46cooldude127?
11:47rhickeycooldude127: primitives are not first-class objects, let of a primitive creates a primitive local, and hints can avoid boxing in arg calls, but whenever a first-class value is required it's going to be boxed
11:47hiredmanclojurebot: amb is also http://paste.lisp.org/display/73311
11:47clojurebotYou don't have to tell me twice.
11:47cooldude127rhickey: so i am fooled
11:47hiredmancooldude127: class is a function, so the int is boxed as it goes in
11:47cooldude127:)
11:47cooldude127got it
11:48cooldude127btw hiredman does your amb work?
11:48cooldude127cuz I was kinda trying a little while ago to implement that
11:48hiredmanby not really being amb
11:48cooldude127and exceptions NEVER occurred to me
11:48cooldude127what do you mean
11:48rhickeyprimitive support is currently only local or into java methods
11:48cooldude127rhickey: got it
11:48cooldude127makes sense
11:49rhickeyI have ideas about expanding IFn for a select set of primitive overloads...
11:49hiredmancooldude127: well, the real amb using continuations and allows for really weird stuff
11:49hiredmanmy amb is just sort of, you know, flow control using exceptions :(
11:50cooldude127hiredman: well i tried doing the CL pseudo continuations from on lisp in clojure
11:50cooldude127and the lack of mutability made me give up
11:50cooldude127very different semantics
11:52hiredmanactually as I was falling asleep last night a modification or two to try #2 occured to me, but nothing really major
11:52cooldude127i'm about to try out #2, see if it does the kinda stuff I wanted it for
11:53cooldude127oh i see this is a little different then amb from, say, arc
11:53cooldude127but i g2g
11:53hiredmanI am sure it is
11:53Chouserwe do have definline already
11:54rhickeyChouser: that still only helps going to Java methods
11:55Chouseror other inlines/macros?
11:55rhickeyright, but must bottom out on method taking primitive to really help
11:56rhickeyThe idea here would be to add some more overloads to IFn, for unary and binary int/long/float/double returning same type
11:56rhickeythen a fn variant that let you say it was a fn of ints/longs/floats/doubles
11:57rhickeyObject sign would map to primitive sig, for use in any unknown context
11:57rhickeyin known context, with known desire for primitive return, all-primitive sig would be called - no boxing
11:58rhickeywould help these silly microbenchmarks where people think Clojure recursion is slow but it's just the arg boxing
11:58rhickeyand the decomposition of math code into fns
11:59rhickeyneeds desired return type inference not currently present
12:00rhickeybut could simply require coercions to signal - give me the primitive version
12:01rhickeyotherwise can't distinguish (f afloat) -> float from (f afloat) -> something-else
12:02rhickeystill thinking about it but mostly done (in my head at least) :)
12:02Chousernot just a smop
12:02Chousernow just a smop
12:02rhickeysmop?
12:02ChouserSimple Matter Of Programming
12:02rhickeyyeh
12:02rhickeyand time
12:03Chousergenerally used with some degree of facetiousness
12:03rhickeyI'm working on getting my streams stuff up into a branch so people can play with it
12:03Chouserinteresting.
12:04Chouserthanks for you recent detailed treatment of non-caching seqs.
12:04leafwbeyond assoc for a vector, are there any other vector-related utilities to find elements (any kind of index of?)
12:04rhickeyChouser: did it make sense?
12:05rhickeyleafw: vectors are Lists, so:
12:05rhickeyuser=> (.indexOf [2 3 1 2] 1)
12:05rhickey2
12:07ChouserI hadn't found the arguments for changing seq behavior to be terribly compelling, but your mention of functional generators "accidentally" hanging onto the previous head was enlightening
12:07leafwfantastic ... had just made a fn to do that
12:07leafwso, fully, java.util.List ?
12:08rhickeyChouser: that is the kicker, and a nasty thing to chase down
12:08rhickeyleafw: yeah
12:09rhickey(ancestors (class [1 2 3]))
12:09leafw(ancestors (class []))
12:09leafwexactly.
12:10zakwilson_Is there a tool that's commonly used for profiling Clojure code?
12:11rhickeyChouser: my idea with the stream stuff is to get the basics up, with a few examples of streamified lib fns (map/filter etc), then if we get enough hands, we might be able to parallelize the effort and make them available sooner rather than later
12:11leafwhum, but .set doesn't work -- of course, wouldn't be persistent then
12:11leafwthrows unsupported exception
12:12rhickeyleafw: all of the mutation methods are optional and Clojure opts out
12:12rhickeyperfectly legal
12:12rhickey:)
12:12leafwindeed.
12:13rhickeyzakwilson: I use YourKit, not free but very nice
12:14rhickey(actually it was free, YourKit generously donated licenses to Clojure)
12:16zakwilsonrhickey: any plans to include basic profiling functions in Clojure itself?
12:16rhickeyzakwilson: nope - the Java tools are great
12:17zakwilsonI guess I need to learn my way around the Java ecosystem better then.
12:19rhickeyzakwilson: yeah, Clojure emits the low-level stuff so Java debuggers and profilers work, yielding tools far more sophisticated than those of langs much older (than Clojure)
12:21zakwilsonI'm used to CL and a little Scheme. I love Clojure the language. I'm still getting used to the Java world though.
12:22rhickeyadmittedly, it's not the same experience as say, CL debugging, but then I was a Lispworks customer for a few years before they had step debugging (Clojure has right now), and the Java profiling is fantastic
12:23technomancyI'm curious, what was the first real program (written for production use) in clojure?
12:25achim_phmm, google groups confuses me. usually, i receive copies of emails i send to the group. not with this one: http://groups.google.com/group/clojure/browse_thread/thread/3db6cb2b71008e73
12:26achim_pand it says "To <me>" instead of "From <me>" in the web view. weird - anybody else received it?
12:26rhickeytechnomancy: none I can talk about, but have several private reports, still a secret-weapon tech I guess :)
12:26technomancyoooh; secret-weapon tech... exciting. =)
12:27rhickeyhopefully not for actual weapons :)
12:27technomancyI was thinking "the pen is mightier than the sword"-type weapons.
12:28danlarkinachim_p: I received it in my inbox with no abnormality
12:29AWizzArdIf I want to make a Java Hashtable in Clojure, what is then the equivalent to
12:29AWizzArdHashtable<String, Integer> numbers = new Hashtable<String, Integer>();
12:29achim_pdanlarkin: good, thanks! just wanted to check before re-posting
12:30AWizzArdor should I just say (def numbers (Hashtable.)) and make sure to have strings as keys and numbers as vals?
12:30rhickeyAWizzArd: just leave out the <...> stuff, Java uses erasure
12:30rhickeyso at runtime they are all Hashtable <Object, Object>
12:31rhickeythat's actually a great feature for dynamic langs like Clojure
12:33jpcooperhas anyone worked with Clojure and J2ME?
12:33AWizzArdyes
12:34AWizzArdalthough it might be nice for speeding up access to specify the types as type hints
12:34jpcooperAWizzArd, was it quite simple?
12:34AWizzArdjpcooper: yes
12:34AWizzArdoh, sorry
12:34AWizzArdmy "yes" was for rhickey
12:34jpcooperoh :(
12:34AWizzArdI think with the J2ME it's a bit problematic, as the ME has ridiculous memory limits.
12:35jpcoopershame
12:35rhickeyAWizzArd: I don't think it would matter at all, the generic types are gone at runtime
12:35AWizzArdjpcooper: The clojure.jar is over one MB in size, but the ME allows only a few kb, like in the 1980ies.
12:35AWizzArdI see
12:35hiredmanalso, j2me is old java
12:35hiredmanjdk1.4? maybe older
12:36jpcooperI wonder whether I could get some kind of embedded Scheme running on one of these phones
12:36AWizzArdA mobile phone that runs the full JRE would be nice.
12:36AWizzArdUnder those all Clojure apps should run...
12:36technomancywould that include Android?
12:37hiredmanbleg
12:37jpcooperI have a Nokia 6500c. I believe that it runs Symbian
12:37hiredmanandroid threw away the best part of java and kept the worst
12:37hiredman(threw away the jvm and kept the java language)
12:37technomancyeww
12:37nsinghal(re-seq #"(.*\\n)|(.+$)" "jajd\nskdk") this used to split the string into "jajd\n" and "skdk"
12:37nsinghalit doesnt work now
12:38hiredman,(.split "\n" "jajd\nskdk")
12:38clojurebot#<String[] [Ljava.lang.String;@119fc9e>
12:38hiredman,(apply vector (.split "\n" "jajd\nskdk"))
12:38clojurebot["\n"]
12:38hiredmanoh
12:38hiredmanduh
12:38hiredman,(apply vector (.split "jajd\nskdk" "\n"))
12:38clojurebot["jajd" "skdk"]
12:38nsinghalstring.split removes the "\n" new line
12:39hiredman*tadda*
12:39nsinghali want to preserve that
12:39nsinghalthe desired results is "jajd\n" "skdk"
12:44rhickeynsinghal: you don't need double \s now: (re-seq #"(.*\n)|(.+$)" "jajd\nskdk")
12:49nsinghalrhickey: thx that works
12:51lisppaste8AWizzArd pasted "Hashtable Java vs. Clojure" at http://paste.lisp.org/display/73331
12:51AWizzArdrhickey: do you see a way how to speed up the code in Clojure here with type hints?
12:52AWizzArdAs I used the Java Hashtables in Clojure the difference in runtime efficiency could maybe be smaller than factor 40?
12:55achim_p_AWizzArd: (time (dotimes [i 1000000] (.put #^java.util.Hashtable x "vier" i))) ?
12:58Chousukeeasier to do that when defing though.
12:58Chousuke(def #^java.util.Hashtable x ...)
13:00danlarkinyeah adding the typehint sped it up to about 100 ms on my machine, down from 2800ish
13:01danlarkinreflection'll kill ya
13:02danlarkinuse (set! *warn-on-reflection* true) to see if the code you're writing has to use reflection
13:02hiredmanisn't there some warn on reflection deal you can set?
13:02hiredmanah
13:02Chousernecessary when writing applets
13:03rhickeyyou shouldn't worry about reflection unless called often
13:03Chouseror if you're writing applets. ;-)
13:04achim_p_Chousuke: shouldn't matter much. i ike the annotations close to method calls, find it easier to see what's happening
13:04rhickeyChouser: all reflection prohibited in applets?
13:04AWizzArdthanks achim_p_
13:04AWizzArdachim_p_: now it funnily runs *faster* in Clojure ;-)
13:04Chouserrhickey: looks like it. I haven't proved it, but certainly some reflection is prohibited.
13:05ChouserI can't use proxy-super in the Applet itself.
13:05rhickeyanyone have an interesting applet or Android app yet?
13:06rhickeyChouser: reflection of non-publics make sense to prohibit
13:06leafwChouser: can't setAccesible(true) in appletS: throws a security violation exception of some sort
13:06Chouserrhickey: dunno if it counts as interesting: http://chouser.n01se.net/misc/tree.html
13:06leafwin Method and Field, that is.
13:06technomancyis there a way to look up all the methods of a Java object from the repl?
13:07eyeris(disclaimer: complete lisp newb here) Is (. (100) (toString)) the proper way to convert an integer to a string?
13:08technomancyeyeris: should be (.toString 100)
13:08leafwtechnomancy: (doseq [m (sort (.getDeclaredMethods (class your-ob)))] (println m))
13:08technomancyor (str 100)
13:08hiredmanclojurebot: show?
13:08clojurebotshow is clojure.contrib.repl-utils/show
13:08technomancyleafw: thanks!
13:08hiredmaneyeris: (str 100)
13:08technomancyeyeris: if you put 100 wrapped in parens, it will try to call the function 100... which doesn't really make sense
13:09hiredmanor
13:09hiredman,(.toString (Integer. 100))
13:09clojurebot"100"
13:09eyeris(str 100) seemed sensible to me but I got an exception (class java.lang.Integerjava.lang.IllegalArgumentException: No formatter for type: class java.lang.Integer
13:09eyeris)
13:09hiredmanerm
13:09technomancyright; that needs to be a Java Integer like hiredman said
13:09hiredman,(str 100)
13:09clojurebot"100"
13:10hiredmanworks fine here
13:10technomancyfor .toString I mean
13:10technomancystr should work on anything
13:10lisppaste8rhickey pasted "applet error" at http://paste.lisp.org/display/73333
13:10rhickeyChouser: I get ^^
13:10vsthesquaresI'm experiencing the same
13:10eyerisOh, the , is meaningful?
13:10eyerisI thought that was a typo :)
13:10Chousukeeyeris: what version of clojure do you have? :/
13:10eyerisChousuke current svn
13:10hiredmanclojurebot: latest?
13:10clojurebotlatest is 1195
13:10Chouserrhickey: ah, yeah, sorry -- doesn't work on Mac. I haven't tried to figure out why.
13:10technomancyrepl-utils/show doesn't have a docstring.
13:11vsthesquareseyeris: no, the comma just tells clojurebot to execute
13:11leafwtechnomancy: sorry, (doseq [m (.getDeclaredMethods String)] (println m))
13:11hiredmanis that right? I think clojurebot's svn stuff is borked
13:11technomancybut it looks useful
13:11hiredmanbah
13:11hiredmanit is
13:11hiredmanborked that is
13:12Chousertechnomancy: yeah, that's not really acceptible, is it.
13:13technomancyChouser: I'll see if I can figure it out and submit a patch.
13:14technomancyit's actually... behaving pretty strangely for me. I show'd a date, then when I show'd an Integer it was telling me it had some of the Date's methods in there.
13:15Chousertechnomancy: I've got it covered -- just a sec.
13:15eyerisWhere can I find documentation for the `( form?
13:15eyeris(the web site search breaks on that input)
13:16vsthesquareseyeris: http://clojure.org/special_forms
13:16technomancyChouser: the docstring or the mixed Date/Integer return value?
13:16lisppaste8technomancy pasted "show strangeness (Date and Integer)" at http://paste.lisp.org/display/73335
13:16Chousertechnomancy: the docstrings
13:17eyerisvsthesquares I see the '( form there but not the `( form. Does it have another name?
13:17Chousukeeyeris: syntax-quote
13:18Chousertechnomancy: what kind of Repl are you using? that's really goofy.
13:18technomancyChouser: just slime.
13:18vsthesquareseyeris: (= `(1 2 3) '(1 2 3))
13:18technomancyI can try to repro in the regular repl if you like
13:19Chousukevsthesquares: ` and ' have crucial differences though.
13:19vsthesquaresoh, I didn't know that
13:19Chousertechnomancy: nothing "just" about slime. :-) The Integer members ought to be listed after "=== public final java.lang.Integer ==="
13:20Chousukevsthesquares: in that case they produce the same output, but `(foo bar) is not the same as '(foo bar)
13:20vsthesquaresinteresting, is this documented somewhere?
13:20Chousukeyes
13:20Chousukeprobably macros section.
13:20eyerisI found the ` docs here: http://clojure.org/reader
13:20technomancyChouser: so do you need me to see if it happens outside of slime for me?
13:21durkaChouser: not reproduced in Gorilla repl
13:22Chousertechnomancy: I can't reproduce it. Are you getting it consistently in Slime?
13:23technomancyChouser: I'm consistently seeing output that makes sense for the previous thing I passed to show.
13:24Chousertechnomancy: docstrings included in svn 358
13:24technomancyso if I show (0) a Date followed by (1) a Date followed by (2) an Integer followed by (3) an Integer, I'll see: (0) nothing (1) Date methods (2) Date methods (3) Integer methods.
13:24technomancyah, thanks
13:25Chouserwith some typos fixed in 359 :-P
13:26Chousertechnomancy: yeah, please try in a plain terminal repl
13:26technomancyok, will do
13:28technomancyok, can't repro there. will try a fresh slime instance
13:30technomancydefinitely reproducible in new slime instances. =\
13:30Chousersounds like a slime bug to me. :-)
13:31technomancyheh. "Connected. Take this REPL, brother, and may it serve you well."
13:31Chouser'show's not doing anything weird with the output, and certainly not hanging onto and state that would allow it to know what you used it on last.
13:31danlarkinI love the slime start messages
13:32technomancymaybe slime is doesn't expect lazy output or something.
13:32Chouserit's not lazy
13:32ChouserI assume you don't have this problem with 'doc'?
13:32technomancyright... hmmm... printf flushes for you, right?
13:32technomancyno, never had problems with doc
13:33Chouserthe only salient difference I see is 'printf' instead of 'println'
13:33eyerisDoes Webjure have any documentation accessible on the web?
13:33clojurebotsvn rev 1202; Make syntax-quote Classname. and .method aware, patch from Meikel Brandmeyer
13:33clojurebotsvn rev 1203; fixed Integer/LongOps.Negate overflow when MIN_VALUE
13:33clojurebotsvn rev 1204; fix range with too large negative index, patch from Olov Lassus made Range implement count()
13:33clojurebotsvn rev 1205; Report more incorrect usages of binding vectors, patch from Chouser
13:33clojurebotsvn rev 1206;
13:33hiredmanclojurebot: be cool
13:33clojurebotPardon?
13:33technomancyoh... hang on. I do have strange things going on with doc sometimes. the output will appear where I don't expect it.
13:33danlarkinclojurebot: max people?
13:33clojurebotmax people is 116
13:33danlarkinwrong!
13:34hiredmanyeah, well, you knwo
13:34technomancyhere's something interesting... when I first run show, I get only "=== public final java.lang.Integer ==="; no methods, but if I follow that with doc, it shows all the methods from the last call with the doc stuff tacked on the end
13:35technomancydefinitely a swank-clojure bug
13:38hiredmanoff hand, anyone know how to get a user count for a channel out of irssi?
13:41Chouserhiredman: /list #clojure
13:41zakwilsonIs there a way to see how many elements of a lazy seq have been cached?
13:44Chouserzakwilson: I don't think so.
13:44Chouserthat information appears to be private and unaccessible inside LazyCons
13:44ChouserI wonder if it would be considered "dangerous"
13:45Chouserit mutates of course, so you could have races and stuff in your otherwise beautifully immutable collection.
13:45zakwilsonI can't see how being able to read that would hurt anything.
13:46zakwilsonSure, writing to the cache would be bad.
13:47eyeris(: is for special forms, right? So how are they defined? (I'm trying to find the implementation of (:h3) in Webjure sources)
13:47Chousukeeyeris: : starts a keyword
13:48Chousukeeyeris: :h3 is not explicitly defined; possibly the html macro just uses them to denote html tags
13:48Chousereyeris: it's probably being used very much like a string in that case.
13:48eyerisOkay. I see that now.
13:48zakwilsoneyeris: there's probably no implementation of (:h3) - just a macro that turns forms starting with arbitrary keywords in to HTML.
13:49eyerisYeah, so I need to find the impementaiton of :html
13:49kotarak:html is also a keyword
13:49Chousukeeyeris: not :html. you need the macro
13:50Chousukeeyeris: a macro defines a kind of mini-language and in this case keywords have a special meaning for the mini-language :)
13:50eyerisRight. So it would be in the definition of whatever uses `(:html ...)?
13:51Chousukeeyeris: probably.
13:51kotarakyep
13:51eyerisDarn. I found that a long time ago.
13:51eyerisIt's a doozie :)
13:53hiredmanclojurebot: max people?
13:53clojurebotmax people is 122
13:53vsthesquaressounds about right :)
13:56danlarkinzakwilson: reading the number of cached values from a lazy-seq would ruin the immutability of clojure collections because it'd be different depending on when you evaluated it
13:57danlarkinerrrrrrrrrrrr
13:57danlarkinI guess it wouldn't actually mutate the collection though..
13:58Chouserdanlarkin: no, but calling 'rest' certainly would
14:08lisppaste8fanda pasted "Type hints" at http://paste.lisp.org/display/73336
14:09fandahello!
14:09fandajust wondering about type hints...
14:09fandacould Clojure infer the type from (class x) ?
14:10fandaor... could be type inferred when doing (new Class) ?
14:10hiredman...
14:10Chouseryou're allowed to re-def, either at the repl with another (def ...) or thread-locally with (binding ...)
14:11fanda(def x (new java.util.Hashtable)) clearly defines the type
14:11Chouserso a type hint is a little promise you're making to Clojure not to change it to an different type
14:11Chousukesome kind of optimisation could probably be implemented when you're compiling clojurecode into something that you will not modify at runtime.
14:12Chouserand also allows you to hint a more base type than the specific instance you're setting it to at the moment.
14:12cemerickJust in case someone was aching to hear my opinion ( :-P ), I'm mostly uninterested in "non-caching" seqs/streams/etc.
14:12Chousukeor even an interface
14:13Chousukelike java.util.Map if you require a map parameter that gets assoced a lot.
14:13fandayes, I know - I am just trying to identify cases, when it could be useful without my help
14:13Chousukeor hm
14:13ChousukeI guess assoc already has a type hint for Map? :)
14:14fanda...to specify type
14:14cemerickrhickey: :-D Oh, I'm sure I'll use them, but off the top of my head, I can think of only two or three situations where they'd be useful to me now.
14:14rhickeycemerick: even if you never use them directly, they are going to speed up map/filter et al by 2x
14:15Chousukewill you have separate map/filter functions for streams? streamfilter or streammap or whatnot?
14:15rhickeyChousuke: nope, just one
14:17cemerickrhickey: that sounds fun; I'm happy to be blissfully ignorant of those impls, tho
14:17rhickeycemerick: until you want to emulate them
14:17Chouserrhickey: were our reasons for checking if a LazyCons is cached correct?
14:17Chousukeare seqs also streams from an interface point of view?
14:17Chouserfor not allowing checking, that is.
14:18rhickeyChouser: you mean getting a count of cached? that's sort of outside the scope of any single element
14:19Chouserbut you could walk the chain, asking each LazyCons if it's 'rest' was cached yet
14:19rhickeyChouser: with access to the implementation, sure
14:19cemerickrhickey: emulate map and filter? You've lost me.
14:20rhickeycemerick: right now you write your own seq fns using lazy cons, and so do many of the seq fns, after streams the seq fns will mostly be defined in terms of streams, and you might want to do the same
14:21ChouserLazyCons.first_cached() { return _first != sentinel; }
14:21rhickeyChouser: I missed why this was important/useful
14:22ChouserNobody said, I'm just curious if you would resist exposing that information.
14:22rhickeyChouser: resisting right now :)
14:22Chousercemerick: just rhickey. :-)
14:22Chouserrhickey: heh. ok. I assumed you would, and was guessing as to the reasons.
14:22Chousernot a big deal.
14:23Chouserto me, anyway.
14:23cemerickChouser: and Mr. Engleberg, perhaps
14:23rhickeyChouser: I'd like to be able to change the implementations of things, if people marry all the details, its game over
14:23Chouser"ClassFormatError: Duplicate field name&signature in class file" however is big-ish.
14:23Chouserrhickey: ok.
14:24rhickeyChouser: ClassFormatError os where?
14:24rhickeyis where?
14:24zakwilsonDid I just stir up a mess here?
14:24danlarkinzakwilson: :)
14:25zakwilsonThe reason I want to be able to get a count of the cached elements is to check the progress of a long calculation from the REPL.
14:25Chousertrimming it down...
14:26Chousukezakwilson: you could do that manually.
14:27Chousukewonder if you could use the monad library to do something like that.
14:27rhickeyChouser: is it "same sig static method in superclass not hidden"
14:28zakwilsonChousuke: how?
14:28Chousukezakwilson: increment a ref at every iteration.
14:29Chouser*sigh* it just disappeard. I didn't see that text anywhere in the stack trace, if that's what you're asking.
14:29rhickeyChouser: no, a known gen-class issue
14:36Chouser_Sorry, power blink
14:36Chousukezakwilson: I thought so too, but then I realised I was wrong.
14:39eyerisI know what (defn (defmacro etc do. But what does (def do?
14:40Chousukeeyeris: def is the special form
14:40danlarkinis *file* blessed for use, or could it be going away?
14:40Chousukeeyeris: defn and defmacro use def; it binds a value to a var.
14:40eyerisOkay
14:41eyerisI saw it in this JDBC post: http://groups.google.com/group/clojure/browse_thread/thread/5b377466ca44886a
14:41eyerisWhy does he use (def rs instead of a let block?
14:42Chousukeeyeris: def is global
14:42Chousukesometimes it's useful to have global values
14:42eyerisI see
14:43lisppaste8Chouser pasted "Duplicate field name&signature in class file" at http://paste.lisp.org/display/73340
14:44Chouserrhickey: If I'm doing something wrong there, I'm not spotting it.
14:45rhickeyChouser: is there already an init?
14:46Chouseroh, there it is. :-)
14:46Chouseryep, that's it. Applet defines init()
14:47Chouserthanks
14:47rhickeythat's why I stick to fred and ethel :)
14:50gnuvince_rhickey: I meant to ask: there do those names come from?
14:51rhickeygnuvince_: I Love Lucy
14:51gnuvince_OK
14:51gnuvince_I'm not familiar with it
14:52rhickeyhttp://en.wikipedia.org/wiki/I_Love_Lucy
14:53Chouserwhich raises the question, do you love Lucy?
14:54rhickeynot really, just a fading childhood memory of watching the reruns
14:54danlarkinIs there a way to get a filename (or File object, whatever) for each symbol in (loaded-libs)? Like (map #(...) (loaded-libs))
14:55rhickeyThe names used to get a good laugh when I used to teach (advanced C++ of all things) at NYU
14:56Chousersome reflection is allowed in applets
14:57eyerisDo functions have to be defined before they are used (before in the source file, not chronologically at runtime)
14:57eyeris?
14:57Chousukeeyeris: no
14:57Chousereyeris: yes
14:57technomancyeyeris: maybe
14:57rhickeyno
14:57technomancyjust to round things out. =)
14:57eyerisHaha
14:57Chouservars have to be defined before you can refer to them in code
14:58rhickeyvars have to be visible, but you can delay the definitions
14:58technomancythey don't have to be defined as functions, but they need to be defined as names
14:58Chousukeyeah, but that can be done with declare
14:58danlarkin(doc declare)
14:58clojurebotdefs the supplied var names with no bindings, useful for making forward declarations.; arglists ([& names])
14:58technomancyso you can (def my-function) (defn function-that-uses-my-function [] [...]) (defn my-function "real definition")
14:59eyerisOkay. I get it.
14:59Chousukewhat's the difference between (declare foo) and (def foo)? or was declare just a convenience if you need multiple empty defs?
15:00technomancydeclare is nicer than def-with-no-value for multiple vars at a time
15:00technomancyChousuke: I think it's the latter
15:00Chouser'declare' suggests you're going to 'def' it later. (def foo) suggestes 'foo' will be used for dynamic binding.
15:01ChouserWhich I suppose means it ought to be (def *foo*)
15:01technomancyI was about to say, yeah, use asterisks
15:15fandaabout type hints - my question generally is:
15:15fandacan (def x (new Class)) be equivalent to (def #^Class x (new class))
15:15fandaalso, can (def x 5) be the same as (def #^int x 5)
15:16fandai am trying to write a macro for it, no luck so far:
15:16fanda(defmacro deftag [x value] `(def #^{:tag (class ~value)} ~x ~value))
15:17hiredmanyou are evaluating value tiwce
15:17hiredmantwice
15:18eyerisIs there a way to list the contents of a .jar?
15:18vsthesquaresunzip it
15:18rhickeyok, Java side of streams is up, in /branches/streams, svn 1207
15:18replaca,(str \L (apply str (replicate 10 \u)) \c \y)
15:18clojurebot"Luuuuuuuuuucy"
15:18eyerisThanks
15:18kotarakThe form must be `(def ~(with-meta x (assoc (meta x) :tag (class value)) ...) which doesn't work, because value is a Symbol.
15:18hiredmanthere is a java api for jar files
15:19clojurebotsvn rev 1207; intial import of streams stuff, Java side
15:19hiredmanI forget what package it is in
15:19hiredmanclojurebot: way late dude
15:19clojurebotI don't understand.
15:19technomancyshould I try to make a TAGS file for my codebase, or is it better to just ask SLIME where stuff is defined?
15:23fandakotarak: let me think about it little...
15:26durkavsthesquares: (enumeration-seq (.entries (java.util.jar.JarFile. "path/to/archive.jar")))
15:26waltersrhickey: i am actually working on a project where i needed a stream-like abstraction; i remember a discussion that you'd looked at a project where the stream API ended up being fairly complicated for e.g. resource management etc.; did you end up deciding that the current approach you have in SVN of just an Object next(); method is good enough?
15:28vsthesquaresdurka: damn, not only am I a lousy lisp programmer, I seems I don't know anything about the java api either
15:28rhickeywalters: I'll not say it's the end of the story, but a necessary subcomponent of many things. It's certainly been 'good enough' for IO for a long time. I kind of like that seq models Lisp lists and streams io read, both venerable apis
15:29vsthesquaresthanks for pointing that out
15:29waltersrhickey: yeah, i agree
15:29rhickeygotta run now
15:29durkawell, i only know that because i learned it a few days ago when i needed to use it
15:32vsthesquaresnet weer een nieuwe duistere krocht van de java api ontdekt
15:32vsthesquareswoops
15:32vsthesquareswrong chan
15:32Chouserfanda: I've got a def-hint working
15:32hiredmanclojurebot: what is <reply>net weer een nieuwe duistere krocht van de java api ontdekt
15:32clojurebotRoger.
15:33Chouserdef-auto-hint is a more accurate name, but too long.
15:33vsthesquaressorry 'bout that :)
15:33fandaChouser: nice :-)
15:33Chouserfanda: you want it, or you want to figure it out yourself?
15:34fandayes, I want it :-)
15:34Chouserbut I think it's good that 'def' doesn't do this by default -- could cause unexpected breakage that might be hard to track down.
15:34Chouser(defmacro def-hint [sym val] `(do (def ~sym ~val) (alter-meta! (var ~sym) assoc :tag (class ~sym)) (var ~sym)))
15:35hiredmanclojurebot: what is your stance on state vs. federal goverment?
15:35clojurebotHuh?
15:35hiredmanhmmm
15:35fandaChouser: thanks
15:36fandamight be useful for other people too
15:36fandaclojure-contrib?
15:36kotarakclojure.contrib.def?
15:36Chousergot a better name for it?
15:36kotarakdeftagged?
15:37hiredmandef-typed
15:38hiredmandef<haskell>
15:39fandadeftag / defhint / deftype
15:39Chouserhinted is more accurate than hint, I think.
15:39Chouserdef-typed
15:39hiredmandef<haskell>
15:39hiredmanfor reals
15:40Chouserfanda: is def-hinted short enough to still be worth it?
15:40kotarakmaybe without -? The other defs, don't have it.
15:40fanda(def #^java.util.Hashtable x (new java.util.Hashtable))
15:40fanda(defhinted x (new java.util.Hashtable))
15:41hiredmanI remind me to start using < and > in fn names
15:41hiredmanfanda: (java.util.Hashtable.)
15:41hiredman,(java.util.Hashtable.)
15:41clojurebot#=(java.util.Hashtable. {})
15:41mmcgrana(doc force)
15:41clojurebotIf x is a Delay, returns the (possibly cached) value of its expression, else returns x; arglists ([x])
15:41fandahiredman: yes, I know, I just like (new Class) better than (Class.)
15:42mmcgranaoops sorry, that was really random
15:42fandaon the other side, I don't like explicit types, so defhinted :-)
15:42hiredman(def<haskell> x (java.util.Hashtable.))
15:42hiredmanthink about it
15:44fandait is supposed to be only syntactic sugar - don't repeat yourself :-)
15:45cooldude127hiredman: i like your amb implementation
15:46cooldude127works way better than the one i tried to write
15:47hiredmangood, I think I going to rename it to amb?
15:47lisppaste8danlarkin pasted "get files for all (loaded-libs)" at http://paste.lisp.org/display/73343
15:47hiredmanugh
15:47cooldude127wait, what is that last symbol? i don't think i have emacs set for the proper encoding
15:47hiredmaninterrobang
15:48cooldude127oh
15:48cooldude127got it
15:48hiredman(prn "amb?")
15:48hiredman,(prn "amb?")
15:48clojurebot"amb?"
15:48hiredmanhmmm
15:48cooldude127it's a box for me everytime, but so are some other UTF-8 symbols
15:48hiredman,(symbol "amb?")
15:48clojurebotamb?
15:48hiredmanhmmm
15:48hiredmanuser=> (def amb? nil)
15:48hiredman#'user/amb=
15:48hiredman:(
15:48cooldude127oh no
15:49danlarkinthat paste I just made is answering my own question from earlier, about how to get filenames for all (loaded-libs)
15:49technomancylooks fine to me
15:49hiredmanwhen I try to def something to amb? clojure defs it to amb=
15:50cooldude127hiredman: maybe we shouldn't mess around with the interrobang anyway
15:50durkaGorilla=> (def amb? "iguous")
15:50durka#'user/amb?
15:50durkaGorilla=> amb?
15:50durka"iguous"
15:50hiredmanoh
15:50kotarak:)
15:50hiredmanI think I remember this
15:51cooldude127i'll be right back, i'm gonna try to fix something
15:51hiredmanjline's fault
15:55lisppaste8Chouser pasted "Be careful with defhinted" at http://paste.lisp.org/display/73344
15:57ChousukeChouser: maybe add a check to defhinted if there is already a hinted definition?
15:57Chousukehm, that sentence could use a different word order.
15:58Chouserbut using 'def' the subsequent times would avoid the check but still cause the exception.
15:58Chouseralso 'binding' can cause the same sort of problem
15:59Chouseranyway, it's in clojure-contrib svn 360
15:59hiredmanthere is the whole range of unicode to play with
15:59kotarakWell, maybe one has to keep the discipline to only assign the same type to a hinted Var....
16:09fandathanks for help and advice
16:09fandatalk to you later!
17:08nsinghal(defmacro set-enable [panel field-name enable]
17:08nsinghal `(.. ~panel ~field-name (setEnabled ~enable)))
17:08nsinghalwhen i do the macroexpand on it
17:08nsinghal(macroexpand '(set-enable panel jCheckBoxExternal true))
17:08nsinghali get (. (. panel jCheckBoxExternal) (user/setEnabled true))
17:08nsinghali want (. (. panel jCheckBoxExternal) (setEnabled true))
17:09Chousukensinghal: use ~'setEnabled in your macro
17:10nsinghalChousuke: Thx so much - that works
17:25ChouserAnyone on Mac want to try http://chouser.n01se.net/misc/snake.html ?
17:26durkaloading...
17:26Chousukehmm
17:26durkasame as before
17:26ChousukeI just get an X :/
17:26Chouserdurka: ok, thanks.
17:27ChouserChousuke: that's Windows?
17:27Chousukenah, Mac OS
17:27Chousukefirefox
17:27Chouseroh, ok. The Mac applet plugin is pickier, apparently.
17:28Chousukesame thing with safari
17:29Chouserworks ok in firefox on linux, and firefox and chrome in XP.
17:29ChousukeChouser: 10/01/2009 00:27:49 [0x0-0x1d70d6f].com.apple.Safari[66560] java.lang.VerifyError: class examples.snake overrides final method
17:29ChouserChousuke: yeah, thanks.
17:29Chouserhttp://paste.lisp.org/display/73333
17:31Chouserhm, Java 1.5?
17:31lpetitapplet does not start for me on Windows XP, firefox 3.0.5
17:31ChousukeChouser: yes
17:31Chousermaybe it's a 1.5 vs 1.6 thing.
17:32lpetit1.5 too
17:34Chouserok
17:38durkachouser: same thing with 64bit 1.6, 1.5 and 32bit 1.5
17:38Chousergah
17:41durkaagain it works fine in appletviewer
17:41Chouserwow. Write once, run ...
17:43ChouserI'm downloading the 1.5 JDK. I'll try building all of clojure and the applet with that, see if it helps any.
17:46lpetitI've a question concerning swank-clojure
17:48Chousukelpetit: you'll have to ask it if you want help.
17:48lpetitDo you know if there exist a client for swank-clojure written in clojure ? I'd like to call swank-clojure from an eclipse plugin, and if there was already the client part written in clojure ...
17:49Chouserlpetit: I'd love to see that. I've not heard of one, though.
17:50ole3is the swank side not always writen in the host language?
17:50ole3at least for the cl implementation that is the case
17:50Chouserdurka: new snake.jar up
17:50durka:(
17:51Chouserbah
17:51lpetitChouser: yes. For the moment, I balance between doing the strict minimum in eclipse-dev with own homegrown client/server inspired from swank-clojure, but more "straight-to-the-point" (not depending on the protocol of e-macs, maybe not that robust ...), or trying to understand slime/swank protocol ... maybe a pain in the ass since I do know nothing about it
17:52lpetitole3: I've downloaded swank-clojure. It does not seem to provide a clojure client side, just configuration files for the emacs ELISP configuration client side.
17:53lpetitThere is a big class in cusp (common lisp -at least SBCL- eclipse plugin) that speaks to a common lisp swank, but it's not well documented and I don't know whether it will take me more time to integrate to swank, or to redo it more "straight to the point"
17:53ole3lpetit: sorry i thought you mean the server side.
17:55technomancythere's a CL plugin for eclipse? wow.
17:56lpetitSomething is stopping me currently from doing it myself : I'm unable to make my server-side part correctly evaluate objects that include defs
17:56lpetittechnomancy: Yes. Try cusp on google. I once tried it, it seemed really interesting
17:57ole3http://www.bitfauna.com/projects/cusp/ a swank client
17:57technomancyit just surprises me that such a thing exists; most CL folk have a low opinion of eclipse.
17:57ole3it is nice
17:58ole3think most of them do not tried eclipse
17:58lpetittechnomancy: Well, most Eclipse folks have a low opinion of emacs :-)
17:58technomancylpetit: that explains why there's no eclipse-mode in Emacs. =)
17:58ole3most stuff works out of the box simple, focused environment
18:01lpetitOK. So back to clojure: can you explain me why the following does not work :
18:01lpetit(eval '(binding [*ns* (create-ns 'foo)] (def bar 1)))
18:01Chouseryes
18:01Chousertry (binding [*ns* (create-ns 'foo)] (eval '(def bar 1)))
18:02lpetitit works
18:05Chouserdef uses the value of *ns* at compile time.
18:06lpetitNow, I want to send the following string from my client : "(ns foo) (def bar 1)"
18:06lpetitI want it read on the server side, and correctly evaluated (so that ns 'foo is created, as well as var 'ns.bar.
18:06lpetitOf course, I would like to not parse the string to search for a 'ns or 'in-ns ... => The string would come from a text editor in eclipse
18:10lpetitSo there's no workaround for the general problem ?
18:11ole3question: why is swank needed anyway? Why could not the eclipse plugin load an clojure instance?
18:14Chousukeole3: you'd still need a protocol for communicating information between clojure and the IDE.
18:15Chousukeole3: and connecting to an external clojure instance can make things a lot nicer if you need to kill it :P
18:16lpetitole3: I thought about this. Maybe something like starting in debugging mode, and using the possibility of straight java interoperability. That's a possibility, but I don't know much about the feasibility of what I describe here.
18:17lpetitole3: and concerning swank-clojure, there's already the whole bunch of services it offers for searching documentation, indentation hints, symbol completion, ... and certainly a lot more I don't know about
18:18lpetitBut there's also the possibility that swank-clojure will evolve with slime, and that thinks will continuously break, be fixed, break ... I don't know how stable this would be as a dependency ... ?
18:18durkathat is the current situation isn't it
18:18lpetitYou haven't answered me ? What IRC client do you use ?
18:19lpetitdon't know how disturbing this situation really is, in practice ?
18:20durkacolloquy
18:20lpetit?
18:21durkapersonally i don't use swank-clojure but as i understand it clojure, swank-clojure and slime keep updating independently, and constantly break compatibility, and the best way to keep a working setup is just to stay on the bleeding edge of all three
18:21durkacolloquy is the irc client
18:21durkai have to go but i will be back later tonight
18:21hiredman,(do (prn (str *ns*)) (binding [*ns* (create-ns 'foo)] (def a 1)))
18:21clojurebot#'sandbox/a
18:21clojurebot"sandbox"
18:21hiredmanI see
18:22durka-gonei thought clojurebot didn't do defs?
18:22hiredmanwell
18:22hiredmanI can reach into his guts
18:22hiredmanit does what I say
18:22technomancyyou must have a long arm
18:22Chousukehiredman: you added an exception for yourself? :P
18:22Chousukeor just poking at it at the repl
18:23technomancygotta wait till hiredman goes offline then /nick hiredman and do as you wish. =)
18:23Chousukedo you run clojurebot from emacs btw?
18:23hiredmanChousuke: poking at the repl
18:23hiredmanno
18:23hiredmanfrom zsh :P
18:23ChousukeI did, when I was testing it. was pretty nice.
18:23hiredmanwell, good, I guess
18:23hiredmanclojurebot: emacs
18:23clojurebotemacs is hard, lets go shopping!
18:24technomancywould be cool do to IRC from the same instance as you had a bot repl in
18:24Chousuketechnomancy: heh.
18:25ChousukeI think I should run the emacs daemon or something.
18:25Chousukethen I could set up my clojure script to just run emacs and show me the slime repl
18:26lpetithiredman: didn't understand your example. Was connected to my question ?
18:26ole3lpetit: did you look at the message protocol of the server side? And at eval-region?
18:27hiredmanlpetit: I was just checking to see how clojurebot's eval handled that
18:27hiredmanif it did
18:27hiredmaneval-in-a-box
18:28lpetit,(+ 1 2)
18:28clojurebot3
18:28lpetitwow!
18:28ole3lpetit: there is a function called fix-namespace, which seem to do what you want
18:28lpetit,(doc fix-namespace)
18:28clojurebotjava.lang.Exception: Unable to resolve var: fix-namespace in this context
18:29hiredmanoh
18:29hiredmanfor doc don't use ,
18:29ole3,(doc ns)
18:29clojurebot------------------------- clojure.core/ns ([name & references]) Macro Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted.
18:29hiredmansee, if you use "," the formating is bad
18:29hiredmanjust do (doc ns) no ","
18:30lpetit(doc ns)
18:30clojurebotSets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ...), when supplied, defaults to :name corresponding to th
18:30Chousukehiredman: you could rebind doc to use your version :/
18:30ole3not much difference :)
18:30hiredmanstill wonky, but better
18:30hiredmanChousuke: I was thinking that
18:32lpetitole3: no I did not look at it because I didn't know it was to be called eval-region ? (swank really is very focused on emacs : maybe technically reusable, but semantically very tight to !)
18:34ole3lpetit: as i understand it, it defines an rpc mechanism, and eval-region takes a string fixes the namespace thing and compiles it
18:35ole3lpetit: no eval needed
18:35lpetit(defn- eval-region
18:35lpetit "Evaluate string, return the results of the last form as a list and
18:35lpetit a secondary value the last form."
18:35lpetit ([string]
18:35lpetit (with-open [rdr (LineNumberingPushbackReader. (StringReader. string))]
18:35lpetit (loop [form (read rdr false rdr), value nil, last-form nil]
18:36lpetit (if (= form rdr)
18:36lpetit [value last-form]
18:36lpetit (recur (read rdr false rdr)
18:36lpetit (eval form)
18:36lpetit form))))))
18:36lpetiteval is here, near the end
18:36ole3:)
18:37lpetitSorry for the whole screen source code. Maybe it's not desirable to do that on IIRC ?
18:37hiredmanirc
18:37hiredmancorrect
18:37hiredmanlisppaste8: url
18:37lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
18:38ole3hm
18:38ole3(eval 'foo)
18:39ole3,(eval 'foo)
18:39clojurebotDENIED
18:39lisppaste8lpetit pasted "test" at http://paste.lisp.org/display/73354
18:39lpetitwow, very cool indeed
18:39ole3,(compile 'foo)
18:39clojurebotjava.io.FileNotFoundException: Could not locate foo__init.class or foo.clj on classpath:
18:39lpetit,*compile-path*
18:39ole3nevermind
18:39lpetit,(prn *compile-path*)
18:39clojurebotnil
18:40ole3,nil
18:40ole3nil
18:40lpetit,(str *compile-path*)
18:40clojurebot""
18:40lpetit,(do *compile-path*)
18:40clojurebotnil
18:40lpetit(doc do)
18:40clojurebotIt's greek to me.
18:40lpetithihi
18:40lpetitOK, I calm down
18:41ole3,(pr 'hoo)
18:41clojurebothoo
18:41lpetitWho is hosting clojurebot ?
18:41hiredman<-
18:41ole3,(loop [i 0]
18:41clojurebotEval-in-box threw an exception:EOF while reading
18:41ole3,(loop (recur))
18:41clojurebotjava.lang.ArrayIndexOutOfBoundsException: 1
18:41Chousukeole3: it does not fall to that.
18:42Chousuke,(loop [] (recur))
18:42Chousukeclojurebot: latest
18:42clojurebotExecution Timed Out
18:42clojurebotlatest is 1207
18:42ole3safe
18:42Chousukeit's a small DOS though apparently :p
18:43lpetitI think we should avoid bad thinks with it, like calling format on C: ? :()
18:43Chousukeyou can try
18:43Chousukethis happens:
18:43Chousuke,(System/exit 0)
18:43clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)
18:43lpetitHehe
18:43hiredmanlpetit: go ahead
18:43hiredmannot windows, no C:
18:44lpetit,(System/getProperties)
18:44clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission * read,write)
18:44Chousukehiredman: does it run as its own user?
18:44hiredmannope
18:44hiredmanI guess I could (should?) do that, but meh
18:44hiredmanI am trusting in the jvm sandboxing, at least until it deletes all my files
18:47lpetit,(java.io.File/listRoots)
18:47clojurebot#<File[] [Ljava.io.File;@e93999>
18:48hiredman,(first (java.io.File/listRoots))
18:48clojurebotnil
18:48hiredman,(apply vector (java.io.File/listRoots))
18:48clojurebot[]
18:48lpetit,(dorun #(.toString %) (java.io.File/listRoots))
18:48clojurebotnil
18:48hiredmanhwa
18:48Chousukenoroots apparently :P
18:49lpetit,(doall #(.toString %) (java.io.File/listRoots))
18:49clojurebot#<File[] [Ljava.io.File;@12a73d9>
18:49lpetit,(seq (doall #(.toString %) (java.io.File/listRoots)))
18:49clojurebotnil
18:49lpetitok ok
18:50Chousuke"If a security manager exists and its SecurityManager.checkRead(java.lang.String) method denies read access to a particular root directory, then that directory will not appear in the result. "
18:50lpetitAnd concerning my def evaluation problem ?
18:51dreishAre you guys trying to do (seq (java.io.File/listRoots)) ?
18:51ole3no, we tried already
18:51lpetit,(.openConnection (new URL "http://www.clojure.org&quot;))
18:51clojurebotjava.lang.IllegalArgumentException: Unable to resolve classname: URL
18:51Chousukelpetit: that will fail
18:51dreishOh, sandbox testing. I see.
18:52lpetit,(.openConnection (new java.net.URL "http://www.clojure.org&quot;))
18:52clojurebot#<HttpURLConnection sun.net.www.protocol.http.HttpURLConnection:http://www.clojure.org&gt;
18:52Chousukeeven if you had the full class name :P
18:52Chousukewait, what.
18:52Chousukeor is that just connection object? not actually connected
18:53Chousukeit should not have any network permissions
18:53dreish,'#=(eval (def what-about "this thing?"))
18:53Chousukedreish: it needs to start with ,(
18:53lpetit,(.getContent (.openConnection (new URL "http://www.clojure.org&quot;)))
18:53dreish,(identity #=(eval (def forgot-the "parens")))
18:53clojurebotjava.lang.IllegalArgumentException: Unable to resolve classname: URL
18:53clojurebot#'clojure.core/forgot-the
18:53lpetitArgh
18:53dreishYeah, still need to reject the string #=
18:53hiredman,(.read (.openConnection (new java.net.URL "http://www.clojure.org&quot;)))
18:53clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.net.www.protocol.http)
18:53lpetit,(.getContent (.openConnection (new java.net.URL "http://www.clojure.org&quot;)))
18:53clojurebotjava.security.AccessControlException: access denied (java.net.SocketPermission www.clojure.org:80 connect,resolve)
18:54Chousuke,(identity forgot-the)
18:54clojurebotjava.lang.Exception: Unable to resolve symbol: forgot-the in this context
18:54Chousukeum.
18:54dreish,(identity #=(eval forgot-the))
18:54clojurebot"parens"
18:54Chousuke,(identity #=(eval '(System/exit 0))
18:54clojurebotEval-in-box threw an exception:EOF while reading
18:54Chousuke,(identity #=(eval '(System/exit 0)))
18:54clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)
18:54Chousukephew.
18:54ole3)))))))))))))))))))))))))))0
18:54dreishAre you sure you want to do that?
18:55ole3((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))
18:55Chousukedreish: the worst would have been that clojurebot would have quit
18:55ole3,(((((())))))))))))))))))))))
18:55clojurebotjava.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn
18:55hiredman,(identity #=(eval forgot-the))
18:55clojurebot"parens"
18:55Chousukewhich would have been preferable to someone actually doing something destructive :P
18:55dreishRight.
18:55ole3,(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
18:55clojurebotjava.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn
18:55Chousuke,(identity #=(eval *ns*))
18:55clojurebotTitim gan �ir� ort.
18:56dreishAre those your extra parens, ole3? Can I use them?
18:56hiredmanChousuke: #= is a naughty form now
18:56ole3dreish: a gift, use them wise.
18:56dreish,(identity #=(eval (+ 21 21)))
18:56clojurebotExcuse me?
18:57lpetit,((fn toto [] (toto)))
18:57clojurebotjava.lang.StackOverflowError
18:58lpetitWeird that nobody tried to make clojurebot compute the infinite fibonacci sequence yet ;-)
18:58hiredman*shrug*
18:58hiredmanno different then the infinite loop
18:59ole3it will give an memory exception, with enough time
18:59hiredmanno
19:00hiredmanclojurebot execution times out after 10 seconds
19:00hiredman(a little less infact)
19:00ole3the computer is then to slow!
19:00hiredmanwell, either that or stackoverflow
19:01ole3who needs a stack
19:01lpetit,(do (doall (repeat "hello") nil)
19:01clojurebotEval-in-box threw an exception:EOF while reading
19:02ole3nevermind
19:02hiredmananyway, you can abuse clojurebot via privmsg
19:03ole3everywhere i go, the singal/noise ratio drops. maybe i am part of it. good night!
19:06lpetitIs it possible to load from a string ?
19:08lpetitIf in clojure-dev, the user has this in a text editor : "(ns foo) (def bar 1)" -> and doesn't want to save the content of the editor, but still wants to send its content for evaluation to a remote clojure environment, how can I handle that in the remote clojure environment (hypothesis : I don' t use an out of the box - read swank - solution, and the remote clojure environment receives the...
19:08lpetit...content as a string) ?
19:10lpetitChouser re-explained me that with eval there's no possibility (the def's would be tied to the compiled value of *ns*, not the value of the last (ns) or (in-ns) found in the eval'd string
19:14rhickeylpetit: create a reader on the string and use load-reader?
19:15lpetitthank you !
19:20lpetitrich : ok, it was in the docs ! I also found (load-string) that seems to do the with-open ... plumbing in the case of strings. Thank you so much !
19:24lpetitRich, do you know of an existing swank-clojure client written in clojure ? I think that if not, for a first version of clojure-dev, I will not attempt to master slime/swank/swank-clojure first (and not try to port eclipse cusp plugin), and go with a quick and (not so dirty I hope) homegrown solution ? A single server with no footprint on the distant REPL (a script loaded which defines no...
19:24lpetit...namespace, and adds no symbol to existing namespaces), and also, maybe, a way to even pilot the installation/deinstallation of helper functions on the server side by injecting them from the client side ! :-)
19:35lpetitgood night
19:43fffejsay I've got a list of characters, how do I turn them into a nice string (e.g. [\f \o \o] => "foo")
19:44Chouser,(apply str [\f \o \o])
19:44clojurebot"foo"
19:44fffejthanks!
21:29wyclefhello, all
21:29wyclefi'm new to lisp programming, period. does anyone know of a step-by-step lisp tutorial for clojure?
21:30Chousukehmm :/
21:30Chousukesadly, the documentation is rather scattered.
21:32wyclefi've been looking at the documentation on clojure.org but i'm not well enough grounded in functional programming to make much headway
21:32Chousukewyclef: I found this http://www.moxleystratton.com/article/clojure/for-non-lisp-programmers
21:33Chousukehm, that page lists str as a special form
21:37wyclefit seems like a condensaton of the material from the screencasts
21:38wyclefi think i'll use sicp, and try to make the necessary conversions as I go along
21:38wyclefthanks for the help
21:38Chousukepractical common lisp might be good too
21:39ChouserProgramming Clojure doesn't assume any lisp background, if you're willing to spring for it.
21:39Chousukewyclef: with these: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure
21:40mmcgranasicp + drscheme would be a good way to get started with lisp as a general idea
21:41mmcgranadrscheme is nice because it just works, unlike most other lisp environments
21:41Chouseris it really worth learning a non-clojure lisp first?
21:41wyclefthanks, i didn't know about either of those
21:42ChouserI read "on lisp" for free online, but that was my only significant lisp before clojure.
21:42mmcgranayeah maybe not, maybe just jump right into the clojure repl
21:43ChouserHm, I sense I'm being mocked. :-)
21:44arbschtI don't think so. it's a fine idea
21:45ChousukeI don't think you need previous lisp experience to get started with clojure
21:45wyclefvery cool. a lot more information that i had a few minutes ago
21:46mmcgranaChouser: not at all
21:46Chouseroh, ok. I do think it's worth reading some kind of lisp introduction, or at the very least watching Rich's "clojure for java programmers" series
21:47mmcgranaWhen I started trying to learn lisp a few years ago I couldn't get any environment set up other than Scheme, I guess I was just thankful for that. And +1 for the screencasts they are so mcuh fun.
21:47Chousukethough they're a slight bit outdated already :)
21:47Chousukestill valid though.
21:48wyclefi stumbled across the recorded lectures from the jvm language summit
21:48wyclefthat's where i heard about clojure
21:48ChouserI think it'd be great if someone transcribed the screencasts. Easier to keep up to date, easier to skim and search.
21:48danlarkinwrite some clojure to do it :)
21:49ChouserIt'd really be taking one for the team, though. TDus.
21:50Chousukehm
21:50Chousukemight actually be fun to write a tutorial
21:51Chouserright, that's what I meant by "TDus". "fun". Chousuke: go for it!
21:53Chousukesome kind of "groundwork" for people with no lisp experience so that they can at least understand the other stuff on the net.
21:54Chousukebut not now. now is time for sleep.
21:55danlarkinwhat's the recommended way to write an infinite loop? trampoline?
21:55Chouserdanlarkin: 'iterate'?
21:56Chouserloop/recur ?
21:56wyclef'(loop [] (recur))'?
21:56danlarkinoh... duh
21:56Chouser:-)
21:57danlarkinfor some reason I was worrying about the stack, but obviously that was unfounded
21:58danlarkinthat's my brain trying to say it's done programming for the day
21:58danlarkinbut I'm not going to listen!
22:00wycleffind the nearest espresso machine
22:02danlarkinshould I use an agent for watching certain files, or should I just use (new Thread ...)?
22:03Chouser(new Thread) is so tedious. :-)
22:04Chouserif the thread is likely to terminate, 'send-off' works from a pool, which ought to improve efficiency.
22:06danlarkinnah, I just want to have an infinite loop on another thread watching for changes to files
22:06danlarkinso it won't terminate
22:08Chouserprobably doesn't matter then. do what feels good. :-)
22:08Chouserhm, an exception from (new Thread) probably dumps directly to your console. That might be convenient, compared to agent-errors.
22:09danlarkinHmmmm that is true
22:11danlarkinalthough haven't agents yet, I think I'm going to now :)
22:19Chouserrhickey: did you see (meta #^:my-tag []) ==> nil ?
22:25danlarkinoh... is it bad form to have my agent performing side effects (if it detects changed files)? I guess it probably is... I suppose I should use (new Thread ...)
22:38rankpif i pass a {1 2 3 4} to a function in clojure and modify it so it is {1 2 3 4 5 6} then both of them exists? isnt that a huge memory hog? can I somehow tell Clojure to delete the old one?
22:40rhickeyChouser: no, thanks for the report
22:40Chouserall of clojure's collections have structural sharing, so if it's quite likely that especially in large collections, the new one will "contain" the old one.
22:40Chouserrhickey: it's from the group. shall I create an Issue?
22:40rhickeyChouser: yes, thanks
22:40Chouserrankp: so that reduces the burden of creating a new one from an old one.
22:41Chouserrankp: also, as soon as you no longer have any references to an object, it will be available for the JVM to garbage collect, freeing it up automatically.
22:41Chouserrankp: in short: don't worry about it. :-)
22:43rankpChouser: ah that's clever, i see