#clojure log - May 16 2009

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

2:35 tsdh: Can anyone enlighten me when `var?' is useful? It seems it's true only for the return value of a `def'. (var? (def foo 17)) ==> true, but (do (def foo 17) (var? 'foo)) ==> false.

2:41 hoeck: ,(let [x #'fn] (var? x))

2:41 clojurebot: true

2:42 hoeck: tsdh: but I haven't used it in 'real' code so far

2:42 tsdh: maybe it's just for completeness sake, or to implement crazy macros ..

2:46 tsdh: What's #' for a reader macro?

2:47 Ah, Var-quote. Thanks, now I've gotten it.

2:50 unlink: I wish lazy-seq were easier to type.

3:08 What's the best way to memoize a lazy-seq? (memoize #(nth (my-seq) %))?

3:08 +)

3:08 *for efficient random access

3:13 hoeck: unlink: putting it in a vector??

3:19 kli: if you hold on to the head of a seq, I think it will memoize it

3:19 not 100% sure

4:09 * Raynes waits for GHC to finish building.

4:20 Raynes: Wow, this is taking forever.

4:33 vy: Raynes: You should also try compiling Open Office. (Wine is a good candidate too.)

4:38 Raynes: vy: It's still going. o_o

4:38 I can picture myself three days from now sitting her all starry eye'd while I watch the text fly in Bash.

4:50 Yay it's done!

8:16 eee: does clj have a concept of generic infinity?

8:17 no matter what type is being compared, it is always bigger?

8:31 marklar: Hi I'm trying to set up emacs + slime on a new machine. I getting a ClassNotFoundException: swank.swank whether I do it manually or using the clojure-mode clojure-install. Has anyone encountered this before?

8:38 eee: i just use clojure-dev eclipse plugin

8:50 achim_p: hi all! did anybody here try to define custom data structures in clojure? i'm playing around with a simple deque (http://gist.github.com/111147), which works with a custom set of ops, but i'm not sure how to best proceed if i wanted first/last/next/butlast to give sensible results

9:06 liebke: achim_p: I've only written custom clojure data structures in java, implementing the ISeq interface. I suppose you could use gen-class to do the same in pure clojure.

10:16 tmi: anyone working with compojure know sessions work (in recent compojure master branch)?

10:31 meredydd: tmi: Yeah

10:31 tmi: You include the value of (session-set) or whatever in the return value

10:32 The way to think of it is that your handler code returns "what I want to happen in response to this request"

10:32 that includes content, headers, etc to return, as well as what changes to make to the session

10:33 sorry - I mean (session-assoc) and friends

10:40 tmi: meredydd: ok, thanks, I'll give it a shot :)

11:56 eee: any clojure-dev users in here?

13:09 biilly: hi. anyone know how to pass expressions to swank-clojure in .emacs?

13:10 of how to read some expressions as a file to pass to swank-clojure-init-files?

14:28 dreish: I wonder whether this is real: http://www.google.com/trends?q=clojure%2Cjruby%2Cjython&ctab=0&geo=all&date=ytd&sort=0

14:28 And if so, why?

14:28 (Referring to the sudden surge in Clojure searches in the last data point.)

14:29 Because it went to 1.0, maybe?

14:30 danlarkin: http://www.google.com/trends?q=clojure%2Cruby%2Cpython&ctab=0&geo=all&date=ytd&sort=0

14:31 dreish: Man bites python. At 90, Ruby's fighting fit. Eric Idle adds an orchestra to Monty Python comedy.

14:32 Not really comparable.

14:32 danlarkin: mmmm

14:32 that's news items though, but yeah I get it

14:34 dreish: I think the surge is from 1.0. Looking at the 30 days chart, it settles back down after early May, though still above where it was before.

15:00 Chouser: I've got a map that's in theory is acting as an identity -- it's got values like an open socket, a thread or two, etc. But many of the values will never change (like the socket and thread).

15:01 So, should I pass it around as a reference type, because it has identity, and then not need to use reference types for the mutable members?

15:01 cp2: ugh

15:01 * cp2 wonders what the .... is going on over at the datacenter

15:01 Chouser: Or, should I pass it around as a map value, because it's largely immutable, and then have specific reference types for the mutable members?

15:02 I've been doing the latter, I'm just not sure it's right.

15:02 danlarkin: reference type as in (ref )?

15:03 If that's what you mean, I would put the whole map in a ref

15:03 IMO

15:03 but I guess it's just personal preference

15:05 Chouser: I mean reference type as in ref, atom or agent

15:05 kotarak: as in IRef?

15:05 Chouser: Um.. yeah, I guess so.

15:06 I also generally have a closure or two. If the "object" is an IRef, then I need to make sure I close over the IRef, not the values it contained originally.

15:07 If the "object" is immutable, then I can close over the values fine, but need to close over each of the internal IRefs as needed.

15:07 hm.

15:21 Lau_of_DK: Good evening gents - Whats new in Clojureland?

15:24 kotarak: Hi Lau.

15:24 cp2: ;)

