#clojure log - Jun 27 2009

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

0:34 _hrrld`: I tried to post my first message to the google group today (about 4 hours ago) and it doesn't seem to have appeared. Is there often a delay?

0:34 Or perhaps was I blocked as spam?

0:34 samjr: Anyone using JavaFX with clojure yet?

0:35 codyK: long delays arent unusual

0:35 _hrrld`: codyK: Thanks, good to hear.

0:37 Chouser: _hrrld`: your first post is held until rhickey approves it manually

0:38 _hrrld`: Oh. I hope he likes it. ;)

0:38 codyK: single moderator? sounds like a lot of work . . .

0:38 duck1123: _hrrld`: aside from determining if it's spam, he doesn't really judge

0:40 Chouser: codyK: only for first post per user. no manual intervention after that.

0:40 rhickey has described it as "works well"

0:41 _hrrld`: Thanks for the insight.\

0:43 duck1123: the clojure list is busy enough. We don't need the spam.

0:45 codyK: 2,000 messages is more than I'd want to look at, but if it works well for him, that's cool

1:07 jjttjj: hmm anyone happen to know why every time I use (flush) it screws up my REPL and doesn't work

1:09 slashus2: jjttjj: What screws up again it?

1:11 jjttjj: whenever I use flush followed by read-line, the REPL just keeps giving me blank prompts no matter what I put in

1:12 like it just doesn't respond to my input

1:12 and I'm copying the ported PCL word for word

1:12 slashus2: Seems to work for me.

1:12 jjttjj: hmmm

1:13 well, on a related note, if the slime REPL just keeps taking input without giving the "user>" prompt, is there a way to break out of that without restarting slime?

1:14 slashus2: I don't use slime. Maybe your problem is with slime and not clojure with the flush.

1:14 jjttjj: hmm maybe, i'll check it out

1:19 ok yep it's slime

1:19 thanks

8:28 blbrown_win2: anyone here. I want to be able to launch a cloure environment from clojure in a thread. I guess this should be easy to do? and the other thread won't share any of the same namespaces?

9:18 yangsx: Can anyone help me understand this: (my-fun (first aseq)) gives me correct result, but (map my-fun aseq) gives NullPointerException: clojure.lang.LazySeq.sval(LazySeq.java:47)

9:54 rhickey: yangsx: could you paste a reproducing snippet?

10:14 yangsx: rhickey: thanks, just found my error: it's because my misunderstanding of if-let

10:14 rhickey: yangsx: ok

10:16 * rhickey is building open source version of Virtuoso: http://www.openlinksw.com/virtuoso/ - has anyone ever played with this?

10:21 yangsx: I still often assume CL's rule that empty sequence is nil/false and thought if-let will choose the other branch. That's a problem for me moving from CL to Clojure.

10:25 Jetien: hi, i couldn't find in the api how to convert a string to an int

10:25 Chousuke: Use java for that.

10:26 ,(Integer/parseInt "10")

10:26 clojurebot: 10

10:26 Jetien: thanks

10:26 * Jetien wonders why there isn't a macro for that yet...

10:27 Chousuke: the core lib avoids duplicating java functionality :)

10:28 Because of that, it helps to know the java standard library.

10:29 fortunately, it's quite well documented. :P

10:29 Jetien: mh i understand

10:29 but what does (num) do then?

10:30 Chousuke: ,(doc num)

10:30 clojurebot: "([x]); Coerce to Number"

10:30 Chousuke: hmm.

10:30 Jetien: yes i know, but what does this mean?

10:30 Chousuke: ,(class (num 4))

10:30 clojurebot: java.lang.Integer

10:30 Chousuke: ,(class (num "3"))

10:30 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

10:30 Jetien: that's what i tried

10:30 Chousuke: it's a cast, not a conversion.

10:31 Jetien: ah, okay

10:36 lisppaste8: danlei pasted "ansi2html" at http://paste.lisp.org/display/82611

10:36 danlei: hm, can someone tell me, why this won't work?

10:39 ansi-code-to-tag does its job, but ansi-to-html won't close all open tags, if the 0 ansi-code is in the string

10:39 in the /same/ sting. it works, if the enclosing tag is in another invocation of a-t-h

10:42 (the messed up character in the paste is a literal escape)

11:44 jackdempsey: has anyone written up a little something on metadata? it seems so simple....you have a symbol foo, and to get its meta data you can call (meta foo) or ^foo

11:44 but then when i get into looking at things like #^ i seem to trip myself up

11:44 like there's metadata for objects and metadata for the compiler

11:45 oops, heh, "objects"

11:46 duck1123: jackdempsey: chances are, you might be wanting with-meta if you want to attach metadata to your values

11:46 jackdempsey: i would expect after #^String foo that ^foo would show {:tag String} but it seems i'm definitely wrong there

11:46 duck1123: yep, read over that last night and that seems to be where i trip up

11:46 attaching metadata to values vs vars maybe?

11:47 i think i also need to review symbols, vars, values, and variables.....maybe sure i get all of it

11:48 rhickey: http://groups.google.com/group/clojure/msg/919455504c57659e

