#clojure log - Sep 17 2009

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

0:01 hiredman: looks like sort of a homebrew implementation of yield

0:02 well, no

0:02 I think I need definitely need more context

0:02 albino: aren't they just calling wait() on whatever the object is in a syncryonized fashion?

0:02 jamesp: Ok can't find an example. It's basically:

0:03 hiredman: jamesp: pastebin!

0:03 jamesp: Yea, I sec

0:03 hiredman: albino: but if they create a new object before every .wait, then how can anyone call notify

0:03 lisppaste8: _mst pasted "wait/notify" at http://paste.lisp.org/display/87214

0:04 hiredman: _mst: sshh

0:04 _mst: evilness, sorry :)

0:04 hiredman: we want to write it better

0:05 whatever api this is should most likely be using a FutureTask or some such instead of whatever weird wait/notify scheme they have

2:19 Bercilak: A couple days ago I was in here asking about doctests for clojure

2:19 There didn't seem to be anything obviously wrong with the idea, so I coded up an implemention

2:19 http://groups.google.com/group/clojure/browse_frm/thread/7fd233ca0beffb1b#

2:20 I'd love it if you folks could take a look and give me feedback

4:18 lowlycoder: has no one in the world writtttten a facebook app in clojure?

4:21 LauJensen: I hope not

4:23 lowlycoder: why not?

4:23 Fossi: lowlycoder: there are some facebook apps on appengine, but i guess none of them in clojure

4:23 LauJensen: I feel it would be very much like taking a diamond and using it to clean your toilet

4:23 lowlycoder: i'm not convined clojure is ready for primetime until i see facebook apps in clojure

4:23 Fossi: thorough?

4:24 arbscht: lowlycoder: why don't you write one? :)

4:24 LauJensen: lowlycoder: haha

4:24 clojurebot: primetime is <lowlycoder> i'm not convined clojure is ready for primetime until i see facebook apps in clojure

4:24 clojurebot: c'est bon!

4:25 lowlycoder: err; you need to pay me royalties

4:26 i actually think clojure/flash can be a very powerful combo

4:26 LauJensen: FLASH?!

4:26 Oh my

4:27 lowlycoder: it sounds like we're not twins separated at birth

4:27 LauJensen: lowlycoder: Please read this: http://en.wikipedia.org/wiki/Computer_programming, once you're done I'll take you to the next step

4:28 (that was a joke)

4:29 lowlycoder: the papervision3d engine is actualllllly pretty cool

4:29 i'd be interested to see a vw powered with papervision3d and clojure

5:14 Fossi: is there a macro in contrib that switches/reverses a functions arguments?

5:17 avital: Hello friends (and Chouser). Is there a simple way to write a version of merge that takes one argument which is a collection instead of multiple arguments? So that I could do something like (merge1 [{:a 3 :b 4} {:c 5}]) and get {:a 3 :b 4 :c 5}?

5:17 Chousuke: apply merge

5:17 :)

5:18 avital: Chousuke are you also Chouser?

5:18 Chousuke: ,(apply merge [{:a 3 :b 4} {:c 5}])

5:18 clojurebot: {:c 5, :a 3, :b 4}

5:18 avital: Thanks :)

5:18 Chousuke: no.

5:18 avital: ,(apply merge #{{:a 3 :b 4} {:c 5}})

5:18 clojurebot: {:b 4, :a 3, :c 5}

5:18 avital: cool

5:19 Chousuke: (doc apply)

5:19 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

5:19 Chousuke: very useful :)

5:20 avital: yes it is!

5:34 G0SUB: has anyone used StringTemplate here?

6:16 how can I convert a relative pathname to an absolute pathname?

6:17 ST expects the absoulte pathname, but I don't want to hardcode it.

6:25 Chousuke: G0SUB: the java.util.File class can do that.

6:26 G0SUB: Chousuke: any link to the docs?

