#clojure log - Jul 07 2009

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

0:32 eyeris: Is there a function or macro establish local bindings from a map?

0:33 e.g. given {:one 1 :two 2}, calling (let-from-map my-map (...)), would give ... the bindings one = 1 and two = 2?

0:34 hiredman: I have thought about that, and fail to see a decent use case

0:35 just use (:one my-map) instead of one

0:35 eyeris: In this case, it'd would be (get-in my-map [:key-one :key two]), 4 times.

0:38 And, in this case, I am going to use every key in the map.

0:57 Knekk: can't make-array of structs?

1:01 eyeris: What about to-array?

1:05 Knekk: that seems to work

1:05 how do I make it a multidimensional array? :)

1:07 eyeris: What do you need a multi-dimensional array for?

1:07 hiredman: java does not have multi diemensional arrays

1:08 just arrays of arrays

1:08 Knekk: which is supported with make-array

1:08 maybe I am just doing to-array wrong.

1:09 oh, duh

1:10 got it

2:10 cataska: any tiny web library/framework for clojure recommended ?

2:11 grrrt: cataska: compojure is the most popular one

2:12 and there's Ring, if you want something smaller and lower level

2:16 cataska: grrrt: thx, i'll give them a try

2:28 grrrt: is there a function to test if something is a ref, similar to "var?" ?

2:29 hiredman: instaceof clojure.lang.IRef ?

2:30 grrrt: hmm I guess that will do yes. thanks!

2:30 slashus2: ,(instance? clojure.lang.IRef (ref 0))

2:30 clojurebot: true

2:48 bradford: is there some idiomatic way of wrapping macros in functions so they can be passed around?