11:48 duck1123: it always bothered my that with-meta put the metadata at the end

11:49 jackdempsey: thanks rhickey that looks great, appreciate it

11:51 danlucraft: is there a fn to find the type of a struct?

11:53 duck1123: danlucraft: they're all structs, but the type of struct is not recorded

11:53 jackdempsey: hmm interesting

11:54 duck1123: I ran into that issue myself

11:54 I wanted to multimethod on struct type

11:54 danlucraft: duck1123: ah, ok. thanks.

11:54 jackdempsey: can we set! things with the bot here?

11:55 ,(set! *warn-on-reflection* true)

11:55 clojurebot: java.lang.IllegalStateException: Can't change/establish root binding of: *warn-on-reflection* with set

11:55 jackdempsey: k

11:55 danlei: what would be idiomatic clojure for something like this: (loop for (a b) on '(a 1 b 2 c 3) by #'cddr collect a collect (* b 2))? that is, processing every other element in a sequence, and returning it afterwards

11:55 kotarak: danlucraft: the usual approach is a type tag on the map itself or in the meta data.

11:55 jackdempsey: the #^ example in that email was interesting....that a reflection warning is shown when just (.length (identity foo))

11:55 but not when (.length #^String (identity foo))

11:56 kotarak: danlei: (map processor (take-nth 2 stuff))?

11:56 danlei: kotarak: I'll try. the expression i showed would return (a 2 b 4 ...

11:56 danlucraft: kotarak: well, I don't think metadata would make sense because I want them to be practically different objects

11:57 so I'll use a :type key I suppose

11:57 duck1123: ,(binding [*warn-on-reflection* true] (.length (identity "foo")))

11:57 clojurebot: 3

11:57 kotarak: ,(mapcat (fn [[a b]] [a (* b 2)]) (partition 2 (list :a 1 :b 2 :c 3)))

11:57 clojurebot: (:a 2 :b 4 :c 6)

11:58 danlei: kotarak: thanks

11:58 kotarak: ,(let [l (list :a 1 :b 2 :c 3)] (interleave (take-nth 2 l) (map #(* % 2) (take-nth 2 (rest l)))))

11:58 clojurebot: (:a 2 :b 4 :c 6)

11:58 kotarak: danlei: dunno which is better

11:58 fffej: is anyone looking at the ICFP contest in Clojure? I'm making slow (but steady!) progress here and wondered if anyone wanted to pool efforts!

11:59 danlei: hm, liked the first one better somehow :) ty

11:59 (partition was what I should have known ...)

12:19 jackdempsey: duck1123: thanks....why doesn't that warning surface

12:19 when not passing in #^String

12:19 (not even sure what that warning really means, but googling :-) )

12:25 Chouser: fffej: is it right now??

12:25 fffej: it's happening now yeah

12:26 I have some truly terrible Clojure code that implements the VM that it requires

12:26 Chouser: hmph. Well, I guess not. I was hoping to have a little time for the contest, but I don't think it'll happen this weekend.

12:33 danlei: is there a way to use partition like this: (partition 2 '[a 1 b 2 c]) -> ((a 1) (b 2) (c nil)) ?

12:35 otherwise, I'll just check, if the sequence's length is un-even, and append nil

12:35 Chousuke: danlei: not yet :)

12:35 danlei: Chousuke: ok, ty

12:36 Chousuke: danlei: partition will get padding in 1.1 though. there's an open bug on it.

12:36 danlei: Chousuke: very nice

12:37 Chousuke: but, *grumble* at google groups

12:37 it swallowed my reply :(

12:38 Chouser: partition with padding is in git master

12:38 (partition 2 2 [nil] '[a 1 b 2 c])

12:39 * danlei pulls

12:45 Chousuke: okay, what the hell

12:46 I'm not seeing my posts on the group :(

13:34 lisppaste8: danlei annotated #82611 "ansi2html" at http://paste.lisp.org/display/82611#1

13:35 danlei: anything unindiomatic in there?

13:36 especially, is an atom the way to go for *closing-tags*?

13:40 well, if nobody critisises

13:41 it's either perfect, or such a mess, that no one even tries to comment on it :)

13:48 Chousuke: m

13:48 hm

13:48 I'm pretty sure you could do away with the atoms

13:48 -s

13:52 danlei: how exactly? i tried with vars and set! but that gave me an error

13:54 like: can't change the root binding

13:55 Chousuke: well, I'm thinking of doing a reduce with an accumulator for the closing tags.

13:56 but I can't quite figure out how to modify the code to do that.

13:56 danlei: hm ... sounds nifty

14:07 Lau_of_DK: Good evening gentlemen

14:18 krumholt: Hello, can someone make a simple example of the difference between alter and commute?

14:20 Lau_of_DK: The difference is that multiple commutes to guarantee that they're executed in the sequence that they were evaluated, alter however protects the order

14:20 s/to/dont

14:33 Chousuke: danlei: do you have a test string I could use with that thing=

14:43 krumholt: thanks

14:45 danlei: Chousuke: sure, for example: (ansi-to-html "[1m[5mfoo[10mbar[0mbaz[37mqux") => "<b><blink>foobar</blink></b></font>baz<font color=white>qux" after that, (a-t-h "0mquux") => "</font>quux"

14:46 that is, in emacs, C-q ESC [ <code> m for the ansi-codes

14:52 hm ... that first </font> shouldn't be there, actually

14:54 ah, was left from a previous test.

14:56 Chousuke: okay

14:56 my version appears to work

14:56 * danlei is curious

14:57 danlei: just annotate my version, if you will

14:57 lisppaste8: Chousuke annotated #82611 "stateless" at http://paste.lisp.org/display/82611#2

14:57 Chousuke: it's not that much more readable but...

15:01 ansi-code-to-tag actually has a misleading name now. it returns a [text-accumulator closing-tags] pair

15:01 danlei: i see. takes a litte for me to grasp it, but It's an educating read

15:03 It'll take me some time, to get used to write in that style.

15:04 Chousuke: the reduce returns a pair of [text-chunks leftover-closing-tags] which are concatenated and then stringified

15:06 danlei: I see, and it's something I can learn from. If you saw that code in the wild, which version would be easier for you to read? Where do you see the advantages?

15:06 Chousuke: well, my version is a pure function

15:07 it won't have any mishaps with state like your atom-version did when you pasted your examples :)

15:07 otherwise, neither of them are particularly simple :P

15:07 danlei: well, the thing is: I want the function to keep state

15:07 because it is feed with strings from a socket

15:08 *fed

15:08 Chousuke: well, in that case you can remove the (str* ...) part from the ansi-to-html function

15:08 in which case it'll return a [text, closing-tags] accumulator which you can use as a starting value for another reduce

15:09 danlei: so you'd close over such a text, closing-tags pair?

15:10 I'll spend some time with your code to fully grasp it, it really is a good example for me

15:23 lisppaste8: Chousuke annotated #82611 "chopped up a bit" at http://paste.lisp.org/display/82611#3

15:23 Chousuke: danlei: ^^

15:24 danlei: Chousuke: :) was just hacking up on it :)

15:24 Chousuke: actually hm, chunk-string should have the two-argument version arglist reversed so it can be used with reduce

15:25 danlei: what I'm trying to do is have make-ansi-to-html-converter, letting it return a closure which keeps the context and can be fed with strings

15:25 Chousuke: then you could do (reduce chunk-string [[] '()] ["foo" "morefoo" "evenmorefoo"])

15:26 * danlei nods

15:26 Chousuke: but that'll still break if the strings are broken in a way that the regexp fails :/

15:27 but that was a problem with the original too :)

15:27 danlei: yes, it is

15:27 it's used in a mud client, btw

15:27 but, as of now, it's still pretty basic

15:28 Chousuke: it sounds like you ought to ensure that the full string is received before converting it to html

15:28 danlei: hm ...

15:29 Chousuke: or at least that it doesn't contain broken ansi sequences

15:29 that method will likely be simpler than hacking ansi-to-html to support broken sequences :)

15:29 danlei: yes, I do see the problem, but how should I know, when the string is "finished"?

15:30 Chousuke: that I suppose is a protocol problem :P

15:30 danlei: :)

15:31 anyway, I thank you for the time you spend doing your solution, it really is appreciated

15:31 Chousuke: no problem. it was fun anyway :)

15:31 finding functional solutions to stateful problems is always fun

15:31 danlei: I'll spend some more time with it, and later I'll decide, which version to include. somehow I like the idea of having a converter-maker :)

