#clojure log - Dec 29 2009

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

1:34 unfo-: if I have (defn myfun [single-arg] (....)) and then call (map myfun a-seq) does that get interpreted as for each element in a-seq apply the fn "myfun" OR for each element in the collection nil apply fn "myfun a-seq" ?

1:35 wooby: unfo-: each element

1:36 unfo-: ok, ty

1:36 wooby: np

1:36 ,(map (fn [x] (+ x 1) [1 2 3])

1:36 oh, no clojurebot anymore

1:37 good thing, that's missing a paren anyways

1:37 unfo-: :)

1:37 wooby: i'm out, see ya

1:37 unfo-: i just got in @office :) see ya

1:55 defn: i have some code: (file-seq *my-dir*), where *my-dir* is (def *my-dir* (java.io.File. "/home/etc/etc/etc"))

1:56 how do i get just the filename of each file in that file-seq?

1:56 right now it looks like #<File /Users/defn/git/cljex/src/docs/core-docs/_with-in-str> #<File /Users/defn/git/cljex/src/docs/core-docs/_with-loading-context>

1:56 etc.

1:56 i want to just get the str _with_in_str

1:57 unfo-: (reduce #(.getFilename %) (file-seq *my-dir*)) or something similar?

1:57 dunno if file.getFilename() is the proper java function to call

2:00 defn: unfo-: http://java.sun.com/javase/6/docs/api/java/io/File.html

2:00 unfo-: im new to the java docs -- could you point me in the right direction?

2:03 vy: defn: (map #(.getName %) (file-seq (java.io.File. "/etc/modprobe.d")))

2:03 defn: vy: i figured it out at the exact moment you posted that

2:03 thanks :)

2:04 how do you do the intersection of two sets?

2:07 mitchellh: defn: http://richhickey.github.com/clojure/clojure.set-api.html#clojure.set/intersection

2:13 unfo-: defn, oh sorry. was debugging a work problem, but glad you got it working :)

2:13 defn: hehe thanks

2:13 mitchellh: thanks for that. works like a charm

2:14 if im making a (defn xyz [] (comment "do something here"))

2:14 should i be a def?

2:14 it*

2:14 unfo-: i use defn for functions and def for vars

2:15 defn: for instance (defn compose-examples [] (let [examples (get-file-names-to-set *examples*) core-docs (get-file-names-to-set *core-docs)] (intersection examples core-docs))

2:15 in a way that seems like a fn

2:15 but in another sense it's really only a var

2:16 i suppose whenever you dont need an input, it's a def

2:17 unfo-: from the Programming Clojure book: (defn whole-numbers [] (iterate inc 1))

2:17 that's an infinite list, so it is not the same as your constant sequence of file names

2:18 defn, that's a pretty good description but what about: whenever you do computation it is a function :-)

2:19 defn, you are calling 3 functions in that def :-)

2:19 whereas if you would say (def my-name "John Doe")

2:20 defn, but this is totally based on my gut feeling, not in actual knowledge of clojure idioms :-)

2:20 defn: unfo-: sure, i understand that i will have functions there no matter what

2:20 but i just struggle to draw the line between function with no inputs

2:21 versus var with functions inside of it

2:21 unfo-: defn, check out clojure-contrib @ github for examples?-)

2:21 i'm sure there are plenty of def's there :)

2:35 tomoj: hmm, how do I depend on a jar that isn't a clojure project for which I can write a project.clj?

3:13 spariev: hello, I have questions about clojureql

3:13 does it support IN predicate, like "id IN (1,2,3)"

3:14 tomoj: is it possible to dynamically take a keyword like :english and get Language/ENGLISH where ENGLISH is a constant in the java class Language?

3:16 spariev: and is it possible to use some kind of connection pooling (ie c3p0) with clojureql ?

3:38 vy: tomoj: Is there a Java class named Language?

3:40 ,(java.util.Locale. (name :english))

3:41 clojurebot: help

3:41 clojurebot: (java.util.Locale. (name :english))

3:42 mitchellh: vy: It appears clojurebot is MIA

3:42 vy: tomoj: Anyway, see (java.util.Locale. (name :english))

4:49 vu3rdd: ,quit

7:38 dabd: anyone knows where I can find zip-query.clj? is is referenced in the documentation for xml-> but I can't find it in clojure-contrib

7:40 the-kenny: dabd: I think they refer to "xml.clj": http://github.com/richhickey/clojure-contrib/blob/81b9e71effbaf6aa2945cd684802d87c762cdcdd/src/clojure/contrib/zip_filter/xml.clj#L86

7:43 dabd: the-kenny: thx

8:32 fliebel: Good morning

8:32 LauJensen: Good morning

8:33 fliebel: What is the normal way to "change" an object's meta? I can do (with-meta a (do-something (meta a))), but that seems strange to do.

8:34 There are alter-meta! and vary-met, but I'm not sue which to use and how

8:34 +a

8:36 chouser: fliebel: (vary-meta a do-something)

8:36 fliebel: chouser: okay, what's the difference with the other one?

8:37 chouser: ,(meta (vary-meta {:a 1} assoc :my :meta))

8:37 Chousuke: no bot :o

8:37 fliebel: *runs to repl*

8:38 cool

8:38 chouser: alter-meta! is for reference types (a.k.a. identities). It changes their metadata in-place.

8:39 fliebel: yew :S

8:39 that is not very immutable is it?

8:40 chouser: well, they're identities not persistent things. They're mutable by nature.

8:40 fliebel: so it's ok to use that all over the place?

8:41 chouser: I don't think there's any object that both alter-meta! and vary-meta both work on

8:41 fliebel: huh… ah!

8:42 Something else: I;m trying to get rid of all the loop…recur structures, but I have some strange ones I'm not sure which function I should use.

8:44 chouser: not all loop/recurs should be gotten rid of. :-)

8:44 fliebel: Basically I need to iterate over a sequence, but the first half of it is done one at a time and made into meta the other half is parsed and gets the meta attached to it.

8:47 chouser: maybe if you can paste that loop?

8:48 fliebel: where is the paste thing?

8:48 chouser: lisppaste8: url?

