#clojure logs

2009-07-09

01:43sayyestolifehm
01:44sayyestolifeI might have missed something; but wouldn't it be nice of the api doc had some concrete examples?
02:04arbscht_sayyestolife: have a look at http://clj-doc.s3.amazonaws.com/tmp/doc-1116/index.html
02:04arbscht_oops, I meant http://java.ociweb.com/mark/clojure/article.html
02:05arbscht_but yes, it would be nice if the api doc had examples :)
02:07arbscht_ah, this has progressed somewhat too: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples
02:09sayyestolifethanks
03:14sayyestolifehmm in python and c++ (and in other languages aswell) you can specify a default value for function parameters; is there a way to do this in clojure too?
03:15sayyestolifelike "void func(int x=0) { return x; }"
03:16hoecksayyestolife: sometimes I'm using arity overloading to specify default arguments
03:16arbscht_not in the params vector, but you can rebind with (let [x (or x 0) ..] ..) in the function body
03:16hiredmanarity or hash destructuring
03:16sayyestolifehmm, no thanks then; that is too much work for something so simple :)
03:17hiredman*shrug*
03:18hiredman,((fn this ([a] (this a 1)) ([a b] (+ a b))) 3)
03:18clojurebot4
03:19Rieconpretty much the same way they do it in java right?
03:22hiredman,((fn [{:keys [a] :or {a 1}}] a) {:a 2})
03:22clojurebot2
03:22hiredman,((fn [{:keys [a] :or {a 1}}] a) {:b 2})
03:22clojurebot1
03:23hiredmanexcept people don't use much hash destructuring it seems
03:23hiredman:(
03:44RieconI donno, I'm a fan :)
03:44Rieconalthough I use it in lets alot
05:46sayyestolifehm
05:47sayyestolifeIf I want to pass an argument when I create a java class instance, how do I do that? I tried (new MyClass arg), but it didn't work
05:55sayyestolifeeh, found the error
05:55sayyestolifehow does one reload an opened file?
06:04sayyestolifeehm
06:04sayyestolifeisn't is possible to add a directory on the classpath?
06:16ceninansayyestolife: don't know if java supports dir in classpath, but either way a shell script could do it
06:18Raynessayyestolife: java -cp <dir>/
06:20eevarsomeone able to help me speed up http://pastebin.com/d64ca3d98 ?
06:40sayyestolifeanyone here used clojure-mode in emacs?
06:41arbscht_I use it
06:42sayyestolifeHow do I make it start automatically when editing .clj files?
06:44eevar(add-to-list 'load-path "/path/to/clojure-mode") (require 'clojure-mode) ;; in your .emacs should do?
06:45sayyestolifeeevar I still have to do a M-x clojure-mode each time I open a new file
06:46asbjxrn(setq auto-mode-alist
06:46asbjxrn (cons '("\\.clj$" . clojure-mode)
06:46asbjxrn auto-mode-alist))
06:48sayyestolifenice, thanks
06:48sayyestolifeone more thing though; how do I make the connection between emacs and the clojure program?
06:48sayyestolife(the interpreter)
06:49asbjxrneevar: Add a type hint for the image var in the render-frame function.
06:49eevaryou'll need swank-clojure and slime, if I understand your question correctly
06:49eevarasbjxrn: how? :)
06:50ceninanany reason why "(do (print "Enter something: ") (read-line))" waits for the input before printing?
06:50sayyestolifehmm okay, what I meant was that I'd like to be able to run the current buffer inside a clojure repl (and all that good stuff)
06:50asbjxrnI changed your paste.
06:50asbjxrn(And paste.lisp.org is nicer, I think...)
06:50asbjxrn (.setRGB #^BufferedImage image (int x) (int y) (int (+ current-time (* x y)))))))
06:50eevarokies, thanks
06:51eevaryay, way snappier :)
06:52asbjxrnI'm not familiar enough with the reflection warnings to understand why there was no reflection warning, though :-/
06:53sayyestolifeI guess that I need to set the variable 'inferior-lisp-buffer' or something like that?
06:53eevarthere was (for me) -- i just had no idea where to add the type hint
06:55asbjxrnceninan: it's buffered. Try: (do (print "someting") (flush) (read-line))
06:55asbjxrn
06:56sayyestolifeeevar I'm just trying to use the Clojure -> Eval region command (inside clojure-mode)
06:56ceninanasbjxrn: thanks :)
06:56asbjxrnsayyestolife: Yes, you need to set that. And then M-x run-lisp
06:59eevarsayyestolife: here's my ~/.emacs -- http://pastebin.com/m2e181d8d
06:59eevarcould probably be better, but C-c C-c does eval a sexp once i've started slime
07:01asbjxrnslime is more complex, which is good and bad.
07:02asbjxrnMore features, and more trouble :)
07:16RaynesI use a very small subset of Slime's features.
08:32Chouserthat's actually a pretty good tag line. "Slime: more features, more trouble"
08:36asbjxrnI think slime is great for Common Lisp (Well, I used Lispworks myself, but still) But clojure is not quite a perfect match.
08:42rhickeyChouser: :)
08:49AWizzArdIs there in contrib (or just somewhere) a text/repl based stepper?
08:50AWizzArdI got jswat working, but it shows way too much variables, everything the jvm has on its stack. I can't see the Clojure data in the way I am thinking about it, but instead deeply hidden in some collections of collections of collections of ...
08:55sddiewwhat is the best way to assoc in nested vector? (similar to assoc-in for maps)
08:57AWizzArdupdate-in maybe?
08:57sddiewwait, it seems that assoc-in works for vectors as well! (but it's not documented)
08:58rhickeyAWizzArd: IntelliJ has intelligent Java collection displays, which show e.g. maps as key-> val entries, show collection sizes etc, without showing the internals (by default) This all works for Clojure collections as well
08:58rhickey,(doc assoc-in)
08:58clojurebot"([m [k & ks] v]); Associates a value in a nested associative structure, where ks is a sequence of keys and v is the new value and returns a new nested structure. If any levels do not exist, hash-maps will be created."
08:59rhickey,(associative? [1 2 3])
08:59clojurebottrue
08:59sddiewok :)
09:00rhickeysddiew: some of these things are doc'ed in terms of abstractions (as opposed to enumerating all supported types) specifically so they are still true when extended
09:01sddiewperfect, because of that "...hash-maps will be created." I thought it's maps-only
09:02rhickeysddiew: right, maps are hardwired as the default constructing type, there has to be one
09:02sddiewis there any other (even more concise) way to get value from nested vector? better than eg: (reduce get [[[[:x]]]] [0 0 0 0])
09:03Chouserhm, it could use (empty coll) instead.
09:03sddiewsomething like a reverse -> macro that would expand to (((some-vector id) id) id)
09:04sddiewI know that I can use (-> some-vector (get id) (get id) ...) but...
09:07sayyestolifeI'm using ClojureBox, and when I evaluate an expression (with C-x C-e) several times I get the error java.lang.reflect.InvocationTargetException
09:07rhickeyChouser: empty the root coll? the problem is the assoc of a new vector will only work for index == count
09:07rhickey,(doc get-in)
09:07clojurebot"([m ks]); returns the value in a nested associative structure, where ks is a sequence of keys"
09:08sddiewoh ;) perfect!
09:08rhickey,(get-in [[[42]]] [0 0 0])
09:08clojurebot42
09:08sddiewthat's just great
09:10rhickeyChouser: begs the question as to whether index of -1 should mean "at end"
09:10clojurebotWho??
09:12Chouserrhickey: hm... well, that question has certainly come up before.
09:17rhickeyit doesn't quite work for this, as ([0 1 2 3] -1) == ([0 1 2 3] 3), but what you want for blinds assoc-at-end is (assoc [0 1 2 3] -1 x) == (assoc [0 1 2 3] 4 x)
09:17ChouserI always found that natural and convenient in python and ruby
09:17Chouseroh. hm.
09:18rhickeymaybe we need conj-in?
09:18Chousernot interested in -0 ?
09:18Chouser:-)
09:18Chouseroh, really? for this or something else?
09:18sddiewwhat would be equivalent to delete-in/remove-in for nested associative structures?
09:18clojurebotfor is not a loop
09:19rhickeyjust tried typing it in, not a concept I desire (-0)
09:19Chouseroh
09:19rhickey,(doc dissoc-in)
09:19clojurebot"clojure.contrib.core/dissoc-in;[[m [k & ks as keys]]]; Dissociates an entry from a nested associative structure returning a new nested structure. keys is a sequence of keys. Any empty maps that result will not be present in the new structure."
09:19sddiewwow! amazing :)
09:19Chouseryeah, I wouldn't have expected you to like the concept of -0
09:20sddiewthat's why i couldn't find it (contrib), any chance that it would land in core soon?
09:21rhickeysddiew: which?
09:21sddiewdissoc-in
09:21rhickeythat's in core
09:21sddiewi mean clojure.core (I know that it's in c.c.core)
09:22sayyestolifehow can I recompile a file inside SLIME? (atm when I try to compile via C-c C-k it complains about stuff being declared/defined more than once)
09:22rhickeythat should be moved
09:22rhickeypatch welcome
09:23rhickeyissue/patch
09:24sddiewhmm so I guess conj-in or similar is welcome as well
09:24rhickeyconj-in has slightly murky semantics - is it assoc-in except for the last step?
09:25sddiewsould insert at the n+1 position (for vectors at least)
09:25rhickeyconj will mean what it does (per collection type) the issue is the inner steps
09:26Chouserwould it conj anytime an inner step exceeds the length of the vector at that step?
09:26rhickeywould prefer not to think about vectors specifically
09:26Chouserso an error in those cases
09:26sddiewby the way, how to insert element in the middle of a vector? assoc and some subvec (n to the end) merged?
09:28rhickeyChouser: I'm trying to think about what conj-in means
09:28rhickeyI think it's maybe not a valid concept
09:28sddiewmaybe just get-in and conj on the last element? (if it's a collection)
09:28rhickey,(doc update-in)
09:28clojurebot"([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."
09:29rhickeymight be enough
09:29Chouserif it just conj's as the last step, then (conj-in v [0 0 0] :b) is just (update-in v [0 0] conj :b)
09:29rhickeyheh
09:31sddiewso, speaking REST verbs: GET would be get-in, DELETE is dissoc-in PUT is assoc-in POST is update-in f?
09:31asbjxrnsddiew: (let [foo (range 20)] (concat (take 10 foo) ['insertedelement] (nthnext foo 10))) kind of works.
09:32asbjxrnUh, not a vector...
09:32rhickeysddiew: that's one way to think about it, I guess, but post really changes something and update-in doesn't
09:32Chouserso does that invalidate using (empty root-coll) for assoc-in and update-in?
09:32sddiewasbjxrn: yeah (vec ...) would do
09:33Chouseror just that it remains less useful on vectors because you have to know the length at steps where you'd want to conj
09:33rhickeyChouser: there really isn't any more reason to match the root coll than there is to hardwire a map, and maps are easier to create from scratch using assoc
09:34Chouserok
09:34rhickeye.g. if the root is a vector of maps
09:34ChouserI don't know that I've ever used the new-collection feature of either fn
09:35rhickeyI think the most common case is maps of maps of ...
09:36Chouserso I've been building up a set of functions for interacting with git and assembla and have most of what I need to automate various patch-wrangling tasks (still missing "attach to ticket")
09:36Chouserbut then this task of creating a new ticket when committing, all in one step, came up.
09:37sayyestolifeCan any nice person here please try to tell me what is wrong the following code (it's pretty short): http://pastebin.com/d5aad3b91 ?
09:38asbjxrnWorks fine for me.
09:38sddiewis there any simple way to extend clojure writer to put ',' between elements in a vector? what i'm trying to do is to emit valid JSON array from nested vector with strings, reading that in would be straightforward (commas omitted, null would be symbol bound to nil), is that a good idea?
09:38Chouserand I was disappointed to find that I was nowhere close to being able to do it with these functions. This case is just different enough that it misses all the apis I've created, and runs into java api areas where I'm weak. A couple hours of hacking at it and I only had the first of 5 or so steps working.
09:39sayyestolifeasbjxrn okay, damn it :/, my biggest problem with clojure isn't the coding but to get an actual (usable) environment up and running :(
09:39danlarkinsddiew: there is a json library you can use in contrib
09:40Chouserso last night I spent a couple hours working on the same task as a bash script, and it's already nearly done. Plus it runs faster (because no jvm startup hit). This all makes me a bit sad.
09:40sddiewyes I know, but all i need is nested vector with strings, I guess 'read' would be much simpler here (and faster)
09:40sddiewread-string actually (and catching eventual exceptions)
09:41danlarkinChouser: yeah clojure doesn't fit every domain
09:41danlarkinnor will it ever, I guess
09:41asbjxrnChouser: I'm a Unix admin. I know how you feel. Really want to use clojure for stuff, but ....
09:44asbjxrnThe one "scripting" niche I found for it was visualization of various stuff by using jfreechart.
09:46sddiewsomebody (hmm, me?) should put online applet or java web startable waterfront or similar +clojure/clojure-contrib, would make clojure much more accessible for newbies
09:46ChouserI know it's popular to say "use the right tool for the job" and apply that to languages and domains, but I tend to believe that's more an idictment of existing languages than any kind of fundamental property of reality.
09:49Chousera general-purpose language should not be like a hammer or screwdriver, it should be like a stack of iron ingots and a forge.
09:49mattreplwith languages, sometimes being the right tool means having the right library
09:49danlarkinChouser: to some extent, I suppose. But even if the JVM start time was a non factor, and even if clojure had easy access to idiomatic shell scripting libraries, writing a shell script would still be a better choice a lot of the time. Sure you can make a "dsl" for what you want to do, but sh is already the dsl
09:50Chouserdanlarkin: but the sh dsl carries a whole lot of baggage with it. some good, and of course that's why it fit well in this case. but some very bad.
09:51asbjxrnBut isn't that the whole point of the "right tool for the job" saying?
09:52Chouserwhy should I put up with bad baggage?
09:52asbjxrnBecause you don't care.
09:52Chouserbut I do!
09:53Chouserthis bash code I wrote has the most horrible string manipulation code blocks
09:53asbjxrnYou shouldn't :)
09:53danlarkinChouser: love it for what it is :)
09:53mccraigChouser: 'cos all baggage is bad baggage
09:54ChouserI reject all your assertions!! :-) I want all the good features of all the languages in a single language, and nobody's yet proved to me that it's impossible.
09:54asbjxrnscripts very quickly become the wrong tool for the job. But for small jobs..
09:55Chouserasbjxrn: that's actually a key point. "small jobs" very frequently don't stay that way, and yet you find yourself saddled with whatever language choice was made initially.
09:55pjstadigthe more general a language is the less useful
09:55asbjxrnAh, but that just means the job changed...
09:56mccraigChouser: i'm not saying it's impossible, just that languages are like species : constantly evolving and yet never perfectly adapted to an ever changing environment
09:56pjstadigif a language does everything, then it really does nothing, and you have to do a *lot* of work to turn those ingots into something useful
09:56Chouserhmph.
09:56asbjxrnps -ef | awk '/styp\id proc/ {print "kill " $2}' | sh
09:56asbjxrnis a "program"
09:57danlarkinin the oh-so-powerful sh dsl :)
09:58asbjxrnAnd when running this I don't care if awk doesn't do closures or referential transparency.
09:58newbiehey all, when i execute this for loop in repl i get nil printed as well besides the number (for [y (range 0 100)] (println y ) ) am i doing it wrong or is this the behaviour?
09:59Chouser~for
09:59clojurebotfor is not used enough
09:59Chouserwrong!
09:59Chouser~for
09:59clojurebotfor is not a loop
09:59Chouserthere you go
09:59Chousernewbie: 'for' is not meant for side-effects. It's lazy.
10:00pjstadig,(for [y (range 1 100)] (println y))
10:00clojurebot(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
10:00asbjxrn,(doc for)
10:00clojurebot"([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test.
10:00Chousernewbie: so what's going on there is your 'for' is producing a lazy seq of whatever println returns (nil for each number)
10:01Chouser...but when the repl prints that seq of nils, it has to realize each value which cause the side-effect of println (actually printing the number) to happen at each step
10:02Chousernewbie: so you have to decide if you actually want the side-effect (in which case use 'doseq') or if you want to produce a lazy-seq (use 'for' but get rid of the println)
10:02mattreplnewbie: (doseq [x (for [y (range 1 100)] y)] (println x))
10:02Chouserhuh
10:04newbiewhat i am trying to do is iterate over x and y values ( coordinates ) i tried doseq but when i have for inside a for it only prints nil?
10:05Chouser,(for [x (range 3), y (range 3)] [x y])
10:05clojurebot([0 0] [0 1] [0 2] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2])
10:07sddiew_so, string is not associative, is it a bug in get-in?
10:08Chouser,(get-in ["abcde"] [0 3]) ; like this?
10:08clojurebot\d
10:09sddiew_,(associative? "abcde")
10:09clojurebotfalse
10:09newbieone last question how can i call a function using these x y values?
10:09sddiew_sure it is ok for ordinary get
10:10Chouser,(for [x (range 3), y (range 3)] (+ x y))
10:10clojurebot(0 1 2 1 2 3 2 3 4)
10:11newbiethis maybe a stupid question but how can i call + on x y but not println?
10:12Chouserdo you mean "why?" because + has no side-effects, but println does.
10:13asbjxrnnewbie: You can still call println, but println will only return nil, the printing is a side-effect. So collecting the result of a println only gives you nil.
10:15asbjxrnyou could use println-str instead:
10:15asbjxrn,(for [x (range 3) y (range 3)] (println-str x y))
10:15clojurebot("0 0\n" "0 1\n" "0 2\n" "1 0\n" "1 1\n" "1 2\n" "2 0\n" "2 1\n" "2 2\n")
10:15Chousukenewbie: for is not a looping construct, it's a list comprehension :)
10:15newbieok now i get the nil is the return value of print and numbers are written inside print thats the reason i am seeing nil, am i right?
10:16asbjxrnright
10:17newbiecoming from java i picked for because thats what i am used to but if you were to iterate a bunch of x y coordinated and do some calculation on them which looping construct would you use? is using for in this case a wrong thing to do?
10:18mblinndepends on what you're trying to do
10:18mblinnthere are a lot of higher level functions that help with that sort of thing
10:18mblinnmap, reduce, etc
10:18mblinnso uh, what are you trying to do :-)
10:19newbiei will iterate each pixel on a panel and depending on the coordinates paint a dot on its location
10:20Chousukethen you need to use doseq or loop
10:22newbiethank you all.
10:24asbjxrnWhat is the reasoning for the [{a :a b :b :or {a 1 b 2}}] destructuring? Why isn't the "or hash" {:a 1 :b 2}?
10:25Chousukeasbjxrn: the a, b, are the names you bind to, and the :a, :b are the keys you use to look up the names.
10:26Chousukein the :or hash, there's no need for the lookup keys, only the names to bind to.
10:26asbjxrnRight. But then I would have thought it would have been {a :a b :b :or [a 1 b 2]}
10:27ChousukeI guess it could be {:a 1 :b 2} too, as in, the default map to destructure.
10:29asbjxrnRight, that's the way I was thinking. Doesn't really matter since it's a special case anyway, but I found it a bit funny.
10:29thickey_isn't it {} instead of [] for lookup reasons when it uses the :or? i.e. it's looking up the value associated with a
10:29Chousukebut you could have something like [{a "foo" b 0 :or {a 2 b 3}}] which is a bit clearer that :or {"foo" 2 0 3}
10:31asbjxrnRight, that's a good point.
10:34asbjxrnthickey_: Ah, maybe the local vars is built up by starting with the "or hash" and assoc'ing the rest of the keys/values? (No, I haven't read the source, and I suspect that local vars may not be stored in a hash like that...)
10:35asbjxrn(BTW: What's the right name in this case? "vars" is obviously wrong as it has a special meaning.)
10:35Chouserlocals
10:36Chouser:-)
10:36Chouser,(macroexpand '(let [{a :a b :b :or {a 1 b 2}} nil]))
10:36clojurebot(let* [map__2197 nil a (clojure.core/get map__2197 :a 1) b (clojure.core/get map__2197 :b 2)])
10:37sddiew_,(get-in [:a [:b]] [1 0]) ; works
10:37clojurebot:b
10:37sddiew_,(dissoc-in [:a [:b]] [1 0]) ; fails, bug?
10:37clojurebotjava.lang.Exception: Unable to resolve symbol: dissoc-in in this context
10:38sddiew_provided that dissoc-in was use-d
10:38ChousukeI don't think that's a bug
10:38Chousukevectors don't support dissoc
10:38asbjxrn,(macroexpand '(let [{a :a b :b :or {a 1}} {:b 2}]))
10:38clojurebot(let* [map__2207 {:b 2} a (clojure.core/get map__2207 :a 1) b (clojure.core/get map__2207 :b)])
10:39sddiew_I guess I should use update-in instead but... one level up?
10:41sddiew_it's a bit inconsistent with the rest of -in functions that work on associative structures
10:45sddiew_is there a better way to 'remove' item from a vector than concat+take/drop or concat+subvec?
10:45Chousermaybe (into (subvec ...) (subvec ...))
10:46sddiew_which would be fastest? :)
10:46ChouserI think the meaning of that is pretty clear, and using into,subvec like that is O(n) where n is the length of the second subvec
10:47sddiew_subvec is much faster than take/drop (that work on sequences so O(n)) but how about into vs concat etc.?
10:47Chouserif you want a vector in the end, you're not going to do better than O(n) as with the into
10:48sddiew_hmm, yes, I want vector, too bad that there is no dissoc for vectors :(
10:48Chouserthe underlying data structure simply doesn't support that
10:49sddiew_hmm is it some kind of trie?
10:49Chouserindeed
10:50sddiew_ok I guess I have to live with that (much better and more performant for most other problems though)
10:58rhickeypersistent finger trees would be a welcome contribution
10:59Chousukehm, I vaguely remember seeing someone working on an improved persistent map data structure on github
10:59ChousukeI wonder what that was.
11:29sayyestolifehm
11:29sayyestolifeI can do a (require 'myfile) but a (require :reload 'myfile) fails due to (reflect.InvocationTargetException), any ideas?
11:34drewrI think I like defnm better than defn-memo
11:38drewrgood work, btw :-)
11:42Chouserdefn-memo too wordy?
11:46drewrfor me, but I like brevity to the extreme
11:50ChousukeI'd go with defn-memoize :P
11:50Chousukethough memo is fine too
11:51Chousukeunnecessary abbreviation is the root of all evil.
11:51drewrit's actually unnecessary unabbreviation :-)
11:51Chousukenot to mention that defnm is unpronounceable.
11:52sddiew_clojure is not arc ;)
11:52drewrsddiew_: I *like* that aspect of arc...
11:52Chousukeseriously, though, I wish people didn't always abbreviate things so much
11:52Chousukeit just makes stuff unreadable.
11:52drewrit's the other way around for me
11:52clojurebotfor is not a loop
11:53Chousukedefnm is so close to defn that it looks like a typo.
11:53ChouserI didn't use defn-memoize because memoize is a verb and ends up in the wrong place there
11:53Chousermaybe def-memoize-fn :-P
11:53drewrChousuke: defn- is too
11:54sayyestolifeexcuse the language but, holy shit it feels good when you make stuff work by yourself :)
11:54Chousukedrewr: yeah, but in that case there's a convention
11:54Chousukedrewr: - = private
11:54sddiew_hm, maybe the way to go is to create abbreviations, similar to call-with-current-continuation => call/cc
11:54ChouserI didn't use defmemo because I didn't want to lose the fn in there
11:54drewrChousuke: I'm trying to shape future conventions :-)
11:54clojurebotdrewr: the fn created by future (like all fns) doesn't close over dynamicly scoped stuff
11:54Chouserhah!
11:54drewrclojurebot: shut your hole
11:54clojurebotexcusez-moi
11:54Chousukeclojurebot is chatty today :p
11:55ChouserI stuck the dash in there becase the nm together in defnmemo makes my eyes go buggy
11:55Chouserall of which matters to me a bit less than the little race condition in my definition
11:56drewryou guys put way too much stock into what looks immediately "right"
11:56drewrwhat matters is what you type over and over again
11:57drewr(not that defn-memo) will be as popular as defn
11:57sayyestolifewell, I've heard that you often write code once but look at it a thousand times
11:57Chouserbut I think that's ok too because even if you're calling defn-memo to redef an existing var, if something calls it in the race state you just get the un-memoized new version, which shouldn't hurt anybody too much
11:57drewrthat close paren should have been at the end
11:58drewrsayyestolife: I've never understood that argument; once you know what stuff means, it makes sense
11:58Chousukedrewr: I still don't like looking at alphabet soup
11:58drewrunmaintainability comes in when you make fns too big and don't modularize properly
11:59Chousukedrewr: having proper names for things helps with being able to discern them quicker amid other code.
11:59ChouserI'm glad it's defn not define-function
11:59drewryes
11:59Chouserseeing that written out wouldn't help me one whit
12:00drewr"defnm" has a distinct flavor to it; I would get used to it
12:00Chousukewell, it's something you write very often.
12:00ChouserChousuke: exactly
12:00Chouserand read often
12:00Chouserand it has a whole lot of character of its own
12:00drewrI will concede since I don't then to memoize very often
12:00Chousukedefn- is fine because it's basically defn
12:01Chousermemoizing a fn is not terribly common, and the word "memo" conveys a whole lot of meaning that "m" doesn't
12:01drewrI always do a double-take at defn-
12:01Chousukedefnm is also basically defn, but the m is not a convention for "memoize" so it fails
12:02drewrwow, s/then/tend/ up there
12:02Chousukeand the thing that it's easy to typo defn into defnm
12:02Chousukeand then you won't be able to tell whether that's intended or not.
12:02Chouserit's a bit unfortunate that (defn- foo ...) and (defn -foo ...) are both valid and mean very different things. ...not that I have any better alternatives to suggest. :-P
12:04ChousukeI'm just saying that if you do abbreviations that are not conventions, they must be *obvious* :)
12:04Chousukem is not.
12:04drewrI screw code up no matter what; I prefer brevity so I can screw it up more quickly and be done
12:04Chousuketyping a couple fewer characters won't make you code faster.
12:04drewrChousuke: fair point
12:05Chousukeno-one codes as fast as they type, anyway
12:05drewrthe above point
12:05Chousukeif they do, something's wrong :)
12:05drewrI dunno, with clojure I can bust out a thought pretty quickly
12:05sddiew_how about defnemo ;)
12:06drewrdefnoize
12:06drewrhas a nice ring to it
12:06drewrdefn01ze
12:06sddiew_:)
12:06Chousukeor for the british, defnoise
12:18guille_hi
12:18guille_what do you use for taking a look to javadocs from clojure-mode?
12:53sayyestolifeI know that Clojure uses STM (I'm not very familiar with that), but I'm making a server and obviously I'd like to server a lot of people at the same time; should I still use java threads?
12:53ChousukeThreads and STM are not mutually exclusive :)
12:54Chousukein fact, without threads the STM would be rather useless.
12:54rhickeyhas anyone tried the ensure branch?
12:54cemericksayyestolife: STM allows you to write programs that have reliable semantics in a multithreaded environment.
12:54sayyestolifeheh, so threads is the way to go in this case?
12:54Chousukebut instead of using threads explicitly you might be able to use agents, too
12:54sayyestolifeagents you say, I better look that up, thanks :)
13:01sayyestolifeI might be stupid but I didn't really get http://clojure.org/agents, do any of you have some other resources regarding agents?
13:02cemerickrhickey: Since you're not on twitter, FYI: https://twitter.com/headius/status/2552807823
13:03rhickeycemerick: I'm on twitter, I just don't follow anyone or say much :)
13:03rhickeyvery interesting though, thanks
13:05rhickeymust be nice to work at Sun and get the things you need :)
13:09rhickeymoving it into Java 6 greatly enhances the viability
13:29drewrsayyestolife: think of agents as refs that don't get updated immediately
13:30drewrand aren't transactional
13:30sayyestolifemkay, (another, unrelated question) is there an easy way to have a variable parameter list such as in python where you can retrieve all of the argumentsin a list?
13:31drewryes, that's what [... & args] does when you see it
13:31drewrargs is a seq of the remaining parameters
13:32sayyestolifeoh I see
13:32sayyestolifethanks
13:33drewr,((fn [a b & c] c) :foo :bar :baz :quux)
13:33clojurebot(:baz :quux)
13:43sayyestolifeI might be totally out there but; when I have a list of items I'd like to print, wouldn't a map do the job?
13:43sayyestolifeI tried with (map #(print (str %)) args) but it didn't print anything at all
13:44cemerickrhickey: the notion of it requiring a flag *and* an rt.jar addition is less than ideal.
13:47ceninansayyestolife: why not use doseq?
13:47ceninan,(doseq [x [1 2]] (println x))
13:47clojurebot1 2
13:48sayyestolifeah thanks
13:52cemericksayyestolife: map is lazy, which is why nothing was printed. see doall
13:52cemerick,(doall (map println (range 5)))
13:52clojurebot(nil nil nil nil nil)
13:52clojurebot0 1 2 3 4
13:52cemerickbut yes, doseq is more idiomatic
13:55maaclI have a recursive call like this inside a traceback-lcs function (traceback-lcs m s1 s2 (- i 1) (- j 1)) (nth s1 (- i 1)). The call generates the return value of the function. If s1 is a string i can just coerce the whole thing into a string and get a sensible return value that way, but the rest of the traceback-lcs function works on all ordered collections. How do I coerce this into returning a collection of the same class as s1?
14:03Chousukemaacl: hm, please clarify. instead of one call, you wrote two separate expressions :)
14:03Chousukebut maybe something like this
14:05Chousuke,(let [f (fn [coll] (into (empty coll) [1 2 3 4]))] [(f {}) (f [])]
14:05clojurebotEOF while reading
14:05Chousukeoops
14:05Chousuke,(let [f (fn [coll] (into (empty coll) [1 2 3 4]))] [(f {}) (f [])])
14:05clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
14:05Chousukehm
14:05maaclsorry missed a paren at the end. when coercing to a string it looks like this: (str (traceback-lcs m s1 s2 (- i 1) (- j 1)) (nth s1 (- i 1)))
14:07Chousukehm
14:10Chousukenow I'm more confused as to why my example gives that error.
14:11Chousuke:o
14:11Chousuke,(empty {})
14:11clojurebot{}
14:11Chousuke,(into (empty {}) [1 2 3 4])
14:12clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer
14:12Chousukeno wonder. :P
14:12Chousuke,(let [f (fn [coll] (into (empty coll) [[1 2] [3 4]]))] [(f {}) (f [])])
14:12clojurebot[{3 4, 1 2} [[1 2] [3 4]]]
14:13Chousukeanyway, into might do what you want.
14:14Chousukethough sadly, it doesn't work for strings
14:15Chousuke(doc show)
14:15clojurebot"clojure.contrib.repl-utils/show;[[x] [x selector]]; With one arg prints all static and instance members of x or (class x). Each member is listed with a number which can be given as 'selector' to return the member object -- the REPL will print more details for that member. The selector also may be a string or regex, in which case only members whose names match 'selector' as a case-insensitive regex will be printed. Finall
14:15maaclthanks - will give it some more thought
14:16sddiew_any reason why you use (into (empty {}) ...) and not simply (into {} ...) ?
14:16Chousukesddiew_: well, the actual parameter might not be empty
14:16Chousuke,(let [f (fn [coll] (into (empty coll) [[1 2] [3 4]]))] (f {1 2}))
14:16clojurebot{3 4, 1 2}
14:16Chousukebad example, though :P
14:17Chousuke,(let [f (fn [coll] (into coll [[1 2] [3 4]]))] (f {5 6})); if you remove the empty
14:17clojurebot{3 4, 1 2, 5 6}
14:17sddiew_actually what's the use of empty? and what is the difference between (empty {}) and eg. (identity {})?
14:17Chousukenothing
14:18Chousuke,(empty {1 2}); this case differs however
14:18clojurebot{}
14:18sddiew_ah ok, in case you want to make empty collection of some type of non-empty one
14:18Chousukeuseful for polymorphism
14:18sddiew_sure sure, I guess I need some sleep ;)
14:46sayyestolifeI have a function where I call print; this function gets called several times inside a loop, but it isn't until the last call in the loop that everything gets printed. How come?
14:47kotaraksayyestolife: try to call (flush) in the loop.
14:47sayyestolifemkay
14:48sayyestolifethat fixed it, thanks.
15:11guille_does exist a function to convert a symbol to a string?
15:11kotarak(doc name)
15:11clojurebot"([x]); Returns the name String of a symbol or keyword."
15:11kotarak(doc namespace)
15:11clojurebot"([x]); Returns the namespace String of a symbol or keyword, or nil if not present."
15:12guille_thanks
16:24j-dotanyone know what would have changed between 1.0 and now regarding the way Clojure is loaded?
16:24j-dotI'm trying to write an Ant task in Clojure using gen-class and a simple build file works fine with 1.0, but not with HEAD
16:25lisppaste8j-dot pasted "Ant task written in Clojure" at http://paste.lisp.org/display/83318
16:25j-dotthat paste is a stripped down task the exhibits the behavior
16:26kotarakWhich is?
16:26j-dotwith 1.0, "Ah-ha" is echoed as expected
16:27j-dotwith HEAD, I get the exception I'm annotating on that paste now
16:27lisppaste8j-dot annotated #83318 "Exception with HEAD" at http://paste.lisp.org/display/83318#1
16:28j-dotmainly, this: "java.lang.IllegalStateException: Var clojure.core/refer is unbound."
16:28j-dotthat gets thrown when clojure.zip goes to refer to clojure
16:30lisppaste8j-dot annotated #83318 "Example build file for testing the task" at http://paste.lisp.org/display/83318#2
16:31kotarakoerk... ugly... but sorry: no clue here.
16:31j-doteh, no worries ... thanks anyway. Maybe I'll send it off to the list
16:33Chouserknow how to use git bisect? :-)
16:34j-dotnope, but I don't expect I'll find a much better time to learn
16:38Chousukeit's pretty easy.
16:38j-dotahh, git bisect looks very cool. Thanks, Chouser!
17:07texodusIs there any way to add java annotations to clojure proxy functions?
17:11hiredmannope
17:17texodustragic
17:19lisppaste8guille_ pasted "Trying to emulate normal recursion (without success)" at http://paste.lisp.org/display/83321
17:19guille_would you take a look to the paste above about how would i change it to use recur? (from PAIP)
17:20guille_i've changed the function name by recur, but it seems that you can only call recur from the bottom
17:21Chousukerecur only works for tail recursion
17:21opqdonutyeh
17:21Chousukeif you don't have tail recursion, you can't get the optimisation anyway and need to use regular recursion :)
17:24guille_i see. thanks
17:24Chousukebut it does look like you could do that without recursion.
17:24Chousukehmm
17:27Chousukebut before I go and do that, you should rename variable-p to "variable?".
17:28guille_is it not recommended to use -p for booleans?
17:29hiredmanuse ?
17:32Chousukeguille_: Clojure follows the Scheme convention that predicates end with ?
17:35Chousukehmm, it looks like your pattern matching algorithm might need to be "truly" recursive after all.
17:36kotarakdoes a zipper help in this case?
17:40guille_it's supposed to match more than one word (up to the next word from the placeholder), so actually the "zipper" is the function itself
18:00Chousukeguille_: you want something like this? http://gist.github.com/144035
18:01Chousukeit's not iterative, but I don't think you can avoid keeping a stack in any case.
18:08guille_Chousuke: yes, concise code yours :)
18:08Chousukegithub screwed up the indentation though
18:08Chousukebut the source is my emacs. it's using tabs again
18:08Chousukefor whatever reason.
18:09ChousukeI'm sure I disabled tabs.
18:12ChousukeI even have "(setq indent-tabs-mode nil); Aquamacs is idiotic" at the top of my init.el but it seems to have no effect :-(
18:23guille_i switched two days ago from aquamacs to cocoa emacs (in macports "emacs-app-devel") because some problems in latex-mode and I don't regret it. Also sometimes aquamacs decided to close erc buffers when killing the contiguous...
18:27ChousukeI might do that too. Though does it have similar support for trickery with the alt key as aquamacs does?
18:28ChousukeI need alt-2 to output @ because I have a finnish keyboard layout and no altgr (this being a mac) :/
18:29guille_i use in .emacs: (setq mac-command-modifier 'meta) (setq mac-option-modifier nil) so you have meta in command and alt free
18:31Chousukehmm.
19:23grrrtI would like to define an event "stream" as a lazy seq. The elements of the seq would be "change" events from, say, a ref (using add-watch to see changes) or a Swing widget (using a ChangeListener or ActionListener for instance). The seq would be blocking, i.e. if you iterate over it, it would wait until new events are available.
19:24grrrtis that a dumb idea?
19:27ceninanfunny, I had a similiar idea earlier today when playing around with DSLs
19:27clojurebotThe most exciting phrase to hear in science, the one that heralds new discoveries, is not 'Eureka!' (I found it!) but 'That's funny ...' -- Asimov
19:28ChousukeDoesn't java provide a BlockingQueue or something?
19:28ceninanfar too inexperienced to know if it's a good idea though :/
19:28grrrtChousuke: it does. But I'd like to avoid writing java :)
19:28grrrtunless it's the best way to do it ofcourse
19:29Chousukegrrrt: you'd be writing Clojure :p
19:29Chousukejust using a java library.
19:29Chousukeseqs are persistent, too. do you want to hold onto the events?
19:29grrrthm
19:29grrrtperhaps not...
19:29Chousukethough only persistent as long as you hold onto the head.
19:29grrrtah that's good
19:29grrrtI'm not sure yet, still experimenting...
19:30grrrtI'm inspired by a paper about FrTime, about a FRP gui library in scheme
19:30Chousukeshould others be able to "consume" the events?
19:31Chousukeor just see a list of them
19:31Chousukein the latter case, a seq of events them could be useful.
19:31grrrtI was thinking, you could have a function that iterates over a seq, consuming events as they appear
19:32Chousukeif you consume them, then it's better to have a BlockingQueue I think
19:32grrrtStill not sure if that's the way to go, but I'm trying to find alternatives to the classic event callback mechanism
19:32grrrtyeah that sounds sensible
19:32Chousukeyou can also try using agents.
19:32ceninanjust a quick newb-question here; could you do what grrrt wants, but somehow "kill" a queue?
19:33Chousukeagents queue the actions sent to them automatically.
19:33grrrtI'm actually using that already
19:33grrrtI have an 'in-ui' macro that calls Swing's invokeLater
19:33ceninan(ie. no more events are accepted)
19:34grrrtan agent + queue combination sends the result of whatever's called in the ui-thread to the caller of in-ui
19:35grrrthm. food for thought, thanks Chousuke
20:36grrrtI often find myself wanting a 'let-default' function, e.g. in situations like this: (let [v (if nil? val) "some default" val])
20:36grrrtis there a better way to do this?
20:37arbscht_try (let [v (or val "default")] ..)
20:38grrrtthat'd work in this case, but I wonder if there's a more general way of doing it (i.e. with predicates other than nil?)
20:39grrrt(let [s (if sequential? arg) arg [arg]) is another one
20:39grrrt- except I'm missing a few () there
20:41arbscht_I can't think of a better way to express that
20:41arbscht_it seems clear enough as it is
20:41grrrtglad I'm not the only one :)
20:42grrrtok fair enough
21:07rhickey(or val default) is the right idiom for nil/non
21:08grrrtrhickey: thanks.
21:15JAS415is there a way to tell (in java) if a class is a subclass of another class
21:16grrrtinstanceof would do it
21:16grrrt("hello world" instanceof String) == true
21:17JAS415what if I have something like 'clojure.lang.LazilyPersistentVector' and 'clojure.lang.IPersistentVector'?
21:18grrrt,(doc isa?)
21:18clojurebot"([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to the global hierarchy"
21:18JAS415and i want to dispatch depending on whether a metadata tag is a subclass of 'clojure.lang.IPersistentVector'
21:18JAS415oo cool
21:18JAS415that would do it
21:24ataggartso, I need to modify the last segment in a variable-length list of values. e.g., '("a" "b" ) --> '("foo" "baz"). Is there a better way than something like (cons new-val (drop 1 (reverse orig-list)))
21:24ataggartoops
21:24ataggartthat example should be ("a" "b" "c") --> ("a" "b" "d")
21:26grrrtataggart: instead of using drop/reverse you could use the butlast function
21:27ataggartyeah I looked at that but couldn't figure out how to append the new value to the end of it
21:28ataggartand my example solution should actually be (reverse (cons new-val (drop 1 (reverse orig-list))))
21:29ataggartwhich just looks bad to me
21:29grrrt,(concat (butlast ["a" "b" "c"]) ["d"])
21:29clojurebot("a" "b" "d")
21:29grrrtthat's one option - don't know if that's the best
21:30ataggartah yes that would do it.
21:31ataggartit has to bet better than a double reverse
21:31ataggartthanks!
22:29JAS415is there a way to update metadata?
22:29JAS415(and preserve what is already there)
22:33JAS415,(def alter-meta!)
22:33clojurebotDENIED
22:33JAS415,(doc alter-meta!)
22:33clojurebot"([iref f & args]); Atomically sets the metadata for a namespace/var/ref/agent/atom to be: (apply f its-current-meta args) f must be free of side-effects"
22:52JAS415why would this work at the repl but not in a source file?
22:52JAS415(let [inlining-arity (rule-set (fn [x] (> x 1)))
22:52JAS415 set-symbol-inline-arity (fn [& symbols]
22:52JAS415 (map (fn [x] (println x) (alter-meta! x #(assoc %1 :inline-arities inlining-arity))) symbols))]
22:52JAS415 (set-symbol-inline-arity #'+ #'* #'- #'/ #'< #'<= #'> #'>= #'==))
22:52JAS415(source file at toplevel)