2008-04-22
| 06:25 | jteo | is someone working on a clojure tutorial already? |
| 10:00 | Chouser | jteo: not that I know of. sounds kinda fun, though. Are you starting one? |
| 10:01 | jteo | maybe, if i can get my head wrapped around this. |
| 10:01 | Chouser | "this"? |
| 10:01 | jteo | certain things are confusing in clojure to someone who just managed to get Common Lisp. |
| 10:01 | jteo | such as...immutables. |
| 10:01 | Chouser | heh. yeah. |
| 10:02 | Chouser | are you trying to do something in particular? |
| 10:04 | jteo | clojure is useful for me as a mental challenge. |
| 10:04 | jteo | anyway, i get bored with imperative languages. |
| 10:06 | jteo | plus clojure seems much more practical than Common Lisp. as in the library support. |
| 10:09 | Chouser | I agree. |
| 10:11 | drewr | jteo: 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:11 | jteo | precisely. |
| 10:12 | jteo | Practical Clojure would be an absolute gem. :) |
| 10:12 | drewr | I'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:13 | drewr | It makes me enjoy Java. That's inconceivable. |
| 10:13 | drewr | Well, Java's libraries. |
| 10:19 | lisppaste8 | drewr pasted "pwning a pdf" at http://paste.lisp.org/display/59535 |
| 10:24 | Chouser | drewr: nice. |
| 10:29 | drewr | Obviously, 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:31 | jteo | precisely. |
| 10:31 | jteo | it's tiring to write libraries/glue from scratch. |
| 13:58 | Chouser | it 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:59 | rhickey | yes |
| 13:59 | Chouser | (let [{a :a b :b c :c} x] ...) |
| 14:00 | Chouser | would it be sensible to provide a shortcut? |
| 14:00 | rhickey | like? |
| 14:00 | Chouser | I have no idea what the syntax would be |
| 14:00 | rhickey | therein lies the rub |
| 14:00 | Chouser | (let [{{a b c}} x] ...) |
| 14:00 | rhickey | but a map is a valid binding form |
| 14:01 | Chouser | there might be something analegous on the calling side, such that a similar syntax could be used. |
| 14:01 | rhickey | e.g. (let [{{a b c} :abc } x] ...) |
| 14:01 | Chouser | when building a hash: (hashsyms a b c) ==> {:a a :b b :c c} |
| 14:02 | Chouser | right. {{ ... }} is a bad syntax. |
| 14:02 | Chouser | (let [(de-hash-syms a b c) x] ...) ? |
| 14:02 | rhickey | ugh |
| 14:02 | Chouser | I assume callable destruturing forms isn't a can of worms you want to open. |
| 14:03 | rhickey | it's something I want to save |
| 14:03 | Chouser | yeah, ok. |
| 14:04 | Chouser | but for destructuring maps, if a sane syntax could be found, you'd be open to something like this? |
| 14:04 | rhickey | yes, I've definitely thought about it |
| 14:05 | Chouser | #:{a b c} ==> {:a a :b b :c c} and (let [#:{a b c} x] ...) |
| 14:05 | rhickey | let's leave hashsyms out of it, much less common |
| 14:06 | Chouser | ok, fine by me. That's easy to write a macro for if I need it. |
| 14:06 | Chouser | I was bringing it up only for symmetry. |
| 14:08 | rhickey | maybe sets (let [#{:a :b :c} x] ...) |
| 14:08 | rhickey | uses name of key for local name |
| 14:09 | rhickey | will work with maps with keyword, symbol and string keys |
| 14:09 | Chouser | right. there's no other useful meaning for a set as a binding form? |
| 14:09 | rhickey | not right now |
| 14:10 | Chouser | the 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:12 | rhickey | no. but note you can't have what you want (let [#{a b c} x] ...) |
| 14:12 | rhickey | because you don't know the type of the keys |
| 14:14 | Chouser | I don't understand. |
| 14:14 | Chouser | I mean I'm content with #{:a :b :c} instead of #{a b c}... |
| 14:14 | rhickey | your first example presumed keyword keys |
| 14:15 | Chouser | oh! good point! |
| 14:17 | Chouser | (let [#{:a :b :c} x] ... ) would be fantastic. |
| 14:18 | Chouser | and if 'name' worked for strings, then you could get the formal param name for each key by calling 'name' on the given key. |
| 14:21 | rhickey | right, that would be added |
| 15:07 | Chouser | No way to use :as in a set. |
| 15:08 | rhickey | right |
| 15:08 | Chouser | are you working on this already? |
| 15:08 | rhickey | no |
| 15:08 | Chouser | ok |
| 15:12 | Modius | rhickey: 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:19 | abrooks | Modius: Doesn't freenet filter private messages? |
| 15:20 | Modius | abrooks: Not for users registered with nickserv |
| 15:20 | abrooks | er... not freenet, freenode |
| 15:21 | abrooks | Modius: Ah, okay. |
| 15:35 | Chouser | rhickey: should symbol keys for sets be quoted or not? That is, should #{:a "b" 'c} work, or #{:a "b" c}, or both? |
| 15:37 | landonf | Howdy all. Anyone have a preferred unit testing framework? |
| 15:47 | landonf | Reading Kearsley Schieder-Wethy's work |
| 15:50 | rhickey | Chouser: in the macro, no. They are not evaluated, just as in the map case: {a :a b :b} |
| 15:50 | drewr | landonf: You could use jUnit. |
| 15:51 | drewr | But it would be more pedagogical to write your own. |
| 15:58 | Chouser | ok, so (let [#{a b c} x] ...) would work, it just wouldn't do what I originally suggested. |
| 15:58 | rhickey | right, that would match symbol keys only |
| 15:59 | rhickey | keywords: (let [#{:a :b :c} x] ...), strings: (let [#{"a" "b" "c"} x] ...) |
| 15:59 | Chouser | great. Well, I have those cases working. |
| 16:00 | rhickey | cool |
| 16:01 | Chouser | I'll post a patch in a minute, though I have no idea if the code is up to your standards. ;-) |
| 16:02 | rhickey | does it work when x is a set? |
| 16:03 | Chouser | nope, that gets you nils |
| 16:03 | rhickey | hmm... |
| 16:04 | Chouser | I'm using 'get' |
| 16:05 | Chouser | I could put the map in function position instead, and that ought to work. |
| 16:05 | rhickey | right |
| 16:05 | rhickey | but not with nil x |
| 16:05 | Chouser | indeed. |
| 16:06 | Chouser | I could put the key in function position, but of course that would only work for keywords. ;-) |
| 16:06 | rhickey | you'll need to special-case nil x |
| 16:07 | Chouser | I could wrap x in (or x #{}) |
| 16:07 | rhickey | (and x (x k)) |
| 16:07 | Chouser | would you prefer your special case on each binding, or mine on the first one? |
| 16:08 | rhickey | either |
| 16:09 | Chouser | done. |
| 16:10 | rhickey | the set stuff will be nice for boolean-flag style & keyword lists |
| 16:22 | Chouser | http://n01se.net/paste/SgX -- Destructure maps using sets |
| 16:22 | drewr | rhickey: What was that paper on tries you used to implement maps in Clojure? |
| 16:22 | drewr | (I'm giving you some props on reddit.) |
| 16:23 | rhickey | http://citeseer.ist.psu.edu/459691.html |
| 16:29 | rhickey | drewr: what reddit thread? |
| 16:30 | drewr | rhickey: http://reddit.com/r/programming/info/6gov3/comments/ |
| 16:31 | drewr | I'm recommending Clojure in there, but I'm attempting to explain why it's compelling. :-) |
| 16:34 | drewr | Do I remember in the concurrency talk that your hash maps are near O(1)? |
| 16:37 | rhickey | They are log32N, so for a million items that's 3 hops, and for a billion, 6. IMO, that's small enough to ignore. |
| 16:42 | rhickey | right |
| 16:52 | nsinghal | Var fnptr = RT.var("nspace", "function"); returns a function - can i pass that variable to another clojure function in Invoke? |
| 16:52 | rhickey | sure |
| 16:53 | nsinghal | can i return a multimethod? so that the caller can call the method using the arity? |
| 16:54 | rhickey | an arity-overloaded function |
| 16:54 | rhickey | sure |
| 16:56 | nsinghal | how 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:56 | rhickey | ? |
| 16:56 | rhickey | functions ar evalues like any other |
| 16:56 | rhickey | they don't get evaluated until called |
| 16:57 | nsinghal | sorry i was confused with multimethid and arity-overloaded fn - i think i understand now. thx |
| 16:59 | rhickey | all 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:11 | nsinghal | (defn multi-arity [] |
| 17:11 | nsinghal | (fn ([] (this false)) |
| 17:11 | nsinghal | ([b] |
| 17:11 | nsinghal | (if b (str "hello") (str "bye bye"))))) |
| 17:12 | nsinghal | what should i use where (this false) is? i want to call the same fn with a default argument |
| 17:12 | rhickey | ns: you can't have the [] after multi-arity |
| 17:12 | rhickey | nor the fn |
| 17:13 | nsinghal | i want to create a function which returns a function with different arity |
| 17:13 | rhickey | ah |
| 17:14 | rhickey | ok, what is this? |
| 17:14 | rhickey | 'this' |
| 17:15 | nsinghal | i just used it - i didnt know how to call the same function with arg |
| 17:15 | rhickey | put the name after fn |
| 17:15 | nsinghal | ok let me try that |
| 17:16 | nsinghal | worked like a charm- great |
| 17:30 | Chouser | rhickey: I don't know if I quite love the set destructuring syntax. (of course I think of this after I'm done...) |
| 17:30 | Chouser | This is the first time you can bind to a symbol name without actually mentioning the name as a symbol. |
| 17:31 | Chouser | a naive text editor looking for "foo" may not find where it's bound using #{:foo} or #{"foo"} |
| 17:31 | rhickey | right, and no :as bothers me |
| 17:32 | rhickey | drewr: thanks for the mention: http://reddit.com/r/programming/info/6gov3/comments/ |
| 17:33 | Chouser | (let [{_ :a _ :b} {:a 1 :b 2}] [a b]) ==> [1 2] ? |
| 17:33 | Chouser | (let [{* :a * :b} {:a 1 :b 2}] [a b]) ==> [1 2] ? |
| 17:35 | rhickey | that still doesn't have the name as a symbol |
| 17:36 | Chouser | oh. heh. right. |
| 17:36 | Chouser | well, it's going to be impossible to have the name as a symbol *and* allow for keyword/string/symbol keys. |
| 17:37 | Chouser | unless there's a completely different syntax for indicating which of the 3 it is. |
| 17:37 | rhickey | right, or marrying keywords |
| 17:38 | Chouser | {a :string b :keyword} <-- icky |
| 17:38 | rhickey | this is the thought process I went through and didn't find anything great |
| 17:38 | Chouser | hmph. |
| 17:39 | rhickey | :string and :keyword might be keys |
| 17:41 | rhickey | as could any other value |
| 17:41 | Chouser | yeah. But it only gets worse. {[:string a] * [:string b] *} |
| 17:41 | rhickey | nope, becaue maps can be binding forms and nested |
| 17:41 | Chouser | * could be a value |
| 17:41 | Chouser | and, right, nested vector form. |
| 17:42 | Chouser | did you borrow :as from somewhere? |
| 17:43 | rhickey | not specifically, but other pattern matchers have similar things |
| 17:43 | rhickey | the Clojure trick is that the binding forms are still data structures and non-conflicting with the things to which they bind |
| 17:45 | Chouser | there's no :as for vectors, though I guess & helps out. |
| 17:46 | rhickey | yes there is |
| 17:46 | Chouser | even just using sets to bind sets would cause problems for :as or & -- no order like & needs, and no value position like :as needs. |
| 17:46 | Chouser | oh, ok. It uses order then as well, like & does? |
| 17:46 | rhickey | ? |
| 17:47 | Chouser | [a & b] works because [] has order and b comes after & |
| 17:47 | Chouser | #{a & b} can't mean anything about b specifically |
| 17:48 | rhickey | :as works in vectors because it is a keyword and thus can't be a bound name |
| 17:48 | rhickey | user=> (let [[a b c :as d] [1 2 3 4]] d) |
| 17:48 | rhickey | [1 2 3 4] |
| 17:49 | Chouser | right, and it's still relying on vectors having order. :as modifies the followind d -- meaningless in a set. |
| 17:49 | rhickey | ok, right |
| 17:51 | Chouser | I'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:51 | drewr | rhickey: You're welcome. Unfortunately, that lame link is getting down-modded so no one will see it. :-/ |
| 17:53 | Chouser | I don't even know where that leads. Gah. I'm going home. |
| 17:54 | rhickey | (let [#{a b c :str/:key/:sym :anything-else-is-as} x] ...) |
| 20:22 | blbrown | hello |
| 20:22 | rhickey | hi |
| 20:25 | blbrown | rhickey, 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:25 | rhickey | cool |
| 20:40 | Chouser | so (let [#{a b c :str} x]) would be the same as (let [{a "a", b "b", c "c"} x]) ? |
| 20:40 | rhickey | prefereably let [#{:str a b c} x]) |
| 20:40 | rhickey | preferably |
| 20:40 | rhickey | yes |
| 20:41 | Chouser | and if unspecified it would default to :key, I hope? |
| 20:41 | Chouser | but what's :anything-else... ? |
| 20:43 | rhickey | only 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:43 | rhickey | (let [#{:str a b c :fred} x]) would be the same as (let [{a "a", b "b", c "c" :as fred} x]) |
| 20:57 | Chouser | really? I guess that's better than what I've got, but will you be satisfied with it? |
| 20:58 | rhickey | I don't know, I wasn't thinking about it until you brought it up - just brainstorming |
| 20:59 | Chouser | ok |
| 21:16 | Chouser | {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:19 | rhickey | neat |
| 21:28 | Chouser | I guess anything that destructures maps can destructure sets just as well. |
| 21:29 | rhickey | yup |
| 22:37 | blbrown | thank god there is an ant script as opposed to mavent |
| 22:38 | blbrown | or not |
| 23:05 | rhickey | is it not working? |
| 23:06 | blbrown | no, I was just making a general comment. |
| 23:13 | Chouser | I build with ant all the time. |
| 23:40 | insectmessiah | Is anyone using webjure on a regular basis? Or is everyone basically rolling their own web frameworks right now? |
| 23:41 | insectmessiah | I 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 |