8:48 lisppaste8: url

8:48 huh. things are broken this morning.

8:48 fliebel: meh… http://gist.github.com/265321

8:49 that is the old one, without metadate

8:50 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

8:50 To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

8:51 chouser: that doesn't work, does it?

8:52 fliebel: nope, I'm messing around with it

8:52 chouser: ok

8:52 fliebel: Just to illustrate what I'm doing

8:53 I'm practically parsing metadata form a file and attaching it to the remainder of the file.

8:53 chouser: what indicates the difference?

8:56 fliebel: the re

8:56 if there is a line without data the rest is considered content

8:58 I just came to the conclusion that doing anything to your date destroys the meta :(

8:58 cemerick: chouser: nice title :-)

8:58 chouser: fliebel: what?

8:58 cemerick: what?? what title?

8:59 fliebel: ,(meta (rest (with-meta [] {:a "b" :c "d"})))

8:59 cemerick: chouser: "Joy of Clojure": http://manning.com/catalog/undercontract.html

9:00 LauJensen: cemerick: I wonder why they didn't go with "Joyjure" :)

9:00 cemerick: LauJensen: "Joy of..." has a long and proud history ;-)

9:00 chouser: cemerick: ooh, there it is. Hadn't seen that. :-)

9:00 LauJensen: Really

9:00 cemerick: chouser: I think fogus tweeted it this morning...?

9:01 LauJensen: Sure. Joy of (Sex|Cooking|Vegan Baking), etc.

9:01 Now we can add Clojure to that canon. :-D

9:02 LauJensen: Vegan is a disease is it not ?

9:02 chouser: cemerick: ah, I'm behind on my tweets.

9:02 cemerick: LauJensen: I think that volume was about baking vegans, not baking *for* vegans.

9:03 fliebel: chouser: Is there any function that would fit my loop? I keep comming back to reduce, but did not yet figure out how to do so.

9:03 LauJensen: hehe

9:03 chouser: fliebel: ah, well, seqs are something else. metadata treats them as cons cells -- each cell gets its own metadata. :-P

9:04 fliebel: chouser: huh...

9:05 chouser: but the metadata should be maintained if you assoc/dissoc/conj/etc...

9:05 fliebel: chouser: You're saying that if I attach metadata to a seq it gets attached to the first item?

9:06 chouser: fliebel: the first cell, yes.

9:06 fliebel: so… (meta (first (with-meta [] {:a "b" :c "d"}))) should work?

9:07 nope… nor does butlast

9:08 chouser: ,(meta (rest (cons 2 (with-meta (seq [3 4 5]) {:my :meta}))))

9:10 fliebel: haha, cool, it works… I'm not sure if I understand that....

9:11 chouser: huh. but lists act different than seqs in this regard

9:12 fliebel: uhoh… Can I attach metadata in any possible way to a string?

9:12 chouser: no

9:13 Strings are final Java objects. no place to store metadata

9:13 fliebel: nooooooooo! I just converted half of my application to use metadata instead of [data meta] only to discover that at the point I arrive at a string it does not work anymore!

9:14 chouser: (-> '(3 4 5) (with-meta {:my :meta}) (conj 2) meta) ;=> {:my :meta}

9:14 (-> (seq [3 4 5]) (with-meta {:my :meta}) (conj 2) meta) ;=> nil

9:14 fliebel: Is there some other way to store a string that can contain meta?

9:16 chouser: you can put the string in a collection that supports metadata :-P

9:16 fliebel: liek this? (println (apply str (seq "hallo wereld")))

9:17 chouser: I was thinking (with-meta ["foo"] {:my :meta})

9:17 fliebel: but then I need to use (first foo) every time I need it :(

9:18 can't I write some ns that extends string?

9:18 cemerick: (with-meta (atom "foo") {:my :meta}) will let you use @foo :-|

9:19 fliebel: String is final -- can't subclass it

9:19 chouser: cemerick: but not vary-meta :-P

9:19 cemerick: details, details :-)

9:19 chouser: even protocols won't really help since you need a place to store the metadata

9:20 cemerick: maybe we can put together a with-meta protocol that uses a global weak map for string metadata...

9:20 * cemerick runs away

9:20 chouser: right. that'd be the only solution, I think.

9:20 cemerick: might not even be so bad, outside of interned strings...

9:20 chouser: even Java 7 pie-in-the-sky interface injection won't help for the same reason.

9:21 fliebel: How about… using future… then the template can uuuhm… compile somweher I don't mind :D

9:22 cemerick: fliebel: you can define a with-meta of your own right now that dispatches to clojure.core/with-meta for IObj things, and store metadata for other types in a global map.

9:23 fliebel: I think I like the future option… except that metadata is gone as soon as you need it :P

9:23 cemerick: just don't intern strings, and you'll be fine.

9:26 fliebel: intern strings?

9:27 chouser: oh, because then you can't have different metadata for two strings with the same text.

9:28 fliebel: hmhm, but what is interning strings?

9:30 cemerick: ,google java string intern

9:30 ~google java string intern

9:30 hrmph

9:30 ,search java string intern

9:31 fliebel: ,(with-meta (future (println "hi")) {:a "test"}) ;java.lang.ClassCastException

9:32 So I can't add meta to agents and future call either! :(

9:34 But.. this works fine! #^String (str "hallo wereld")

9:34 that is also metadata, right?

9:34 cemerick: that's a type hint

9:35 technically, yes, :tag metadata on the form following the hint

9:35 fliebel: cemerick: but a type hint is meta data, isn't it?

9:35 cemerick: it's metadata on the list '(str "hallo wereld") though, not on the string itself.

9:35 fliebel: hmmm

9:36 stupid java strings....

9:37 cemerick: their being final is important for other things. It's the lack of a mixin protocol of some sort in the jvm itself that trips this up.

9:37 fliebel: so what do I do now? I have some data to put with the string…

9:37 chouser: (with-meta ["foo"] {:my :meta})

9:38 fliebel: The only other option is writing my own with-meta?

9:38 chouser: not pretty, but any other solution is going to end up doing something essentially like that, I think.

9:39 fliebel: how about (with-meta #("foo") {:my :meta})

9:39 chouser: did you try it?

9:40 fliebel: no...

9:40 cemerick: chouser: mean bastard ;-)

9:40 chouser: You can't attach metadata to fns via with-meta either

9:40 fliebel: so… really only collections? :(

9:40 cemerick: fliebel: no, anything that implements clojure.lang.IObj

9:40 fliebel: being?

9:41 chouser: collections and reference types, I guess.

9:41 cemerick: ...or any type you create that implements IObj

9:41 rhickey: and symbols

9:41 fliebel: :D How do i create a type?

9:44 Maybe I'll just add the data to the meta i.e. just use :body data, I'll have to do something ugly anyway :(

9:50 rhickey: fliebel: deftype in new branch

9:51 chouser: (defn metafn [o m] (proxy [clojure.lang.IFn clojure.lang.IMeta] [] (meta [] m) (invoke [] o)))

9:51 rhickey: implements meta support (IObj) automatically

9:51 chouser: (meta (metafn "hello" {:my :meta})) ;=> {:my :meta}

9:51 ((metafn "hello" {:my :meta})) ;=> "hello"

9:53 rhickey: chouser: yikes, I'll move up fn metadata support :)

9:53 will just be IMeta, not IObj

9:56 chouser: :-)

9:58 fliebel: chouser: that looks fun, but hacky :)

9:59 chouser: I don't seem to have an invoke function

10:13 piccolino: Can someone help me figure out what is going on in either of the two revisions of this code? https://gist.github.com/264592/

10:15 chouser: fliebel: invoke is a method of IFn

10:17 fliebel: chouser: ah… Thanks for your help. I decided to go for one big map with the data included in the meta as it were.

10:17 chouser: fliebel: sounds less hacky. :-)