15:32 Chousuke: You should try to avoid state. your program is basically the definition of a function :)

15:32 danlei: about the protocol: at least, in most MUDs ansi-sequences are left to the magicians, so, if it fails, I'll know whom to blame :D

15:32 Chousuke: it gets input, processes it, and produces output

15:32 no need for state.

15:33 danlei: well, the state is there, but it's kept on the stack, isn't it?

15:33 Chousuke: well, it's "state", but it's not mutable :)

15:34 danlei: yes

15:34 one question, that also is important for me: which version will I be able to understand better, say, after two years

15:34 Chousuke: since you'll be doing IO you will have some mutable state too but you should isolate that from the actual processing logic

15:34 danlei: which is no criticism, but just a practical consideration

15:35 Chousuke: Heh, well, I'd bet on the functional version.

15:35 danlei: :)

15:35 Chousuke: mutable state always complicates things

15:35 you actually need to care about how a function affects it, instead of what its inputs and outputs are.

15:35 danlei: are you sure about the "always"?

15:35 Chousuke: yes. :)

15:36 sometimes you can't avoid it though :/

15:36 danlei: hm, I'm not. but I'm willing to change my opinion over time. In general, I am with you, but always is pretty often, innit? =)

15:36 Chousuke: well, yeah

15:37 danlei: at the moment, I'm taking it as a lesson. You provided another view at the problem, which I just solved, as I would have solved it in CL.

15:38 (more or less)

15:38 Chousuke: well, you basically used a mutable stack. I replaced it with an accumulator parameter

15:38 danlei: yes

