#clojure logs

2009-12-26

08:35hchbawどこかを参考にしていたのですけれども、どこを参考にしていたのか忘れた!
08:35hchbawOh! I'm very sorry. :)
08:36chouserooh, your exclemation point looks much nicer than mine.
08:57hchbawJust a FYI, http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06789-1
08:57hchbaw"Programming Clojure" Japanese edition :)
08:58hchbawI would like to buy it, thanks!
09:16emacsenhchbaw, I think that if they translate it back to English, it will be very popular
09:16emacsenafter the Japanese translation it has all those cartoon high school girls
09:56emacsenliebke: morning
09:57liebkeemacsen: good morning
09:57emacsenliebke, where in DC are you?
09:58liebkeI'm a few miles outside of DC in MD, up in the Silver Spring area
09:58emacsenOh. I'm right downtown
09:58emacsen(downtown SS)
09:58emacsenI was thinking of heading to the Wheaton Maul later
09:59emacsenIt's too bad no one's taken up Conrad's request to run FringeDC
10:01liebkeyeah, it's also too bad that dc study group has been inactive
10:02emacsenliebke, well you can revive it :)
10:02emacsenMichael and I have been busy, but if you took it over, I'd help again
10:04liebkeI'm hoping the new Reston group will get some momentum.
10:04emacsentoo far for my blood :)
10:05liebke DC and Reston are equally inconvenient locations for me
11:07neotykHi
11:07samlhi neotyk
11:07samlhow are you doing?
11:08neotykI'm good, how are you?
11:08samlI am ok. Thank you
11:09neotykIf in silme repl I do (use '(ns-name mod)) I get error that file not found
11:09neotykhow do I specify path for swank?
11:10the-kennyneotyk: It's the java classpath.
11:11neotykthe-kenny: ok, but how do I set it?
11:11bagucodeIs there anyone in here that knows a lot about java bytecode generation with the asm lib?
11:12the-kennyneotyk: Either with -cp.. at the command line or some config-variable in emacs
11:12the-kennyswank-clojure-classpath or so
11:12the-kennyHave to go, sorry
11:12the-kennySee you later
11:12neotykthe-kenny: thanks
11:16chouserbagucode: I've done a little bit with it, what are you trying to do?
11:20bagucodechouser: I'm interested in making a clojure wrapper for JNA (I know you made a small one already :)) and I want it to be as fast as possible. JNA supports something called "direct call mapping" but that requires static initializer code and use of the native keyword. So I was thinking of using clojure.asm to generate interface classes. But I don't know if the native keyword is supported by asm or even if it's necessary for JNA to work. I'm
11:20bagucodedoing a little research at the moment.
11:22bagucodechouser: the approach you used is easy, but it's slower and a bit unsafe if you get the parameters wrong.
11:23hiredmanasm does have a method modifier ACC_NATIVE
11:24bagucodehiredman: cool, thanks
11:24bagucodeI did a search of the manual but didn't find anything. Couldn't be bothered to read the whole thing :P
11:24hiredmanOpcodes.java
11:26bagucodeAnd the static initializer of a java class is just a static method with the name clinit right?
11:26hiredmansounds plausable, but I don't know
11:27bagucodehiredman: Alright, thanks a bunch for finding the ACC_NATIVE thing. I guess I can give this a go then.
11:38erikpriceI'm getting a ClassNotFoundException when trying to compile a trivial Clojure file via the compile function in the REPL. I think my classpath is fine because I can run the file directly as a script at the command line. Any ideas?
11:41somniumerikprice: check *compile-path*
11:43erikpricesomnium: Thanks. It was set to "classes" so I (set! *compile-path* ".") and retried the compile. Must be making progress because I no longer get an error, although the call to compile hasn't returned yet.
11:48erikpriceInteresting. Ctrl-D stopped whatever was hanging the REPL and showed that the problem was a NoSuchElementException on a line in which I was calling a function directly in the Clojure file. Commenting out that line allowed it to finish compiling. Thanks!
11:49joshua-choiAnyone here good at monads? I'm trying to create a monad operation (m-repeat pred m) that is like m-seq except in that it repeats a single monadic value until the result fulfills the predicate. But I'm stuck.
11:49somniumjoshua-choi: try #haskell :P
11:50joshua-choiHa ha, I can't understand Haskell at all, unfortunately
11:50joshua-choiI only understand monads in Clojure :)
11:55somniumjoshua-choi: I think Im still two or three tutorial (re)reads away from getting m-seq
11:55joshua-choiI was lucky in that I found monads at exactly the right time for myself
11:55joshua-choiI was trying to write a parser library, and monads turned out to be perfect
11:56joshua-choiI found it much easier thinking in terms of let and for, the two built-in Clojure monads
11:56technomancythere's never really a good time for it =)
11:56somniumjoshua-choi: is there anything you need them for that you cant do with ->/->>/comp, do, and a macro or two?
11:57joshua-choiFor my parser library, yes
11:57joshua-choiAnd I'm sure for other things too
11:57joshua-choiBut the most useful usage of monads for me by far is the domonad form
11:57somniumjoshua-choi: hmm, Id like to learn about the details
12:00somniumjoshua-choi: can you recommend any detailed explanations of the monad laws? (I only found an utterly incomprehensible haskell page)
12:00notostracaWarm Fuzzy Things
12:00joshua-choiThe monad laws? I only pay attention to them when I need to, which is only when I'm creating a new monad that has m-zero and/or m-plus
12:01joshua-choiThey're important, but I suggest that you try to get what monads are good for first; the laws are more petty practically in my opinion
12:02joshua-choiMy parser library uses monads like this: a "parser" is essentially a function that takes a sequence of tokens and returns two things: a new sequence of tokens with some tokens at the front consumed, and a data structure representing the consumed tokens
12:02somniumjoshua-choi: all the tutorials Ive seen seem to show uses that are trivial without them
12:03joshua-choiWell, probably without m-zero and m-plus
12:03joshua-choiI forgot: are there laws that involve just m-bind and m-result too?
12:03somniumjoshua-choi: Ive been writing compiler, but I just pass a map up a recursive chain
12:03joshua-choiYeah, you can do that
12:03notostracamaybe asking this in #haskell is a good idea
12:04somniumjoshua-choi: I dont know, but it bothered me that the associative property made no sense to me
12:04joshua-choinotostraca: Well, I'm kind of afraid; I don't understand Haskell at all, so they might be annoyed at some non-Haskell person asking them questions
12:04joshua-choisomnium: What do you mean by the associative property?
12:04notostracathey weren't annoyed when i tried to learn it
12:05somniumjoshua-choi: theres probably some graduate students who will be to discuss monads in #haskell
12:05somniumwill be delighted
12:05somniumjoshua-choi: I think its the third LAW OF MONADS
12:07joshua-choiYeah...it's "(m-bind (m-bind mv f) g) is equal to (m-bind mv (fn [x] (m-bind (f x) g)))" from Intensive System's tutorial
12:07joshua-choiYeah, I don't think about that at all
12:07joshua-choiI'm sure there's some theory behind the law that has a good, non-arbitrary reason for it
12:09joshua-choiBut I find that I usually don't need to care about it to use (or even create) monads, as long as I'm using (or carefully altering) already made monads
12:09joshua-choiI don't think you should worry about the laws for now; are they the only things hindering you?
12:10somniumjoshua-choi: I think if I believed that I understood the algebra I would have an easier time
12:11joshua-choiWell, you'd probably have a deeper understanding, but I found that they're not necessary; I think of them as just axioms that monads happen to have to fulfill, or else monadic operations don't work on them
12:11joshua-choi(not necessary to work through, I mean)
12:11somniumjoshua-choi: clojure made much more sense to me once I understood exactly what fn* let* and var meant, but I suppose thats different
12:12joshua-choiYeah, I still don't know what fn* and let* do
12:12somniumuseless fact:
12:12somnium,(macroexpand '(fn [] :x))
12:12clojurebot(fn* ([] :x))
12:13joshua-choiOh, I see
12:13somnium,(macroexpand #(keyword 'x))
12:13hiredmanfn* is the primitive
12:13clojurebot#<sandbox$eval__4654$fn__4656 sandbox$eval__4654$fn__4656@19a83f3>
12:13joshua-choiI was under the impression than fn and let were considered special forms
12:13Chousukethey are.
12:13somnium,(macroexpand '#(keyword 'x))
12:13clojurebot(fn* [] (keyword (quote x)))
12:13Chousukethe real special forms are fn* and let* but that's just a detail :P
12:13joshua-choiI see
12:14joshua-choiIncidentally, which form implements the unpacking of parameter vectors: fn* or let*? I've always wondered
12:14somniumIm curious as to why #() expands different than single arity (fn [])
12:15somniumif its intentional or accidental
12:15joshua-choi,(macroexpand '#())
12:15clojurebot(fn* [] ())
12:15hiredman~#()
12:15clojurebot#() is not a replacement for fn
12:16somniumhiredman: that wasnt the question :)
12:16somniumhiredman: my js compiler is almost done, and the different expansions caused some odd behavior before I noticed them
12:19somniumargh, and Ive seen the #([1 2 3]) mistake so many times...
12:19hiredmanif #() didn't expand the way it does you would have to double wrap everthing
12:20hiredman#(first x) v. #((first x))
12:20somniumyeah, for some reason I just saw fn* and assumed they would be the same
12:21somniumis that behavior of fn* documented anywhere?
12:21somnium(fn* [] ()) vs (fn* ([] ()) ?
12:22somnium,(doc fn)
12:22clojurebot"([& sigs]); (fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+) params => positional-params* , or positional-params* & next-param positional-param => binding-form next-param => binding-form name => symbol Defines a function"
12:30chousersomnium: no, "fn*" is an internal detail -- intentionally undocumented.
12:31chouserjoshua-choi: neither fn* nor let* implement destructuring.
12:31joshua-choichouser: Where, then? I couldn't find it whenever I looked at the source
12:31chouserdestructure is a Clojure fn used by both the 'fn' and 'let' macros
12:32joshua-choiI see
12:32chouserI think. I'm seeing it in 'let' anyway.
12:33somnium,(macroexpand '(let [[x y] [1 2]] {:keys [a b]} {:a 1 :b 2}))
12:33clojurebot(let* [vec__4682 [1 2] x (clojure.core/nth vec__4682 0 nil) y (clojure.core/nth vec__4682 1 nil)] {:keys [a b]} {:a 1, :b 2})
12:34chouseroh, I see -- 'fn' jsut detects that destructuring is required and expands to use 'let'
12:36somniumchouser: are there any examples of the core datastructures with deftype/defprotocol?
12:39somniumsomething like (deftype Cons [first more]) (deftype List [head size]) seems a reasonable start, but it would be good to seen an implementation by an experienced lisper
12:42drewrsomnium: clojure doesn't have cons cells, but I was doing something similar a few weeks ago http://gist.github.com/248466
12:44chouserClojure has a couple things very very close to a cons cell.
12:44somnium,clojure.lang.Cons
12:44clojurebotclojure.lang.Cons
12:44chouserright, like that. :-)
12:45chouser,(clojure.lang.Cons. :foo nil)
12:45clojurebot(:foo)
12:45drewrthat's an abstration on top of seqs
12:46drewrbut I see that somnium never really mentioned "cons cell" so I'll drop it :-)
12:48rlbSince java/clojure represents filenames as (utf-16) strings, what happens if the filename can't be represented as a valid utf-16 sequence?
12:49chouserrlb: is there such a filename?
12:49rlbi.e. in linux, filenames are arbitrary byte sequences
12:49rlbchouser: sure.
12:49rlbchouser: you can create any file name you want
12:50rlb(and there's also no way for java to know how to convert it to utf-16)
12:50rlbi.e. the filesystem doesn't have anything like a source encoding
12:50rlb(for names)
12:50chouserrlb: try it and let us know what happens. :-)
12:50rlbheh
12:51rlbchouser: the "correct" representation for a filename is probably a raw byte array, but that's not what java does afaik.
12:51chouserI think you may find any filename can be encoded into a Java string, even if it's not a "correct" translation. As long as the results are legal utf-16 and can be accurately translated back to filesystem filename bytes, you should be all set.
12:52rlbchouser: but some byte seqences won't be legal utf-16...
12:53chouserbut what byte sequence can't be converted to legal utf-16?
12:53rlbchouser: I suppose there could be some escaping/unescaping, but how would java know the fs was in, say big5 rather than utf-8?
12:53chouserthat's what I meant by it may not be "correct"
12:53somnium drewr: did you try using your implementation for map/filter et. all?
12:55rlbchouser: ahh, so you just mean that java may just assume that the fs is in a given encoding, say utf-8, and then perform the conversion. As long as the conversion is reversable, and you don't care which utf-16 strings you get, you may be all set.
12:55chouserright, though probably not utf-8 since there byte sequences that are invalid utf-8
12:55rlbchouser: That may be fine, as long as it's always possible to create *some* reversable valid utf-16 string from an arbitrary byte sequence.
12:55chouserright
12:56chouserbut this is all speculation on my part
12:56rlbchouser: well, java's going to have to assume some encoding for the source, and I imagine the default is utf-8 (or something locale based).
12:56rlbsounds like a mess...
12:57drewrsomnium: no, it was more a foray into mimicking haskell's type classes
12:57rlbNo wonder you don't see many lower-level java "utility" programs (i.e. backup/restore, etc.)
12:57chouserare you sure filesystems can't report an encoding for their filenames?
12:58drewrsomnium: but the example I was porting was illustrating recursion in type classes so it didn't really translate
12:58rlbchouser: most of the ones I know consider that an application layer issue.
12:58rlbchouser: the "official" type for a filename is "array of byte".
12:59rlbchouser: could be anything (except perhaps null).
12:59rlb(not sure about null)
13:00rlbAt least for POSIX, it's dirent/opendir/readdir.
13:00rlbchouser: anyway, thanks for the help.
13:01rlbclojure doesn't have anything like a read/write syntax for arrays of bytes, does it?
13:01chouserrlb: into-array, aset, aget
13:01somniumrelated to seqs, what precisely is the difference between rest and next?
13:02somniumother that nil on '()?
13:02chouserthat's it
13:02chouserin order to return nil instead of (), 'next' has to force an extra step of the lazy seq than 'rest' does.
13:04somniumare force and delay used to implement sazy seq
13:04somnium/s/sazy/lazy
13:04chousernope
13:05rlbchouser: ok, right. Though for this purpose, I'd love something like "od -t a" where anything that was ascii was shown as a char, and other things were escaped, but I know that's a bit special-purpose. I think guile may do something like that i.e. "foo\005\001bar".
13:05chouserlazy-seq has what amounts to direct compiler support.
13:05chouserrlb: oh, I see what you meant by "syntax". There's no byte-array literal.
13:06rlbchouser: right, I figured there wasn't. Thanks.
13:06chouseror char-array, for that matter.
13:07somniumchouser: are there any usages of force/delay in the wild? the doc strings made me think of a contract for lazy seq
13:08rlbSeems like there are a number of practical things that java (and by extension clojure) would need before it could realistically be considered as a natural language for system use (a la perl/python/whatever). Though that just may not be a goal.
13:09chousersomnium: I used force/delay in finger-trees. I think cemerick has used them a bunch too.
13:10chouserrlb: mostly things that could be supported by libraries, though. swig and jna both attempt to solve several related problems while trying to provide easy access to C libs.
13:10rlbIn this case, I wonder if the java posix lib might handle the filenames appropriately -- have to check.
13:12rlbchouser: true, though I just meant that (for example), in all the other languages, you immediately have getenv, the ability to see symlinks (at all), etc.
13:13chouseryeah, java has apparently tried hard to remove low level access to the host platform.
13:13chouserI'm sure they had their reasons, though I can't imagine I'd find them convincing.
13:13rysportability? :p
13:14chouserfortunately, jni was included and lets you work around those restrictions, and jna+clojure can pretty up the interface quite well.
13:14chouserrys: it's one thing to support writing portable code, another to try to enforce it (yet while leaving back doors like jni).
13:15rlbchouser: I certainly don't -- that stuff should just be optional, and have feature tests, or similar.
13:16rlb(don't find them convincing)
13:16rlbhmm -- hadn't seen jtux - that might be interesting...
13:16chouserrlb: I'd recommend jna instead
13:17chouserthe posix and posix-like java libs I've tried so far have been hard to build and deploy, poorly documented, and poorly maintained compared to jna.
13:18chouser~jna?
13:18clojurebotclojure-jna is http://github.com/Chouser/clojure-jna/tree/master
13:18chouserand apparently bagucode is working on something even better.
13:21rlbchouser: hmm, I'll have to look at that -- though I'm always a bit wary of the dynamic invocation stuff, presuming you have to hard-code the function sigs.
13:21rlbmove from one arch to another... boom.
13:21chouseryeah, good point.
13:21rlbi386 -> amd64, etc.
13:22rlb(insensitivity to compiler defines, etc.) -- at least with jni/swig, the compilation step handles all that
13:22chouserbut again, JNA is likely to have addressed common problems -- it's been a while since I looked at it.
13:22rlb(but it's much more tedious)
13:23rlbor unwieldy, rather -- to have to build the shared-libs, per-platform, etc.
13:23rlbAnyway, for my purposes, all really want a bulletproof subset of posix.
13:26bagucoderlb, chouser: Looks like the JNA folks got the native type size differences covered https://jna.dev.java.net/javadoc/com/sun/jna/NativeLong.html
13:29bagucoderlb: To get it right every time using clojure-jna you may just need to pick which native lib to load depending on what (System/getProperty "system.arch") reports. You can bundle your app with many different native libs, one for each supported platform and architecture.
13:32joshua-choiIs there a function f so that (f [1 2 3] [5 7 2]) is the same as (for [x [1 2 3], y [5 7 2]] (list x y))?
13:35rlbbagucode: nice, though you can still have trouble figuring out what the right type is if there are a lot of header #ifdefs, etc. (and if they can vary per compilation).
13:36rlbbut still -- it's interesting
13:49KirinDaveMan, reading blogs on clojure by Java programmers is a tooth-grinding experience.
13:50KirinDaveReading things like, "clojure removes a few constructs which make “sense” (for loops for example)"
13:50KirinDavegrind grind grind someone-wrong-on-the-internet grind grind.
13:50pdk`i like how "sense" is quoted
13:51tolstoyDoes that mean it makes sense to remove them, or that clojure removes them, even though they make sense?
13:52KirinDaveThat guy is in the US. I've noticed that most of my peers in the US don't get exposed to much functional programing.
13:52KirinDaveSeems like its more popular in Europe and China.
13:52tolstoyLink?
13:52KirinDavehttp://ossareh.wordpress.com/2009/10/12/learning-nio-via-clojure/
13:52KirinDaveBitching about NIO+Clojure.
13:52KirinDaveWhich is a pain. I'm still trying to figure out the right way to approach it.
13:53somniumKirinDave: if you figure it out let me know
13:53KirinDavesomnium: I am going to try and mask things with the continuation monad.
13:53pdk`lots of colleges have moved to using more java than anything in their introductory cs cirricula
13:54somniumKirinDave: wow
13:54pdk`and beyond that even
13:54KirinDavesomnium: ?
13:54KirinDavesomnium: It makes sense since IO is chunked. It's kind of a pain to "read a line"
13:54rlbpdk`: unfortunately...
13:54KirinDaveYou have a Selector and a hash table carrying the current continuation for that selector.
13:54somniumKirinDave: right, I hadnt thought of involving monads
13:54KirinDaveWell really, I want continuations. ;)
13:55KirinDaveSo you could have a (read-line) function.
13:55KirinDaveAnd if it can't get a line it drops a continuation back out.
13:55somniumtheres a few chunks of .java nio that read like C that Id like to get into clojure, but nio's been winning so far
13:59KirinDaveWell I'm super impressed by netty, and I'd like to try seeing if I can make a more clojure-native system for that.
13:59somniumKirinDave: would it be possible to do something similar by just returning a function? or is the m-word really necessary?
13:59KirinDavesomnium: You could, but then it makes all that work explicit.
14:00somniumhmm, I guess I ought to reread some haskell blogs
14:00KirinDavesomnium: Without continuations, you'd write a macro to make a FSM language.
14:00somniumFSM?
14:00KirinDaveAnd basically have things like (transition-> read-login) which would end with (transition-> chat-room-loop) etc etc
14:01somniumah
14:01KirinDavesomnium: finite state machine
14:03carki solved the nio wait-line problem this way : the text is coming into an agent, when the agent sees a full text line it sends a message to itself, then i have the wait-line macro that only exits, leaving a "continuation function" in the agent state
14:03carkwhen then line is received, it runs the function
14:04KirinDavecark: That's a nice resolution.
14:04KirinDavecark: I'm doing something somewhat like that now, myself.
14:05carki'm not sure that's the best performance you can get, but the good point is that you can use send instead of send-off
14:05carkthere's no waiting
14:05KirinDaveRight.
14:05carkso i had my whole encoding decoding line in an agent from the pool
14:05carkline/stack
14:06carkthat's bytebuffer -> ssl -> utf -> processing then back again
14:06carkerr and per line chunking of course =)
14:06KirinDaveYeah, thats a good solution. Much simpler. :)
14:07DeusExPikachuanyone have any tips for learning about clojure's implementation of fn and defn? I want to read the source but looking at just how many files, I don't know where to start. Is there a way to trace evaluating a 'fn'?
14:07KirinDaveThe only reason I'm curious about this approach is that it lets you write huge long swaths of code as if you had blocking IO and a thread, transparently. Also, it lets you control the mechanism for threadpooling more carefully.
14:08carkKirinDave : well that's not like real continuations since the code of the "continuation" needs to be one level below the wait-line macro
14:08carkbut with smaller functions that's pretty readable
14:08KirinDaveyeah.
14:09KirinDaveAlso, if you bury the acceptor code in a state monad, you can get away with having no refs.
14:09KirinDaveWhich I like very much.
14:10carkwell you need state for the utf decoding if that's what you're doing
14:10KirinDaveWhy?
14:10KirinDaveCan you just do that on the way down to the event handler?
14:10KirinDaveThat's what netty does.
14:10carkbuit an atom can do, or you can stach it in the agent state
14:10carkhum well
14:10KirinDaveAll your handler has to do is handle a string.
14:10carkyou can but you never know if you're done with the decoding
14:10KirinDaveAnd you can specify what kind of encoding it wants.
14:11KirinDaveWhy?
14:11somniumDeusExPikachu: clojure.core and (macroexpand '(fn []) are a start
14:11carkbecause utf might need 1 to 4 bytes for a single character
14:11KirinDaveThat's why you write your read-until function to abstract all that.
14:11carkso you have a byte buffer of say 1024, and it might be that the 2 last bytes are only part of a character
14:12KirinDaveand then base things like read-line.
14:12carkbut your read-until needs to return the state of the decoder !
14:12carkunless you're using us ascii of course
14:12KirinDaveThat's in the continuation.
14:13KirinDaveThe decoder itself gets preserved in the continuation.
14:13carkoh i see
14:13KirinDaveThat's why I want to use a continuation, actually. :)
14:13KirinDaveIt's more efficient that way, you don't bind up threads on reads across blocks.
14:13KirinDaveOr I suspect. I'd have to profile it to back that up with more than suspicion.
14:14carki don't know if delimited continuations via monads are very efficient
14:14KirinDaveI suspect they're plenty space efficient. I should profile trampoline to see how slow that is.
14:15KirinDaveIf trampoline is slow, then it's kind of a pain.
14:15carkthat's pretty low level stuff, you want it very efficient (speed efficient), if it isn't you're as good using standard sockets
14:15KirinDaveOf course, if it's slow but can handle 100,000 concurrent connections with a limited threadpool, then it's probably a fair tradeoff.
14:16KirinDavecark: That's the thing, you're not as well off using standard sockets.
14:16carkright
14:16somniumwould having a form like (loop [...] (continue ...)), where continue returns a fn with the new state of the loop be equivalent to monad continuations?
14:17KirinDaveUm, yes and no. :)
14:17carkthough i'm yet to work on a server that requires 100k connections and does not require responsiveness
14:17somniumthats what I figured :)
14:17KirinDaveIt would not do everything that the continuation monad can do. But it would do a lot of what we want here.
14:17KirinDaveWhere the continuations shine is in allowing for abstractions over the block reads in the event of full buffers or chunked reads.
14:18somniumthat should be possible with a macro, capturing closed over state would be the trickiest part, hmm...
14:18carkanyways the java codec are statefull so there isn't much to change
14:19carki mean not much state bookkeeping to do
14:20KirinDavesomnium: Macros are a given for this.
14:20KirinDavecark: Did you see that amazing use of the continuation monad for web sequences with clojure?
14:21KirinDavecark: http://intensivesystems.net/tutorials/web_sessions.html
14:22somniumKirinDave: I looked at that code, but without a demo I think it was lost on me
14:22somniumsomething like Seaside in 90 lines of code?
14:22KirinDaveYes.
14:22KirinDaveAnd the way you write the code is pleasant too.
14:23KirinDaveThe use case he has and the use case that an nio socket-server has are basically identical.
14:23somniumI find the nio socket case more compelling (not a big fan of continuation based web apps)
14:23KirinDaveOne thing I've noticed about nio though.
14:24KirinDaveIt seems like using threads that include reads is very… difficult.
14:24carkyes i did read this blog post
14:24KirinDaveBecause you have no guarantee that you're going to end up in your thread with enough data to process things.
14:24carkbut i'm not sold on contiuations for the web
14:24carkunless you can serialize these
14:25somniumI think state is better handled on the client, but thats a digression
14:25KirinDavecark: yes, that is a problem for web continuations. Not for event-driven socket servers though.
14:25KirinDave:)
14:26KirinDaveAnd what's an ideal place for an event-driven socket server? How about a WebSockets implementation? :D
14:27carkmhh well, your web socket will surely need to access a database at some point, and that's blocking
14:27KirinDaveAh, well...
14:27KirinDaveThat's where your agent solution would come into play.
14:28carkthat's what i did for database access on this project i was talking about
14:28carkbut it's annoying
14:29carkyou know : (with-db-request customer-by-id 25)
14:29carkactually more like this: (with-db-request [customer-by-id 25] .....)
14:30carkbut in practice that was rather ugly
14:30KirinDaveyeah well
14:30KirinDaveNo one ever said it wouldn't be. ;)
14:30KirinDaveWebSockets is a fairly ugly idea.
14:31carkalso you need to be extra carefull
14:31carkjust a single blocking call anywhere inside your app, and that's all for nothing
14:32carkgive the code to a maintainer, and he WILL break it
14:32KirinDaveI'm not from that camp. :)_
14:32KirinDaveIf the maintainer breaks it, it's his problem. I'm not the kind of developer that's going to play read-the-future with stupidity in play.
14:34somniumI wonder if they say things like that in #perl :P
14:34KirinDaveGoogle my screen name and find out which camp I come from. It's not hard.
14:35KirinDaveBut I'm not going to argue developer philosophy here. I know I'm in a radical minority opinion. :)
14:38DeusExPikachusomnium, any tools for tracing code? I'm used to using slime for CL
14:39somniumDeusExPikachu: clojure.contrib.trace?
14:42somniumor stuff like this?
14:42somnium,(let [f #(* % %) g (fn [f x] (let [a (f x)] (println x a) a))] (map #(g f %) (range 5)))
14:42clojurebot(0 1 4 9 16)
14:43somnium:/
14:43somniumwheres his *out*?
14:46somnium,(let [f #(* % %) g (fn [f x] {:input x :output (f x)})] (map #(g f %) (range 5)))
14:46clojurebot({:input 0, :output 0} {:input 1, :output 1} {:input 2, :output 4} {:input 3, :output 9} {:input 4, :output 16})
14:47quizmehttp://github.com/ztellman/penumbra/blob/master/src/examples/tetris.clj <--- i am trying to get clojure tetris to work. but getting an error
14:47the-kennyquizme: "an error" shouldn't be there. Why aren't you fixing the error? ;)
14:47quizmehttp://pastie.org/757172
14:48quizmethe-kenny: http://pastie.org/757172
14:48the-kennyah sorry
14:48the-kennyquizme: Is penumbra in your classpath?
14:49quizmethe-kenny i don't think so, i couldn't find any .jar files so not sure what to do
14:49the-kennyquizme: Take a look at the readme
14:50the-kennyhm.. nothing there
14:50quizmethe README is in .md format
14:50quizmenot sure how to read that
14:50quizmesorry i'm not a java guy
14:50quizmei'm lost
14:51quizmehey i found some jar files
14:52the-kennyquizme: readme is just text, but there aren't any instructions there
14:53quizmei'm going to copy all the jar files to my classpath
14:53quizmeand see if that helps
14:54the-kennyquizme: ahh got it
14:55the-kennyhttp://wiki.github.com/ztellman/penumbra/getting-started
14:55the-kennyFound at the bottom of the readme
14:55quizmethanks
14:56the-kennyYou're welcome
14:58fliebelWhat is a good web framework in Clojure? All I need is some prxml like stuff and an included server. I noticed thare are a few different ones, ant I wanted to know your opinions.
14:59fliebelI'm not writing a web application, but an application that can serve some pages.
15:01carkfliebel : i think compojure is the most used
15:02the-kennyYes, compojure is very nice
15:02the-kennyIntegrated tools which are almost like prxml, simple start
15:02fliebelcark: but how about the other ones I found? I beleive they where caled webjure and cascade...
15:02the-kennyYou'll have a simple application up in a few minutes
15:03the-kennyfliebel: Isn't cascade more like gwt?
15:03the-kenny(Widgets etc.)
15:03fliebelDoes any of them have their own server, or do they all use servlets?
15:04fliebelthe-kenny: I only need to serve strings and files...
15:04LauJensenfliebel: Compojure runs both Grizzly and Jetty
15:05LauJensendanlarkin: ~ was working on something called clabango a while ago when suddenly
15:05fliebelLauJensen: that java stuff means nothing to me… Can I run it alone, or do I need a servlet container?
15:05LauJensenoh, that used to trigger something from clojurebot I think
15:05danlarkin:-D
15:05LauJensenfliebel: It stands on its own
15:05LauJensenDid you see my screencast?
15:06the-kennyfliebel: If you use leiningen, it pulls everything you need
15:06fliebelLauJensen: yea, You typed something like that, but it might just as well be configuration for the conatiner.
15:06the-kennyjust add compojure to the dependencies and it will pull you a jetty.jar and everything
15:06quizmeit is customary to put source files *and* .jar files in the CLASSPATH ?
15:06LauJensenfliebel: No, you actually saw Jetty boot up in the inferior lisp buffer
15:07fliebelLauJensen: Might have missed that… I'll look at it again now that I know more about Compojure :)
15:10quizmethe-kenny: i copied the linux/64 *.jar files into ~/jars/penumbra/lib/ and the src files into ~/jars/penumbra/src/ and added those two directories to my $CLASSPATH environment variable, so do i have to restart the JVM ?
15:11fliebelLauJensen: you worked quite fast at times, at least for people who don't know emacs+clojure+compojure like me.
15:11the-kennyquizme: Quit the repl and restart it :)
15:11quizmethe-kenny ok thanks
15:14fliebelLauJensen: Yea, It's at 9 min. I remember asking you about the html thing, but I must have missed the details of the server part.
15:20quizmehttp://pastie.org/757199 <--- is there a more intelligent way of adding multiple directories to my CLASSPATH? I have a feeling I'm doing something dumb.
15:21neotykslime/swank question: how do I make swank see *clj files from src of my leiningen poject
15:21neotykI start swank via lein swank, and connect from emacs via slime-connect
15:27fliebelLauJensen: Now that I am going to use Compojure, are you going to do more screen casts about that? Your previous was a good overview of what is possible, it would be cool to see more detailed action of those things.
15:28LauJensenI'm actually preparing a screencast now which I hope to release in a few hours - its just about getting started with swank-clojure. You're looking for more Compojure oriented screencasts?
15:30neotykLauJensen: I would like you to describe a bit more your setup, really liked this interactiveness in it, and now I'm struggling with emacs
15:30LauJensenneotyk: then this next screencast is for you
15:30LauJensenI show how to set up slime on emacs on a fresh install, so should be easy to follow
15:31neotykLauJensen: this is awesome
15:31LauJensen:)
15:32neotykIf you can include some basic stuff after setup
15:32neotykthat would make it great
15:32LauJensenI'm throwing in the kitchen sink, my .emacs
15:32fliebelLauJensen: Yes, I'll stick to Vim, but I will keep an eye on your blog.
15:33LauJensenfliebel: Thats fine, not everybody can handle the speed and power which comes with Emacs - and we respect that
15:33fliebellol
15:33neotykLauJensen, fliebel : you know that real man use ed, right?
15:34fliebelneotyk: no, what's that?
15:34LauJensenneotyk: M-x ed ?
15:34LauJensenVim is M-x viper
15:34neotyked is less than sed
15:34neotykclojurebot: google ed
15:34clojurebotFirst, out of 40900000 results is:
15:34fliebelbtw: real man don't eat honey, they chew bee's :D
15:34clojurebotMain Page - Encyclopedia Dramatica
15:34clojurebothttp://www.encyclopediadramatica.com/
15:35neotykclojurebot: not that
15:35clojurebotwhose job is<reply>that is turbo24p1gs job
15:35neotykclojurebot: google ed editor
15:35clojurebotFirst, out of 33400000 results is:
15:35clojureboted (text editor) - Wikipedia, the free encyclopedia
15:35clojurebothttp://en.wikipedia.org/wiki/Ed_(text_editor)
15:36neotykohh my, just look at Example and its friendliness
15:39fliebelneotyk: you actually use this stuff?
15:39fliebel"In current practice, ed is rarely used interactively"
15:40neotykdo you know some tutorial on how to manage windows/splits/buffers in emacs?
15:40neotykfliebel: noway, I'm VIM by nature
15:44carkneotyk : you should do the emacs tutorial
15:44carkthere you learn how to get healp
15:44carkhelp =/
15:44fliebelneotyk: I also use Vim, but I just started, so in a very noobish way… only when I'm moving around stuff I'll try to use command mode. Sometime I even use the mouse as a quick way to move around and copy stuff! *hides*
15:45neotykfliebel: I love vim, been using it for last decade, but emacs lisp powers are very attractive :)
15:46neotykcark: thanks, I'm starting Emacs tutorial right now
15:48fliebelI know lein downloads dependencies automatically, but half of them time I'm just running of the repl or running clj files directly. Is there a way I can have those dependencies in my cp? At the moment I keep copies of everything installed somewhere, which is not very nice.
15:48tolstoyJust remember Control-G. Backs you out of any command sequence. That was the key for me learning enough emacs to get by.
15:53fliebelfind ~/.m2/repository | grep .jar$ sort of gets me a list of jars, but that is not exactly what I had in mind…
16:03fliebelFound a solution I think… lein deps adds them to /lib, so I need to add that to cp.
16:04fliebelHow can I add Compojure to dependencies? I'm not sure about the version.
16:05LauJensenneotyk: Vimeo is converting the file now, so if it looks good, blogpost should be ready soon
16:06neotykLauJensen: very nice, will provide feedback :)
16:06LauJensenYe
16:06LauJensenyes, please send me a lot of positive feedback as I'm new to screencasting, if you happen to have some negative criticism, please send it to cgrand instead
16:08fliebelLauJensen: You said I can add Compojure to lein… what is the artifact and the version? http://clojars.org/repo/compojure/compojure/0.3.1/ == 404 :(
16:08LauJensenI did ? I don't use Lein
16:09LauJensenI remember somebody saying it, but it wasn't me
16:09fliebelSorry...
16:09fliebel*scrolling*
16:09the-kennyfliebel: wait
16:10the-kennyI have [org.clojars.liebke/compojure "0.3.1-master"] in my project.clj
16:11fliebelthe-kenny: thanks! I found out via google that ato also contains it.
16:13fliebelthe-kenny: working!
16:13the-kennyfliebel: Nice :)
16:15fliebelbooom! 10 extra jars in lib :D
16:15neotykhey, what is with this versioning scheme all dependency resolution is done by maven subsystem, but version number contain -master-SNAPSHOT?
16:18neotykLauJensen: on what platform you record screencasts?
16:21fliebelCan someone tell me the correct line to show my cp? This is not it, apparently: (.getProperty (System.getProperties.) "java.class.path", null)
16:23bagucodefliebel: (import 'java.lang.management.ManagementFactory) (.getClasspath (ManagementFactory/getRuntimeMXBean))
16:24bagucodeor rather (.getClasspath (java.lang.management.ManagementFactory/getRumtimeMXBean))
16:24fliebelbagucode: "intensive research" turns out it's (System/getProperty "java.class.path") Prior java examples consisted of at least 10 lines.. man, these people got to love lines...
16:25LauJensenneotyk: Ubuntu 9.10
16:25neotykLauJensen: what do you use to record sessions?
16:26LauJensengtk-recordmydesktop
16:26bagucodefliebel: Oh I misread your previous post. I thought you said (System/getProperty... and that it didn't work :)
16:26bagucodefliebel: My way is not the preferred, rather an alternative to getProperty
16:27fliebelbagucode: I would think so… It's about as long as most java examples I found.
16:27fliebelwell, probably not
16:27bagucodefliebel: One cool thing about the RuntimeMXBean though is that it knows the jvm arguments as well, if you want to get at those.
16:28fliebelcool
16:28neotyk,(System/getProperty "java.class.path")
16:28clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission java.class.path read)
16:28fliebelWhat happens when I have multiple clojure jars on the cp?
16:28bagucode,(.getClasspath (java.lang.management.ManagementFactory/getRumtimeMXBean))
16:28clojurebotjava.lang.NoSuchFieldException: getRumtimeMXBean
16:28bagucodehaha Rumtime
16:29LauJensenneotyk: http://www.bestinclass.dk/index.php/2009/12/clojure-101-getting-clojure-slime-installed/
16:29bagucode,(.getClasspath (java.lang.management.ManagementFactory/getRuntimeMXBean))
16:29clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.management)
16:29LauJensenHope it makes entry a little easier
16:29hamzaguys what was the name of the function that returned a dir as a sequence? which lib it is located?
16:29fliebelfile-seq
16:29fliebeljust core i guess
16:29bagucode,(doc file-seq)
16:29clojurebot"([dir]); A tree seq on java.io.Files"
16:30hamzai was checking contrib lol , thanks..
16:30fliebelbagucode: I got the repl runnign with 2 versions of clojure and contrib on the cp… strange...
16:30neotykLauJensen: thanks, watching
16:31fliebelLauJensen: me to...
16:32LauJensenGreat
16:32LauJensen(I hope)
16:32fliebelBut not with 100% attention… I'm just a little curious.
16:32bagucodefliebel: That totally works. I hate when stuff like that happens. I do Java at work, large webapp stuff and there is actually pretty often trouble with "version salad" and classloader issues related to stuff like that.
16:33fliebelbagucode: meh… bad! I'll have to work around that.
16:33bagucodefliebel: Here is the link to the doc for that bean thing by the way: http://java.sun.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html
16:44fliebelI made a clj script that works with the lib directory of any lein project and puts you in src :)
16:46bagucodeNot an emacs fan? I always use lein swank.
16:46neotykfliebel: you know that this is named JarHell?
16:46neotykLauJensen: Very nice video
16:47neotykLauJensen: informative will help a lot of people
16:47fliebelneotyk: how do you mean? I just put the dependencies of that project on the cp...
16:47LauJensenneotyk: Great - Glad you could use it (just realized who you were when I saw your photo on twitter)
16:47neotykfliebel: multiple version of same thing on CP
16:48bagucodeneotyk: I call it version salad :)
16:48fliebelneotyk: not anymore, I removed the other clojure… now I got clj for normal repl and cljp fro projects :)
16:48fliebelso only lib and current directory on cp
16:48neotykbagucode: I was hoping for OSGi to solve those problems
16:49fliebelneotyk; this also means I'm also using the actual clojure version that lein uses.
16:50bagucodeneotyk: I don't know much about OSGi, I always distrust stuff at first and I haven't been forced to look at it at work so I haven't bothered learning more about it. Not really into Java stuff actually, it just pays the bills :(
16:51fliebelTime to leave, bye!
16:51neotykfliebel: bye
16:51bagucodeneotyk: Clojure actually made me more interested in Java hehe, at least the jvm bit
16:51bagucodebye
16:52neotykbagucode: agree, java is not much fun
17:14quizmeis there a way to do this: -Djava.library.path=/.../penumbra/lib/osx with environment variables?
17:17neotykquizme: what is ... ?
17:17quizme... is the path to penumbra
17:18quizmeneotyk: /home/david/.jars/
17:18neotykthan you do $ ENVNAME=env_value your_command and its parameters
17:19quizmeneotyk: export java.library.path=/home/david/.jars/penumbra/lib/linux/64 ?
17:19neotykCP=myjars java -cp $CP clojure.main
17:20neotykI think we are not on same page
17:20quizmei agree with that lol
17:20the-kennyneotyk: java.library.path is not the classpath
17:20neotykwhat you want is not to provide -D to java but provide env vars that will do the job?
17:20quizmeit's a library bpath
17:21quizmei remember seeing some documentation that clojure.main reads some environment variables besides CLASSPATH
17:21quizmesomething like LIB_OPT or something like that
17:22the-kennyquizme: Maybe the following works: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#setProperty(java.lang.String,%20java.lang.String)
17:22neotykthe-kenny: I was thinking of defining local env vars per execution, but I miss understood the question in first place
17:22neotykquizme: LD_LIBRARY_PATH ?
17:23quizmeneotyk: there are a bunch of *.so files i want to load up
17:24quizmehttp://wiki.github.com/ztellman/penumbra/getting-started
17:24neotykthat's what we had to do for a client month ago, and nether bothered to blog about it
17:24neotykinteracting with native code from JVM
17:29quizmethe-kenny neotyk: maybe this DYLD_LIBRARY_PATH ?
17:29neotykon Mac DYLD_LIBRARY_PATH on Lin LD_LIBRARY_PATH should contain all *.so you need and loading it from jvm should be ok
17:30quizmeLD_LIBRARY_PATH
17:50quizmehttp://pastie.org/757287 <--- can somebody help me plz sorry...
17:51quizmei'm on 64 bit java on ubuntu 9.10,
17:51quizmetrying to get the penumbra examples working...
17:53the-kennyquizme: Add clojure to your classpath
17:53quizme/opt/clojure ?
17:53the-kennywait.. strange
17:54the-kennyquizme: Is $CLJ_ROOT/clojure/clojure.jar the location of clojure.jar
17:54the-kenny/opt/clojure/clojure/clojure.jar
17:54quizmei, ;e,,e cjecl
17:54quizmeino such file
17:54quizme/opt/clojure/clojure.jar
17:55quizmethat's where it is
17:55quizmeand also it's in /home/david/.jars/clojure.jar
17:55quizme/opt/clojure/clojure/clojure.jar doesn't exist
17:55the-kennyThen correct your call to java
17:57quizmeoh i see
17:57quizmethe guy who wrote that make a directory called /opt/clojure
17:57quizmethen inside that directory, he did git clone
17:57polypusany overtone hackers in here?
17:58quizmethe-kenny that makes sense
17:58quizmethe-kenny i'll do it his way
18:04quizmethe-kenny: finally got it working. Thanks so much.
18:04the-kennyquizme: You're welcome
18:08quizmethe-kenny: a clojure version of tetris is what I always wanted for Christmas...
18:22RaynesI think somebody wrote a tetris clone a while back.
18:40joolsaDoes anyone have experience of using clojure.xml/parse ?
18:40joolsaI'm having trouble getting it to read from an InputStream
18:43joolsaThe repl give me "org.xml.sax.SAXParseException: Content is not allowed in prolog. (hist.clj:12)"
18:57emacsenis it valid XML?
19:05PrinceOfAhow do i convert a list to a map?
19:07PrinceOfAi mean (1 2 3 4) --> {1 2, 3 4}
19:07joolsaYes. I can run the process from the command line, pipe the output to a file, then (parse) that file fine.
19:08joolsaI think I've a problem with whether I have bytes or characters and what encoding they are in.
19:09joolsaI come from a C++ and Python background. I'm not familiar with Java at all :(
19:11emacsenhow are you trying to parse the inputstream?
19:11the-kennyPrinceOfA: (hash-map 1 2 3 4)
19:11the-kenny,(hash-map 1 2 3 4)
19:11clojurebot{1 2, 3 4}
19:12Chousukeuse apply if the values are in a seq
19:13PrinceOfAthx!
19:15PrinceOfAobviously apply did the trick.. what does it do?
19:18PrinceOfA(doc apply) is not really helpful :)
19:18clojurebot"([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."
19:20joolsaAh, thanks. It turns out my xml was malformed. It's amazing how you miss the obvious, until someone points it out! When I was spawning the process to generate the xml I wasn't using the same parameters that I used to generate the test xml. Doh!
19:20Chousukewell, function f applied to arguments x, y means (f x y)
19:21Chousukeso basically apply does function application :P
19:22Chousukeone of those things you just need to know
19:26PrinceOfAso (apply hash-map [1 2 3 4]) means (hash-map 1 2 3 4)
19:26PrinceOfAwhy args* argseq?
19:26PrinceOfAwhat does it mean?
19:30the-kennyPrinceOfA: You can supply an arbitrary number (or zero) of "normal" args, and after that, a sequence of args
19:31the-kennyPrinceOfA: (apply + 1 2 [3 4 5]) == (apply + [1 2 3 4 5]) == (+ 1 2 3 4 5)
19:31PrinceOfAthe-kenny: can you give me an example where the args* need to be separate from argseq?
19:33the-kennyPrinceOfA: hm.. it's just for convenience
19:34the-kennyyou can always cons all args* to argseq and use (apply argseq)
19:34PrinceOfAso basically it could be [f argseq]
19:35the-kennyhm no, that would be like (+ [1 2 3]), but apply applies the supplied list to f: (apply + [1 2 3]) = (+ 1 2 3)
19:37quizmeis there a way to suspend garbage collection? It's annoying to get hit by an asteroid while the jvm is doing garbage collection...
19:38slashus2quizme: Are you okay? :-P
19:38quizmeslashus2 hehe it didn't hurt that much
19:41quizmeand sometimes the keyboard inputs are not snappy responsive
22:47chouserugh
22:48devlinsf?
22:56chouserI've got code snippets I need to eval
22:57chouserI need to capture anything they print
22:58chouserbut some of them start a new thread and print from there.
22:58chouserI'm stumped
23:00chouserI guess I could alter-var-root and then change it back again.
23:00chouser...and that brings me back to "ugh"
23:01devlinsfHmmm
23:01devlinsfIt's ugly... but you could set up a temp dir, give each thread a file and look at the results
23:02devlinsfbut I mean UGLY
23:02hugodDoes (set! *out* ....) not work?
23:02quizmeis there a way for a macro to grab what preceded it ?
23:04quizmei want to make clojure understand 1 + 2
23:04quizmerather than + 1 2
23:04chouserquizme: haha!
23:04chouserno
23:04devlinsfchouser: Get this one
23:04quizmehmm
23:05slashus2quizme: By the time you end up finishing that macro, you will probably realize you don't need it.
23:05chouserquizme: http://paste.lisp.org/display/75230
23:05quizmei'm sure i don't need it
23:05quizmejust wanna mess with clojure's head
23:05devlinsfquizme: Just to see what happens?
23:05quizmeto see if it's possible
23:06devlinsfOkay, so when you say 1 + 2, do you mean "1 + 2" or (1 + 2)?
23:06quizme1 + 2
23:06devlinsfA string, not a datastructure
23:07quizmedata structure
23:07quizmei want to type in 1 + 2 at the REPL
23:08devlinsfOkay, that's a string
23:08devlinsfAt least, from the REPL's perspective
23:08quizmek
23:08pdk`that's not going to be read by your macro either way if you enter just that
23:08pdk`if you enter it like (mymacro 1 + 2) maybe
23:09devlinsfYou could implement a custom reader... I don't recommend it
23:09devlinsfWhy do you want 1 + 2 at the REPL?
23:09quizmejust to see what the limits of macros are
23:09devlinsfMacros operate on datastrutrues.
23:10devlinsfAs long as you get the 1+ 2 in the repl as a data structure, you're golden.
23:10quizmethanks
23:10quizmethat answers my question
23:10slashus2As was shone by chouser, it doesn't really need to be a macro.
23:11slashus2Try a function first before you write a macro.
23:12quizme i was mainly wondering if it's possible to break out of the parentheses
23:12quizmeand make up a new syntax
23:12devlinsfYeah, it's possible
23:13devlinsfHighly discourages
23:13devlinsfdiscouraged
23:13slashus2You would probably have to mess with the reader macros.
23:13devlinsfActually, worse
23:13devlinsfYou'd have to parse your result into an abstract syntax tree
23:13devlinsfIt's something a list reader doesn't have to worry about
23:14quizmeinteresting
23:14devlinsfquizme: If you're really really really really really really interested, start at LispReader.java
23:15quizmeprobably not that interested
23:15quizmejust trying to understand macros
23:15devlinsfIt's amazingly small for what it does
23:15quizmethanks a lot
23:15devlinsfNo problem
23:16chouserwell, another option is to have an outer macro or fn, one set of parens. Then inside that is your playground, as long as the reader doesn't choke on anything you need.
23:16devlinsfOr, simply put everything in a string
23:17devlinsf( because the reader WILL choke on SOMETHING)
23:17chouserheh
23:17chouserthe reader chokes on " in strings. :-P
23:17devlinsfAnd it should
23:17devlinsfOr do you mean \"
23:17devlinsf?
23:18chouserwell. I still wish for alternate string-quoting syntax.
23:18devlinsfYeah, except ' is taken
23:18devlinsf:(
23:18chouserlike python's triple-quote or here-docs, or something.
23:19devlinsfDid you see Chas Emerick's interpolator?
23:19chouserI did
23:19devlinsfDid you like it?
23:19devlinsfOr are we talking about a different problem?
23:20chouserdifferent problem
23:20devlinsfAh, okay
23:21chouserperl and ruby support using different quoting delimiters, like q{string here with "quotes" even}
23:21devlinsfI've hacked Ruby, I see what you mean now
23:21chouserpython has """triple quotes that allow singe " and double "" internally with no problem"""
23:23devlinsfHmmm... triple quotes would be doable. The trick would be to add support for multiple character closing delimiters in the reader
23:23chouserwell, alter-var-root works. :-/
23:23devlinsfIf the plan is to add block comments eventually, this might be doable
23:23devlinsfGlad it to hear it
23:23lisppaste8Chouser pasted "with-root-out-str" at http://paste.lisp.org/display/92670
23:24chouserso horrible
23:24_mstthat's the wonder of macros... now you can repress the implementation and never think of it again :)
23:24chouserheh
23:25chouseractually, should be just a high-order fn, I suppose.
23:26devlinsfchouser: Hmmm... I like the macro better
23:27devlinsfUnless you want to map it
23:29chousernah, I'll leave it as it is. This whole program is a giant ugly hack.
23:29chouserleaving it as a macro keeps it more like with-out-str, which is the impression I want to give.
23:30chouserthis is for checking the examples in our book
23:30devlinsfWhen will an electronic version come out?
23:32_mstif you've got multiple threads sending output non-deterministically, isn't it going to be hard to check the output?
23:32chouserI wish I knew. We were hoping to have the first 4 chapters up before Christmas, but that didn't happen.
23:32_mstor is there an equal amount of regex hackery involved? ;)
23:32chouser_mst: indeed, very ugly regex hackery.
23:33chouserthis script is also the source of the pop quiz a few nights ago.
23:33_mstah, the Pattern one? heh
23:34chouserright, comments in regex. :-P