10:18 fliebel: chouser: indeed… now I need to do (:body data) instead of (first data) or (deref data)

10:18 and can just do the same for the meta

10:19 But it would be great if metadata on values was possible someday.

10:20 chouser: piccolino: I think your older version of deftype usage is correct

10:20 piccolino: That's what I would have thought.

10:20 But it won't work.

10:20 chouser: piccolino: your defprotocol may be the problem

10:20 try (position [obj] [obj newpos] "") ?

10:21 piccolino: Ugh. Thank god this stupidity will be logged for posterity on #clojure log.

10:21 Thanks chouser.

10:21 That was driving me nuts.

10:21 chouser: piccolino: np

10:22 _fogus_: ,(let [[f & r] [1 2 3]] [f r])

10:22 chouser: clojurebot's on vacation, apparently.

10:23 _fogus_: Oh well, my question... is r constructed from (rest) or (next)?

10:24 Looks like next, but my head swims when I look at the code for destructuring

10:29 chouser: heh. yeah, 'next'

10:29 there has been some talk of an alternate & for 'rest', but not much demand.

10:31 _fogus_: I'm on the side of keeping it the way it is, I get confused by the alternative & forms in other languages

10:33 chouser: yeah, turns out 'rest' is needed pretty rarely -- just carefully constrained lazy-seq-producing code. special syntax there doesn't seem justified.

10:35 _fogus_: Are there implications of using (fn foo [[f & r]] (lazy-seq ... (foo r))) over (fn foo [s] (lazy-seq ... (rest s))) ?

10:36 chouser: yes, with 'next' foo will force the incoming seq one step further ahead than it needs to.

10:38 _fogus_: And by next you mean [[& r]]

10:38 chouser: yes

10:38 (rest s) only forces as much as (first s) already did.

10:39 _fogus_: I see

10:41 thanks!

10:41 chouser: :-) sure!

10:49 rhickey: Does the description here: http://clojure.org/special_forms which mentions that & is destructured via nthnext, need something more?

11:02 fliebel: I'm having 2 strange problems: I'm getting clojure.lang.MapEntry cannot be cast to clojure.lang.IDeref, but I'm not using deref of @ anywhere that I'm aware of. the other problem is an unmatched delimiter: ), while my editor shows none.

11:07 _fogus_: rhickey: Is this discussion on nthnext in destructuring new?

11:08 rhickey: _fogus_: no

11:09 I recently fixed the URL and changed the word rest to remaining

11:09 but the reference to nthnext was there

11:10 _fogus_: rhickey: I suppose I missed that then. It would have eliminated my question above had I originally absorbed it.

11:13 rhickey: I read it as c is bound to (nthnext coll 2) where coll is destructured as [[a b & c]]

11:15 rhickey: _fogus_: right. What's missing is some prose distinguishing that from a call to rest, but I don't really want to digress at that point

11:19 _fogus_: rhickey: Perhaps adding that digression in the section about sequences would be useful instead, with some additional talk about the implications on the lazy sequence recipe

11:39 fliebel: How can I find a java.lang.NullPointerException? I encounter tons of them, and it takes me hours to find them. I think exception handling in Clojure is horrid.