6:31 Chousuke: http://java.sun.com/j2se/1.4.2/docs/api/java/io/File.html ? :)

6:31 oh, it was io

6:32 vy: Why does (class (.getBytes "as")) prints out "[B"?

6:32 G0SUB: Chousuke: :)

6:32 Chousuke: vy: [B is the class of a primitive byte array

6:32 vy: or that's what the JVM calls it, anyway

6:34 vy: I was expecting something akin to "#<byte [B@37a04c>".

6:35 Umm... Nevermind.

6:35 Chousuke: ,(.getBytes "as")

6:35 clojurebot: #<byte[] [B@86d597>

6:35 Chousuke: like that? :)

6:59 LauJensen: I have an agent who is calling himself on a regular interval. For the task at hand this is bad, he should rather respond to an event than poll - like wait/notifyAll - Any takes on how to implement that idiomatically?

7:15 arbscht: LauJensen: how about updating a reference which has a watcher?

7:15 LauJensen: watcher.... Thats might be what I was looking for :)

7:17 arbscht: Thanks, that looks good, I'll dig in

7:36 user> (add-watcher tst :send-off (agent 0) #(javax.swing.JOptionPane/showMessageDialog nil "triggered"))

7:37 I define tst as an atom with an int value, and after this expression I swap! inc on it, making it 3, but I never get a pop-up, why is that ?

7:39 hamza: hey guys, i am using Clojure 1.1.0-alpha-SNAPSHOT but select function is not avaible?

7:40 LauJensen: hamza: select-keys is

7:40 arbscht: Any clue on that watcher?

7:40 hamza: do i have to upgrade for select?

7:43 LauJensen: I imagine so, since its in the API spec

7:46 hamza: ,(doc select)

7:46 clojurebot: "clojure.contrib.datalog.database/select;[[db rn pt]]; finds all matching tuples to the partial tuple (pt) in the relation named (rn)"

7:48 arbscht: LauJensen: does the agent have errors?

7:48 LauJensen: the action-fn should take more arguments

7:49 hamza: the thing is i can not reference any of the set function union select rename do i have to import them?

7:49 LauJensen: arbscht: tried that also

7:50 hmm

7:50 I had add-watch/add-watcher a little mixed up arbscht :)

7:50 2 not 4 args

7:52 jdz: ,(doc clojure.set/select)

7:52 clojurebot: "([pred xset]); Returns a set of the elements for which pred is true"

7:52 * Fossi has just found ns-utils/immigrate

7:52 jdz: i think clojure.set is not used by default

7:52 Fossi: excellent. just what i was looking for a few days ago

7:52 hamza: thx that worked.

8:25 in a dosync block i need to some operations before setting a ref is safe to assume that the will not change until i exit the dosync block?

8:27 Chouser: the value of the ref seen within the transaction will not change.

8:28 hamza: kk, so any other write to the ref will be blocked until i am done?

8:28 Chousuke: no.

8:28 your transaction will just retry

8:30 hamza: kk, everthing starts over and i do everything again with fresh data?

8:30 Chousuke: pretty much

8:30 that's why you should not have side-effects in transactions

8:31 hamza: what i am trying to do is i am going to create a serial number than check if it is already used using a set. i don't want to assing same serial twice.

8:32 Chousuke: I think in that case you could just use an atom /:

8:32 using (swap! atom inc) to increment the counter

8:33 you don't even need a transaction :)

8:33 hamza: kk, thx i'll look at atoms

8:34 Chousuke: (doc swap!

8:34 clojurebot: EOF while reading

8:34 Chousuke: (doc swap!)

8:34 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & args]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

8:34 Chouser: but transactions compose in a way that atoms do not. If you're using refs elsewhere in related parts of the code, you might want a ref and transaction for this.

8:35 hamza: i didn't know about atom's so pretty much ref's every where.

8:36 Chousuke: you should keep the number of atoms and refs small though.

8:37 eg. if you need a global map of values that might vary, start with a single ref containing the entire map instead of a map containig refs :)