15:39 Chousuke: though since you're doing parsing, you might want to take a look at fnparse

15:40 it's a third party library for writing functional parsers.

15:40 danlei: that's what I meant. Your version's state is encapsulated in the function itself, as the arguments of sucessive calls. In my version, state is kept at another place.

15:40 fnparse?

15:40 I'll check up on it

15:40 ty

15:41 Chousuke: danlei: the problem with your version is that there's no referential transparency. a previous call to your function may affect the following ones; something that you want to avoid

15:42 if you call your function twice with the same arguments, the results might not be the same.

15:42 danlei: in general, yes. if I make a make-converter, returning functions which close over the state, I have the re-invocability, and the encapsulation. I guess that would be a nice solution

15:43 Chousuke: it's not very idiomatic for clojure though :/

15:43 danlei: hm

15:43 why exactly?

15:43 Chousuke: well, your functions still encapsulate mutable state.

15:44 danlei: yes, but in a more encapsulated, "tidier" manner, I'd say

15:44 Chousuke: if you call make-converter, feed it a string, and then the same string again, the output may still differ, right?

15:44 danlei: like a little chunk of mess :)

15:44 yes, it's not a pure function, I agree

15:44 Chousuke: danlei: it's a lot like OOP :)

15:44 danlei: it's OOPs twin :)

15:45 whether the evil, or the good one :)

15:45 Chousuke: anyway, my general advice is to avoid any mutable state until you truly need it.

15:46 you simply won't need to care at all about what a function does if it's pure :)

15:46 duck1123: which one has the mustache? That's how you can tell

15:46 Chousuke: which is not the case if you encapsulate mutable state

15:47 danlei: you see, I do agree with you

15:47 I'm just not sure, if the generality of the statement applies

15:47 but who am I. we can discuss that again, when I'm more familiar with that style,

15:48 Chousuke: heh

15:48 danlei: until then, I'll have a bias toward things I do already understand well ;)

15:48 Chousuke: have you read http://clojure.org/state ?

15:48 danlei: yes, but it's been a while and I'll re-read it

15:48 but, for example:

15:49 if mutable state was generally wrong, why would rich allow it?

15:49 there seem to be situations, where it's just te better solution, don't you agree?

15:49 Chousuke: I'm sure you'll grow to appreciate functional style a great deal if you stick with Clojure. :)

15:49 danlei: (don't wanne be heretic)

15:49 Chousuke: danlei: well, yes. some things are inherently stateful

15:50 your ansicode->html transformer however, is inherently a functional problem.

15:50 danlei: point taken

15:51 for the most part, I already stick with functional solutions

15:52 Chousuke: the stateful part of your problem is the network IO, I suppose.

15:52 danlei: I guess it's been the problem at hand, which made me use a known solution ... habits :)

15:52 clojurebot: People have a problem and think "Hey! I'll use a regular expression!". Now they have two problems....

15:52 danlei: clojurebot: botsnack

15:52 clojurebot: thanks; that was delicious. (nom nom nom)

15:52 Chousuke: but if you isolate the transformation from the IO, I think you will have a much more robust program :)

15:52 duck1123: I don't have much experience with them, but would this be a good job for monads?

15:52 Chousuke: possibly.

15:53 I'm still not comfortable with monads though :/

15:53 danlei: are monads idiomatic style in clojure?

15:53 duck1123: I wish Programming Clojure had covered monads. Here's hoping for the next book

15:53 Chousuke: danlei: well, yes.

15:53 * danlei just knows them (a tiny wee bit) from haskell

15:53 Chousuke: danlei: monads are purely functional after all

15:53 Lau_of_DK: clojurebot: seen eyeris?

15:53 clojurebot: eyeris was last seen quiting IRC, 1242 minutes ago

15:55 danlei: I think I haven't even understood the basic principles of them. I know there used to keep side-effects and functional code separate.

15:55 but /how/, I don't know

15:55 Chousuke: danlei: though you don't *have* to use them -- unlike haskell -- because Clojure is impure, and you can separate stateful logic from functional logic simply with discipline

15:55 * danlei nods

15:55 duck1123: there was a good series on monads in clojure, but my head started spinning halfway through

15:56 danlei: at the google group?

15:57 duck1123: I think it was this one: http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/

15:57 perhaps I should try reading it again.

15:57 danlei: http://tinyurl.com/cfr9le

15:57 yes, just found it

15:58 thanks

15:58 going to be a tough read, I guess :)

15:58 I'll give it a try

16:01 (and have a look at that fnparse thing)

16:02 Chousuke: using the state monad you could rewrite the transformation functions so that the state (the accumulator) is encapsulated away, but still functional

16:03 that is, without resorting to atoms or other mutable state trickery :)

16:12 danlei: there is to much knowledge missing, right now. I'll have to read up on it ... But one further question: If you're so convinced of /pure/ functional code, what exactly keeps you using clojure, and not some language like haskell? (I, for one, have dabbled a little with it, but found it somehow ... just to "strict" for my taste. A subjective statement, I know ...)