11:40 chouser: :-(

11:40 rhickey: rc3 is up: http://code.google.com/p/clojure/downloads/list

11:40 chouser: usually a full stack trace will point you right at the line that's failing. Are you able to get that far easily?

11:41 fliebel: chouser: no, it's always pointing to line 0

11:41 Exception in thread "main" java.lang.NullPointerException (kickstart.clj:0)

11:41 chouser: fliebel: are you loading the code dynamically somehow, via slime or something? Or from named files on disk?

11:42 fliebel: just clj file.clj

11:42 chouser: fliebel: that's odd. are there any other lines from your own .clj files mentioned elsewhere in the stack trace?

11:43 perhaps under a cause printed later in the stacktrace?

11:43 fliebel: chouser: Yea, everything under 100 is mine I guess :P

11:44 chouser: there are more of them, the 2 I found are just simple function call to the possible error.

11:44 chouser: I'd recommend looking at the first lines printed under the last cause.

11:45 fliebel: I'll show you the trace...

11:45 then you can tell me what to look for

11:45 chouser: ok

11:45 fliebel: http://gist.github.com/265321

11:47 chouser: ok, you can completely ignore the outer cause (printed first) that's all Clojure setup stuff. Skip right down to "Caused by: ...", this is the "root cause"

11:47 fliebel: ah

11:47 so it is either kickstart.clj:5 or generator.clj:20

11:47 chouser: File.<init> is the root-most error line. That's the ctor for File, so probably what amounts to a call like (File. null)

11:47 (File. nil), sorry

11:48 right. so, does generator.clj:20 create a File instance?

11:48 fliebel: not directly… It invokes a function that creates some.

11:49 chouser: what does it pass in?

11:49 a filename string?

11:50 fliebel: no, a sequence of maps containing a filename somwhere… at least it should

11:50 at least I know now that it's a missing file at utterson.core$writer

11:51 chouser: so yeah, I'd look at generator.clj:20 and kickstart.clj:5 -- maybe print out some values there to make sure they look like you expect them to.

11:51 or put breakpoints there if you're set up for such things.

11:52 fliebel: breakpoints?

11:52 I only did that in Javascript :P

11:53 chouser: yeah, I don't do them much in Clojure. Apparently some of the IDE plugins support them.

11:54 fliebel: Not macvim I guess...

11:59 Working! Indeed the destinationg got lost somewhere,

12:07 huh, i'm overlooking something… A function that should get called for every file is called only once it seems, but all the files are outputted. Just putting a print statement over there prints only once.

12:40 jweiss: i thought def would produce public variables? i keep getting "xyz is not public" when i "use" it in a ns form in another file.

12:41 i also tried defvar but i get the same error.

12:42 chouser: that's weird

12:42 jweiss: by the way, the doc for ns is woefully insufficient.

12:42 tolstoy: It could use a few examples.

12:43 jweiss: the only example doesn't even use multiple items in any of the refer/require/import etc

12:43 technomancy: jweiss: this has come up on the mailing list

12:43 jweiss: the consensus was that the proper solution is to make the usage simpler so it will be easier to document. =)

12:44 jweiss: technomancy: that'd be better :)

12:44 technomancy: but it'll have to wait for 1.2

12:44 jweiss: that's ok

12:44 technomancy: (which is going to be an awesome release)

12:44 jweiss: anyway, can someone see what's wrong with this:

12:44 (ns vara.api.hooks

12:44 (:use com.ashafa.clutch

12:44 [vara :only (mydb)]))

12:44 mydb is not public

12:44 [Thrown class java.lang.IllegalAccessError]

12:45 technomancy: jweiss: (:use [com.ashafa.clutch.vara :only (mydb)])

12:45 jweiss: technomancy: no, my intent was to use only "mydb" from the namespace "vara".

12:46 technomancy: jweiss: oh, vara is its own top-level ns?

12:46 jweiss: technomancy: yeah

12:46 technomancy: it's not recommended to have namespaces without a dot in them

12:46 jweiss: ah

12:46 did not know that

12:46 technomancy: not sure if that's the problem here, but yeah.

12:47 jweiss: this could use a little work for 1.2 also - apparently you can't use java classes in the default package either.

12:47 (without a package name)

12:47 these are some very arbitrary limitations that i'm sure were not intentional and probably fixable

12:48 chouser: doesn't java also have some trouble supporting classes in the default package? certain things you can't do?

12:48 jweiss: chouser: nothing that i'm aware of

12:48 technomancy: is there a notion of strong code ownership in contrib? I'm wondering if it would be kosher to apply mattrepl's fix for #44 without waiting for ataggart's go-ahead.

12:49 chouser: technomancy: My impression is that that's acceptible, assuming you're confident it's a good fix.

12:50 jweiss: is there any good convention for what to name your "main" or "core" clj file for a project? x.core? x.main? since i have to give it some name in addition to the toplevel ns...

12:50 technomancy: cemerick: what was your objection to just turning off AOT for logging.clj?

12:50 that seems like the simplest fix

12:51 jweiss: core is the most common

12:51 jweiss: technomancy: k thx

12:53 technomancy: chouser: yeah, I'm not sure I understand 100% the implications of mattrepl's fix

12:53 but cemerick raised objections I don't understand to the obvious fix

