#clojure log - Aug 23 2009

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

0:48 elben: I'm confused by the apply function. Why does (apply + [1 2]) return 3, but (apply print [1 2]) return "1 2nil"? Aren't we applying the function + and print to each item in the given vector? Then, why did the first example add up 1 and 2?

0:49 cark: it prints 1 and 2 ...then returns nil

0:50 you get the same result with (print 1 2)

0:50 ,(print 1 2)

0:50 clojurebot: 1 2

0:50 cark: hum clojurebot refuses to show it =/

0:50 elben: i see it

0:51 so what does apply actually do? calls the function on each item in the given arg right?

0:51 replaca__: I think clojurebot special cases print

0:52 lowlycoder: gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

0:52 how do I get bit or in clojure?

0:52 cark: (apply + [1 2 3 4]) is the same thing as (+ 1 2 3 4)

0:52 tomoj: ,(bit-or 1 2)

0:52 clojurebot: 3

0:53 elben: cark: I see.. kinda. My experinece w/ functional langs are virtually nil (a tiny bit of haskell is all ;)

0:54 tomoj: elben: (apply print [1 2]) returns only nil

0:54 lowlycoder: tomoj: thanks

0:54 tomoj: it prints "1 2", but because there's no newline, the return value is shown immediately afterward on the repl

0:54 clojurebot: thanks; that was delicious. (nom nom nom)

0:55 elben: tomoj: yes that makes sense, thanks

0:55 cark: you'll get used to apply =)

0:56 replaca__: elben: compare apply to map. Map calls the function on each element of the sequence and returns a (lazy) sequence of the results

0:57 apply call 1 func with n args, map calls the func n times with 1 arg (unless you give it multiple sequences)

0:57 *apply calls ...

0:58 elben: replaca__: I just started learning clojure, and I haven't gotten to map yet =P

0:59 but i assume it's the same as other languages

0:59 or similar

0:59 replaca__: elben: yup, pretty much

0:59 as is apply (or at least other lisps)

1:00 clojure's laziness is a little different, though. Not as pervasive as Haskell, but more aggressive than most langs

1:01 elben: i'm sure i'll get to all that fun stuff eventually =)

1:01 replaca__: yup, it's all cool!

1:02 elben: going through pragmatic's book right now. I wished it went into more detail (for the benefit of those that do not know a lisp), but I suppose it will work for now