9:25 AWizzArd: rhickey: When I have /hg/app/src/ in my classpath and also /hg/app/build/ into which I compile my app and then start a fresh repl and (use 'my.namespace), from which path will it then load? From the .class files or the .clj files?

9:26 Chouser: AWizzArd: whichever has a more recent mtime

9:32 Here's the logic for that: http://tinyurl.com/mqkfyd

9:35 AWizzArd: thx

10:21 laktek: Hi I got a problem in using clojure-contrib classes

10:22 Chouser: ok

10:22 laktek: I have included it in my class path

10:23 but yet when I do something like ((:import (clojure.contrib.server-socket))

10:23 it gives "java.lang.ClassNotFoundException: clojure.contrib.server-socket (NO_SOURCE_FILE:2)" error

10:23 What might be the problem?

10:24 Chouser: you're at a repl?

10:24 laktek: yes

10:24 Chouser: try: (require '[clojure.contrib.server-socket :as ss])

10:25 laktek: I use the following command to launch repl - java -cp $CLOJURE_JAR:$CONTRIB_JAR clojure.lang.Repl

10:25 and I have defined correct paths to Clojure and contrib jars

10:26 Chouser: try: (require '[clojure.contrib.server-socket :as ss])

10:26 laktek: it gives nil as output

10:27 how do I know whether it's loaded correctly?

10:27 Chouser: it worked! :-)

10:28 try (doc ss/create-server)

10:28 laktek: yeppee!!! it did really work!

10:28 :)

10:29 thanks so much Chouser!

10:29 btw, what is the difference with import and require?

10:29 Chouser: your classpath was fine. the problem was that :import only works in the ns macro. a stand-alond function call needs (import ...)

10:29 yes, that was the other problem

10:30 import is for getting a shorter name to a Java class.

10:30 laktek: so that means I need to require it first?

10:30 Chousuke: no.

10:30 Chouser: you can either say java.security.MessageDigest, or say (import 'java.security.MessageDigest) first and later just MessageDigest

10:30 Chousuke: the java classes in your classpath are always available.

10:31 but clojure stuff needs to be required first.

10:31 Chouser: or 'use'd

10:31 laktek: ah ok..so that means if it a general Java class such as IO i can use it without require or use?

10:32 Chousuke: yeah.

10:32 laktek: but for clojure specific stuff needs to be required?

10:32 cool..now I'm really getting it

10:32 Chousuke: actually, require and use don't *work* with java classes :)

10:32 they're just for clojure.

10:32 laktek: and in a case how can I use an external java library?

10:32 clojurebot:

10:33 Chousuke: laktek: just add it to your classpath

10:33 laktek: then it will be automatically available.

10:33 laktek: you'll just need to give its fully qualified name, unless you use import beforehand, like Chouser described.

10:33 laktek: cool..now I get it..

10:34 that convention anyhow doesn't apply to clojure namespaces right?

10:34 Chousuke: yeah

10:34 Clojure stuff is not automatically available because it needs to be "executed" on load.

10:34 unlike java classes.

10:34 laktek: ah right

10:34 because they are interpreted?

10:35 Chousuke: nah, it's compiled.

10:35 but if the namespace is not AOT-compiled, then clojure will compile it when you do a require or a use

10:36 I'm not sure what it does if the stuff is AOT-compiled, but that's an implementation detail anyway :

10:36 Chouser: clojure has namespace objects that keep track of all available vars in the namespace

10:36 to populate that list, you need to 'use' or 'require'

10:36 Chousuke: ah, right. namespaces are actual objects. :/

10:36 Chouser: Java simply doesn't provide a way to see all the available classes in a package

10:37 laktek: ah ok..so when I do a require what it does is generating the available functions and variables in that namespace?

10:38 Chouser: I'm not sure I'd use the word "generating", but that's roughly the idea, yes.

10:38 laktek: ok cool..

10:38 and another question

10:38 Chouser: it'll create the namespace object and intern the vars in it

10:38 laktek: ok

10:39 :require and :use is interchangeable?

10:39 Chouser: no

10:39 laktek: or are there any specific cases to use them?

10:39 Knekk: if I invoke the repl with a scriptname argument it runs the script... but does it run it under a different namespace? I am not seeing what I expect.

10:40 Chouser: there's a lot of overlap in what they do, but some options are available only in 'use'

10:40 on the other hand 'use's default behavior is not what I'd usually recommend.

10:40 Knekk: at the end of the script I call (run) which does some simple array manips and displays a JFrame... but it doesn't look like the array is modified

10:41 but it gets modified if I paste the command straight into the repl

10:41 Chousuke: you sure you're not trying to modify an immutable thing?

10:41 Chouser: laktek: These days I recommend: (ns my.ns.foo (:use [clojure.contrib.sql :as sql :only []]))

10:42 Chousuke: if you do (conj [1 2 3] 5) that won't actually modify [1 2 3] :P

10:42 Knekk: I am modifying an array

10:42 Chousuke: can you show the code?

10:42 laktek: Chouser: ok cool

10:42 Chouser: Knekk: are you using clojure.main or Script ?

10:42 Knekk: yeah, but I need to get off this train first :) I'll be back from the office in 15

10:43 Chouser: Neither of those rings a bell, so I am guessing that's part of my problem

10:44 Chouser: hm, they both seem to start you in the 'user' namespace

10:44 Knekk: back in a few.

10:44 Chouser: I thought one of them used to default to 'clojure.core', but I guess that's been fixed.

10:49 laktek: Chouser, Chousuke: thanks again for the help :)

10:58 Knekk: ok.. let's see.

11:05 Shall I paste here or to the paste board I don't remember the location of?

11:06 drewr: lisppaste8: url

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

11:08 achim: Knekk: the error you described sounds like you're doing side effects stuff within lazy seqs (maps, for, ...). the REPL will print those and thus force evaluation, running as a script will not

11:09 Knekk: achim: you are most likely right, and it's something that keeps tripping me

11:09 but wouldn't (aget ) force evaluation?

11:10 Chousuke: is it inside a (for...)? :)

11:10 lisppaste8: Knekk pasted "repl" at http://paste.lisp.org/display/83176

11:10 Knekk: http://paste.lisp.org/+1S6G

11:10 Chousuke: yeah, it's the for.

11:11 use (doseq) instead

11:11 Knekk: ah

11:11 Chousuke: in general, the do* functions are what you want to use if you're dealing with side-effects.

11:12 like manipulating arrays :)

11:13 (find-doc "side-effect") is probably useful

11:13 achim: for is not a looping construct but a list comprehension. the same thing maths has for sets (like { x^2 | x in N }), but for lists. they don't actually do anything, just define a sequence in an abstract way