13:07 rrc7cz: ,(use 'clojure.contrib.pprint)

13:07 jweiss: technomancy: i'm starting to think this "mydb is not public" error might be a circular dependency problem. my core ns uses one item from my "hooks" ns, and "hooks" uses one item from "core". do ihave to be careful doing mutual :use(s)?

13:07 rrc7cz: how does the ClojureBot work? I'm trying to confirm that the error I'm getting in my latest pull from master is just my prob

13:10 replaca: rrc7cz: clojurebot doesn't support contrib

13:10 rrc7cz: okay

13:10 replaca: the source is at http://github.com/hiredman/clojurebot

13:11 rrc7cz: cool, thanks

13:11 arohner_: I didn't get a response to http://groups.google.com/group/clojure/browse_frm/thread/d4dd1a0a1ffee6c5#

13:12 can anyone comment on whether this is a bug or I'm doing something stupid?

13:16 jweiss: anyone know if it's possible to have 2 ns's have :use clauses that point to each other?

13:16 i keep getting "xyz is not public" and i know that it IS public

13:16 maybe it's because the first file loads its deps first, and when the dep points back at the original file, the stuff it needs hasn't been defined yet?

13:17 arohner_: jweiss: ns declarations can't fix circular loads

13:17 my guess is you have a circular loading problem

13:17 jweiss: arohner_ what's the solution?

13:18 i guess i could put the mutally used items in a 3rd namespace...

13:18 drewr: jweiss: yes, factor out those vars

13:18 arohner_: jweiss: yeah. The only solution is don't circular load

13:19 rhickey: Is this a bug? http://groups.google.com/group/clojure/browse_frm/thread/d4dd1a0a1ffee6c5#

13:20 or am I doing something wrong?

13:24 rrc7cz: Can anyone confirm (use 'clojure.contrib.pprint) works on clojure + clojure.contrib master HEADs? I'm getting "java.lang.IllegalStateException: Var clojure.core/chunked-seq? is unbound. (dispatch.clj:90)"

13:31 arohner_: rrc7cz: sorry, I can't help you. I can confirm that the new branch + contrib from about a week ago works. that's what I'm running

13:31 rhickey: arohner_: yes, generated conj is not as flexible as e.g. hash-map conj yet

13:31 rrc7cz: make sure you run 'ant clean' first on any new contrib build

13:32 arohner_: rhickey: if you give me a hint, I can work on a patch. I got lost on where that call to nth came from on the second line of the stack trace

13:32 cemerick: technomancy: where's the ticket regarding logging? I'm not remembering the issue off the top of my head.

13:34 rhickey: arohner_: it's from the destructuring here: http://github.com/richhickey/clojure/blob/new/src/clj/clojure/core_deftype.clj#L168

13:34 rrc7cz: rhickey: that did it; I was rebuilding with the -Dclojure.jar set for pprint. It's working now, thanks

13:35 rhickey: arohner_: it needs instead to mimic: http://github.com/richhickey/clojure/blob/new/src/jvm/clojure/lang/APersistentMap.java#L31

13:36 arohner_: rhickey: great! thanks

13:36 rhickey: arohner_: best to place that code (which can be implemented in terms of calls to assoc) in a helper fn which is called by .cons

13:36 jweiss: i am sure this must be possible but i'm not finding the answer in the docs- if i want to name my function in my namespace "assert", i get an error "Name conflict, can't def assert because namespace: vara.api.hooks refers to:#'clojure.core/assert

13:36 [Thrown class java.lang.Exception]" - how do i use my own function instead of clojure.core's

13:37 since core is used implicitly...

13:37 technomancy: cemerick: it's http://www.assembla.com/spaces/clojure-contrib/tickets/44

13:38 arohner_: jweiss: you need a refer clojure.core :except assert

13:38 jweiss: arohner_ ok i'll try that ,thanks

13:38 arohner_: if you refer clojure.core explicitly in your ns declaration, you can control which vars get imported

13:41 jweiss: sorry, :exclude. (doc ns) has an example of how to do it

13:44 cemerick: technomancy: I was just looking out for those environments where AOT is required (either because of security policy or issues with loading runtime-generated classes in various module systems).

13:46 defn: hmm -- anyone ever read Manning books before>?

13:47 drewr: defn: I read the Perl OO book a long time ago

13:47 defn: Are they good books?

13:47 drewr: all depends on the author

13:47 defn: I've never seem them -- kind of surprising really

13:48 technomancy: defn: the typesetting on their ebooks is sometimes amateurish and the covers are silly. other than that yeah, it's all up to the author.

13:48 defn: drewr: there's a new clojure book coming out

13:48 chouser: two

13:49 drewr: defn: I looked through the first chap of rathore's book

13:49 defn: chouser: i already pre-ordered one

13:49 cemerick: chouser: do you guys have TOC somewhere?

13:49 chouser: "Clojure in Action" is partially available as an e-book now. "Joy of Clojure" will hopefully be available soon.

13:49 defn: ahhh, manning has two

13:49 i ordered the apress clojure book from amazon

13:49 err pre-ordered

13:50 chouser: cemerick: nothing public yet. and it keeps changing. :-P

13:50 drewr: I'm looking forward to advanced CS books that speak Clojure

13:50 cemerick: chouser: when I saw fogus asking about CPS, I got excited :-)

13:50 chouser: :-) well, hopefully we won't disappoint.

13:51 defn: im looking forward to getting a job someday programming clojure

13:51 but im not holding my breath just yet :)

13:51 arohner_: defn: you have to make your own luck

13:52 defn: you could say rhickey decided he wanted a job programming clojure

13:52 defn: arohner_: sure -- i hear you there

13:52 im not one of the "I learned Java so I should get a job by default" guys

13:53 im just gonna keep hacking clojure and trying to do interesting stuff -- eventually someone will say "hey, can you do that for me?", and hopefully they say "hey, can you do this for me all the time?"

13:55 chouser: defn: maybe there are people who know if a plan like that is good or not. But until they speak up, it sure sounds reasonable. Hope it goes well for you. :-)

13:55 _fogus_: cemerick: I'm still trying to think of an intuitive way to explain CPS, and then come up with a compelling Clojure case. It's a double whammy at this point.

13:57 cemerick: _fogus_: yeah, either way, stuff that pushes boundaries is good. I suppose I'm not where the market is, but more "let me tell you what an atom is" isn't going to make my socks roll up and down anymore. :-)

13:58 jweiss: i've heard it said that some people think 'eval' shouldn't be used at all, but what's the alternative? i tried to make a macro to read a string and turn it into the form data to define a fn. but i'm not sure how to go beyond that and have the macro return the actual function, without using eval.

13:59 chouser: cemerick: such information is also rather dull to write. we have every intention of pushing past that level.

13:59 * _fogus_ TODO - remove the chapter "Everything You've Always Wanted to Know About Atoms, but Were Afraid to Ask"

13:59 cemerick: heh

13:59 I'm suddenly reminded of those Java tomes from yesteryear that simply printed the javadoc-of-the-time.

14:00 arohner_: jweiss: if you're reading a string, you can just read it. There are a few cases where eval is the only option, but they're rare

14:00 jweiss: as in (read) it

14:00 drewr: I want the clojure PAIP or SICP that then pushes the envelope with concurrent overtones

14:00 _fogus_: Chouser and I wrote up a whole intro chapter and honestly, I have to say that I admire authors who can sustain that type of work for an entire book.

14:00 drewr: more examples like ants.clj

14:00 arohner_: _fogus_: yeah, can you just go ahead and write another SICP?

14:00 :-)

14:00 jweiss: arohner_ but my macro just returns the form (fn [x] (inc x)) - i want it to be a function, not the form

14:01 chouser: jweiss: sounds like you're close. Can you paste that macro?

14:01 jweiss: (defmacro eval-hook [fn-str]

14:01 (read-string fn-str))

14:01 drewr: arohner_: rhickey has set high standards around here ;-)

14:02 chouser: jweiss: (eval-hook "(prn :hi)") prints :hi for me -- doesn't it work for you?

14:03 jweiss: chouser: hehe would be nice if i actually called the macro instead of macro-expand-1 on it :)