16:14 (atm common lisp and clojure are the languages I prefer, and then there's a huge gap ...)

16:30 duck1123: personally, I don't like languages where indentation is significant

16:30 that was what turned me off to python as well

16:30 danlei: hm .. I think that's optional in haskell

16:32 duck1123: I've only read a little bit into Haskell. Seems like a decent language, but I'm happy with Clojure for the time being

16:32 fffej: it's funny how indentation isn't significant in Lisp, but everyone does it the same way anyway

16:32 danlei: you mean: emacs does it the same anyway =)

16:32 kencausey: yes, no more consistent than in most other languages

16:32 duck1123: right, I do whatever emacs does for me

16:33 Chousuke: fffej: indentation is very significant in lisp for readability though.

16:33 fffej: exactly my point

16:34 * eevar thinks clojure (and lisp in general, e.g. scheme) is great

16:34 fffej: (if indentation turns you off Python, it could turn you off lisp too)

16:34 Chousuke: I have noticed that instead of looking at the parentheses I get all the needed information from the indentation :P

16:34 the parentheses kind of disappear

16:34 eevar: wonder if i'm not missing out on something tho. there has to be a reason for why people use (oca/s)ml and haskell

16:34 danlei: I agree, lisp in general is great. But now, that there's clojure I find myself missing each others features in both of them :)

16:36 eevar: there are too many languages out there, and not enough time :/

16:36 duck1123: I like that (in clojure-mode at least) I have control over the "shape" of my code by deciding where i put the newlines

16:36 kencausey: sexps to the rescue

