#clojure logs

2008-04-22

06:25jteois someone working on a clojure tutorial already?
10:00Chouserjteo: not that I know of. sounds kinda fun, though. Are you starting one?
10:01jteomaybe, if i can get my head wrapped around this.
10:01Chouser"this"?
10:01jteocertain things are confusing in clojure to someone who just managed to get Common Lisp.
10:01jteosuch as...immutables.
10:01Chouserheh. yeah.
10:02Chouserare you trying to do something in particular?
10:04jteoclojure is useful for me as a mental challenge.
10:04jteoanyway, i get bored with imperative languages.
10:06jteoplus clojure seems much more practical than Common Lisp. as in the library support.
10:09ChouserI agree.
10:11drewrjteo: We're in the same boat. I've been wanting to use CL, but it's hard to justify when I can get something done quickly in Python. Clojure's been scratching my Lisp itch but with the ability to solve real problems quickly.
10:11jteoprecisely.
10:12jteoPractical Clojure would be an absolute gem. :)
10:12drewrI've been migrating some data for a client and they gave us part of it in a PDF. I used about 10 lines of Clojure with the PDFBox jar to extract the information.
10:13drewrIt makes me enjoy Java. That's inconceivable.
10:13drewrWell, Java's libraries.
10:19lisppaste8drewr pasted "pwning a pdf" at http://paste.lisp.org/display/59535
10:24Chouserdrewr: nice.
10:29drewrObviously, you could make a fine PDF library with CL, but I'm guessing that problem is too uninteresting for a Lisper to solve (I wouldn't want to either) since I can't find CL-PDF. Clojure is like having an inexhaustible FFI for the Business Programmer.
10:31jteoprecisely.
10:31jteoit's tiring to write libraries/glue from scratch.
13:58Chouserit seems like it would be common, when destructuring a map, to use the same names for the local formal args as the keys of the map.
13:59rhickeyyes
13:59Chouser(let [{a :a b :b c :c} x] ...)
14:00Chouserwould it be sensible to provide a shortcut?
14:00rhickeylike?
14:00ChouserI have no idea what the syntax would be
14:00rhickeytherein lies the rub
14:00Chouser(let [{{a b c}} x] ...)
14:00rhickeybut a map is a valid binding form
14:01Chouserthere might be something analegous on the calling side, such that a similar syntax could be used.
14:01rhickeye.g. (let [{{a b c} :abc } x] ...)
14:01Chouserwhen building a hash: (hashsyms a b c) ==> {:a a :b b :c c}
14:02Chouserright. {{ ... }} is a bad syntax.
14:02Chouser(let [(de-hash-syms a b c) x] ...) ?
14:02rhickeyugh
14:02ChouserI assume callable destruturing forms isn't a can of worms you want to open.
14:03rhickeyit's something I want to save
14:03Chouseryeah, ok.
14:04Chouserbut for destructuring maps, if a sane syntax could be found, you'd be open to something like this?
14:04rhickeyyes, I've definitely thought about it
14:05Chouser#:{a b c} ==> {:a a :b b :c c} and (let [#:{a b c} x] ...)
14:05rhickeylet's leave hashsyms out of it, much less common
14:06Chouserok, fine by me. That's easy to write a macro for if I need it.
14:06ChouserI was bringing it up only for symmetry.
14:08rhickeymaybe sets (let [#{:a :b :c} x] ...)
14:08rhickeyuses name of key for local name
14:09rhickeywill work with maps with keyword, symbol and string keys
14:09Chouserright. there's no other useful meaning for a set as a binding form?
14:09rhickeynot right now
14:10Chouserthe only thing I can think of would be to allow you to pluck out truth values from a passed-in set, but that doesn't seem terribly useful.
14:12rhickeyno. but note you can't have what you want (let [#{a b c} x] ...)
14:12rhickeybecause you don't know the type of the keys
14:14ChouserI don't understand.
14:14ChouserI mean I'm content with #{:a :b :c} instead of #{a b c}...
14:14rhickeyyour first example presumed keyword keys
14:15Chouseroh! good point!
14:17Chouser(let [#{:a :b :c} x] ... ) would be fantastic.
14:18Chouserand if 'name' worked for strings, then you could get the formal param name for each key by calling 'name' on the given key.
14:21rhickeyright, that would be added
15:07ChouserNo way to use :as in a set.
15:08rhickeyright
15:08Chouserare you working on this already?
15:08rhickeyno
15:08Chouserok
15:12Modiusrhickey: Sent you a private message/question - uncertain if you have them filtered, or if you don't want to answer - if the former, just wanted to get feedback.
15:19abrooksModius: Doesn't freenet filter private messages?
15:20Modiusabrooks: Not for users registered with nickserv
15:20abrookser... not freenet, freenode
15:21abrooksModius: Ah, okay.
15:35Chouserrhickey: should symbol keys for sets be quoted or not? That is, should #{:a "b" 'c} work, or #{:a "b" c}, or both?
15:37landonfHowdy all. Anyone have a preferred unit testing framework?
15:47landonfReading Kearsley Schieder-Wethy's work
15:50rhickeyChouser: in the macro, no. They are not evaluated, just as in the map case: {a :a b :b}
15:50drewrlandonf: You could use jUnit.
15:51drewrBut it would be more pedagogical to write your own.
15:58Chouserok, so (let [#{a b c} x] ...) would work, it just wouldn't do what I originally suggested.
15:58rhickeyright, that would match symbol keys only
15:59rhickeykeywords: (let [#{:a :b :c} x] ...), strings: (let [#{"a" "b" "c"} x] ...)
15:59Chousergreat. Well, I have those cases working.
16:00rhickeycool
16:01ChouserI'll post a patch in a minute, though I have no idea if the code is up to your standards. ;-)
16:02rhickeydoes it work when x is a set?
16:03Chousernope, that gets you nils
16:03rhickeyhmm...
16:04ChouserI'm using 'get'
16:05ChouserI could put the map in function position instead, and that ought to work.
16:05rhickeyright
16:05rhickeybut not with nil x
16:05Chouserindeed.
16:06ChouserI could put the key in function position, but of course that would only work for keywords. ;-)
16:06rhickeyyou'll need to special-case nil x
16:07ChouserI could wrap x in (or x #{})
16:07rhickey(and x (x k))
16:07Chouserwould you prefer your special case on each binding, or mine on the first one?
16:08rhickeyeither
16:09Chouserdone.
16:10rhickeythe set stuff will be nice for boolean-flag style & keyword lists
16:22Chouserhttp://n01se.net/paste/SgX -- Destructure maps using sets
16:22drewrrhickey: What was that paper on tries you used to implement maps in Clojure?
16:22drewr(I'm giving you some props on reddit.)
16:23rhickeyhttp://citeseer.ist.psu.edu/459691.html
16:29rhickeydrewr: what reddit thread?
16:30drewrrhickey: http://reddit.com/r/programming/info/6gov3/comments/
16:31drewrI'm recommending Clojure in there, but I'm attempting to explain why it's compelling. :-)
16:34drewrDo I remember in the concurrency talk that your hash maps are near O(1)?
16:37rhickeyThey are log32N, so for a million items that's 3 hops, and for a billion, 6. IMO, that's small enough to ignore.
16:42rhickeyright
16:52nsinghalVar fnptr = RT.var("nspace", "function"); returns a function - can i pass that variable to another clojure function in Invoke?
16:52rhickeysure
16:53nsinghalcan i return a multimethod? so that the caller can call the method using the arity?
16:54rhickeyan arity-overloaded function
16:54rhickeysure
16:56nsinghalhow can i return that? I have written a multimethod. then when i will retunr that in a separate fn - wont it evaluate or something?
16:56rhickey?
16:56rhickeyfunctions ar evalues like any other
16:56rhickeythey don't get evaluated until called
16:57nsinghalsorry i was confused with multimethid and arity-overloaded fn - i think i understand now. thx
16:59rhickeyall interested - here's an amortized O(1) persistent array design, but the constant factors are substantial, and the implementation very complex; http://citeseer.ist.psu.edu/328736.html
17:11nsinghal(defn multi-arity []
17:11nsinghal (fn ([] (this false))
17:11nsinghal ([b]
17:11nsinghal (if b (str "hello") (str "bye bye")))))
17:12nsinghalwhat should i use where (this false) is? i want to call the same fn with a default argument
17:12rhickeyns: you can't have the [] after multi-arity
17:12rhickeynor the fn
17:13nsinghali want to create a function which returns a function with different arity
17:13rhickeyah
17:14rhickeyok, what is this?
17:14rhickey'this'
17:15nsinghali just used it - i didnt know how to call the same function with arg
17:15rhickeyput the name after fn
17:15nsinghalok let me try that
17:16nsinghalworked like a charm- great
17:30Chouserrhickey: I don't know if I quite love the set destructuring syntax. (of course I think of this after I'm done...)
17:30ChouserThis is the first time you can bind to a symbol name without actually mentioning the name as a symbol.
17:31Chousera naive text editor looking for "foo" may not find where it's bound using #{:foo} or #{"foo"}
17:31rhickeyright, and no :as bothers me
17:32rhickeydrewr: thanks for the mention: http://reddit.com/r/programming/info/6gov3/comments/
17:33Chouser(let [{_ :a _ :b} {:a 1 :b 2}] [a b]) ==> [1 2] ?
17:33Chouser(let [{* :a * :b} {:a 1 :b 2}] [a b]) ==> [1 2] ?
17:35rhickeythat still doesn't have the name as a symbol
17:36Chouseroh. heh. right.
17:36Chouserwell, it's going to be impossible to have the name as a symbol *and* allow for keyword/string/symbol keys.
17:37Chouserunless there's a completely different syntax for indicating which of the 3 it is.
17:37rhickeyright, or marrying keywords
17:38Chouser{a :string b :keyword} <-- icky
17:38rhickeythis is the thought process I went through and didn't find anything great
17:38Chouserhmph.
17:39rhickey:string and :keyword might be keys
17:41rhickeyas could any other value
17:41Chouseryeah. But it only gets worse. {[:string a] * [:string b] *}
17:41rhickeynope, becaue maps can be binding forms and nested
17:41Chouser* could be a value
17:41Chouserand, right, nested vector form.
17:42Chouserdid you borrow :as from somewhere?
17:43rhickeynot specifically, but other pattern matchers have similar things
17:43rhickeythe Clojure trick is that the binding forms are still data structures and non-conflicting with the things to which they bind
17:45Chouserthere's no :as for vectors, though I guess & helps out.
17:46rhickeyyes there is
17:46Chousereven just using sets to bind sets would cause problems for :as or & -- no order like & needs, and no value position like :as needs.
17:46Chouseroh, ok. It uses order then as well, like & does?
17:46rhickey?
17:47Chouser[a & b] works because [] has order and b comes after &
17:47Chouser#{a & b} can't mean anything about b specifically
17:48rhickey:as works in vectors because it is a keyword and thus can't be a bound name
17:48rhickeyuser=> (let [[a b c :as d] [1 2 3 4]] d)
17:48rhickey[1 2 3 4]
17:49Chouserright, and it's still relying on vectors having order. :as modifies the followind d -- meaningless in a set.
17:49rhickeyok, right
17:51ChouserI'm thinking that almost completely rules out sets as a robust binding form. If you were open to sets binding maps, would you be open to other mis-matches?
17:51drewrrhickey: You're welcome. Unfortunately, that lame link is getting down-modded so no one will see it. :-/
17:53ChouserI don't even know where that leads. Gah. I'm going home.
17:54rhickey(let [#{a b c :str/:key/:sym :anything-else-is-as} x] ...)
20:22blbrownhello
20:22rhickeyhi
20:25blbrownrhickey, I am thinking of converting some swing/abcl code to clojure. it isn't much, but 6 months to a year from now, I think I will have made the right choice
20:25rhickeycool
20:40Chouserso (let [#{a b c :str} x]) would be the same as (let [{a "a", b "b", c "c"} x]) ?
20:40rhickeyprefereably let [#{:str a b c} x])
20:40rhickeypreferably
20:40rhickeyyes
20:41Chouserand if unspecified it would default to :key, I hope?
20:41Chouserbut what's :anything-else... ?
20:43rhickeyonly one of :str, :sym, :key can be supplied, if another keyword is supplied, it names the aggregate (i.e. fills the role of :as)
20:43rhickey(let [#{:str a b c :fred} x]) would be the same as (let [{a "a", b "b", c "c" :as fred} x])
20:57Chouserreally? I guess that's better than what I've got, but will you be satisfied with it?
20:58rhickeyI don't know, I wasn't thinking about it until you brought it up - just brainstorming
20:59Chouserok
21:16Chouser{a :a, :keys [b c d], :strs [e f g], :as foo} = {a :a, b :b, c :c, d :d, e "e", f "f", g "g", :as foo}
21:19rhickeyneat
21:28ChouserI guess anything that destructures maps can destructure sets just as well.
21:29rhickeyyup
22:37blbrownthank god there is an ant script as opposed to mavent
22:38blbrownor not
23:05rhickeyis it not working?
23:06blbrownno, I was just making a general comment.
23:13ChouserI build with ant all the time.
23:40insectmessiahIs anyone using webjure on a regular basis? Or is everyone basically rolling their own web frameworks right now?
23:41insectmessiahI need to stop being lazy and learn a Lisp, and no matter how many times I fire up SBCL, I keep coming back to wanting to pick up Clojure instead :D