14:03 duh

14:03 chouser: :-)

14:03 though note it'll only work for literal strings.

14:03 cemerick: I'm not sure SICP needs rewriting. On Lisp though, that's ripe for a refresh.

14:04 chouser: (let [x "(prn :hi)"] (eval-hook x)) ; failure

14:05 _fogus_: cemerick: Wouldn't that be ANSI CL?

14:05 chouser: cemerick: I already wrote the chapter on how to do anaphric macros in Clojure.

14:05 jweiss: chouser: hm, i think that'll be ok, these are strings i'm pulling from a couchdb instance. so it should always be literal

14:05 chouser: anaphoric

14:05 jweiss: no, probably not.

14:05 rrc7cz: I'd rather see The Little Schemer series in Clojure.. but the name would be hell to say

14:05 arohner_: jweiss: you might not even need a macro in that case

14:05 cemerick: _fogus_: I mean with a clojure bias :-)

14:05 chouser: jweiss: if you're pulling strings from somewhere at runtime and want to treat them like code, then you really do need eval.

14:05 jweiss: chouser: oh wait you're right

14:06 drewr: cemerick: rewrite isn't what I had in mind; just that academic caliber

14:06 _fogus_: Before I started working on the book, I was considering doing a whole series of blog posts along the Little Schemer lines

14:06 arohner_: jweiss: and that wouldn't be a macro. Just read-string + eval

14:06 jweiss: chouser: ok good to know this is one of the times when eval really is needed.

14:06 cemerick: I never could get into the Little Schemer series.

14:06 jweiss: that's the way i wrote it originally

14:07 cemerick: I get too impatient with the narrative. I want to see the hill I'm climbing.

14:07 arohner_: cemerick: yeah, I never got into it either. I find I rarely think about the problem the same way the author presents it

14:07 so I always got lost in the transitions from one little problem to the next

14:08 jweiss: chouser: one thing about using eval is it's always evaluated in the clojure.core namespace

14:08 which i'd rather not do

14:08 technomancy: cemerick: I don't get it. what kind of environments require .class files?

14:08 rrc7cz: for me it's the opposite: I have to push myself a bit through SICP, but the Schemer series just felt lightweight

14:08 lightweight and fun. You get immediate feedback because it's like a neverending series of puzzles

14:09 chouser: jweiss: I don't think that's right. It seems to use the current value of *ns*

14:09 * technomancy digs dialog

14:09 rrc7cz: although I still don't get the chapter where they explain Y