16:38 danlei: apropos features in cl/clojure ... is something like cl's debugger planned for clojure? that's one of the things I miss. (yes, know about the possibility to attach debuggers, but it's just not the same)

16:38 Chousuke: hmm :/

16:39 Chouser: danlei: I don't think rhickey plans to create such a thing, but it seems likely you could.

16:39 use the JVM debugger api (whatever that is) and just do it.

16:39 danlei: Chouser: I fear, I don't have the skills to tackle such a thing

16:40 duck1123: I've been wanting to try out cljdb, but I couldn't figure out how to get it working with maven

16:40 danlei: that'd be a fairly advanced project, I guess

16:40 not one of the things I can hack up in a few weeks

16:41 (one of the major problems my not really knowing java)

16:42 but in general, yes, I'd be willing to offer my work/time for such a project (with someones more knowledgeable by my side)

16:43 fffej: putting type hints in programs in annoying - would (in theory) it be possible to annotate functions with metadata about types (in Clojure core) and use type inference to insert the necessary casts automatically? It seems like it should from my basic understanding, but before I go off to read more about Hindley–Milner inference, I wondered if there were any holes in that plan?

16:45 danlei: would some of you guys be interested in such a project? (cl-like debugger for clojure)

16:47 Chouser: danlei: I must admit I've never used a cl-like debugger, so I only have a vague sense of what that means.

16:48 danlei: Chouser: well, you can select stack frames, see local vars, evaluate expressions within a stack-frame, and so on. everything built into the language itself. (you'd just have to fire up clisp or something and have a look)

16:48 Chouser: fffej: one issue to keep in mind is the dynamic nature of clojure programs. just because (defn foo [] 5) alreays returns an Integer right now does not mean it will throughout the life of the program.

16:48 fffej: chouser: thanks, that was the dose of reality I needed :)

16:48 danlei: and, of course, the error messages are a lot more telling than some java-related messages I get sometimes in clojure

16:49 but I'm not sure how to do that, without the condition system

16:49 you're offered different restarts (restartable conditions), which you can choose

16:49 Chouser: fffej: you're alreays (???) welcome.

16:54 danlei: in general, the debugger is a kind of global handler, which opens up, if a sent (error-)condition is not bound to a restart, or some other code which handles it. so in the debugger, you become somewhat a "human" handler, which can decide, what to do. you always can set up a handler in code, which knows, how to decide and restart the code further down the calls (where the restarts are set up for it)

16:55 if a condition is not handled in the code (via handler-bind for example), you'll have to do it "by hand", in the debugger

16:57 so the condition system, on top of which de debugger is the "last resort" is kind of a superset of java

16:57 *java's exceptions

16:57 (as far as I can tell)

17:01 . o O (now I've made them all fall asleep :)

17:02 Chouser: I wonder if the java debugger api (I say that as if I knew it existed) allows you to catch an exception at it's moment of creation such that it could be continued right there.

17:02 I wouldn't be surprised if the answer was "no", in which case the project may be doomed already. :-)

17:02 danlei: unfortunately, I have no idea (my java knowledge is very basic)

17:04 but, as I said, my offer stands: if someone wants to tackle it, I'll be glad to help (don't know how much that's worth though :) )

17:04 kotarak: Maybe one can modify throw (the Clojure one) to drop into a debugger.

17:07 danlei: the basic principle (don't think I formulated it well) are: a function which does something generally knows, how to back up in case of an error. let's say a read error: read another file, try reading same file again, enter values manually. then, further up the calls, it's known /how/ to handle best, which of the offered restarts would be best. the handler now chooses a restart, which fits. if there is no handler, which chooses in the

17:07 code, you'll drop into the debugger, and choose yourself. (think, that is a better explanation than the one above)

17:08 so there are three parts: the condition, the restart, and the handler

17:11 Chouser: danlei: much of that (not including the interactive debugger part) has been implemented in contrib.error-kit

17:11 duck1123: wasn't there a contrib library that was working towards something like this?

17:11 danlei: Chouser: thanks for the pointer

17:11 Chouser: ...though I'm not sure I endorse it anymore.

17:13 it's explicitly an attempt to provide (some of) the features of the CL conditions system, but I think in the process I brought over unnecessary baggage (esp. object-system related cruft).

17:13 danlei: (now I've collected pretty much stuff, that I'll have to have a look at today :)

17:14 well that's another discussion: If one /wants/ a cl-like condition-system and debugger

17:15 I, for one, find it pretty useful

17:17 but then, one can't have the cake and eat it too. there is a kinda long list of things, I would love to have in CL from clojure, and vice-versa. (keyword arguments in clojure, more general sequence abstractions in CL for example)

17:18 everything is somehow a compromise ...

17:18 duck1123: doesn't defk try to do the keyword argument thing?

17:19 danlei: for inclusion in core?

17:19 that'd be very nice to have IMHO

17:19 duck1123: IIRC, c.c.def/defk

17:20 haven't gotten around to using it yet, but I have a few functions where it might fit

17:20 danlei: you're not alone ;)

17:20 kotarak: defnk.

17:21 (defnk foo [a b c :x default-for-x :y default-for-y] ...) (foo some-a a-b another-c :y 5)

17:23 danlei: I'd love to see something like this in core ... Things like :from-end-t, :key, etc. are a nice thing to have, imho. you get used to it ;)

17:23 duck1123: I wonder though if using defnk might be overkill for what i needed

17:23 danlei: like ... garbage collection is overkill for most c-programmers? ;)

17:24 kotarak: duck1123: multi-arity also helps sometimes: (defn foo ([x] (foo x some-default-y)) ([x y] ...))

17:24 danlei: things like that shouldn't be done by hand everytime, I think

17:25 it's just sad, that many (if not all) of the discussion at c.l.l are rants, rants and ... more rants

17:25 duck1123: I did some pseudo-keyword arguments for my fork of clj-record

17:25 danlei: when both languages are actually so nice ...

17:26 kotarak: danlei: instead of wasting time with c.l.l one should program in CL or Clojure. That is a much better of the time...

17:27 danlei: well, I do, with my mud-client, for example (which is not that much, but some friends do actually use it) as far as c.l.l. goes: you really can learn an awful lot over there, but signal/noise is not that high, unfortunately

17:28 duck1123: Has anyone else found that since learning clojure they can't read a java book without mentally converting the code samples to clojure?

17:28 danlei: and the threads about clojure were especially disgusting, IMHO

17:30 dmiles_afk: danlei: i am working ona secondlife client that uses Clojure

17:30 duck1123: dmiles_afk: will it support opensim?

17:30 dmiles_afk: i presently test on OpenSim about 60% of the time

17:31 since there are little nits between them

17:31 danlei: dmiles_afk: very nice, atm, I've enough work with the text thingy (and learn a lot, for example the discussion with chosuke)

17:32 dmiles_afk: its funny.. i've one arround text and network things like openmemtavere.. it's funny the text one isnt much easier ;P

17:32 duck1123: dmiles_afk: do you have a public repository anywhere?

17:32 danlei: :)

17:33 dmiles_afk: duck1123: http://code.google.com/p/opensim4opencog/

17:33 duck1123: thanks

17:33 dmiles_afk: the clojure stuff: http://code.google.com/p/opensim4opencog/source/browse/trunk/bin/cogbot.lisp

17:34 setj = set, progn = block. i am trying to make the code feel more common lispy.. so been trying to avoid name conflicts

17:35 * danlei made himself a prog1 today

17:35 kotarak: danlei: the function or the macro version?

17:36 danlei: anyway, thanks for the discussions, guys. learned a little today. afk

17:36 duck1123: so do you CL'ers find much use for I think it was called PROGV?

17:36 danlei: kotarak: macro, quick and dirty

17:36 duck1123: there was a post on the things this guy didn't like about clojure, and the missing progv was one of them

17:37 danlei: duck1123: for interpreters, I think. haven't actually used it, besides for educational purposes.

17:37 duck1123: The only way I could think to do it in clojure was to use eval

17:37 dmiles_afk: i use ikvmc.exe to compile clojure.dll .. but for everyday testing i use DotLisp.dll (clojure's predicessor)

17:37 kotarak: duck1123: If it's the Var/pushThreadBindings thing: yes, I needed that already several times.

17:38 dmiles_afk: clojure on .NET i am hoping will be able to call events code

17:38 events are methodlists that you call one method.. but it fires to several methods

17:41 what .NET has on the JVM is the ValueTypes which is the deatch of many JVM languages

17:41 yet however everythiong .NET i've used is still much slower than JVM based things :)

17:42 thats not just mono.. its even win64.NET vs Sun

17:43 but i am not trying to bash one or the otehr.. its just JVMs only 7 valuetypes makes things harder in the long run

18:22 jackdempsey: just a general comment, but damn, there really are some practical features in closure

18:22 can tell it wasn't designed by committee in an ivory tower.

18:24 cgrand: quidnunc: haven't had time to check text-node before, it was plain broken. sorry :-(

18:25 quidnunc: (select (html-resource (java.io.StringReader. "<html><b>hello<abbr>wrld")) [:abbr :> text-node]) works now

18:31 quidnunc: cgrand: Thanks

18:34 I feel a little less stupid for not being able to get it working

18:37 durka42: is there like a map difference function?

18:38 as in, take this map and remove the key/value pairs where the keys are in this other map

18:38 that was not very articulate

18:38 (map-difference {:a 1 :b 2 :c 3} {:a 42 :c 1}) => {:b 2}

18:39 hmm, in writing out that example i realized this isn't the function i'm looking for...

18:40 duck11231: move along

18:40 opqdonut: :P

18:44 Chousuke: ,(reduce dissoc {:a 1 :b 2 :c 3} (keys {:a 3 :c 2})); anyway :)

18:44 clojurebot: {:b 2}

19:12 jackdempsey: hmm

19:13 is there another more union related way ? set algebra? cant' think of the words atm

19:14 Chouser: relational

19:14 jackdempsey: haha, whew, yes

19:14 * jackdempsey blames the ale

19:14 Chouser: :-)