15:24 i havent dropped in over 5 minutes, this must be a good sign

15:29 biilly: how come when i javadoc from my repl in emacs it hangs, but in the console script it launches the browser fine?

15:41 cp2: looks like a spoke too soon

15:42 rhickey: Chouser: could the closures take the value as an arg?

15:44 biilly: in repl-utils/javadoc, it uses "browse-url" which i know is an emacs command, is this in clojure.contrib as well?

15:44 kotarak: rhickey: did you read the thread about the latest ns macro changes on the list?

15:44 I had problems with the anon fn there

15:44 rhickey: kotarak: yes, I'm working on that now

15:45 kotarak: ok :)

15:45 rhickey: I hae a workaround but would rather get the 'right thing' in there - which is unwrapping do at top level

15:46 * kotarak has no clue about classloaders and stuff whatsoever. :|

15:55 Chouser: the only closures I have so far are for Threads -- but anyway, they can only take the object if its an IRef

15:56 (def new-obj [a] (let [b (LinkedBlockingQueue.)] {:t (Thread. #(work a b)) :a a :b c}))

15:56 should be defn

15:58 (defn new-obj2 [a] (let [obj (atom {:a a :b (LinkedBlockingQueue.)})] (swap! obj assoc :t (Thread. #(work2 obj))) obj))

15:58 I guess that's the other option?

16:00 I like how the obj produced by new-obj can't be messed with -- I can't replace the LBQ with something else, because work is dealing with it directly and the map's immutable

16:01 with new-obj2, I could swap in a new value for :a or :b, and depending on how work2 is written, it may or may not notice the change.

16:03 or do I have that backwards, and being able to change it while running is actually a benefit?

16:19 cads: is there a clojure script that takes options and arguments for stuff like loading extra jars?

16:21 rhickey: kotarak: try 1370

16:21 kotarak: k, just a sec

16:25 stuhood: cads: to add jars, you add them to java's classpath. see http://clojure.org/repl_and_main

16:27 cads: I have written a bash script that takes these arguments: clojure [-j= & jars] [script file]

16:28 it either runs a script with the or if the script argument is left blank, starts

16:28 oh, wait

16:28 kotarak: rhickey: two thumbs up. Seems to work. :) At least I didn't get a failure up to now.

16:28 thanks for quick fix!

16:29 cads: it'll start a repl if it has no script to run, but if you give it a script it also passes the remaining commandline arguments to the script

16:29 clojurebot: http://www.pigdog.org/auto/mr_bads_list/shortcolumn/1914.html

16:34 kotarak: rhickey: yep, works now.

16:43 cads: I love clojure, and how tiny it is

16:44 dnolen_: ditto.

16:44 cads: I can leisurely skim its sourcecode and get a good feeling of how whatever I want to know about works

16:44 kotarak: No 1000 page Spec. Phew...

16:45 * kotarak liked that about R5RS, too.

16:47 cads: does scheme have unicode yet?

16:52 kotarak: cads: dunno, I didn't follow R6RS...

17:20 cads: hey, I'd like to use a clojure script as part of a unix pipe, but I'm not entirely sure how it is that pipes are able to control the processes that generate the data so as not to have to queue data up

17:21 kotarak: Just read from the pipe. The producer is stopped as soon as the buffer is full.

17:22 cads: say the producer is a clojure script writing stuff to standard io, then the whole java process is just stopped?

17:22 kotarak: Hmmm... I think the thread writing to the output buffer is stopped. The rest probably goes on.

17:24 cads: I'll have to test it

17:26 one last thing, for io stream output, I'd like to write a special print function for a datastructure containing 3d particles. But I'd like the function to be called print, and in fact it would be neat for the actual print function to be able to print these structures specially, mixed in with normal printing for other things

17:26 can I overload print like that?

17:27 kotarak: cads: (defmethod print-method :your-dispatch ...) should do the trick

17:27 cads: is the dispatch method for print in clojure.core?

17:28 kotarak: cads: dispatch is type

17:35 StartsWithK: fyuryu: hi

18:01 danlarkin: Can't decide if I should return nil/error code or throw an exception when something goes wrong with this couchdb api

18:03 Chouser: both!

18:03 rsynnott: possibly best throw an exception; then the user can catch it and use error codes if they want to

18:03 the other way round is slightly more awkward for the user, IMO

18:04 danlarkin: or use error-kit!!!

18:10 yeah returning nil isn't really working out for me, because first you have to check for nil, then you have to either check for the error code or result, blah

18:28 quidnunc: What should "swank-clojure-extra-classpaths" be set to in emacs? I'm having trouble setting it to anything non-nil (can't find swank.clj anymore).

18:46 danlarkin: Chouser: first real use of error-kit... I love it :)

19:17 Chouser: danlarkin: hah, great.

19:19 danlarkin: Also looking at david nolen's spinoza, it's also really cool!

19:19 Chouser: that's an object system, right?

19:20 I think error-kit incorrectly contains parts of an object system. :-/

19:21 danlarkin: yeah, it's an object system, which is why I passed it over initially when I saw it on the ML

19:21 clojurebot: why not?

19:22 danlarkin: but it integrates with multimethods "correctly" (IMO) and doesn't reinvent too much, it looks like

19:22 I think it might be just-enough of an object system

19:23 Chouser: I'm not sure what I think of "object systems" in clojure, but even if they're ok, I don't think having error-kit invent its own is acceptible.

19:24 danlarkin: objects are just struct-maps

19:24 with extra sauce on top, so it looks like you can take it or leave it

19:24 Chouser: sure, but it's what you do with them that makes or breaks it.

19:24 right

19:24 danlarkin: (I'm saying all this without having used it yet :) )

19:25 Chouser: well, error-kit error objects are just maps, but they have types which have inheritence, and they have constructors, etc.

19:26 It seems likely to me either error-kit doesn't need all that, or that other things do.

19:27 danlarkin: sorry, do you mean "...doesn't need all that, and that other things also don't"?

19:29 if so, I sortof agree initially, but I haven't made up my mind yet

19:30 it's all degrees anyway, as long as it's turing complete you can do whatever you want anyway, it's just how convenient it is to work with

19:49 tashafa: hello

19:49 qq....

19:49 how do i get the arglists of a function passed into another function

19:49 >=?

19:49 ?

19:52 Chouser: I don't think there's any way to get that.

19:52 You can get the arglists of a ver defined using defn, but even that's not 100% reliable.

19:53 tashafa: cool thanks

19:54 now i have to figure out a workaround

19:58 danlarkin: tashafa: what do you need to accomplish? maybe there's another way we can help you think of

20:02 tashafa: sorr..im back

20:05 i have a library that takes a function from a user and applies to 3 or 2 arguments

20:05 i want the user to be able to provide a function with either 2 or 3 items in the arglist vector

20:06 so i need to be able to tell how many arguments the function the user provides has

20:07 sorry let me rephrase that last sentence

20:07 Chouser: a callback with an optional 3 arg

20:08 danlarkin: so if they pass in a two arg function, you take one code path, and if they pass in a 3 arg function you take another

20:08 tashafa: yup

20:09 but i dont want them to pass a function with optional args

20:10 Chouser: yeah, that seems very reasonable. Functions could provide a way to find out what numbers of args they could take, they just don't currently.

20:10 dreish: What about passing a function and a number?

20:11 Chouser: and it wouldn't be as simple as in some langages -- javascript provides a single arity int, and that just wouldn't cut it in Clojure.

20:11 tashafa: Chouser: yeah it looks like so

20:11 dreish: or {:fn x :arity n}?

20:11 danlarkin: or try to call with 3 args and catch IllegalArgumentException, and then try with 2?

20:11 tashafa: dreish: seems a little to hacky for me

20:11 dreish: tashafa: Why?

20:12 Chouser: (fn foo ([a] a) ([a b c] c) ([a b c d & e] d))

20:12 dreish: danlarkin: Exceptions take a long time to construct.

20:13 tashafa: because i'm trying to mimic how javascript

20:13 dreish^

20:13 danlarkin: dreish: don't dismiss them flat out, though. maybe this isn't a critical code path

20:13 tashafa: it isnt

20:13 the exception route seems like the forerunner

20:13 dreish: Yech.

20:13 That's the hackiest possible route, but whatever floats your boat.

20:14 tashafa: yeah but it hides the hack from the user

20:14 danlarkin: tashafa: are you relying on the user not to pass you a function on one argument, 4, 2 with an optional.. etc?

20:16 tashafa: im hoping the user passes a function with any number of arguments

20:16 *a function that takes any number of arguments

20:17 quidnunc: Do .clj files need to (manually) compiled to Java byte-code or is it enough to have it in the classpath?

20:17 tashafa: but i just need to know how many arguments the function uses

20:18 danlarkin: quidnunc: it's enough to have it in the classpath

20:18 Chouser: tashafa: I think wanting to know that is reasonable, and this sounds like a solid use-case.

20:19 tashafa: python has this functionality i think

20:19 i need to look it up though

20:19 Chouser: I can imagine wanting to be able to pass in general-purpose functions and have your fn look at them and do the right thing.

20:20 So, you could certainly choose to pursue a feature request.

20:20 quidnunc: danlarkin: Thanks.

20:20 Chouser: ...but that's not going to help you today. For today you need to find an acceptible work-around

20:20 dreish: I can't think of any good reason IFn couldn't have a .getArities()

20:21 Chouser: dreish: returning a set? plus a flag to indicate variadic?

20:21 dreish: I'd think a set.

20:22 tashafa: cool... i'll try and pursue a feature reauest and find a workaround. If i get anywhere i'll be sure to post back here

20:22 Chouser: one work-around would be a func that takes a 2-arg fn, and returns a 3-arg fn that ignores the 3rd arg

20:22 (do-callback (fn [a b c] ...)) would just work.

20:22 tashafa: Chouser: you are a genius

20:23 Chouser: (do-callback (fix-it (fn [a b] ...))) would also work.

20:30 hiredman: I think .getArities would return a boolean IFn

20:31 dreish: How would you iterate over that?

20:31 hiredman: dreish: I am just thinking it would make handling & rest easier

20:32 dreish: Good point.

20:33 hiredman: hmmm

20:33 I guess it could be some subclass of set

20:35 that allows you to specificy some rule, like (> x 3) for set membership

20:42 ~def c.l.PersistentHashSet

20:46 danlarkin: Chouser: I can't call error-kit/raise with a sexp that returns the correct error because raise is a macro, so should I be using raise* for this?

20:51 * Chouser pulls up error_kit.clj

20:52 Chouser: looks right

20:53 appears to even be documented.

20:53 danlarkin: 'doh!

20:53 where, do you mean the docstring?

20:53 Chouser: yes, just that.

20:53 hiredman: hmmmm

20:54 Chouser: I didn't mean to suggest you shouldn't have asked.

20:54 hiredman: IPersistentSet does not have a seq method, but the repl seems to call seq on it when trying to print it out

20:55 java.lang.UnsupportedOperationException: seq

20:55 Chouser: ,(seq #{:a :b :c})

20:55 clojurebot: (:a :c :b)

20:55 Chouser: ?

20:55 hiredman: ~def c.l.IPersistentSet

20:55 if you proxy IPersistentSet, and try to print out the resulting object

20:55 *boom*

20:57 Chouser: It's just and interface. You have to provide all the functions if you want them to do anything.

20:57 s/and/an/

20:57 (proxy [clojure.lang.IPersistentSet] [] (seq [] '(1 2 3)))

20:58 hiredman: Chouser: I don't want them to do anything

20:58 I don't want a seq method, the interface does not contain one, but when the repl tries to print out my proxy object it tries to call a seq method on the object

20:59 I imagine in some print function somewhere there is an IPersistentSet that should be an APersistentSet

21:00 ,(map #(.getName %) (.getMethods clojure.lang.IPersistentSet))

21:00 clojurebot: ("disjoin" "get" "contains" "equiv" "count" "cons" "empty" "seq" "count")

21:00 hiredman: hmmm

21:00 ah

21:00 extends

21:00 of course

21:03 danlarkin: for the records regarding error-kit and raise: yes I just ran macroexpand-1 on raise and substituted as necessary

21:03 Chouser: so thanks :)

21:04 Chouser: heh, ok.

21:07 danlarkin: clojurebot: exceptions?

21:07 clojurebot: http://paste.lisp.org/display/74305

21:07 danlarkin: clojurebot: thanks :)

21:07 clojurebot: Pardon?

21:11 hiredman: ~def clojure.set/union

21:12 that reduce is a drag

21:16 I don't see how clojure.set/union can be made to work with rule defined sets

21:20 ~paste

21:20 clojurebot: lisppaste8, url

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

21:22 hiredman pasted "rule set" at http://paste.lisp.org/display/80355

21:57 unlink: Is there any way to access what type of struct a struct instance is?

22:01 Chouser: it's a map. that should be enough. :-)

22:01 danlarkin_: you can have a :type key

22:01 and then call clojure.core/type on it

22:01 if you must

22:02 or at least I thought you could

22:02 unlink: It's in there as a private field `def`, so tantalizingly inaccessible...

22:02 danlarkin_: oh, :type key on the metadata

22:03 unlink: user=> (meta (struct a 1 2))

22:03 nil

22:03 danlarkin_: it doesn't put it there for you :)

22:05 unlink: So I can't access it?

22:06 danlarkin_: a struct-map is just an optimized map

22:06 it isn't a special thing

22:07 unlink: It is a clojure.lang.PersistentStructMap

22:07 Which has knowledge of what struct type it is.

22:08 danlarkin_: implementation detail

22:09 unlink: Except for the fact that it might be useful to know what kind of struct you are.

22:09 danlarkin_: the point is that you shouldn't be trying to use structs like classes

22:10 unlink: What's the right way to have a typed structure, then?

22:13 danlarkin_: put a :type key in the metadata

22:13 hiredman: (type #^{:type :foo} {:a 1})

22:13 ,(type #^{:type :foo} {:a 1})

22:13 clojurebot: :foo

22:17 mattdw: does anyone know if there's a way to provide class/interface names to 'proxy' at runtime?

22:18 say (defn mk-proxy [cls] (proxy [cls] [])) ?

22:19 Chouser: get-proxy-class

22:19 init-proxy

22:20 mattdw: ah sweet

22:20 so proxy is just a wrapper around those two?

22:21 unlink: danlarkin_: I found what I was looking for. clojure.contrib.types/deftype

22:22 danlarkin_: clojurebot: def deftype

22:34 Hm. couchdb returns the same status code & error message when you try to access a database that doesn't exist and try to access a document that doesn't exist

22:34 so (document-get "foo" "bar") doesn't know if it's the DB or document that doesn't exist... in its current incarnation, at least

22:35 mattdw: Chouser: sweet, that's working great

23:07 Chouser: does anyone have a link for the blog that listed various ways to bundle data and functions in clojure?

23:07 it talked about namespaces, mapfulls of closures, etc.

23:27 cads: hey chouser, you about?

23:27 Chouser: a bit -- on the phone too

23:28 cads: cool, lemme know when you got a sec, want to ask about your work with jscript and c, wrt clojure

23:44 danlarkin_: aw darn, and I can't even have multimethods like get and list that'd work on a server and database map, because clojure.core already defines them.

23:50 stuhood: danlarkin_: i thought namespaces handle that?

23:50 danlarkin_: stuhood: well all of clojure.core is refer'ed into the current namespace by default

23:51 you can exclude specific functions and then write your own of the same name, but it breaks anyone use "use"ing your library

23:52 stuhood: danlarkin_: gotcha... so they'd have to rename the functions themselves during (use) anyway

23:53 danlarkin_: yep :-/

23:57 Chouser: cads: ok, anything quick? gotta run soon.

Logging service provided by n01se.net