1:16 lowlycoder: user=> (import '(javax.media.opengl GLDrawableFactory))

1:16 nil

1:16 user=> (show GLDrawableFactory)

1:16 java.lang.Exception: Unable to resolve symbol: show in this context (NO_SOURCE_FILE:17)

1:16 how do I get clojure to show me all the functions of GLDrawableFactory ?

1:20 user=> (import 'java.util.HashMap)

1:20 nil

1:20 user=> (show java.util.HashMap)

1:20 java.lang.Exception: Unable to resolve symbol: show in this context (NO_SOURCE_FILE:22)

1:21 why does the above not work?

1:24 replaca__: lowlycoder: you've gotta use c.c.repl-utils

1:24 lowlycoder: clojure.contrib ?

1:25 replaca__: yah

1:25 http://richhickey.github.com/clojure-contrib/repl-utils-api.html#repl-utils/show

1:27 tomoj: lowlycoder: are you using slime?

1:27 lowlycoder: no

1:27 vim user

1:28 tomoj: oh well

1:28 in slime you can do C-c I, then type the class (or it guesses it if you're pointing at it), and you can browse all the methods/fields

1:29 doesn't work too well for clojure stuff yet but gives you the signatures for java methods

1:29 lowlycoder: user=> GLDrawableFactory/getFactory

1:29 java.lang.Exception: Unable to find static field: getFactory in class javax.media.opengl.GLDrawableFactory (NO_SOURCE_FILE:0)

1:29 however, I also have:

1:29 user=> (show GLDrawableFactory)

1:29 === public abstract javax.media.opengl.GLDrawableFactory ===

1:29 [ 0] static getFactory : GLDrawableFactory ()

1:29 so why can't I go GLDrawableFactory/getFactory ?

1:29 tomoj: getFactory is a method

1:29 (GLDrawableFactory/getFactory)

1:29 lowlycoder: user=> (GLDrawableFactory/getFactory)

1:29 #<X11GLDrawableFactory com.sun.opengl.impl.x11.X11GLDrawableFactory@45b34126>

1:29 nice

1:29 thanks

1:29 tomoj: http://clojure.org/java_interop

1:30 lowlycoder: yeah, it just confuses me that if (f) evalutes the function,

1:31 f # won't give me "hey, this is a function"

1:31 tomoj: normally it would

1:31 but the java interop is a bit different

1:31 GLDrawableFactory/getFactory looks for a static field

1:53 lowlycoder: how can a function refer to itself?

1:54 (let [my-fun (fn [] .... i want to refer to my-fun from in here)])

1:57 tomoj: lowlycoder: refer? for calling?

1:57 lowlycoder: yes

1:57 tomoj: you should use recur

1:57 lowlycoder: so this function my-fun does some stuff then stuffs itself into a callback function

1:57 the last line of my-fun is:

1:58 tomoj: oh, then no

1:58 lowlycoder: (. display asyncExec my-fun)

1:58 tomoj: fn is hygienic I believe

1:59 so it won't bind a special variable to refer to the function itself

1:59 lowlycoder: how do I express these idioms?

2:00 tomoj: are you doing continuation passing?

2:00 just curious

2:00 lowlycoder: no, converint a swt/jogl app into clojure

2:00 tomoj: having a function that refers to itself seems pretty odd to me

2:01 lowlycoder: supose you have a timer function

2:01 that wants to add itself to the callback at the end of the timer

2:01 tomoj: I think you might be able to do it with letfn though

2:01 ,(letfn [(foo [] foo)] (foo))

2:01 clojurebot: #<sandbox$eval__2562$foo__2564 sandbox$eval__2562$foo__2564@169baee>

2:03 lowlycoder: tomoj: nice; thanks

2:05 tomoj: that function just keeps returning copies of itself I think

2:06 yup

2:06 pretty bizarre

2:41 lowlycoder: does clojure have it's own timer classes, or do i need to use java's?

2:41 basically i want to create a thread and have it run at 30fps

2:41 err, a function called at 30 fps

2:43 tomoj: the way the ants demo does it is by sending off to an agent that runs the thread

2:43 and then within that, create a new thread that just sleeps for however many ms

2:45 lowlycoder: do agents / clojure automatically create threads behind my back, or do I manually create / manage threads?

2:47 tomoj: normally you manually create/manage threads

2:47 agents can make their own though

3:22 lowlycoder: user=> Thread/NORM_PRIORITY

3:22 5

3:22 does this change per jvm run, or is iit failry static?

3:32 tomoj: it's always 5

3:32 except maybe if you switch jvm versions

3:32 lowlycoder: so reading the java dos, is I have two threads, one of priority 6, one of priority 5, on a single CPU machine

3:32 tomoj: not sure if there are any historical differences or differences in other implementations

3:32 lowlycoder: and the priority 6 thread is while(1) { };

3:33 then the priority 5 thread just starves?

3:33 (assuming the JIT doesn't optimize that out)

3:45 tomoj: I suppose so

8:43 angerman: is there a fn that does ['a' 'b' 'c'] [1 2 3] -> ['a' 1 'b' 2 'c' 3] ?

8:44 mikem`_: angerman: isn't that zip?

8:44 ,(doc zip)

8:44 clojurebot: It's greek to me.

8:45 mikem`_: ,(find-doc zip*)

8:45 clojurebot: java.lang.Exception: Unable to resolve symbol: zip* in this context

8:45 mikem`_: ,(find-doc zip)

8:45 clojurebot: java.lang.Exception: Unable to resolve symbol: zip in this context

8:45 angerman: ,(zip ['a' 'b' 'c'] [1 2 3])

8:45 clojurebot: Unmatched delimiter: ]

8:46 angerman: hmm

8:46 ,(zipmap ['a' 'b' 'c'] [1 2 3])

8:46 clojurebot: Unmatched delimiter: ]

8:46 mikem`_: ,(doc interleave)

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

8:47 mikem`_: ,(interleave ['a' 'b' 'c'] [1 2 3])

8:47 clojurebot: Unmatched delimiter: ]

8:47 kotarak: ,(zipmap ["a" "b" "c"] [1 2 3])

8:47 clojurebot: {"c" 3, "b" 2, "a" 1}

8:48 mikem`_: ,(interleave ["a" "b" "c"] [1 2 3])

8:48 clojurebot: ("a" 1 "b" 2 "c" 3)

8:48 angerman: ahh. thanks

8:48 mikem`_: haha, took a few tries

8:50 kotarak: the correct delimiter for string is " not '

8:50 ,(macroexpand-1 ''x)

8:50 clojurebot: (quote x)

8:50 kotarak: ,(macroexpand-1 '"x")

8:51 clojurebot: "x"

9:30 hamza: hey guys, if i create a file containing [ 1 2 3 ] and read this in to string is it possible to turn this into a vector?

9:31 cark: ,(read-string "[1 2 3]")

9:31 clojurebot: [1 2 3]

9:31 hamza: ,(doc read-string)

9:31 clojurebot: "([s]); Reads one object from the string s"

9:32 hamza: thank you can i use this to read a while snippet of code and execute it?

9:32 cark: ,(eval (read-string "(println \"hello\")"))

9:32 clojurebot: DENIED

9:32 cark: eval denied =/

9:32 but yes it works

9:33 hamza: thanks you.

9:33 *thank

9:33 cark: add a read and a loop, and you have your very own repl !

9:35 hamza: i was thinking to store state i would just write the object to disk as lisp statements and read them back to restore state is this good/bad practice?

9:36 cark: i do this as well

9:36 but don't eval if you do this

9:36 there is a limit to the size of what you can eval

9:36 while reading has no size limitation

9:37 prudence would also require you to disable read-eval

9:37 hamza: kk

9:37 cark: i mean *read-eval*

9:38 mhhh let's see if we can cheat with clojurebot =P

9:38 ,(read-string "#=(eval (def x 3))")

9:38 clojurebot: #'sandbox/x

9:38 cark: hehe

9:38 ,x

9:38 clojurebot: 3

9:39 cark: hiredmaaaan !

9:39 hamza: hehe

11:36 Licenser__: hmmm hmmm what is a good thing to start of with clojure

11:37 Chouser_: projecteuler

11:38 Licenser__: Chouser: my favourite channel user ^^. And that is a nice ida

11:38 *idea

11:38 Chouser: :-)

11:51 cark: mhh if i want to avoid too many side effects due to retries in a function in a dosync, would it be ok to temporarily memoize that function ?

11:51 or should i avoid side effects alltogether ?

11:52 sometimes you need to check the state of a ref, depending on it maybe do side effects, then update the ref

11:53 or is it bad architecture ?

12:01 Chouser: I'd be suspicious of the desire to put any kind of side-effect in a transaction.

12:07 cark: yes =/

12:07 but there are different kind of ..huh ... side effect severity

12:08 LauJensen: I would recommend you try, as far as humanly possible, to code without sideeffects. Its not hard to go back from, but its hard to get there.

12:09 cark: opening a database connection is side effect, and there's no way around it =)

12:09 Chouser: cark: yeah. don't do that in a transaction. :-)

12:09 cark: well

12:10 if the function that returns the connection is memoized for the duration of the dosync

12:10 i mean memoized around it

12:10 then i get at worst one connection created

12:11 or the transaction might fail, and then my connection is up for garbage collection

12:12 that sounds hacky doesn't it ?

12:12 Chouser: why not open the connection before the dosync, use it inside, and close it after?

12:12 cark: the whole point is about creating connections, that's a connection pool i'm trying to do

12:12 Chouser: oh

12:13 are you coordinating with other refs, or is there just the one pool?

12:14 cark: that's another thing i'm not sure about

12:14 i'd like to have a count of in-use connections

12:14 so that i can gracefully exit, waiting for all connections to be returned

12:14 (to th pool)

12:15 actually this last part is the reason why i need coordination, and risk problems if i'm not creating the connection inside the dosync

12:17 Chouser: just musing aloud here, but I wonder if it would help to have new connections be created by a lazy seq

12:17 cark: mhh

12:18 it is truely some kind of memoization

12:18 Chouser: in your dosync you'd (alter connection-seq rest)

12:19 if the transaction retries, you'll keep reusing the first of the connection-seq

12:20 cark: right this makes sense

12:20 though the connection might become unavailable in the mean-time

12:20 Chouser: when it succeeds and commits that alter, your next transaction will cause the next new connection to be created when it callse (first connection-seq)

12:20 hm

12:21 well, connections can become unavailable at any point, couldn't they?

12:21 that's just a general real-world failure case.

12:21 cark: right

12:21 connetions are checked before handing these out to the caller

12:22 and a new one might be recreated on failure

12:22 so i guess that's a non-issue

12:23 well thanks, i might go this direction =)

12:24 Chouser: it's still a side-effect in a transaction, I guess, but packaged up sufficiently safely. I hope. :-)

12:24 Licenser__: hmm I like this ^^

12:27 rhickey: http://dobbscodetalk.com/index.php?option=com_myblog&show=Clojure-vs.-Scala.html&Itemid=29

12:27 Chouser: not dramatically different than your memoization idea, since that's what lazy seqs do for you anyway, but this allows the consumer to indicate when it wants to reuse the old one (on retry) vs. getting a new one (after commit)

12:29 cark: i think both memoization and lazy-seq are overkill, memoization has this hash-table stuff that i don't need for a no-parameter function, and lazy-seq all the lazy-stuff for a one-off

12:30 rhickey : hey i'm working in telecoms ! i'm in the fortune 1bazillon bracket

12:31 Chouser: cark: (repeatedly create-connection) ; that's it

12:31 cark: chouser : right but i need to maintain a reference to the sequence

12:32 woodz: rhickey: interesting article, although I'm not sure about the "I think Scala's got the edge because I've never grokked Lisp" line of thinking.

12:32 Although I can imagine moving from Java to Scala being a gentler experience than Clojure.

12:33 rhickey: woodz: probably, I'm not too keen on the whole 'vs' way of thinking - the Java market is positively huge and has more than enough room for Clojure and Scala

12:33 woodz: Agreed. Language wars tend not to go anywhere.

12:35 Licenser__: I found the article pretty empty. It's a prefference there are hardly any facts at all presentet :/

12:35 Ruby isn't better then Clojure because I am more used to it either :P

12:37 rhickey: I think the fact that it is a question - whether or not a mostly functional Lisp will be a contender, that is most interesting

12:38 Ultimately tools get adopted because people accomplish things with them, not due to any arguments for/against

12:38 e.g. PHP gets not much love as a language in and of itself

12:39 cark: ~paste?

12:39 clojurebot: lisppaste8, url

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

12:40 cark pasted "once" at http://paste.lisp.org/display/85905

12:40 cark: chouser : there !

12:41 LauJensen: rhickey: Hows newnew coming along ?

12:47 Licenser__: rhickey: PHP is a horrible language :/

12:47 rhickey: LauJensen: I hope to get back to it this week - only 2 things left - fabrication of bridge methods and non-reflective self calls

12:47 LauJensen: great

12:51 jwr7: Is there anything that would prohibit a dosync block inside a watch function?

12:52 I have a watch function (added to an agent via add-watch) and I'd like it to update some refs. But it seems as though my dosync just quietly does nothing...

12:53 LauJensen: It can be tough to catch errors in threads, but dosync should work fine

12:53 jwr7: LauJensen: you mean there could be exceptions thrown without them being visible to me?

13:11 Licenser__: hrm clojugre gives errors that are about as helpfull as Java exception :/

13:11 what is this meaning: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Boolean (NO_SOURCE_FILE:0)

13:11 ?

13:14 The code that caiuses it is: http://pastie.org/592293

13:15 woodz: (true) on line 10 doesn't look right.

13:15 Licenser__: never mind I found it ^^

13:15 woodz: yes exactly

13:15 I had the impression that I need to put everything in ()

13:16 woodz: Too many parentheses in a Lisp... Who'd have thought..? ;-)

13:16 Licenser__: :P

13:19 alinp: hi

13:19 Licenser__: hi alinp

13:20 alinp: something weird is happening here when using memoize function

13:20 (def x (memoize reduce))

13:21 and running (x + (range 0 99999999))

13:21 no improvement

13:21 I mean, running it for few times

13:22 when used for ... fib function for instance, everything is ok

13:24 LauJensen: jwr7: I appologize for the delay. Yes - I dont remeber ever seeing exceptions from threads in my lisp buffers

13:24 luis: alinp: how do you test for equality between two sequences?

13:24 jwr7: LauJensen: it seems you're right -- removing some println statements cured the issue.

13:24 alinp: luis: yeah ... now I'm starting to figure it out :)

13:25 (range 0 9999) will yield each time other object :)

13:25 so, different param

13:25 LauJensen: jwr7: k, cool. The one certain debug instance you have is (javax.swing.JOptionPane/showMessageDialog nil "foo")

13:25 alinp: true

13:25 thanks luis

13:25 luis: alinp: it wasn't a rethorical question, but glad I could help. :)

13:25 alinp: :)

13:26 luis: eq between 2 seq ... are eq if all elements are in the same order and the same elements

13:26 some naive comparator .. it would sould like this

13:26 right ?

13:26 luis: it would what?

13:27 alinp: s/sould/sound/g

13:27 :D

13:28 luis: ,(== (range 0 1) (range 0 1))

13:28 clojurebot: false

13:28 alinp: so, it's using the java approach ? :)

13:28 comparing hashCode ?

13:29 luis: alinp: IIUC, == calls the equal() method.

13:29 Chouser: == is for numbers

13:29 ,(= (range 0 1) (range 0 1))

13:29 clojurebot: true

13:29 alinp: so, Chouser why my memoization doesn't work ?

13:30 * Chouser reads back...

13:30 alinp: (def x (memoize reduce))

13:30 (x + (range 0 99999999))

13:31 running it for few times -> no improvement

13:31 for sure I'm missing something, but don't know what

13:32 jwr7: I'm curious -- why do the watch functions (see add-watch) take a reference argument? You're not supposed to deref it anyway, and you are definitely not supposed to mutate it. So what is it for?

13:32 luis: alinp: see, I told you I didn't know how test for equality. :)

13:32 * luis shuts up now

13:32 alinp: :)

13:33 Chouser: alinp: (hash (range 0 1e7)) takes a long time -- that has to be done even to get a cache hit

13:33 alinp: oh, I see

13:34 Chouser: it's probably taking almost as long to get the hash in order to do a lookup as it does to sum them

13:34 hm

13:34 alinp: yeah

13:34 true

13:34 it seems so

13:35 ,(time (hash (range 0 9999999)))

13:35 clojurebot: Execution Timed Out

13:35 Chouser: oh, neat -- the assoc of a big range on a small map is fast because it's an array map and doesn't have to hash to insert

13:35 alinp: ok Chouser, it makes sense now

13:38 thanks also for hash function, didn't know about it

13:38 I used (. xxxx hashCode) :)

13:39 in fact, range returns a lazy seq ... ok

13:39 and .... in order to get the hash code, you need to evaluate all of it's elements

13:39 so, that's why I think it takes so long

13:40 Licenser__: hmm clojure is really nice for such nifty things as the problems on the project thing

13:43 luis: Licenser_: project euler?

13:44 Licenser_: http://projecteuler.net/ <- this one. Chouser was so nice to remind me of it, it's nice to get used a bit to the way you deal with things in clojure

13:44 I love how you can create a lazy sequence of prime numbers ^^

13:55 jwr7: java.util.concurrent.RejectedExecutionException -- hints, anyone?

13:56 Licenser_: Java feels rejected?

13:58 Chouser: need a stack trace

13:58 I think thread pools throw that when you try to queue something after they've been stopped

13:59 jwr7: Chouser: are there any limits to the number of actions I can enqueue?

13:59 Chouser: dunno

14:00 jwr7: Chouser: I'm sending lots of agent actions (well, in the thousands) and there is something wrong with the code, so they might get queued somewhere...

14:08 LauJensen: jwr7: I think you should keep it below 2000 as a general rule of thumb

14:09 jwr7: LauJensen: uh-oh, then I might have a problem.

14:10 Any reasons for this limit? I would love to be able to enqueue more, as this means less data structures in my application.

14:11 ok, I think the exception was caused by bugs in the code and my testing session. Restarting clojure made it go away.

14:11 LauJensen: jwr7: Check out James Reeves reply in this post, his first one: http://groups.google.com/group/compojure/browse_thread/thread/1f0df9d6656fa069

14:11 According to him - And I've learned not to question what he says - Its a limitation of Java

14:12 Chouser: that's number of simultaneous threads, isn't it? That's not the same as number of agents or number of actions.

14:12 jwr7: LauJensen: oh, but he's talking about threads, and I mean actions.

14:13 The thread pool is CPUs+2, from what I know. It's just that I expect to enqueue lots of agent actions.

14:13 LauJensen: I'm talking about threads as well.

14:13 Chouser: ,(let [a (agent 0)] (send a #(do (Thread/sleep 3000) %)) (dotimes [i 1e4] (send a inc)) (await a) @a)

14:13 clojurebot: 10000

14:13 Chouser: 10000 actions, no problem.

14:13 jwr7: Chouser: oh, cool. I should be fine, then.

14:14 Chouser: ,(let [a (agent 0)] (dotimes [i 4] (send a #(do (Thread/sleep 2000) %))) (dotimes [i 1e4] (send a inc)) (println "awaiting") (await a) @a)

14:14 clojurebot: Execution Timed Out

14:15 Chouser: ,(let [a (agent 0)] (dotimes [i 4] (send a #(do (Thread/sleep 1000) %))) (dotimes [i 1e4] (send a inc)) (println "awaiting") (await a) @a)

14:15 clojurebot: 10000

14:15 awaiting

14:15 Chouser: you can't see the timing of it there, but if you run it yourself you'll see

14:16 there I'm clogging up the send queue so that all the inc actions will queue up. You'll see "awaiting" almost instantly.

14:16 oh, I didn't need that -- this is one agent, so my first example was sufficient.

14:22 stuarthalloway: am I crazy, or didn't somebody start writing seq-utils tests? Don't see them in contrib...

14:22 clojurebot: contrib is http://github.com/richhickey/clojure-contrib/tree/master

14:23 stuarthalloway: did I just accidentally invoke the clojurebot...

14:24 Licenser_: How is the regexp support in clojure?

14:27 Chouser: Licenser_: stellar

14:27 stuarthalloway: he just chimes in on his own at times.

14:27 * Licenser_ googles for that

14:27 Chouser: Licenser_: er, I just meant that clojure has fantastic regex support.

14:27 Licenser_: oops oh okay

14:28 Chousuke: ,(class #"foo")

14:28 clojurebot: java.util.regex.Pattern

14:28 Chousuke: like that.

14:28 Licenser_: Good start

14:28 Chouser: contrib str-utils2 has nice helper functions if what's in core is insufficient.

14:28 Licenser_: *nods*

14:29 Chousuke: It'd be really neat if regexps could be used as functions though :/

14:29 Chouser: Chousuke: would they act like re-seq or re-find or something else?

14:30 Licenser_: yes it would be nice if you could use them as functions something like: (/"/'/s string)

14:30 * Licenser_ thinks that would be very niceish

14:31 Chouser: (str2/replace string #"\"" "'")

14:31 not quite as succinct as perl, I suppose

14:31 Licenser_: Chouser: yes but the other one would be nicer :P

14:32 I love how nice ruby (sorry I love the language) handles regexp's :P

14:32 Chousuke: Chouser: probably just returning the match or nil if none. could be used as a filter. hmm.

14:32 Chouser: Chousuke: both re-find and re-seq do that

14:33 Licenser_: hmm you could actually give back a lazs seq that gives all matches peace for peace if possible ^^

14:33 Chouser: Licenser_: that's re-seq

14:33 :-)

14:33 Licenser_: ow

14:33 that is incredible nice

14:35 hmmm I really really like the lazy sequence idea is really really great

14:37 Chouser: I've done some experiments mmaping a large text file, then using re-seq on it to load and search only as much as needed until I have the matches I need.

14:37 pretty fast

14:38 (take 3 (re-seq #"this.*stuff" mmaped-file))

14:38 * Licenser_ thinks the fastest way would be to read the next step while you process this one

14:38 Licenser_: like the further thingy

14:39 Chouser: seque will do that for you.

14:39 it allows a lazy-seq producer to, in another thread, get ahead of the consumer by however much you want to allow

14:39 Licenser_: neat

14:50 Chouser: chunking 'for' just passed all the regression tests. Now to see if it's actually any faster...

14:51 oh, whoops, no it didn't...

14:51 Licenser_: I wonder why did they made up a new regexp syntax?

14:51 Chouser: Licenser_: who?

14:51 Licenser_: why not use /<regexp>/ but #"<regexp>"

14:51 Chouser: oh

14:51 Licenser_: clojure

14:52 I think that isn't a good step, it will scare some people

14:53 Chouser: it's hard to tell at read time if / foo / is a regex or the / symbol twice and the symbol foo in between

14:53 in clojure # always indicates special reader behavior, the exact sort indicated by the following char

14:54 Chousuke: Licenser_: / would have complicated things a LOT.

14:54 Licenser_: hmmm but it would be nicer .p

14:54 Chouser: #^ is metadata, #_ a comment, #( an anonymous fn, #" a regex

14:54 I guess one could make a case for #/regex/

14:54 Chousuke: though #/foo/ would perhaps have been a better... yeah.

14:54 Licenser_: I was about to say that

14:55 get out of my head :P

14:55 it's getting crowded in here

14:55 Chouser: heh

14:55 Licenser_: I think using // would be possible but I understand that it would make stuff a lot harder

14:55 Chousuke: for the reader, anyway :P

14:56 Licenser_: yes

14:56 I think people would understand stuff

14:56 Chouser: and there are always lots of readers. rhickey is wary of making up new parsing rules that make it hard for syntax coloring tools, etc.

14:56 Licenser_: and who would write if( / foo /)

14:56 I'm not even sur eif that would make any sense

14:56 or even be conform syntax

14:57 it is good syntax but it makes little to no sense

14:57 who would ever want to test /?

14:58 Chousuke: hmm

14:58 ,/

14:58 clojurebot: #<core$_SLASH___4112 clojure.core$_SLASH___4112@9830bc>

14:58 Chousuke: that's actually the only symbol allowed to contain / :P

14:58 ,foo/

14:58 clojurebot: Invalid token: foo/

14:58 Licenser_: so it is special

14:59 well you use it to seperate namespace and thing

14:59 Chouser: right

14:59 Chousuke: yeah. normally / is the namespace separator

14:59 ,'core/foo/bar

14:59 clojurebot: core/foo/bar

14:59 Chousuke: hmm.

14:59 ,'core/foo/

14:59 clojurebot: Invalid token: core/foo/

15:00 Chouser: ,(namespace 'core/foo/bar)

15:00 Chousuke: apparently it's only forbidden at the end :/

15:00 clojurebot: "core/foo"

15:00 Licenser_: (ns/bla /) still would be non confusable since you can't call a namespace

15:00 you can use / within namespaces o.O

15:00 ,(namespace 'core/fooµbar)

15:00 clojurebot: "core"

15:01 Licenser_: he does not like that :P

15:01 Chousuke: well, you can but I don't think it's supported :P

15:01 Licenser_: no unicode namespaces?

15:01 Chousuke: your namespace is core in that symbol

15:02 ,(namespace 'cœre/foo)

15:02 clojurebot: "cœre"

15:02 Chouser: gah

15:02 Licenser_: heh

15:02 Chousuke: but I think that might not work when actually creating a namespace :P

15:02 Licenser_: nice

15:03 (ns µbla)

15:03 nil

15:03 1:48 µbla=>

15:03 weeh I can use µ as a namespace

15:04 Chousuke: ,(namespace ' / )

15:04 clojurebot: nil

15:04 Licenser_: I wonder if the rhickey here is the guy who started the whole thingy?

15:05 Chousuke: he is.

15:05 Licenser_: so we can pester him to make #" #/? *dodges and hides*

15:05 Chousuke: Well, you can but you'll probably fail :P

15:05 and I don't recommend trying.

15:06 gko: Hello: In SLIME, how do you interrupt a stuck REPL because of socket problem?

15:06 Licenser_: Oh apple will be happy:

15:06 ,(ns )

15:06 clojurebot: nil

15:07 Licenser_: I like that you can make funky namespaces this way :D

15:07 Chousuke: I think most of unicode works.

15:07 Though I'm not sure if things beyond the BMP will

15:07 Licenser_: No idea

15:09 * Licenser_ is just hearing 'Clojure for Java Programmers' and thinks it is really good

15:10 Licenser_: Hmm okay another question, clojure is really nice for one machine pralelism, but is there a build in way to utilize more then one system?

15:11 Chouser: it can take advantage of any of the several systems for spreading java work across multiple machines.

15:11 LauJensen: gko: slime-abort-connection

15:11 Licenser_: so nothing clojure intern thingy

15:11 Chouser: people are working to make several of them play as nicely with clojure as possible.

15:11 right, nothing internal.

15:12 Licenser_: something like

15:12 Chouser: though the print/read stuff may be a nice way to send data around.

15:13 Licenser_: (register <ip>) or so would be nice when it then connects to a clojure on the other end and pmap or so automatically uses the second host

15:13 rathore_: chouser: i'm using print/read to send data between requesters and workers in swarmiji

15:13 icey: so... I've recently cocked up my emacs installation... who currently has the best dox on getting emacs + clojure up and running from scratch (on a mac if it makes a difference) technomancy is the one I used previously, I think

15:13 Chouser: rathore_: I've heard good things about swarmiji, but I haven't looked at it yet.

15:13 gko: LauJensen: Thanks!

15:13 Licenser_: what is swarmiji? (googeling for it too)

15:13 rathore_: chouser: thanks, maybe u will need it some day :)

15:14 licenser_: swarmiji is a parallel, distributed computing framework for Clojure

15:14 Licenser_: Ah neatisch

15:14 rathore_: we use it at runa.com to split up computations in real-time

15:14 http://swarmiji.org

15:16 Licenser_: ah neat

15:17 looks cool

15:18 it's nice how good clojure seems to be for paralelism

15:18 Chouser: hmph. chunked 'for' is right except it does an extra 'seq' in some cases.

15:19 rathore_: licenser_: it absolutely is... and with swarmiji you can go across jvms on different machines also

15:19 Licenser_: Yes that is like a perfectish thing

15:19 psmyth_: I'm trying to implement a Java interface using (proxy <class...> <args..> & <fns>)

15:20 sets up ok but some callbacks don't seem to get tripped

15:21 anybody have experience with this? maybe there are threading issues?

15:22 StartsWithK: what part of clojure.contrib.expect depends on 'immigrate'?

15:23 Chouser: psmyth_: threading shouldn't be an issue unless you're using proxy-super

15:25 psmyth_: almost like the API I am coding against isn't "grabbing" the callback methods.

15:25 Chouser: if you misspell a method, no error is generated

15:26 Licenser_: why is this happening:

15:26 ,((first '(+)) 1 2)

15:26 clojurebot: 2

15:26 Chouser: ,(class (first '(+)))

15:26 clojurebot: clojure.lang.Symbol

15:26 psmyth_: gotcha

15:26 Licenser_: ,(class +)

15:26 clojurebot: clojure.core$_PLUS___4094

15:27 Chouser: ('+ {:a 1, :b 2, '+ 3})

15:27 ,('+ {:a 1, :b 2, '+ 3})

15:27 clojurebot: 3

15:28 Licenser_: hmm how could I get this to work o.O

15:28 Chousuke: you want the function from the symbol?

15:28 Licenser_: yap

15:28 Chousuke: ,(resolve '+)

15:28 clojurebot: #'clojure.core/+

15:28 Licenser_: ah nice

15:28 Chousuke: that way you get the var

15:28 which just forwards to the function

15:29 Licenser_: :D thanks

15:32 danlei: also (class (first (list +))), ' quotes

15:33 (or: (class (first [+])))

15:33 Licenser_: dankthanks

17:21 dave[csc]: Anyone suggest a good tutorial/howto on tearing apart a file in Clojure? What I've found so far isn't so helpful...

17:26 Chouser: mostly you use normal Java libs for IO

17:27 there are a couple helpers, suchs line-seq and contrib's duck-streams, but it's still all built on Java libs.

17:34 dave[csc]: Chouser: I've looked in to duck-streams a bit... I guess I'll just have to stumble through. Thanks though

17:36 octe: whye does this: http://pastebin.ca/1540870 cause an infinite loop?

17:36 i presume, because i get an outofmemory error..

17:38 Chouser: iterate creates an infinite seq

17:38 Chousuke: next returns a seq. :)

17:38 octe: yes. what does next to do a seq when it's trying to return a seq?

17:38 Chouser: all of which is fine, but the repl then tries to print that still infinite seq that 'next' returns

17:39 ,(next '(1 2 3 4 5))

17:39 clojurebot: (2 3 4 5)

17:39 octe: ah

17:39 clojurebot: Paul Graham is the creator of the other new lisp

17:39 octe: i see

17:39 Chousuke: Clojurebot's sudden interjection made me laugh :P

17:40 apparently "ah" matches graham :P

17:40 octe: i want to create a sequence that generates numbers like for example: 1,3,5,7,9,1,3,5,7 and so on

17:40 i guess a sequence is what i'd want?

17:40 Chouser: ,(take 20 (cycle [1 3 5 7 9]))

17:40 clojurebot: (1 3 5 7 9 1 3 5 7 9 1 3 5 7 9 1 3 5 7 9)

17:41 octe: nice

17:42 Chousuke: though remember that seqs are persistent, so if you have a reference to the head, you'll end up keeping all the generated numbers in memory.

17:42 octe: hmm

17:42 dave[csc]: clojurebot: Are you open source?

17:42 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

17:42 Chousuke: so doing (def foo (cycle [1 2 3])) is not recommended, because then foo will always hold onto the entire seq

17:42 dave[csc]: Outstanding ^_^

17:42 octe: well, that's bad

17:43 Chousuke: octe: but you can do (defn foo [] (cycle [1 2 3])) to have a function that returns a new seq

17:43 then pass that onto whatever needs it.

17:44 eg. (dostuff (foo))

17:44 then the dostuff code can avoid holding onto the entire seq

17:44 octe: cool

17:46 dmix: is there a function to check if a string contains another string or regex?

17:47 Chouser: ,(re-find #"needle" "There is a needle in the haystack")

17:47 clojurebot: "needle"

17:47 Chousuke: there are regex functions. most string stuff is directly from java.

17:47 dmix: ty

17:53 krumholt: how can i check if clojure.contrib is loaded correctly?

17:55 danlei: (find-ns 'clojure.contrib) would be an indicator

17:55 but "loaded correctly" is a rather broad term

17:57 krumholt: ok that returns nil so i guess no it's not loaded

17:57 tomoj: yeah... e.g. I've been using stuff from it fine for weeks, but just realized my clojure.contrib.pprint is broken

17:58 danlei: krumholt: yes. for example: (find-ns 'clojure.contrib.monads) -> nil (require 'clojure.contrib.monads) -> nil (find-ns 'clojure.contrib.monads) -> #<Namespace clojure.contrib.monads>

18:00 dmix: has anyone found not knowing any java to be a significant drawback while using clojure?

18:00 krumholt: danlei, thanks

18:00 danlei, no i know it found the jar files and added them to the classpath

18:01 no/now

18:01 danlei: krumholt: but beware that it will still return nil for (find-ns 'clojure.contrib) after (require 'clojure.contrib.monads)

18:02 krumholt: danlei, yes i just wanted to check if the additional jar files are added to the class-path. i am trying to use the lightweight java gaming library

18:02 danlei: krumholt: there is something for this in contrib

18:03 krumholt: danlei, really? that would be nice

18:03 danlei: krumholt: clojure.contrib.classpath/classpath.jarfiles

18:03 krumholt: clojure.contrib.classpath/classpath-jarfiles

18:03 krumholt: danlei, thanks i look into that

18:03 danlei: you're welcome

18:16 cow-orker: dmix: I'd say so.... I don't know Java, what I know of it (the language that is) I don't line. I know common lisp well enough, but I find "learning clojure" (mostly the std java libs) fairly unpleasant. I wish more was wrapped in std libs :-)

18:17 /line/like

18:23 danlei: cow-orker: I somehow feel the same way, but wrapping is seen as against the "embraces the jvm" philosophy

18:28 cow-orker: yes, I guess... although I feel it should be possible to wrap more in std clojure libs and still embrace the JVM (but to a lesser extent the Java language). But thats just me!

18:30 ikitat: is anyone having problems getting clojure-mode + slime + clojure-swank working property in cocoa emacs 23? I can't seem to get my clojure results to echo in the REPL window, though they seem to compile.

18:30 danlei: atm I'm just using a little toolbox in which I collect my own little wrappers. In general I agree with you, but we're a minority. ;) (another thing I really didn't like was dropping nil-punning, but that's another story)

18:30 Chousuke: I think there aren't so many wrappers because it's still extra work.

18:31 and mostly redundant.

18:31 danlei: Chousuke: well, I pointed out a few things which really should be wrapped (for my taste at least) but there was not much positive response to that

18:32 Chousuke: it might be good to include some wrappers in contrib.

18:32 danlei: redundant, yes, if you are willing to "use java". it's more a personal taste thing I guess

18:32 tomoj: danlei: "nil-punning" means nil=='() ?

18:32 Chousuke: then it'd be easier to make a case for moving them to core :P

18:32 danlei: tomoj: (rest []) used to be nil

18:33 tomoj: don't like using next instead?

18:33 Chousuke: I don't miss nil punning, really. the (if (seq foo) ...) idiom is good enough.

18:34 tomoj: is (seq [...]) linear?

18:34 danlei: tomoj: no, because that only holds for restish things, not, e.g. ... map, or things like (filter zero? [1 2 3]). younow have to wrap them in seq. again, maybe it's only taste

18:34 clojurebot: for is not used often enough.

18:34 Chousuke: tomoj: seq is constant time.

18:34 tomoj: Chousuke: great

18:35 danlei: ah yeah I see what you mean I think

18:35 danlei: Chousuke: it feels awkward to me. as I said, it's a taste thing, I guess. It just doesn't feel "right" to me (maybe because of CL background)

18:36 Chousuke: It's not a real show-stopper, just a change I didn't like

18:39 dmix: similar to re-find, is there a function to check if a string contains any values in a collection? (not exact match) for ex "cat in craddle" contains? ["cat" "dog" "bird"] equals true

18:40 or should I just write one? :)

18:40 Chousuke: hm

18:40 tomoj: dmix: you can use "some" in addition to whatever string thing you're using

18:41 e.g.

18:41 ,(some #(.contains "cat in craddle" %) ["cat" "dog" "bird"])

18:41 clojurebot: true

18:42 Chousuke: hmm

18:43 ~def contains?

18:43 Wonder if that will work on strings. /:

18:44 tomoj: if you're looking for indexes, yeah :)

18:44 ,(contains? "foo" 1)

18:44 clojurebot: true

18:44 Chousuke: right.

18:44 dmix: thanks tomoj

18:44 why does that bot use tinyurl?

18:44 Chousuke: the urls are long :P

18:45 dmix: ah github, true

18:58 danlei: hm

18:59 (xxx 'bar '(foo bar baz)) -> true (or bar)?

19:00 Chousuke: (some '#{bar} '[foo bar baz])

19:00 ,(some '#{bar} '[foo bar baz])

19:01 clojurebot: bar

19:01 danlei: I see, or (.contains 'bar '[foo bar baz])

19:01 Chousuke: yeah.

19:01 danlei: so, thats a good example, where I would add "member" or "find"(taken) to my wrappers

19:02 tomoj: confused... you can't call .contains on a symbol

19:02 danlei: and that's pretty close to what I discussed a while ago. such things, in my opinion, should be in core, or at least contrib

19:03 tomoj: oh, you're right, sorry

19:03 tomoj: thaught it'd work

19:03 I mean, that's not something exotic

19:03 tomoj: I still don't understand what you're looking for

19:04 danlei: cl's MEMBER or FIND

19:04 (find 'foo '(foo)) -> foo

19:04 (member 'foo '(foo bar)) -> (foo bar)

19:05 Just wanted to show an example of (to my feelings) missing things in the core

19:05 clojurebot: show is clojure.contrib.repl-utils/show

19:05 tomoj: ah, I think I see what you mean

19:05 contains? promises to be constant/log time so it can't do that

19:05 you want a function that wraps the "some" idiom?

19:06 danlei: some is 2 steps more general

19:07 and it doesn't feel nice to have (some #{bla} '[bla]) to me

19:07 *just have

19:07 tomoj: (defn find-member [coll x] (some #{x} coll))

19:07 :)

19:07 but yeah I see what you mean

19:07 danlei: if I looked for this functionality, the first thing I would look for would be someting like find, or member

19:07 Chousuke: ,(drop-while (complement '#{bar}) '(foo bar zonk)) the member equivalent is a bit less nice.

19:07 clojurebot: (bar zonk)

19:08 danlei: oh, thanks, but that I could have done myself

19:08 It's not about member specifically

19:08 Chousuke: using sets is a clojure idiom though so I think teaching people to use them is better than introducing a function for it. :)

19:08 tomoj: well, hmm

19:08 danlei: It's just that I often have to search java documentation on some classes for things I just except in a languages core

19:08 that's what I wanted to point out

19:09 maybe it was not the best example

19:09 tomoj: ,(.contains '[foo bar] 'foo)

19:09 clojurebot: true

19:09 danlei: hehe

19:09 tomoj: oh, but that's boolean

19:09 danlei: yes, but it's ok

19:09 Chousuke: danlei: well, that's half-intended for clojure.

19:09 danlei: Chousuke: yes, I know

19:09 Chousuke: I'm always free to write my own toolbox of wrappers (and I do so)

19:10 but somehow it just ... sometimes really gets on my nervers ;)

19:10 *nerves

19:10 Chousuke: It might be possible to get these things into core through contrib though.

19:10 I doubt anyone would object to some more utility functions in contrib.

19:10 clojurebot: functions are maps

19:11 danlei: and, what's really bad about that: In some point in time, no other clojure user will understand my code, without knowing my whole wrapper toolbox

19:11 that's why I'd like this stuff at least in contrib

19:11 Chousuke: well, all you need is a CA and then a post to the mailing list for discussion :/

19:11 danlei: Chousuke: well, I'd surely appreciate that

19:11 ah, yes. that CA thingie

19:11 should maybe really do that

19:12 once I had some snipped I felt belonged in core

19:12 but thought it wasn't worth the CA

19:12 Chousuke: It doesn't take much, really.

19:12 danlei: s/core/contrib

19:12 yes, It's just a minor inconvenience, you're right

19:13 If I understand you right, even for contrib I'd have to "pass" some kind of "vote"(?)

19:13 I mean, you don't get an CA and can add what you want, can you?

19:14 Chousuke: danlei: well, yeah. contrib is not a dump for random things.

19:14 danlei: sure, but how exactly does it work?

19:14 Chousuke: but if enough people show interest in your library I think it'll get in. :P

19:14 danlei: so it's not clearly defined how you get things in?

19:14 Chousuke: I guess that's right.

19:14 danlei: hm, I see

19:15 Chousuke: you just need one of the committers to support you I guess.

19:15 danlei: you have that CA?

19:15 *done

19:15 Chousuke: yeah, though I'm not a contrib committere

19:15 -e

19:17 danlei: http://paste.lisp.org/+1UAQ is what I had in mind

19:17 I think there's nothing like that in contrib right now (last time I checked)

19:17 nothing earth-shaking but I sometimes have use for it

19:17 Chousuke: that would do fine in repl-utils I think.

19:18 danlei: I think I should just do that CA and try to convince at the list about my thoughts about wrappers

19:18 maybe some people would support that idea

19:19 tomoj: I get worried about old mappings left in my namespace when using slime

19:19 that would be neat

19:19 Chousuke: I've been bitten by that a few times :P

19:19 once I had all the needed functions in my code, but in the wrong order :)

19:19 tomoj: jeez I hadn't even thought about order

19:20 Chousuke: then it broke when I "rebooted"

19:20 dmix: tomoj, in the code earlier (some #(.contains "cat in craddle" %) ["cat" "dog" "bird"]) is there a way to return which value it was? (cat) or is it limited to true/false because of some

19:20 tomoj: it's limited to true/false because of .contains

19:20 danlei: there we go :) cl:find is needed ;)

19:20 tomoj: but you could use find-first from contrib

19:21 dmix: thanks ill try it

19:21 tomoj: ,find-first

19:21 clojurebot: java.lang.Exception: Unable to resolve symbol: find-first in this context

19:22 Chousuke: (doc find-first)

19:22 clojurebot: "clojure.contrib.seq-utils/find-first;[[pred coll]]; Returns the first item of coll for which (pred item) returns logical true. Consumes sequences up to the first match, will consume the entire sequence and return nil if no match is found."

19:22 tomoj: ,clojure.contrib.seq-utils/find-first

19:22 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.seq-utils

19:22 tomoj: :(

19:22 danlei: ah, and there it is ;)

19:22 tomoj: he has the docs but can't use the functions?

19:22 Chousuke: clojurebot's doc is a bit specia.

19:22 l

19:23 ,(refer 'clojure.contrib.seq-utils)

19:23 clojurebot: java.lang.Exception: No namespace: clojure.contrib.seq-utils

19:23 danlei: ,(require 'clojure.contrib.seq-utils)

19:23 clojurebot: nil

19:23 danlei: ,(refer 'clojure.contrib.seq-utils)

19:23 clojurebot: nil

19:24 tomoj: ,(find-first #(.contains "cat craddle" %) ["foo" "cat"])

19:24 clojurebot: "cat"

19:24 dmix: yeah it works :)

19:24 danlei: :)

19:24 tomoj: weird.. is clojurebot polluted with seq-utils now until it dies?

19:24 Chousuke: yes :P

19:25 * danlei ducks

19:25 Chousuke: though I suppose hiredman can always unmap the stuff.

19:25 tomoj: oh, there's a contains? for strings in str-utils2

19:26 heh, http://is.gd/2vuhh

19:26 (contains? s substr) == (.contains s substr)

19:26 apparently someone agrees with you, danlei :)

19:27 danlei: :)

19:27 tomoj: also, there's includes? in seq-utils too

19:27 ,(includes? '(foo bar baz) 'bar)

19:27 clojurebot: true

19:28 Chousuke: hmm :/

19:28 danlei: bit confusing that they all share names. should maybe be generic functions, or someting

19:28 tomoj: wonder why it uses (fn [y] (= y x)) instead of #{y}

19:29 lowlycoder: since Thread/stop is being deprecated, what's the clojure way to stop a thread?

19:29 to have the thread share a global ref with the main program? to use agents? ....

19:30 tomoj: ants.clj uses agents that check a global var

19:32 * danlei looks for a cl:member equivalent in seq-utils

19:33 ikitat: uhg. Does anyone know why I can't get *slime-repl clojure* to display anything useful?

19:34 it's just the user> prompt

19:34 (+ 1 1) C-c C-c

19:34 minibuffer says compilation finished 0 errors 0 warnings 0 notes

19:34 REPL doesn't blink

19:34 danlei: you mean, (+ 1 1) <return> doesn't evaluate and print the result?

19:35 * danlei only C-c C-c's in source files

19:35 ikitat: danlei, I'm using clojure-mode in emacs and I'm C-c C-c'ing in a s ource file

19:35 but it doesn't show the result in the repl

19:35 tomoj: the repl doesn't do anything when you compile..

19:35 ikitat: how can I get the code to show up in the repl?

19:36 tomoj: go over there and type it in :)

19:36 danlei: try C-c C-c'ing a defn and use it in the repl

19:36 tomoj: you can see the result in the minibuffer with C-x C-e

19:36 ikitat: heh.. oh, I swore I've seen videos of people just executing in the repl from their clojure buffer

19:36 tomoj: or C-M-x

19:36 ikitat: and though.. danm, that's cool

19:37 tomoj: I saw a trick someone had for that somewhere

19:37 but afaik it's not built-in

19:37 ikitat: actually, I think it even did that for me in aqua emacs, but I've been stuck since going to cocoa emacs 23

19:38 tomoj: ikitat: http://bc.tech.coop/blog/070424.html

19:38 that's old, maybe slime has something for it now

19:38 I'm in aquamacs emacs, and it doesn't do that

19:39 (by default)

19:41 I've never really noticed because I don't usually have top-level forms in source files for which I want to see the result

19:41 danlei: so, no member in seq-utils. should get that CA and add something like (defn member [thing coll] (drop-while #(not= 'bar %) coll)) in there

19:41 Anniepoo: Is there a way I can run a clojure script from within a java program?

19:41 tomoj: I'd vote for a less CL-like name :)

19:42 "member" doesn't really make sense to me as a name for that function

19:42 Chousuke: ikitat: the result of a C-x C-e is shown in the minibuffer.

19:42 ikitat: heh.. ok, you are all right, I must have been seeing things... :)

19:42 danlei: well, ... it looks for a member, but is restartable. what would you prefer?

19:42 ikitat: I just checked it in aquamacs again

19:43 overall I'm pretty excited about emacs, I've used vim for over 10 years... I was probably hallucinating from excitement ;)

19:43 Chousuke: heh :P

19:43 danlei: btw, that's just a toy member function, it should also take test and key keyword args, to come close

19:43 :)

19:43 Chousuke: I used viper some when I went to emacs, but it doesn't play well with paredit so I'm using it less and less...

19:43 danlei: ikitat: was the same for me :)

19:44 btw, chosuke: you know a convenient way in paredit to "close all sexps"?

19:44 Chousuke: hmm :/

19:44 no.

19:45 tomoj: danlei: good point, I can't think of another name

19:45 ikitat: Chousuke, yeah, viper just doesn't cut it... I'd rather go cold turkey.. though it's hard I have a lot of built up vim knowledge. I'm still trying to pick up the things that I absolutely need to do a lot

19:45 Chousuke: the sexps should always stay closed though. But that's not what often happens

19:46 ikitat: remapping my brain is harder than it used to be

19:46 Anniepoo: danlei continues to rock for having gotten noobie me up on slime, swank, paredit, emacs, etc stack the other nite

19:46 danlei: Chousuke: well, in my case it's more that I used to close-all-sexp's before I started using paredit, I'm just looking for a convenient way to get to the end of a form quickly

19:46 Anniepoo: you're welcome

19:47 C-M-e would be a candidate, I guess

19:47 but it's not quite the same

19:48 Anniepoo: you like it?

19:48 Chousuke: danlei: end of a form? ctrl-k?

19:48 danlei: Chousuke: bound to paredit-kill for me, what is it bound to normally?

19:49 Chousuke: isn't paredit-kill what you want?

19:49 it kills whatever comes after point, but keeps the sexp structure intact.

19:49 danlei: no, I want to move point after the form I just entered

19:49 Anniepoo: so far I'm still in the 'I get all tangled up and eventually ctrl-alt-del kill it' stage

19:49 danlei: s/after/behind/

19:49 Chousuke: danlei: ah, I misunderstood you then. hmm.

19:49 Anniepoo: but am still willing to believe some day I'll love it

19:49 danlei: Anniepoo: :)

19:50 Chousuke: danlei: actually, it looks like ) should do that :/

19:50 danlei: Anniepoo: It'll take some time, but (for me) it was worth it

19:50 Chousuke: yes, what I want is like ) but it goes behind ALL closed parens

19:51 Chousuke: no idea then :/

19:51 Anniepoo: ok

19:51 danlei: Chousuke: atm I'm doing something like end-of-defun paredit-forward

19:51 Chousuke: thanks anyway

19:52 Anniepoo: I'm skeptical now because I don't see any ez way of navigating from file to file within it

19:52 Chousuke: Anniepoo: within emacs?

19:52 danlei: Anniepoo: C-x b in ido-mode is quite comfortable

19:52 Anniepoo: yes

19:52 danlei: Anniepoo: and did you check out M-.?

19:53 Anniepoo: no, but if it's got those tools, cool

19:53 danlei: M-. and M-, actually

19:53 Anniepoo: 8cD

19:53 danlei: for quick buffer switching i recommend ido-mode

19:53 Anniepoo: ok

19:53 danlei: also helps for opening files

19:53 Chousuke: heh, yeah

19:53 danlei: it's build in, just try M-x ido-mode and switch buffers or open a file

19:54 tomoj: (or get the starter kit)

19:54 Anniepoo: I'm going to have to find a day and write some totally toy project where I can just focus on learning the dev env

19:54 Chousuke: most of the time I just type some part of the file name and emacs somehow magically finds it for me.

19:54 even if the path part is completely wrong.

19:54 danlei: that's what I do, too ;)

19:54 tomoj: sometimes I hate that

19:54 I try to make a new file and emacs says, "hey, are you looking for this file in that other project?"

19:55 danlei: tomoj: maybe you don't like the fuzzy part of it

19:55 tomoj: ah :)

19:55 Anniepoo: question about JVM's - I'm running a java program, I want to execute some clojure within it and have them share the JVM

19:55 Chousuke: tomoj: heh, you don't type fast enough ;)

19:55 danlei: tomoj: you have to be quicker :)

19:55 pretty sure you can tweak the time, though

19:56 tomoj: I usually just switch to regular old find-file at that poit

19:56 Anniepoo: if I go clojure.main("path/to/myclojure.clj") will that be in the same jvm?

19:56 danlei: to make sure everyone knows about it: try C-SPACE to narrow search in ido, really convenient

19:57 Chousuke: hm, what an unconvenient keybinding

19:57 danlei: why unconvenient?

19:57 Chousuke: I have cmd acting as control and cmd-space is captured by OS X before emacs gets to it :P

19:57 danlei: aaah

19:58 that search function, innit?

19:58 tomoj: caps lock ctrl ftw

19:58 Anniepoo: not to mention that it's what initiates autocomplete in IntelliJ

19:58 Chousuke: danlei: it changes the input method for me, actually.

19:58 danlei: Chousuke: ah, ok

19:58 Chousuke: tomoj: I decided that caps lock is better as meta.

19:58 * danlei has input method change on M-S

19:59 lowlycoder: how does send and send-off differ? send uses from a thread pool, wheras send-off creates its own thread?

19:59 danlei: (meta-right shift)

19:59 tomoj: lowlycoder: exactly

19:59 danlei: *left

19:59 lowlycoder: tomoj: in practice, why do I care about this difference?

19:59 tomoj: if the function you're sending blocks, you could lock up all the threads in the thread pool

20:00 dmix: how come when you press up in repl (in osx term) it doesnt bring up the last command?

20:00 I seem to do a lot of copy/pasting

20:01 tomoj: you probably need JLine or something

20:01 ikitat: dmix you need to set up rlwrap or jline

20:01 tomoj: (but really, switch to a real repl :))

20:01 dmix: real repl, like in emacs?

20:01 tomoj: yeah

20:02 dmix: i wad putting that off :)

20:02 i spend too much time playing around with my .emac file

20:02 ikitat: tomoj how do you pull up recent expressions in the repl on emacs?

20:02 tomoj: M-p/M-n

20:03 and if you type a bit and hit M-p, it'll search for recent expressions starting with that

20:03 lowlycoder: is there a way in clojure to break on currenct function call w/o killing clojure; C-c tends to kill clojure as well

20:04 ikitat: hrm... is there a way to get it to do the search without anchoring it with a ^?

20:04 eg

20:04 user> (factorial 10)

20:04 user> facM-p

20:04 that doesn't find the previous expression

20:06 tomoj: hmm

20:06 M-r lets you type in a regexp

20:07 and then you can use M-p/M-n to navigate the results

20:07 ikitat: that works :)

20:09 tomoj: I think you'd have to write a new function to use the current input as the regexp

20:10 lowlycoder: (def blah (agent 3)) (send blah (fn [val] 4))

20:10 (await blah) (println @blah)

20:10 why do I get an error on the await?

20:12 tomoj: what's the error?

20:13 krumholt: how should i do an infinite loop in clojure?

20:16 tomoj: (while true ..) is an infinite loop

20:16 Chousuke: there is a while macro

20:16 you'll need some kind of a side-effect to break out of it, obviously.

20:16 an atom or a ref

20:16 lowlycoder: anyone actually have an example of how to use 'await' in clojure?

20:16 tomoj: lowlycoder: what's the error?

20:17 lowlycoder: java.lang.IllegalStateException: await in transaction

20:17 (def blah (agent 3)) (send blah (fn [val] 4))

20:17 (await 100 blah) (println @blah)

20:17 is the code ... i don't see where the transation is

20:17 tomoj: what is "(await 100 blah)" ?

20:18 Chousuke: (doc await)

20:18 clojurebot: "([& agents]); Blocks the current thread (indefinitely!) until all actions dispatched thus far, from this thread or agent, to the agent(s) have occurred."

20:18 lowlycoder: err, sorry, let's retry this:

20:18 (def blah (agent 3)) (send blah (fn [val] 4))

20:18 (await blah) (println @blah)

20:18 gives me: java.lang.IllegalStateException: await in transaction

20:19 tomoj: works fine for me

20:19 you're doing that at the repl?

20:19 Chousuke: are you sure it's not in a dosync block? :/

20:20 lowlycoder: ~/tmp:$ cat t3.clj

20:20 (ns t3) (def blah (agent 3)) (send blah (fn [val] 4)) (await blah)

20:20 clojurebot: No entiendo

20:20 lowlycoder: user=> (use :reload-all 't3)

20:20 java.lang.IllegalStateException: await in transaction (t3.clj:0)

20:22 tomoj: ~def use

20:23 lowlycoder: ah, the problem is that (use ...) is in a transaction?

20:24 tomoj: doesn't appear to be to me

20:24 but that's what I guess

20:24 s/guess/guessed/

20:25 but what you're doing looks strange to me anyway

20:26 lowlycoder: what i' doing is pointless; just trying to learn how agent works

20:26 tomoj: try putting it in a function and use then call the function

20:27 oh, refer calls out to java stuff looks like, maybe the transaction is in there

20:35 lowlycoder: eturns nil if returning due to timeout, non-nil otherwise.

20:35 so is returning 'false' fair game for this function?

20:37 tomoj: I think it's safe to assume "non-nil" means truthy

20:37 lowlycoder: tomoj: i'm getting false ... somehow

20:38 tomoj: weird

20:38 are you awaiting-for your send there that just replaces it with 4?

20:38 lowlycoder: yes

20:38 here, let me get a complete demo

20:40 (ns t3) (def blah (agent 3)) (send blah (fn [val] 4))

20:40 (defn mytest [] (println (await-for 0 blah)) (println @blah))

20:40 user=> (mytest)

20:40 false

20:40 4

20:40 nil

20:40 the false is surprising :-)

20:40 tomoj: well.. why are you awaiting for 0ms ??

20:40 lowlycoder: because i want to just check if it's ready

20:41 if it's ready, great; if not, i want it to return immediately

20:42 tomoj: well, await-for 1 then I guess

20:43 the docs are wrong there, I think

20:43 await-for returns _false_ if it times out

20:44 otherwise it returns true

20:44 but (await-for 0 ...) always times out

20:45 lowlycoder: lthat's too bad

20:45 in erlang, the wait for 0 seconds is a non-wating way to check "is there data?"

20:46 Chouser: an agent always has data, doesn't it? though it can be nil

20:46 just deref the agent to instantly see what its value is

20:47 tomoj: I think lowlycoder wants to get the data only if it's been updated

20:48 but not sleep (even for 1ms) if it hasn't

20:48 Chouser: yes, so never sleep, just fetch the value, right?

20:49 tomoj: but then you get a value back even if the send-off hasn't completed

20:50 lowlycoder: http://paste.lisp.org/+1UAU <-- why does this continue to print out true 4

20:50 tomoj: I think it's an imaginary problem :)

20:51 lowlycoder: i was under the impressession that @ or deref would 'consume' a value ... if not; waht's the point of await?

20:51 tomoj: consume??

20:52 Chouser: no, an agent hold a value. That's what it does.

20:52 tomoj: deref doesn't change anything, that would break clojure

20:52 Chouser: it always has exactly one current value

20:52 lowlycoder: i'm completely misunderstanding agents

20:52 tomoj: send says "hey agent, use this function to update your value"

20:53 await says "wait until the agent's done doing that"

20:53 lowlycoder: yeah; this looks very different from mailboxes

20:53 clojurebot: this is not a bug

20:54 tomoj: agents are not actors

20:54 Chouser: once upon a time I think Clojure called them actors, but rhickey changed it to help reduce the expectation that they would behave like erlang actors.

20:56 rhickey: Chouser: they were never called actors once implemented

20:57 Chouser: renamed Actor to IRef Dec 2 16:17:12 2007 -- That's just the interface then?

20:58 lowlycoder: rhickey: why aren't there continuations in clojure? not caputing java stack frames i understand, but being able t have continuations for just clojure code seems feasible

20:59 Chouser: lowlycoder: Someone wrote some macro stuff to do something like continuations for Clojure code.

21:00 lowlycoder: Chouser: have a link? :-)

21:00 i would just write all my code in continuation passing style, ... but clojure doesnt have tail call optimiation either :-)

21:00 rhickey: Chouser: no one was supposed to use them prior to 1203/2007 :)

21:01 12/03

21:01 lowlycoder: when/if the JVM gets continuations Clojure will too, not before

21:02 Chouser: lowlycoder: I haven't looked at this beyond the description: http://github.com/swannodette/clj-cont/

21:02 lowlycoder: are trampolines expensive?

21:12 rhickey: ooh, much better group search via: http://groups.google.com/advanced_search?q=&

21:12 select google groups radio button and specify clojure as the group

21:13 Chouser: even message id. nice.

21:13 cark: chhouser : after much thinging about this database ocnnection thing, i'll go with neither solution, agents instead of refs, and a blocking queue to make these actors

21:14 Chouser: cark: ok, that sounds sane.

21:14 cark: the side effect the clue

21:14 was the clue

21:14 Chouser: ok, *now* 'for' passes all tests.

21:19 huh, the timing is all over the place. but the average for chunked for is definitely better.

21:20 rhickey: Chouser: cool!

21:33 Chouser: seriously subsequent runs after plenty of warm up can still vary but about 2x

21:39 ok, chunked concat and for are at http://www.assembla.com/spaces/clojure/tickets/1

Logging service provided by n01se.net