11:14 Knekk: I getcha

11:14 I was under the mistaken impression that aget/aset would force the evaluation

11:15 thank you very much

11:15 Chousuke: lazy-seqs aren't smart enough to know when you're doing side-effecty stuff with their data :)

11:15 Knekk: lazy and apathetic is what they are

11:16 Chousuke: heh

11:17 is there a reason you're working with arrays though?

11:17 generally, you should avoid them

11:17 Knekk: I also have a vector implementation

11:18 I am dicking around so I can learn

11:18 Chousuke: that's valid

11:18 Knekk: I do want to maintain a large array of mutable data

11:19 with elements that'll be updated frequently

11:19 Chousuke: Honestly, working with arrays is probably easier from Java.

11:20 so if a vector + a ref is not fast enough for you, consider writing a java class to wrap your array and using that from clojure :)

11:21 Knekk: I'll add that to my list of things to try. I already tried a vectors of refs, which was not... speedy

11:24 Chousuke: and if you wrap your array in an object you can use the (locking) macro to keep it safe I guess. :)

11:30 Knekk: safe data is happy data

12:45 drewr: whoa, Chouser posted to his blog

12:45 oh, it was agriffis

12:45 anyway, n01se.net lives!

13:17 Chouser: drewr: heh

13:54 bpattison: I'm looking for a function that behaves similarly to map where it take [f coll init-value] where f is a function that takes [item prev-value] where item is an item out of coll and prev-value is the results of the previous invocation of f on the previous item, init-value is just the initial value to be sent to f -- does anyone know of such a function?

13:54 Chousuke: reduce

13:54 :P

13:54 danlarkin: haha

13:54 Chousuke: it is (reduce init coll) though

13:55 danlarkin: I love that... describing a function perfectly that already exists

13:55 a nice surprise

13:55 bpattison: reduce? excellent -- I'll take a look at that

13:55 technomancy: danlarkin: at least he asked instead of trying to implement it anew; that's what I often end up doing. =)

13:56 Chousuke: if you can find a functional programming language that *doesn't* have reduce as a standard function, I'd be interested :)

13:56 Chouser: bpattison: the fact that you're even asking that question shows you're really starting to "get" how to solve problems with high-level functions.

13:56 Chousuke: it's probably one of the first functions you'd implement when writing a standard library for functional programming :P

13:58 mauritslamers: question: is there a way to retain the intermediate values when using reduce and put them in a list?

13:58 Chousuke: there's a reductions function in contrib

13:58 mauritslamers: ah, thanks, I'll take a look at it :)

13:59 Chousuke: ~def reductions

14:00 kencausey: um, is it normal for clojurebot to tell everyone the answers to such things privately?

14:00 or maybe this IRC client (weechat) somehow does not like clojurebot's responses and so is failing to render it in the appropriate buffer

14:01 Chousuke: it uses a notice

14:01 not a private message.

14:01 your client is funky :)

14:01 kencausey: OK, that shows up in the server buffer here

14:01 there is no information on the appropriate channel in the response it seems

14:02 Chousuke: that's your client being funky.

14:02 as far as I know, NOTICE is the proper method for automatic responses.

14:02 actual messages are reserved for human chatter I guess.

14:03 though clojurebot breaks that rule sometimes :P

14:06 kencausey: Well, I'll just say I interact with other bots without that particular result and leave it at that

15:55 bhurt_: Stupid question of the day: is there something like javadoc for clojure?

15:55 replaca__: bhurt_: folks use doc strings in the function

15:56 bhurt_: but there's no inherent format for that

15:56 bhurt_: that you can use to generate html

15:56 bhurt_: I had thought doc comments were supposed to be short, just enough to remind you how to use the function when looking at it in the repl.

15:56 replaca__: but it is possible to generate html from namespaces pretty easily

15:57 bhurt_: well, they shouldn't be a book, but I think they should be fairly complete

15:57 in contrib we've been working on a system where folks doc their functions, but can provide longer doc with a wiki link

15:58 but that's just a metadata convention I made up

15:58 Chousuke: I think the :doc metadata is too restricted :/

15:58 it'd be useful to have a map of documentation attributes.