19:15 jackdempsey: for differences?

19:15 jackdempsey: yep

19:16 the dissoc felt more like take this map and remove the elements with these keys

19:16 Chouser: there's clojure.set/difference, but that operates on sets

19:16 jackdempsey: gotcha yeah, makes sense there

19:17 Chouser: I think dissoc is exactly how you get a map with something removed. *shrug*

19:17 jackdempsey: i'm so used to thinking "hash" and with the function "map", thinking of maps always gets a bit backwards in my head

19:17 yep, no that makes sense, with difference for sets

19:53 bpattison: I want to "update" a value of a give key in a struct-map, is there a function that will allow me to do and return an updated copy of the original or do I need to reset all the values from the original?

19:54 drewr: ,(doc update-in)

19:54 clojurebot: "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created."

19:55 bpattison: drewr: excellent -- thanks

19:56 drewr: ,(update-in {:foo {:bar {:baz 1}}} [:foo :bar :baz] inc)

19:56 clojurebot: {:foo {:bar {:baz 2}}}

19:57 drewr: ,(update-in {} [:foo :bar :baz] #(or % (inc %)))

19:57 clojurebot: java.lang.NullPointerException

19:57 duck1123: assoc should also work if the value is at the top

19:58 Chousuke: hmm

19:58 bpattison: yeah, its just a simple struct-map

19:58 Chousuke: ,(update-in {} [:foo :bar] (fn [] 1))

19:58 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--4429$fn

19:58 Chousuke: ,(update-in {} [:foo :bar] (fn [_] 1))

19:58 clojurebot: {:foo {:bar 1}}

19:59 Chousuke: ah, right, you should've used and, not or :)

20:01 bpattison: I guess I was looking for something like (setter gc :x (inc x 1)) where gc is a struct-map

20:02 Chousuke: that's not really a "setter"

20:02 since it doesn't modify anything :)

20:02 bpattison: sure -- but something that acts like a setter

20:02 Chousuke: well, update-in works

20:03 or just assoc

20:03 bpattison: okay, I'll give those a try

20:04 yep, assoc works perfectly

20:04 Chousuke: structmaps are just normal maps that you can generate optimised getters for

20:04 there's usually no reason to use them at all.

20:04 still for some reason, they're popular

20:05 I guess the structmap base key definition has documentation value, but... :)

20:06 bpattison: well that's why I used it -- the "struct" has meaning

20:07 plus, doesn't it provide a defined hash structure that get's defaulted if key values aren't initialized?

20:07 Chousuke: it's no different from a map

20:07 (:foo {})

20:07 ,(:foo {})

20:07 clojurebot: nil

20:07 Chousuke: same happens with a struct map

20:08 I suppose the other nice thing about struct maps is that you can create them with (struct foo some vals here)

20:10 but that may actually be less readable than explicitly specifying the keys

20:10 though it saves a bit of typing

20:38 Mark_Addleman: hi, i've got a question about walking parallel lists using for... suppose i've got two lists, a and b. a=[1 2 3] and b=[a b c]. i want to walk them in parallel (not nested) using a list comprehension. something like (for [x a, y b] (x y)) -> (1 a 2 b 3 c)

20:39 i don't know how to construct the binding to do anything other than nesting. i thought about a function to interpose elements of a with b, but i couldn't find a core/contrib function to do that

20:39 Chousuke: interleave