8:37 even if the values could change independently of each other.

8:37 the fewer refs you have, the simpler your code will be :P

8:39 hamza: kk,

8:39 lisppaste8: crios pasted "untitled" at http://paste.lisp.org/display/87223

8:41 crios: hello

8:41 just as my first clojure program, I was trying to emulate this java code: http://paste.lisp.org/display/87223

8:42 a simple "ping" "pong" program

8:42 where two threads write alternating strings, waiting each other

8:43 lisppaste8: crios pasted "untitled" at http://paste.lisp.org/display/87224

8:44 crios: this is my "clojure" version, of cource not working: http://paste.lisp.org/display/87224

8:44 I'm trying to understand what would be an idiomatic clojure way of doing something of similar

8:46 I should use really the locking macro?

8:48 adityo: hello

8:48 anyone done XML parsing with Clojure

8:49 Chouser: adityo: sure, there are namescapes clojure.xml and clojure.contrib.lazy-xml

8:52 adityo: i am using clojure.xml/parse and it returns a tree like map of tags, attrs and content, my question is how do i parse it?

8:52 once i am down to the first level of content it is a vector which is again a map of tag...

8:53 Chouser: adityo: that *is* parsed. what do you want to do with it?

8:53 if you want to query it, you might like clojure.contrib.zip-filter

8:54 adityo: Chouser: yeah its parsed, sorry. i want to get to the value of something nested

8:54 Chouser: crios: perhaps more idiomatic clojure would be to have to agents (instead of threads) telling each other to proceed.

8:54 hamza: may be that will help http://stackoverflow.com/questions/1194044/clojure-xml-parsing

8:55 crios: having two agents? so with a "await-for" the other agent?

8:56 Chouser: crios: well, with agents you'd mostly likely just let them go idle in between

8:56 crios: it's hard to know the best clojure idiom when the task isn't accomplishing much.

8:57 adityo: Chouser: wow zip-filter is the cool, but why call is zip-filter :)

8:58 Chouser: adityo: it filters zippers. zippers are built by clojure.zip over any kind of nested structure (nested vectors, xml, etc.)

8:59 crios: Chouser: the task should be having two threads which alternativamente print a string. Each thread prints always the same string :)

8:59 Chouser: crios: but why two threads? if you use two agents, it's possible only one thread would be used in the end. Is that acceptible?

9:01 * adityo has yet to learn a lot about Clojure ..yay

9:07 crios: Chouser: yes for this example should be acceptable. I'll try it.

9:08 now I'm just studying Clojure, no "ping pong" business yet :)

9:12 Anyway, if I really wanted handle a thread pool in clojure, I should use the locking macro, monitor-enter etc?

9:12 Chouser: crios: that's really low-level stuff -- I haven't needed any of it yet in clojure.

9:15 lisppaste8: Chouser annotated #87224 "a bit like ping-pong, but using agents" at http://paste.lisp.org/display/87224#1

9:17 Chouser: crios: so there's a somewhat idiomatic example of something. Not sure if it's enough like your two-thread java ping-pong example to be useful or not.

9:18 note there's no need for locking. Also the agent that's waiting to be triggered isn't monopolizing a thread.

9:23 somnium: macro-fu question: how to convert the arguments to a macro to a seq of symbols? ie (my-macro foo bar baz) #=> '('foo 'bar 'baz)

9:24 Chouser: somnium: the args to my-macro in that example should be symbols already