15:58 cemerick: heh, yeah, we've been down this road before :-)

15:59 Chousuke: if you had a map of doc data it could contain additional stuff without polluting the "main" metadata too much.

16:00 liebke: bhurt_: I use clojure.contrib.gen-html-docs to generate html from the doc strings

16:01 bhurt_: The problem with using html in doc strings is that it looks bad when you do (doc some-function) in the repl.

16:02 liebke: yeah, i don't use html in the doc strings because of that, but here's an example of what the generated html looks like: http://incanter.org/docs/api/

16:08 replaca__: yeah, I've been doing the stuff for contrib. (which is at github.com/tomfaulhaber/contrib-autodoc). It's in transition now, moving to github pages

16:08 one of the things I had to do was use <pre> for the docstrs

16:09 liebke: nice, <pre> would be very helpful

16:09 replaca__: liebke: I was looking at the incanter doc and thought it might benefit from my new autodoc

16:09 liebke: I think so

16:09 replaca__: I've got a couple of steps to go though, before it will be useful for other projects

16:10 I'll let you know when it is.

16:10 liebke: the formatting is great!

16:10 replaca__: liebke: btw, big props for incanter. I'm very excited about it.

16:10 liebke: thanks, I'll definitely switch to autodoc

16:10 thanks :)

16:11 replaca__: cool. The new version does everything "right" with HTML templates, enlive, etc.

16:11 so it will be easy to make html bundles as well as static web sites

16:11 (and even info files :-))

16:11 technomancy: wow, info files?

16:11 crazy talk. =)

16:12 replaca__: well, that's a later stage. but it should be easy, cause I've abstracted out building a big datastructure to describe what's going on so it's easy to go over that and produce whatever you want

16:12 liebke: that will be great

16:13 replaca__: liebke: cool, I'll keep you posted

16:13 technomancy: texinfo is a pretty crazy format though.

16:13 but I guess you're not doing a lot of fancy formatting

16:13 replaca__: technomancy: nah, but I haven't looked at texinfo in about 15 years, so we'll see :-)

16:14 technomancy: replaca__: 15 years ago it probably wouldn't have seemed so crazy. =)

16:15 * technomancy tried to write a texinfo export for Ruby's doc system and gave up, but more than half of that was because Ruby's doc system is insane.

16:15 replaca__: technomancy: yeah, the nice thing is that I've got the doc stuff on our side pretty well organized now. So all the craziness is on the target :-)

16:17 technomancy: yeah, having doc strings is _so_ much nicer than having to run another parse over the source.

16:17 replaca__: yup

16:17 technomancy: and having simply vars with strings attached to them is much simpler than Ruby's OOP model.

16:17 replaca__: and being able to add metadata

16:18 jackdempsey: technomancy: hey man, yt?

16:18 technomancy: jackdempsey: yeah, sure

16:18 replaca__: but I've reduced it to maps, keywords, and strings

16:18 clojurebot: maps are *AWESOME*

16:18 technomancy: what's up?

16:19 jackdempsey: playing with compojure a bit more

16:19 there's no such function as "param" right

16:19 its just params?

16:19 reason i ask, on your readme there's "(alter session assoc :name (param :name))"

16:19 technomancy: my readme?

16:19 jackdempsey: and param doesnt' seem to work for me

16:19 yeah sry, your fork of compojure:-)

16:19 clojurebot: compojure is a concise web framework inspired by Sinatra

16:19 jackdempsey: http://github.com/technomancy/compojure/tree/master

16:19 hahah

16:19 thx bot

16:20 technomancy: oh... don't trust my fork!

16:20 jackdempsey: i'm posting some json and doing something a bit wrong with params, so was just looking around

16:20 haha, ah ok

16:20 technomancy: I haven't used it since like January

16:20 jackdempsey: ah i see

16:20 your readme is so much nicer tho :-)

16:20 technomancy: heh; really?

16:21 jackdempsey: yeah, you actually ahve examples and stuff

16:21 weavejester should pull it in

16:21 technomancy: well not if the examples are out of date. =)

16:21 hiredman: I think the mainline was being rewritten to build on top of ring?

16:22 technomancy: the only thing I added to compojure was the html5 doctype. =)