20:39 durka42: ,(map list [1 2 3] '[a b c])

20:39 clojurebot: ((1 a) (2 b) (3 c))

20:39 Chousuke: for can't do parallel walking

20:39 (doc interleave)

20:39 clojurebot: "([& colls]); Returns a lazy seq of the first item in each coll, then the second etc."

20:40 Mark_Addleman: ah, that's perfect. thanks!

20:57 durka42: ,(with-out-str (.write *out* 65) (.write *out* 0) (.write *out* 66))

20:57 clojurebot: "A

20:57 durka42: ^ is this a bug?

21:01 kyle_burton: question re: serializatino of object graphs with both clojure and java data types in them - I'm sure there is logic behind it, does anyone know the ratinoale for keywords (:foo) not being serializable?

21:02 Chouser: durka42: I think that's an encoding thing

21:03 character encoding

21:03 durka42: but why did it never print the closing quote?

21:06 Chouser: durka42: I'm not sure yet, but the \0 code must be telling it somehow that the " should not be printed. The final \n as well, in my tests.

21:07 no, I'm wrong.

21:07 ,"a\000bcdefghijkl"

21:07 clojurebot: "a

21:48 dreish: That prints as "a^@b" in my Aquamacs.

21:49 Chouser: dreish: that sounds better than what I see

21:49 dreish: What are you using to run your repl?

21:50 I've got Aquamacs, a fairly recent 1.1.0 alpha, and Java 1.6.

21:51 Chouser: ah, rlwrap changes things

21:51 dreish: And I'm using Inferior Lisp.

21:52 durka42: grumble grumble

21:53 why doesn't dataoutputstream use overloading

21:54 Chouser: just java on a linux command-line...

21:55 (print "a\000bcdef\000ghi") ==> abcdefghinil

21:55 oh, the nil is the return value

21:55 so the nil chars are just ignored

21:55 dreish: Well, they're non-printing.

21:55 Chouser: indeed

21:55 dreish: Same with any other language.

21:56 Chouser: (prn "a\000bcdefghij") ==> "abcdefghij"

21:56 durka42: i guess somewhere between sockets, nailgun, vim and vimclojure somebody stops on nulls

21:57 dreish: perl -e 'print "a\x00b\n"' => ab

21:58 Chouser: adding rlwrap causes it to stop after at the null char

22:06 it would be nice if null string printed an escaped form, line \newline does

22:07 dreish: Same with the various other non-printing chars, like 1, 2, etc.

22:08 Chouser: yeah. there are a few, but more would be better

22:08 dreish: ,(char 2)

22:08 clojurebot: \

22:08 Chouser: ,(pr-str (char 12))

22:08 clojurebot: "\\formfeed"

22:10 Chouser: "\f"

22:10 ,"\f"

22:10 clojurebot: "\f"

22:10 Chouser: ,(nth "\f" 0)

22:10 clojurebot: \formfeed

22:48 Mark_Addleman: hi, i've got a question using destructuring in a for macro. (for [[a b c] [1 2 3]] nil) -> "java.lang.UnsupportedOperationException: nth not supported on this type: Integer"

22:48 i'm trying to get a binding of 1->a, 2->b, 3->c. it seems to work in let, but not for

22:49 Chouser: right, because for destructures each item in the seq

22:49 not the whole seq

22:50 ,(for [[a b c] [[1 2 3] [4 5 6]]] b)

22:50 clojurebot: (2 5)

22:50 Mark_Addleman: i'm struggling to understand what that means... does that imply (for [[a b c] [[1 2 3]...) ?

22:50 ah, i think i got it

22:57 ok, this is coming to me slowly (sometimes agonizingly!). i have two lists: a list of database tables and another,parallel list, of primary keys. i want to walk the lists in parallel so i get a pairing of table & primary key. how can i do this?

22:58 ,(for [[t pkey] [[:t1-table :t2-table] [:t1-pkey :t2-pkey]]] [t pkey])

22:58 clojurebot: ([:t1-table :t2-table] [:t1-pkey :t2-pkey])

22:58 Mark_Addleman: i want ([:t1-table :t1-pkey] [:t2-table :t2-pkey])

23:04 Chouser: 'for' can't do it by itself

23:06 Mark_Addleman: i'm not wedded to for :) is there a parallel list walking function in the core library or in contrib? I couldn't find one. i found "walk" but that doesn't seem to do what i want either

23:06 Chouser: map

23:06 ,(for [[a b] (map vector [1 2 3 4] [5 6 7 8])] {:a a, :b b})

23:06 clojurebot: ({:a 1, :b 5} {:a 2, :b 6} {:a 3, :b 7} {:a 4, :b 8})

23:08 Chouser: ,(map + [1 2 3 4] [5 6 7 8])

23:08 clojurebot: (6 8 10 12)

23:09 Mark_Addleman: ok. i get it. it would have taken me a long time to come up with that on my own. thanks

23:10 i'm at the neophyte stage: i understand the little bits but not how to put them together in interesting ways yet

23:10 anyway, thanks for the pointer

23:10 Chouser: not a problem

23:10 it's fun stage but won't last long. :-)

23:13 Mark_Addleman: i hope not! right now, i'm pushing myself through the frustration. the examples on the forum as well as this channel have been enormously helpful

23:38 agc: hello

Logging service provided by n01se.net