9:25 Chousuke: somnium: hm, you don't usually want '('foo 'bar 'zonk)

9:25 ,'('foo 'bar)

9:25 clojurebot: ((quote foo) (quote bar))

9:25 crios: Chouser: yes it seems mono-thread. I'll study it carefully, thank you. If I well remember, any action on an agent is done by an internal ad-hoc thread. When using send-off, you don't "waste" an internal thread for blocking operation

9:25 Chousuke: ,'(foo bar) ; foo and bar are symbols

9:26 clojurebot: (foo bar)

9:26 Chouser: crios: yes, you're right. When I added the Thread/sleep I should have changed to send-off

9:26 somnium: Chousuke: probably I'm not getting something simpler then, what I want to do is take the args as symbols, see if they're defined, if not convert them to strings and process

9:28 Chousuke: you can't do that with a macro I think :/

9:28 somnium: ... yeah kind of trying to emulate reader macros

9:28 trying to write a wrapper for js library

9:28 Chousuke: reader macros don't check whether stuff is defined :/

9:29 it's just a simple code -> other code transformation

9:30 Chouser: (defmacro mymac [& syms] `(for [sym# '~syms] (or (resolve sym#) (str sym#))))

9:30 (mymac map foo inc bar) ==> (#'clojure.core/map "foo" #'clojure.core/inc "bar")

9:30 somnium: mygod how do you guys learn this stuff

9:31 thats exactly what Ive been trying to do :)) thanks

9:31 Chousuke: it's not that difficult once you get it :P

9:31 the trick is to know what a macro produces and how the compiler handles whatever it produces :)

9:32 a macro is just like a normal function except for two things: 1) it's arguments are NOT evaluated and 2) it's return value is evaluated by the compiler

9:32 Chouser: somnium: Chousuke's right -- simply dedicate every waking moment to asking and answering questions on this channel, and 12 to 18 months later you'll be an expert! :-)

9:32 Chousuke: its*

9:32 :P

9:33 Chouser: Chousuke: :-)

9:33 Chousuke: hmm, 2) is not exactly correct. :/

9:34 2) its return value replaces the macro invocation in the code approximately at compile time :P

9:35 somnium: sound advice I suppose :-)

9:35 if you called (my macro foo (bar baz) zonk) how does (bar baz) get handled by the reader at macro expand time?

9:36 Chouser: somnium: the reader produces the list of two symbols: (bar baz)

9:37 somnium: the compiler resolves my-macro, sees it's a macro call, and passes three args to my-macro

9:37 somnium: (It took me months to get the hang of ruby meta-programming, which seems really overly complicated, though I haven't gotten the hang of this yet)

9:37 Chouser: arg 1, the symbol foo; arg 2, the list of two symbols (bar baz), etc.

9:37 somnium: ok, I think I get it, will have to spend some time with macroexpand for it to make sense

9:37 really make sense

9:38 lisppaste8: crios annotated #87224 "untitled" at http://paste.lisp.org/display/87224#2

9:38 Chouser: one way to think about the difference between ruby (and python) "meta programming" and lisp macros is to think about when each operate.

9:39 crios: Chouser: really each agent is using an its own thread, for a total of two threads. So your example should be operationally equivalent to the mine written in Java. Great!

9:39 (I've added the print of the thread name)

9:40 Chouser: macros run very early -- some vars may be defined, locals are not. args that might eventually become anonymous fns aren't yet -- all the args are just symbols and groups of symbols.

9:40 contrast with, say, python decerators, which run *after* their targets have been fully processed into function objects which you can then examine, wrap, etc.

9:41 crios: there's no promise that those agents will get different threads, or that a1 will get the same thread each time.

9:41 crios: ah ok

9:43 somnium: Chouser: will defs and defns that come earlier in the file than the defmacro be available within the macro code?

9:43 Chouser: somnium: yes

9:43 somnium: ok

9:44 Chouser: somnium: that's actually the key difference in my mind between read "lisp macros" and the weak macro languages provided via preprocessors for languages like C and, if I understand correctly, Haskell.

9:45 somnium: lisp allows you to build up the language and utilities available to your macros

9:45 Chousuke: in most languages macros are just a text transformation

9:46 clojure macros are *data structure* transformations

9:46 avital: Hi. Is there a function that returns a string representation of the name of a function or symbol in general? So that I could do something like (fn-name map) should return "map". (str map) returns something like "clojure.core$map__3815@5a83b00f". Bleh.

9:46 Chouser: Chousuke: yes, but I don't actually think that's so terribly important.

9:47 Chousuke: Chouser: processing text is much more difficult than processing data structures.

9:47 because text is, well, unstructured :P

9:48 Chouser: Chousuke: yes, but with the ability to write functions that are then available to your macros, you could have what amounts to readers and printers, and abstract away most or all of that extra difficulty

9:49 Chousuke: Chouser: and in the end your macros would work with data structures, reducing to lisp macros :)

9:49 Chouser: I'm not saying that's desirable (though it would actually give you added power) I'm just saying that's not what sets lisp macros apart, AFAIU

9:49 somnium: hmm, if thats true why are sexps such a big deal for macro systems?

9:49 Chousuke: Chouser: if you abstract away the reader and the printer you get lisp macros :P

9:50 somnium: sexps are just a convenient way to represent the data structure as text; they don't actually matter to the macros.

9:50 Chouser: Chousuke: not quite, but yes very close

9:50 avital: Ok I figured it out - since we're within a macro we can use ~'

9:51 Chousuke: somnium: you could have your lisp *text* as XML and process it with a macro normally, because by the time the macro sees it it's not XML any more (the reader has read it and transformed it into data structures, which are the actual code)

9:51 somnium: for the record now that I'm accustomed to them I like lisp syntax (as was foretold), but I always thought (perhaps incorrectly) the lisp macro system was the primary argument for getting accustomed to the syntax

9:52 Chousuke: somnium: well, the syntax is the simplest possible representation for the data structures.

9:52 somnium: and it allows things like syntax-quote to work naturally

9:53 Chouser: I actually built a working macro system for JavaScript. It can be done, but it's much clumsier.

9:53 Chousuke: if the textual syntax didn't correspond to the actual code, it would be much more difficult to write macros

9:54 Chouser: it's already often difficult to write macros in lisp, where the syntax is very much staying out of your way. And syntax complexities and things get ugly fast.

9:55 somnium: in practice, almost every language that has macros as powerful as lisp also has a lisp-like syntax. So in that sense,you're right.

9:56 Chousuke: that said, lists aren't the only way to have homoiconicity. there's a language that uses maps instead of lists :)

9:56 http://will.thimbleby.net/misc/

9:56 somnium: I guess you need access to the source ast too, or the source text at least

9:56 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

9:58 Chouser: somnium: right. http://blog.n01se.net/?p=9

10:00 somnium: it looks cool, is it fast enough to run in a browser?

10:00 Chouser: but that was the last installment. I got JaM working enough to prove to myself that (a) it was possible and (b) it was really hard to get right.

10:01 somnium: generally, yes. Its speed depends mainly on how much code there is to process -- once you get to running the code of course the macros are all done.

10:02 you could potentially do this work on the server or even at build time and send only the resulting JS.

10:02 jdz: talking about macros and syntax: http://users.rcn.com/david-moon/PLOT/index.html

10:02 Chouser: huh. that was only 3 years ago. seems so much longer.

10:02 somnium: lisp has more dialects than chinese it seems

10:05 triyo: How would I go about converting a struct map into a non-struct map?

10:05 jdz: into?

10:06 and why do you use struct-maps in the first place if you want to do things like that?

10:06 Chousuke: triyo: you don't need to

10:09 triyo: I am trying to store my sql query result that is a struct in my memcached server...however I get that the Object is not serializable which is weird as I ran:

10:09 ,(ancestors clojure.lang.PersistentStructMap)

10:09 clojurebot: #{java.lang.Iterable clojure.lang.Seqable clojure.lang.APersistentMap clojure.lang.IMeta clojure.lang.IFn clojure.lang.IObj java.lang.Object clojure.lang.Associative clojure.lang.IPersistentMap clojure.lang.Obj java.util.concurrent.Callable java.lang.Runnable java.util.Map :clojure.contrib.generic/any java.io.Serializable clojure.lang.Counted clojure.lang.IPersistentCollection clojure.lang.AFn}

10:14 somnium: Chouser: I get a clojure.lang.PeristentList cannot be cast to clojure.lang.Symbol when I try your example with a list as an argument...

10:15 Chouser: somnium: yeah, 'resolve' wants a symbol

10:16 ok, I take back what I said about Template Haskell. Its macros are written in Haskell, and you can build up a library to use in your macro definitions.

10:16 triyo: jdz: struct map into normal map. If i try to store a normal map into memcached server it all work fine. If I try to store a struct, memcached throws an exception stating that Object is not serializable.

10:16 somnium: is it necessary to catch those exceptions?

10:16 jdz: ,(doc into)

10:16 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

10:16 jdz: triyo: that's what i meant...

10:16 Chouser: somnium: depends on what you're trying to do, I suppose. Do you want to allow the user to pass in lists?

10:17 achim: triyo: could it be the contents of the struct map? for instance, PersistentLists, Conses and LazySeqs don't implement Serializable

10:17 Chouser: code that uses a Haskell macro has to use special $() syntax at the call site. I think this is the only drawback on the user side.

10:18 triyo: jdz: I am trying to store result of the with-query-results of clojure.contrib.sql which seems to return a struct.

10:18 Chouser: writing macros looks dramatically more difficult because of the strict type system, complex syntax, etc. And yet the full power is there I believe.

10:18 jdz: triyo: try (into (hash-map) <your-struct-map>)

10:19 somnium: I think so, there might be alternatives, right now I'm just trying to something like ($ #foo :click (fun ($ #bar :hide))) and get ("$('#foo').click(function() { $('bar').hide()});"

10:20 triyo: Chousuke: you right, I saw that PersistentStructMap implements serializable. But I still then can't exaplain why it works for a simple map and not a struct.

10:21 somnium: I did something similiar with functions but having to quote things made it kind of ugly

10:22 Chouser: the reader doesn't like #foo

10:22 somnium: hmm

10:22 maybe keywords are better then, that's what I ended up doing for tokens to become strings

10:22 Chouser: you could certainly process any literal keywords, but let everything else through unchanged

10:23 use 'keyword?' instead of 'resolve'

10:23 somnium: I want to setup a list of json rpcs functions at the beginning of the file and then be able to plug those into 'components' in the templates, so I need some way to resolve between js-tokens and server-side tokens...

10:24 maybe I should follow the rules and make it all work with functions first

10:24 Chouser: somnium: that's likely to make your life easier. :-)

10:25 triyo: achim: initially I though it might be one of the types. But when I tried same keys and values in a simple map instead of a struct it worked.

10:27 jdz: into did the trick

10:27 thx

10:29 Now that is really strange. Is this a bug? I saw the #174 that was related to Keyword with similar problem. Keyword didn't implement Serializable though but PersistentStructMap does. hmm

11:07 icylisper: http://icylisper.blogspot.com/2009/09/bootstrapping-lisp-environment.html . kindly comment :)

11:10 Chousuke: looks neat

11:11 icylisper: Chousuke: basically i found it quite useful for CL, thought would extend it to clojure apps.

11:12 the value add is the attach/deatchtty and be able to embed swank in clojure apps

11:13 Chousuke: I'm content with my clojure setup so I'm not going to test that thing but maybe someone else will

11:14 icylisper: Chousuke: :)

11:29 kunley: Hi!

11:30 Is there anything in Clojure which resembles the CL's conditions aka restartable exceptions?

11:31 Chouser: kunley: you might be interested in clojure.contrib.error-kit

11:34 kunley: Chouser: yeah looks interesting :)

11:45 Chouser: Looking at the examples, I'm impressed. Looks like exactly what I needed.

11:46 crios: Chouser: about http://paste.lisp.org/display/87224#1,

11:47 msg is the return value of each task invokation?

11:53 Chouser: crios: the value returned by an agent task becomes the new value of the agent

11:55 crios: the last 'msg' evaluation becomes the new agent value, correct?

11:55 (fn task [msg cnt x y] (prn msg) (when (pos? cnt) (Thread/sleep 1000) (println (. (Thread/currentThread) getName )) (send-off y task (dec cnt) y x)) msg)

11:57 Chouser: so that a1 will always print :ping and a2 print :pong

11:57 Chouser: right.

11:57 crios: wow, thank you

11:58 Chouser: which actually raises an point about the design of this thing. Since the entire difference between on agent and the other is the value that's getting passed in each time, and because send-off's from an agent task don't actually happen until the task is done, you only really need one agent.

12:01 crios: Chouser: yes, you are correct

12:01 lisppaste8: Chouser annotated #87224 "single-agent ping pong" at http://paste.lisp.org/display/87224#3

12:03 Chousuke: there's also *agent* which could be used instead of agt in that example

12:04 lisppaste8: Chouser annotated #87224 "single-agent ping-pong without 'let'" at http://paste.lisp.org/display/87224#4

12:05 crios: *agent* ^

12:05 ?

12:05 Chouser: *agent* is dynamically bound inside and agent task to the currently-running agent.

12:06 crios: ok

12:07 much more readable than the java version!

12:07 compliments!

12:10 time to go

12:10 bye

12:40 slava: I'm at rich hickey's keynote

12:41 'yo rich, I'm gonna let you finish, but parrot is one of the best VMs ever!'

12:42 hiredman: :D

12:43 drewr: haha

12:50 futuranon: slava: well played

13:12 slava: poor rich, people are asking dumb questions

13:13 hiredman: why do you tease so

13:13 Chouser: because teasing is more fun that transcribing dumb questions?

13:14 hiredman: http://twitter.com/al3x/statuses/4057515252

13:14 http://grailspodcast.com/blog/list

13:22 replaca__: Check out Alex's notes on the summit wiki: http://wiki.jvmlangsummit.com/Keynote_-_Hickey

13:25 hiredman: http://www.youtube.com/watch?v=zRTx1oGG_1Y&feature=channel_page

13:26 stuartsierra: hiredman: do you know if video of the complete talk will be online later?

13:26 hiredman: I don't

13:26 stuartsierra: ok

13:26 slava: I think so

13:27 hiredman: I hope all the talks are put online

13:29 slava: yeah they will be

14:56 licoresse: ...

16:09 spuz: Hi, I'm struggling to get started with clojure, if I load a .clj file into ClojureBox for example, how do I run it?

16:11 futuranon: spuz: Ctrl+c, Ctrl+k

16:11 If by load, you mean you have it open

16:12 spuz: I would google "slime cheatsheet"

16:12 spuz: futuranon: thanks

16:13 futuranon: spuz: this also may come in handy depending on your background: http://bc.tech.coop/blog/081209.html

16:14 spuz: and of you have no idea what it means; bookmark it for later ;)

16:14 if you*

16:14 spuz: heh I will :)

16:30 rafsoaken: hi there, my question is if one can in foll. expression avoid the duplicated (- a 2)? -->(for [a (range 10) :when (= (* (- a 2) 6) 18)] (- a 2))

16:33 Chouser: rafsoaken: 'for' allows a :let clause

16:34 rafsoaken: Chouser: ah great, thx!

16:35 true overlooked it in the api

16:37 Chouser: yeah, not included in the example. easy to miss.

16:48 LauJensen: Ladies and gents, I've looked at the STM vs Actors and actually found a bug in the O'Reilley solution to the Sleeping Barber problem, comments are as always encouraged and appreciated: http://www.dzone.com/links/scala_vs_clojure_round_2_concurrency.html

16:57 _mst: maybe a minor thing, but isn't IO from within a dosync discouraged?

16:57 hiredman: yes

16:57 side effects inside a transaction are a bad idea

16:57 Chouser: _mst: yes, since it can retry. best to pump io through an agent to keep it from retrying and to keep it cleanly serialized.

16:58 hiredman: all io (file access, db access, other kinds of mutation) are a bad idea

16:58 should be all side effects

16:58 LauJensen: Agreed :)

17:11 And if you're not busy and like the post feel free to vote - #Scala isn't hesitating :)

17:56 grosours: hi

19:37 wtetzner: is there a way to get the arity or arities of a function?

19:43 dnolen`: wtetzner you can look at the metadata of a functions.

19:43 ,(:arglist ^#'reduce)

19:43 clojurebot: nil

19:43 dnolen`: ,^#'reduce

19:44 clojurebot: {:ns #<Namespace clojure.core>, :name reduce, :file "clojure/core.clj", :line 598, :arglists ([f coll] [f val coll]), :doc "f should be a function of 2 arguments. If val is not supplied,\n returns the result of applying f to the first 2 items in coll, then\n applying f to that result and the 3rd item, etc. If coll contains no\n items, f must accept no arguments as well, and reduce returns the\n result of calling f with no

19:44 dnolen`: ,(:arglists ^#'reduce)

19:44 clojurebot: ([f coll] [f val coll])

19:44 dnolen`: ,(first (:arglists ^#'reduce))

19:44 clojurebot: [f coll]

19:44 wtetzner: dnolen`: thanks

19:52 ,(count (first (:arglists ^#'reduce)))

19:52 clojurebot: 2

20:00 Chouser: or you can use reflection to look at the invoke methods available

20:06 wtetzner: Chouser: yeah, i think that's the only way to do it for anonymous methods

20:33 dthomas: Is there a nice method to get a sequence of values from a map given a sequence of keys? I was thinking maybe get-in or select-keys but they have different purposes. (Not that it's hard to just use map, get, and an anonymous fn.)

20:42 dnolen`: ,(select-keys {:foo 0 :bar 1 :baz 2} [:foo :bar])

20:42 clojurebot: {:bar 1, :foo 0}

20:43 dnolen`: dthomas: ^

20:45 dthomas: dnolen`: Oh, yeah, and then just (vals) that? And it's no big deal to "throw away" the result since it's efficient and shares with the map you selected out of?

20:45 dnolen`: dthomas: on caveat is that order isn't guaranteed here.

20:45 one

20:46 dthomas: dnolen`: Another good point; ordering is important in my case.

20:47 dnolen`: dthomas fortunatey trivial to write because maps can be used as fns.

20:47 (defn get-keys [amap keyseq] (map amap keyseq))

20:47 Guest64829: Forgive my slight bit of noise, but I'm testing this out. IRC newbie alert!

20:48 dnolen`: dthomas: isn't clojure nice ;)

20:48 dthomas: dnolen`: Duh! I forgot that maps are callable like that. Thanks for all the tips.

20:48 dnolen`: np

20:49 dthomas: I always remember (:foo bar) but never (bar :foo).

20:50 wtetzner__: actually you might as well just use (map amap keyseq) instead of defining get-keys, since it's shorter than using (get-keys amap keyseq)

20:51 dthomas: I was also pleased to learn that (let [[head & tail] nil]) works and leaves both head and tail at nil. I don't know why I expected that to be a problem in the first place.

20:52 (Well, it doesn't _leave_ them at nil, it binds them to nil.)

20:52 dnolen`: wtetzner: heh, true enough.

21:58 jhawk28: has anyone used incanter on very large datasets?

22:02 JAS415: Alfred North Whitehead quotes, sweet

23:31 is it possible to do a sorted set that takes a comparator?

23:41 hmm

23:41 looks like someone already made the patch it just never got included

23:41 http://code.google.com/p/clojure/issues/detail?id=76

23:41 interferon: i want to use JAX-RS, which requires annotated classes and methods

23:42 does clojure support this?

Logging service provided by n01se.net