16:22 hiredman: compojure.org is very, uh, sparse

16:23 jackdempsey: cool hiredman, looked at ring as well

16:23 will be interested to see where it goes

16:37 so 'show' from contrib shows info about the java aspect of something, right?

16:37 is there a way to take something, say a float, and see what methods i can call on it?

16:38 kind of thought that's what show was for but appears i was mistaken

16:38 clojure methods that is...just realized i can add a dot to the beginning of what i see from show and make the call to java which is useful...

16:49 technomancy: it's conventional to capitalize gen-classed java classes, right?

16:50 Chouser: I think so. I don't think - are allowed

16:57 hiredman: ,(Character/isJavaIdnetifierStart \-)

16:57 clojurebot: java.lang.IllegalArgumentException: No matching method: isJavaIdnetifierStart

16:57 hiredman: ,(Character/isJavaIdentifierStart \-)

16:57 clojurebot: false

16:58 hiredman: ,(Character/isJavaIdentifierPart \-)

16:58 clojurebot: false

16:58 hiredman: :|

16:59 jackdempsey: i have a function that alters a ref..."add-channel"...is it more common to put the do-sync inside that function or outside?

16:59 technomancy: jackdempsey: depends on what you need it to be synchronized with

16:59 jackdempsey: hmm ok

17:00 technomancy: (if you need unsynchronized mutability, use an atom instead of a ref)

17:00 jackdempsey: yeah, pretty simple scenario

17:00 (def *db* (ref {:channels #{}, :subscribers {}}))

17:00 just need to add to that on certain http requests

17:01 no deletes for now...so maybe an atom makes more sense then?

17:02 hmm, says atoms are for uncoordinated synchronous changes

17:02 just trying to get my terminology right :-)

17:02 technomancy: right; in those terms you need to ask if that change needs to be coordinated with others.

17:02 jackdempsey: yea, ok cool

17:03 yea i think the answer is a no then

17:06 probalby would be good to implement this with all three varieties..

17:07 back to the higher level question though, i think i see what you mean about what needs to be synched

17:07 if you have a couple pieces that all need to run in the same transaction, then a dosync around all three would be necessary

17:08 if i can do what i need inside one method that does a simple alter, and i'm just throwing a dosync in there to get it to work, maybe an atom could work as well....

17:09 technomancy: exactly; no need to pull in the STM if you don't need the promises it provides.

17:09 jackdempsey: yep.

17:10 ah, these rusty gears in my skull need oil. been a while since i've had to think. damn web development ;-)

17:12 technomancy: heh. well STM is a sexy tool. =)

17:15 jackdempsey: heh

17:20 achim: hi all!

17:20 given a class name (string), is there a way if that would resolve to a currently imported class?

17:21 ^ is there a way *to see* if that...

17:22 ah, plus the class name is unqualified

17:23 hiredman: ,(class (resolve (symbol "String")))

17:23 clojurebot: java.lang.Class

17:24 hiredman: ,(class (resolve (symbol "NotAString")))

17:24 clojurebot: nil

17:25 achim: hiredman: thanks!

17:50 technomancy: just committed functionality to swank-clojure to search the classpath for a class and insert import statements for it

17:50 feedback welcome: http://github.com/technomancy/swank-clojure/tree/master

17:50 hornbeck: nice

17:51 technomancy: it inserts a new import line every time you run it; not smart enough to combine them yet

17:52 durka421: awesome

17:52 technomancy: but it beats using unix find for .class files. =)

17:52 * durka421 plots to steal this functionality for vimclojure

17:53 technomancy: durka42: well I stole it from http://dishevelled.net/Generating-Clojure-import-lines-using-SLIME.html (after asking of course.)

17:54 durka42: indeed, he has something very similar to my "smuggler" in his user.clj code

18:57 Raynes: Holy shit. I just realized that after using XMonad for any length of time, I literally can't work with Compiz at all.

18:58 Chousuke: can't? :/

18:59 Raynes: I feel so out of it in Compiz.

18:59 Chousuke: is it like getting used to vimperator and becoming uncomfortable using any other browser on the planet?

19:00 Raynes: I guess...