14:09 chouser: ,(eval '(prn *ns*))

14:09 drewr: I think the camel book is what I'm targeting -- an idiomatic book by the language author that goes in depth but also contains plenty of examples

14:09 technomancy: it seems like if your environment requires .class files then it's up to you to make sure all your stuff is AOT'd

14:09 jweiss: chouser: ok, maybe i'm misreading the symptoms here, i'm calling my own "assert" but it tries to call core's instead, i thought it was because of the reason i stated, but maybe i didn't exclude assert correctly

14:10 technomancy: it shouldn't be the duty of contrib

14:12 _fogus_: rrc7cz: No one does.

14:16 cemerick: technomancy: I was under the impression that android couldn't cope with loading from .clj files at all. The same was true for the module system in netbeans 6.5 at some point, although that was patched before 6.7 if memory serves.

14:16 rrc7cz: fogus: that's heartening to know. The book looks like it was designed for children. Being crushed by that chapter made me feel even worse when it's covered in elephant cartoons and jokes about ice cream

14:17 chouser: hehe

14:23 technomancy: cemerick: but the process of preparation for android will need to AOT everything anyway

14:24 so what does it matter if contrib's build does it or not?

14:25 cemerick: I think it'd be a shame if AOT needed to be performed on every clojure lib one wanted to use. This goes back to lib authors providing slim and AOT artifacts.

14:25 technomancy: I don't understand why that's a shame

14:26 preparing code for android is already a pretty involved task; adding AOT to it is not a big deal

14:27 tolstoy: Is there a simple clojure way to get all the text from an InputStream?

14:27 devlinsf: tolstoy: c.c.duck-streams

14:27 tolstoy: devlinsf: I've been looking at that.

14:27 devlinsf: tolstoy: Does slurp* work?

14:28 tolstoy: Alas, (duck/slurp* (duck/reader (-> request :body))) gets me nothing. (Compojure.)

14:28 devlinsf: Hmmm

14:28 cemerick: technomancy: There are other advantages to AOT'ing code (faster startup, interop with various tools, weak obfuscation) -- totally aside from any particular deployment target's requirements.

14:29 devlinsf: tolstoy: Did you try it w/o the intermediate call to reader?

14:29 tolstoy: slurp* has an implicit one

14:29 tolstoy: devlinsf: yep.

14:29 devlinsf: tolstoy: Hmmm... You got me

14:29 Stupid question

14:30 tolstoy: Maybe my "POST" isn't working like I think it does. That might be it.

14:30 devlinsf: tolstoy: what is (class (:body request))?

14:30 tolstoy: Using http-agent for that.

14:30 org.mortbay.jetty.HttpParser$Input

14:31 technomancy: cemerick: interop is only an advantage for a small set of nses, and obfuscation is a miniscule use case

14:31 devlinsf: tolstoy: and it extends input stream?

14:31 tolstoy: No idea. Can't seem to find java-doc for Jetty at the moment.

14:32 devlinsf: Try isa?

14:33 tolstoy: Okay.

14:33 Yeah, that class descends from InputStream.

14:33 devlinsf: Hmmm.. totally stumped :(

14:34 Did anyone on the Compojure list know what to do

14:34 * devlinsf wonders if any compojure wizards are here

14:34 chouser: tolstoy: it gets you nothing? no error?

14:34 defn: whatcha tryin to do?

14:34 tolstoy: chouser: right. No error. Just an empty, uh, string, I think.

14:35 On one side: (http-agent "http://myapp" :method "POST" :body "<some-stuff/>")

14:35 On the compojure side: (println (-> request :body))

14:36 cemerick: technomancy: Then I'm out of objections, until I hit a specific problem. It might be worthwhile to dig back into the discussion that occurred when clojure.core began applying AOT regularly. I remember it being a very welcome move.

14:36 tolstoy: :character-encoding nil, :body #<Input org.mortbay.jetty.HttpParser$Input@4c5e43ee>,

14:36 chouser: tolstoy: are you sure the body is not in fact empty?

14:37 tolstoy: chouser: I'm not sure of that. Which is why I'm trying to print it out. I'll check the sender.

14:38 chouser: or use an alternate client, just to check it. curl or wget, for example.

14:38 rrc7cz: why does clojure.zip/append-child require the node to already have children?

14:38 tolstoy: HTTP Client (Mac thing) proves that the POST is not arriving. Phew!

14:39 duck-streams slurp* works like I'd hoped it would, so that'l all cool.

14:39 technomancy: cemerick: yeah, in the case of logging.clj there are already other contrib namespaces that are excluded from AOT

14:39 rrc7cz: and for that matter, why doesn't clojure.zip/children return an empty seq instead of throwing an exception when the node is a leaf?

14:40 devlinsf: tolstoy: Glad it worked out (sorta)

14:40 tolstoy: devlinsf: Yeah. Now I have to figure out why http-agent isn't posting the body in :body.

14:40 devlinsf: tolstoy: Sounds like fun. Good luck.

14:40 tolstoy: Probably some inappropriately bound *out*.

14:41 devlinsf: tolstoy: Or laziness

14:41 That's bit me before with I/O

14:53 tolstoy: I wonder if http-agent is broken?

14:54 If I post :body "a=1&b=2" I can get them via :params in compojure. Content-length is 7. But no payload. Weird.

14:54 Yet some other http-client works fine.

14:57 Maybe it's the content-type....

14:59 Yep. That was it. c.c.http.agent assumes if the method is a post, the body is application/x-www-form-urlencoded, which messes things up, I guess, for Jetty.

15:01 defn: hmmm, i have clojureql via clojars but i cant seem to (use) it

15:02 [org.clojars.snuxoll/clojureql "1.0.0"]

15:07 * rhickey finally caught up the ggroup following holidays - phew

15:12 jweiss: would using in-ns be a valid (simple) way to run code in a sandbox (so that code i'm loading from a db and eval'ing only has access to certain stuff, i don't want my users to be able to write and execute stuff in some of my namespaces)

15:13 replaca: jweiss: I don't think that's sufficient

15:13 jweiss: i mean, it doesn't have to be *impossible* - i basically just want to stop accidental screw ups

15:13 arohner_: jweiss: yes, it will stop accidental screwups, it won't do anything to prevent intentional breaking

15:14 replaca: jweiss: users will still have complete access to your system. If that's ok, then you shhould be good

15:14 jweiss: arohner_ yeah, all they'd have to do is "use" the ns's i want to protect and voila, but better protection will have to wait

15:14 replaca: jweiss: otherwise, I recommend you look at clojurebot. That uses some "standard" java sandboxing

15:15 jweiss: replaca: ok thx

15:15 it's on github right?

15:15 nvm got it

15:37 LauJensen: Blogged about improving Clojure-mode's highlighting using Enlive: http://www.bestinclass.dk/index.php/2009/12/enlive-vs-clojure-mode/

15:39 devlinsf: LauJensen: This is awesome

15:39 LauJensen: Wow - You read it already? :)

15:39 devlinsf: RSS

15:39 LauJensen: Ahh, great - glad you liked it

15:43 devlinsf: LauJensen: Could we get your work merged into swank-clojure?

15:43 LauJensen: Then it should be cleaned up a little, but I think technomancy can take care of that pretty quickly ?

15:45 devlinsf: technomancy: Please? :)

15:46 chouser: it seems odd for the information to flow from clojure namespaces, through the doc processing to html, to github, through http back to clojure.

15:46 LauJensen: chouser: But how else would you show off Enlive ?

15:46 chouser: heh

15:47 LauJensen: Actually I pasted some code in here a few weeks ago which printed all functions in any namespace, didn't save it though

15:48 q1: Lau use this.

15:48 (defn print-public-binds "Prints all binds defined in library $sym." [s] (doseq [k (keys (ns-publics s))] (println k)))

15:49 (doseq [s *supported-libraries*] (print-public-binds s))

15:49 LauJensen: q1 I'll stick with Enlive, but we need to get technomancy motivated to employ either technique :)

15:49 q1: :)

15:50 I'm probably the only one using slickedit for clojure dev heh.

15:52 LauJensen: q1, whats that?

15:55 q1: Just a heavy-duty editor written in C/C++: http://www.slickedit.com/ ; it's heavily customizable.

15:56 cemerick: slickedit has always been appealing, but its lack of a useful OS X version is a problem for me.

15:56 technomancy: I'll merge a swank-clojure patch that read it directly from the ns for sure

15:56 enlive is great for a tutorial, but not for everyday work. =)

15:57 q1: i thnik that makes the most sense.

15:58 cemerick: does it make sense to put symbol tables and such right into core?

15:58 * rhickey remembers fondly his first version of SlickEdit for DOS

16:00 q1: hehe. for DOS? slickedit is still speedy, i like that aspect of it.

16:00 rrc7cz: technomancy: "enlive is great for a tutorial, but not for everyday work" why's that? I'm using it in my new project and I'd be interested in any thoughts

16:01 devlinsf: rrc7cz: It's not good for THIS problem

16:01 technomancy: rrc7cz: I mean for the purposes of determining what vars are in clojure.core

16:02 rrc7cz: got it

16:03 q1: tech: if you need a jump start, i can send you some clojure code.

16:04 technomancy: well there's two potential packges

16:04 0) update clojure-mode to match the current list from clojure.core

16:04 rhickey: q1: yeah, and for OS/2 also

16:04 technomancy: and 1) add a feature to swank-clojure to add to that list at runtime

21:00 chouser: hmph. someone stepped on my router power cord -- lost about 5 hours of IRC logging.

21:00 I hope nothing momentus was discussed?

21:19 polypus: best way of getting last two items in collection?