19:01 Chousuke: I would like to dump firefox but so long as there's no Webkit-based vimperator clone for OS X I'm unable to do so :P

19:02 FF is good enough as of 3.5 anyway

19:49 drewr: have you guys tried running swank/start-server from outside emacs?

19:52 clojure.core/*3 is unbound

19:57 technomancy: drewr: thought about it. would love to hear if you figure it out. =)

20:00 drewr: it's odd because in dothread-keeping-clj where the expanded code generates the exception, *3 gets loaded as part of ns-publics

20:10 ah, got it

20:19 http://github.com/drewr/swank-clojure/commit/03158e47d9e8e18dfc5af9d61cd4f73cf7edfa36

20:20 think I'll redo that with a regexp instead

20:22 the asterisks just make it so ugly

20:24 http://github.com/drewr/swank-clojure/commit/99628e5f4ab9e46e4b8d30ad5380e96b86358e5a

20:29 mblinn: is there a way to do forward declarations in the ns or do you just use declare?

20:29 hmm

20:29 extra the in here

20:29 there

20:30 replaca__: mblinn: declare *is* the way to do forward decls

20:30 mblinn: this is a subject of constant discussion, but that's the way it is

20:31 mblinn: okay was just curious since you seem to be able to do all the other housekeeping type stuff in ns

20:31 thanks

20:42 technomancy: drewr: that code is a little weird

20:42 lots of unnecessary type hints

20:43 mblinn: that's not a bad idea; seems like it would look cleaner that way

20:43 mblinn: yeah it's a little cosmetic thing

20:47 drewr: technomancy: yep

20:48 JAS415: i get this error: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NullPointerException (repl-1:7)

20:48 is there any way to make it more descriptive

20:48 it really isn't helping me figure outwhat is going on

20:50 hiredman: you are doing something you shouldn't with nil

20:51 JAS415: sure that's reasonable

20:51 but like in CL i get a whole long stack trace

20:52 hiredman: oh

20:52 you want the full stacktrace

20:52 (.printStackTrace *e)

20:53 JAS415: ah sweet

20:53 that will make this much easier

20:57 technomancy: has anyone actually used the mstor library?

20:57 I don't mean anyone in here, I mean anyone anywhere...

20:59 durka42: JAS415: also, clojure.contrib.stacktrace/print-cause-trace

21:08 JAS415: very nice, exactly what i'm looking for

22:33 something: is there a way to get the string value of a keyword without colon? basically opposite of keyword

22:35 Chouser: ,(name :foo)

22:36 something: Chouser: ah, yes. thanks

22:41 kmartin: Hi, anyone know if there is a reason the function "reverse" is not lazy?

22:41 Chouser: kmartin: how could it be?

22:42 the first item it returns is the last of the input seq, so it's got to get to the last of the input seq first, which forces the whole thing.

22:43 gstamp: Anyone know of a decent web based IRC client? I'm behind a proxy here. I'm currently using http://webchat.freenode.net/ but it tends to hang silently.

22:43 kmartin: I was assuming that it could be done with a closure, but I see what you are saying. Thanks.

22:50 drewr: technomancy: ran into other problems

22:53 haven't figured out how these bindings work

23:11 technomancy: drewr: =\

23:20 lisppaste8: technomancy pasted "with-preserving-file macro" at http://paste.lisp.org/display/83209

23:20 technomancy: any idea why that macro fails when AOT'd but seems to work from the repl?

23:24 drewr: hm, similar issue I'm seeing with swank

23:25 mine's not with compilation though

23:26 Chouser: 'if' isn't a var (anymore)

23:27 durka42: ,if

23:27 in my repl that gives var unbound

23:29 Chouser: I get "Unable to resolve"

23:29 technomancy: Chouser: is the usage in that macro such that it expects it to be a var?

23:29 Chouser: (resolve 'if) returns nil

23:31 I don't see anything wrong with your usage, but exception seems to indicate it thought it was a var. or something. odd.

23:37 technomancy: it's gone now... I'm using the exact same code (checked in). =\

23:37 Chouser: maybe just needed a clean re-compile?

23:37 technomancy: I guess so

23:56 Knekk: can't get to the clojure google groups pages.. bleh

23:56 ah there we are

Logging service provided by n01se.net