21:19 the-kenny: ,(doc take-last)

21:19 polypus: ty, looks like clojurebots dead

21:20 the-kenny: Yes :(

21:20 polypus: ~ping

21:20 the-kenny: May he rest in peace

21:20 polypus: :)

21:22 too bad split-at doesn't take negative indices. would be nice if it started from the end backwards in that case

21:23 the-kenny: hm.. I think it's more intuitive to pass a reversed sequence

21:24 polypus: right!

21:38 _mst: chouser: nothing momentous, but I can give you a dump of my erc buffer if you're worried about historical accuracy ;)

21:44 polypus: is there a function like vector which returns a map: (map* :foo "bar") -> {:foo "bar"}

21:54 chouser: _mst: eh. Thanks for the offer. If the format doesn't match exactly, it probably isn't worth the effort to convert it.

21:55 polypus: hash-map or array-map

21:55 _mst: polypus: it depends a bit on what you're trying to do. If you've just got a key and value, I'd use the literal syntax above. If you've got a collection of keys and another of values, I'd use zipmap to turn it into a map. If you've got a collection like (key1 val1 key2 val2), maybe (apply hash-map that-coll)

21:55 chouser: yeah, it's unlikely to match. Plus I seem to be something like 16 hours ahead, so converting the times wouldn't be much fun :)

21:55 polypus: ty, zipmap is what i need

21:55 chouser: bleh. timezones.

21:57 duper: is there a way with irb to display the ruby statements that make up a class initialize method?

21:59 chouser: duper: this is #clojure

22:00 duper: w00pz wrong window sorry guys

22:00 polypus: duper: do you mean introspecting to get the actual source? cuz ruby doesn't support that.

22:01 duper: reflection i guess

22:01 does clojure support that

22:03 chouser: duper: for any function (var, really) defined in a named .clj file in the classpath, you can print its source code with (source foo)

22:04 duper: can you treat that as datat to rewrite it on the fly?

22:04 fanatico: duper: yes. http://clojure.org/macros

22:05 chouser: probably, though 'source' will still use the contents of the file each time, so what it prints could become out of date.

23:05 technomancy: devlinsf: looks like that clojure-mode patch doesn't apply cleanly on the latest git master

23:05 devlinsf: technomancy: BLARGH!

23:05 technomancy: were you basing it off a copy from elpa?

23:05 devlinsf: technomancy: Hmm... I pulled this afternoon. Did you do anything since then?

23:06 Ooh... maybe

23:06 technomancy: my last commit was last week

23:07 adding defprotocol and friends

23:08 devlinsf: url = git://github.com/jochu/clojure-mode.git

23:08 I pull from thee

23:08 there

23:08 Is that the wrong one?

23:08 wdouglas: technomancy: By the way the slime-fuzzy from your slime repo on get has the same problem =(

23:09 technomancy: devlinsf: yeah, try s/jochu/technomancy/

23:09 devlinsf: Ah

23:09 technomancy: I mean to keep the jochu one up to date, but I forget a lot

23:09 devlinsf: http://github.com/technomancy/clojure-mode

23:09 That one?

23:09 technomancy: yup

23:10 devlinsf: Okay.

23:10 Did you see the sample png, though?

23:12 technomancy: devlinsf: yeah, I like the way it looks

23:12 using the warning face for deprecated stuff is a good idea

23:12 devlinsf: Okay. And the green for "extended" is good too?

23:13 technomancy: yeah, I think so

23:13 what's the name of that face?

23:13 devlinsf: GImme a sec...

23:14 font-lock-type-face

23:14 technomancy: that's fine... those are always used loosely anyway

23:14 devlinsf: There's also this cool looking one for single quoted stuff, that's light blue

23:15 In el mode, anyway

23:15 technomancy: that's not in the screenshot though?

23:15 devlinsf: A long term idea might be using it for quoted data structures

23:15 No.

23:15 It's in the clojure-mode file

23:16 I figured I'd try to sell one change at a time.

23:16 Two is pushing it :)

23:16 And three... well, I don't even know where to start

23:16 technomancy: hehe

23:17 if you could get an updated patch from the latest, I will apply it post haste

23:18 wdouglas: what was the problem with fuzzy again?

23:19 wdouglas: technomancy: synchronous lisp evaluation error

23:19 devlinsf: technomancy: just pulled from the proper repo... will get hacking

23:19 technomancy: much obliged

23:20 wdouglas: java.util.concurrent.RejectedExecutionException

23:20 technomancy: feels like these days I don't have time to hack on my own projects, but if I squeeze I can find enough time to apply patches that people send me. =)

23:20 wdouglas: You are working through others, technical manager of oss =)

23:21 technomancy: it's easier than herding cats at least

23:26 wdouglas: http://pastebin.com/m262e42f0 is a paste of debugger and backtrace. I really need to work on being able to debug in emacs.

23:30 technomancy: wdouglas: some of that old swank-clojure code is just so crazy

23:31 a lot of it was implemented before many features we take for granted today

23:31 and a lot of it is needlessly complicated

23:31 ... or at least appears that way, so then when you make changes to simplify it turns out the break important stuff because there's no test coverage. =\

23:31 (swap! timed-out (constantly true)) ; <= someone is unaware of the reset! function? or what...

23:32 wdouglas: I'm sure that was emacs 18 or something

23:38 So when it does the slime-rex call in the slime-eval from the error I'd think there were multiple at once and clojure throws an error from that.

23:39 Now to try and verify speculation

23:40 technomancy: that timeout stuff should be replaced with java.util.Timer, I think

23:41 I have no idea why the future would throw a rejected execution exception though =\ no calls to cancel or anything

23:42 wdouglas: It doesn't make much sense since this will work if you are running from a regular slime instead of a lein swank

23:42 technomancy: wdouglas: oh! I didn't realize that

23:43 do you know if the versions of swank-clojure.jar are the same?

23:43 wdouglas: Oh.. they might not be. I was just using clojureql lein project

23:43 I will try that out.

23:44 I'm using clojure 1.0 on the default slime

23:55 technomancy: that's probably it

Logging service provided by n01se.net