#clojure log - Jan 12 2011

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

0:10 amalloy: what do i have to do to hack on the compiler? that is, how do i compile the clojure runtime and make my projects use it?

0:15 hiredman: amalloy: ant

0:15 that kind of depends

0:16 you can infact upoad your own version of clojure to clojars if you want

0:17 http://clojars.org/org.clojars.hiredman/clojure

0:17 or just use maven to install it in your local m2

0:18 amalloy: hiredman: aha, thanks, that's a simpler solution than i expected

0:19 hiredman: if you run ant test it runs the tests with the clojure.jar you just compiled

0:19 so you can just add test cases

0:24 amalloy: hiredman: deviouser and deviouser!

0:54 how do folks here feel about having #|...|# common-lisp-like comments?

0:57 Raynes: Totally for it.

0:58 tomoj: huh, we have no block comments now that will take non-forms?

0:58 I never noticed

0:58 Raynes: http://dev.clojure.org/jira/browse/CLJ-714

1:19 bartj: facing a precision issue: is there anyway 0.7 != (float 7/10)

1:24 amalloy: &(= 0.7 (double 7/10))

1:24 sexpbot: ⟹ true

1:24 amalloy: &(= 0.7 (float 7/10))

1:24 sexpbot: ⟹ false

1:24 amalloy: bartj: ^

1:25 cheezey: so basicallly clojure defaults to doubles? o_O

1:25 amalloy: cheezey: um...yeah, just like every other language in the world [citation needed]

1:26 bartj: why is this!??

1:26 I mean why doesn't float work?

1:26 amalloy: bartj: because of precision, just like you said

1:26 0.7<decimal> is not representable precisely in base 2

1:27 cheezey: bartj: cuz floats are less precise than doubles

1:28 amalloy: &(Double/toHexString 0.7)

1:28 sexpbot: ⟹ "0x1.6666666666666p-1"

1:29 amalloy: &(Float/toHexString 0.7)

1:29 sexpbot: ⟹ "0x1.666666p-1"

1:29 bartj: voila!

1:29 I wanted to know how it gets stored, thanks!

1:31 cheezey: amalloy: i print the classpath from my repl and i see something like #<URL file:/...> that points to my file. but when i try to :use it in one of my files, it says it's not found. any ideas?

1:32 amalloy: cheezey: if your directory structure is like src/org/mycompany/myproject/core.clj, you want src on the classpath, not core.clj (or any of the other directories)

1:33 bartj: amalloy, cheezey thank you!

1:34 cheezey: amalloy: when you say you want src to be inthe classpath, you mean the absolute path to src right?

1:35 amalloy: cheezey: yes, although a relative path would probably work if you were sure of what the cwd is

1:39 cheezey: hmm. i dunno what the issue is (prretty much same thing as last time)

1:42 amalloy: so i've two files both with the same (ns foo) located in folder foo. a.clj has :use b (and assume foo is in the classpath), is this the right set up?

1:43 amalloy: no

1:43 cheezey: :x

1:43 amalloy: the filename is part of the namespace as well

1:43 so you want (ns a), not (ns foo)

1:44 or ns foo.a, if foo's parent is on the classpath

1:51 cheezey: amalloy: hm. i dunno why i can't figure this out...

1:56 amalloy: cheezey: try checking out a project from github: if you can run that there's something wrong with your files; if you can't there's something wrong with your setup

2:20 tomoj: cheezey: are you still following that guide that told you to check clojure and contrib out of github and build them, and use that 'clj' script?

2:21 or was that someone else

2:21 cheezey: tomoj: yeah that was me

2:22 tomoj: any particular reason you chose that guide?

2:22 cheezey: what's the alternative? o_O

2:22 tomoj: I recommend trying to get set up with leiningen or cake instead

2:22 cheezey: tomoj: yeah im using leinigen now

2:23 tomoj: then you shouldn't have to compile clojure/contrib from source

2:23 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

2:23 tomoj: or use any 'clj' script

2:23 cheezey: ya, i just switched =P

2:25 tomoj: good

2:25 single-segment namespaces (like (ns foo)) are discouraged, by the way

2:26 amalloy: cheezey: so just $ lein new myproject, and it'll set up a skeleton project for you

2:26 then you can see how things are supposed to be organized

2:26 cheezey: amalloy: i've built my project, but when i run it, something about main-class manifest

2:26 still looking stuff up but ify ou know the solution :P

2:40 Licenser: morning

2:41 Scriptor: marnin Licenser

3:05 LauJensen: Morning crew

3:13 amalloy: mornin LauJensen

3:16 hey LauJensen, go upvote my issue at http://dev.clojure.org/jira/browse/CLJ-714 - i'd like to get evidence of community support for a new feature

3:20 LauJensen: done

3:23 amalloy: sweet. thanks

3:24 m1ndvirus: Is Clojure similar to CL?

3:25 amalloy: for certain values of similar

3:26 _na_ka_na_: I have a doubt, is a var, just a more flexible atom ?

3:27 semantically I mean

3:28 amalloy, why not use #_ for multiline comments?

3:28 LauJensen: m1ndvirus: not really

3:29 amalloy: _na_ka_na_: for the same reason you can't use (comment)

3:29 m1ndvirus: LauJensen: Is it like Scheme?

3:29 LauJensen: Well, not really

3:29 m1ndvirus: LauJensen: Arc?

3:29 amalloy: m1ndvirus: keep going till you get to clojure :)

3:30 LauJensen: I dont know Arc that well, but from what I know, its not like it

3:30 m1ndvirus: If you were to describe Clojure's philosophy in a brief phrase, what would it be?

3:30 talios: Evening

3:30 _na_ka_na_: amalloy, you can do (list 1 2 #_" blah blah multiline comment" 3 4)

3:30 LauJensen: http://clojure.org/rationale

3:30 m1ndvirus: talios: That tells me almost nothing. :P

3:31 LauJensen: m1ndvirus: slurp that link ^^

3:31 m1ndvirus: Did so.

3:31 amalloy: _na_ka_na_: yeah, and you can do the same in perl with <<<, but that doesn't make it a real comment

3:31 and you can't nest those either

3:31 talios: m1ndvirus: ok - Glorious evening of cool summer Auckland breeze to you - I hope you and yours are safe, warm, and cuddly. :)

3:32 _na_ka_na_: amalloy, by real comment you mean ?

3:32 amalloy: _na_ka_na_: for example i can't include a string in your "comment"

3:32 m1ndvirus: talios: I felt a warm gust of light wind breeze through my nostrils.

3:33 _na_ka_na_: amalloy, ya but you can use \" \"

3:33 amalloy: _na_ka_na_: yes, we can pile hack upon hack to get something that acts kinda like multi-line comments, or we can just get real ones

3:35 _na_ka_na_: amalloy, :) I would also like to have them, but for a moment assume I'm a person who opposes them and says #_"" is your multiline comment, what are your complains

3:35 amalloy: _na_ka_na_: you can't use #_"" to write a comment describing how to use #_"" comments - you have to escape the quotes

3:36 you can't comment out a chunk of code that's malformed but you want to keep around for now

3:36 _na_ka_na_: amalloy, doesn't this go with any literal? in java we have /* */ ... now how do i write '*/' in comments?

3:37 amalloy: _na_ka_na_: the lisp #|...|# comments, as well as my clojure impl, nest

3:39 _na_ka_na_: amalloy, you mean i can write #| ..comment.. |# .. comment continues ... #| ..comment continues further |# ?

3:39 so its like a stack

3:39 amalloy: you can write #| comment #| more comment |# still comment |# now real code

3:40 see the attached patch for my jira issue - i include a test case for that

3:40 _na_ka_na_: amalloy, but its the same thing then, who do i write |# inside the comment itself?

3:42 amalloy: well, fair enough. you could do it by writing an extra, otherwise-unneeded #| before it, which the other solutions couldn't do, but it's kinda gross

3:43 _na_ka_na_: so equivalent to escaping " inside #""

3:43 plus editors can provide support for commenting/uncommenting a chunk of code

3:44 amalloy: not if it's not well-formed

3:45 _na_ka_na_: this works (list 1 2 #_"(a" 3 4)

3:45 amalloy: *chuckle* oh, all right

3:46 but you could say the same of any language that allows multi-line strings - why allow multi-line comments?

3:47 _na_ka_na_: I was just arguing for the sake of it, so the only complaint is that #_"" really looks like a string and not a "real multi line comment"

3:47 amalloy: and requires more escaping

3:47 _na_ka_na_: yes

3:48 amalloy: it's also clearer in editors without good syntax highlighting

3:48 |# is the end of a comment, but " is harder to spot

3:50 _na_ka_na_: I agree, that's why I'm upvoting your patch

3:51 ejackson: greetings

3:51 amalloy: thanks for the argument, though. i hadn't realized how good a substitute #_ is

3:51 _na_ka_na_: I too didn't know, i just use ; for every line

3:52 amalloy: me too :)

3:53 _na_ka_na_: I have a doubt, is a var, just a more flexible atom ?

3:55 alter-var-root & swap! seem similar

3:56 amalloy: _na_ka_na_: vars have per-thread bindings and an automatic stack/history, and are interned in namespaces; they also deref by default

3:56 i think that's most of the interesting differences

3:57 _na_ka_na_: so I can use a var inplace of a global (ns-level) atom

3:58 amalloy: uhhh, i suppose you could. i'm not sure what the concurrency semantics of vars are, but it's probably okay

3:58 _na_ka_na_: ,(doc alter-var-root)

3:58 clojurebot: DENIED

3:58 _na_ka_na_: nice clojurebot

3:58 amalloy: $source alter-var-root

3:58 sexpbot: alter-var-root is http://is.gd/kBPoN

3:59 _na_ka_na_: so it also atomically alters the var

4:02 i cant think why I would want to do (def s (atom x)) instead of just (def s x)

4:03 plus in 1.3 binding is also multithreaded

4:09 tomoj: hmm.. only one thread can alter-var-root at a time

4:11 multiple threads can swap! at the same time, but if the winner changes the value the rest have to retry anyway

4:15 _na_ka_na_: tomoj, didn't get what you meant by only one thread can alter-var-root at a time?

4:15 I can do (def a 0) and then (dotimes [_ 100] (future (alter-var-root #'a inc)))

4:16 tomoj: yeah, and they all block waiting for the previous ones to finish

4:16 _na_ka_na_: hmm so the difference is that, alter-var-root uses a lock, whereas atom is compare-and-swap ?

4:18 tomoj: sounds right to me

4:22 _na_ka_na_: it will be very interesting to see in highly contentious times (lots of threads trying to modify a reference) which one performs better, a lock or atom

4:24 amalloy: _na_ka_na_: a lock will perform better. but atoms won't deadlock

4:25 i guess i might even be wrong about a lock performing better

4:25 tomoj: also

4:25 alter-var-root seems to block readers

4:26 with the atom, you might have lots of retries, but anyone can always get the current value

4:27 _na_ka_na_: hmm so vars are synchronized objects in java

4:27 tomoj: for a stupid test where each of 100 swap!/alter-var-root just sleeps for 100ms and incs, they perform almost the same

4:28 if I kick off all the alter-var-roots before all the swaps, by the time I can read the var, all but one of the swaps are done

4:44 TobiasRaeder: morning

4:50 bartj: what is the *easiest* way to read command line arguments in Clojure?

4:51 Berengal_work_: bartj: Require they be valid clojure datastructures, and call read on them

4:51 bartj: I mean is there a "Perlish" way so that the command line variables are stored in ARGV

4:52 or a "Javaish" way where the main method takes arguments

4:52 I am looking at this: http://stackoverflow.com/questions/1341154/building-a-clojure-app-with-a-command-line-interface

4:53 and when I run the example from the accepted answer, changing the value of "foo" it doesn't get printed

4:54 put another way:

4:56 why doesn't *command-line-args* print anything, even though I pass arguments

4:59 _na_ka_na_: bartj, $ java -cp lib/clojure-1.2.0.jar clojure.main -r 1 2 3

4:59 Clojure 1.2.0

4:59 user=> *command-line-args*

4:59 ("1" "2" "3")

4:59 user=>

5:00 bartj: do I need to give the -r flag?

5:00 _na_ka_na_: -r is for the repl

5:01 I think it will work even if you're running a main method

5:02 bartj: hmm, yes!

5:03 I am confused regarding which option to use:

5:03 I mean what is the difference b/w

5:03 *command-line-args*

5:03 (with-command-line args) as can be seen in this example: http://stackoverflow.com/questions/1341154/building-a-clojure-app-with-a-command-line-interface

5:06 _na_ka_na_: i guess with-command-line is a useful utility if you're building a CLI app

5:07 clgv: it seems to do the parsing of *command-line-args* and gives you variables with the given values assigned

5:08 so you dont have to do that task yourself

5:09 thanks for the link btw :)

5:10 Raynes: Man, moving wiki pages is real grunt work.

5:14 bartj: so, using *command-line-ags* is definitely much easier

5:15 _na_ka_na_, by app I think you mean "command menus" for naviagation, not a hacky utility ?

5:17 _na_ka_na_: bartj, by CLI app I meant any command line interface program

5:17 bartj: _na_ka_na_, ok, thanks for the help

5:17 _na_ka_na_: bartj, welcome

5:20 raek: bartj: *command-line-ags* is for when the clojure repl is the main class, the args of -main are for when your own AOT'ed namespace is the main class

5:21 bartj: raek, that makes a lot of sense, thanks!

5:22 clgv: bartj: if you take that example: java -classpath . cmd_line_demo --foo test --bar 4711 filename

5:22 *command-line-args* would be ["-foo" "test" "--bar" "4711" "filename"]

5:22 afair with-command-line would provide you the variables: "foo" with value "test", "bar with value "4711" and "remaining" with value "filename" (when used like in your example)

5:24 _na_ka_na_: bartj, if this is just a throw away program go with *command-line-args*, if this is something important I'd suggest go with with-command-line

5:26 raek: also, amalloy_ has made a command line option parser: https://github.com/amalloy/clojopts/tree/

5:27 bartj: its just a small hacky utility; I'll go with *command-line-args*

5:27 thanks again everyone

5:31 raek: I got an idea last night: wouldn't it be nice to have a version of defrecords that instead of being a map would be a fixed-size vector?

5:32 you could call it deftuple

5:33 (deftuple Foo [a b c] ...)

5:33 clgv: what is the goal of that? performance? "typesafety" of this deftuple since it can't get more fields/attributes?

5:33 raek: (Foo. 1 2 3) => #:user.Foo[1 2 3]

5:33 _na_ka_na_: raek, I think (deftuple Foo 3)

5:33 raek: I often feel that I want something like haskells ADTs

5:34 LauJensen: And SQL masters in here?

5:34 raek: the parts should have names if you want to reference them in method bodies

5:34 one feature of these tuples would be that they destructure as lists/vectors

5:35 (let [[a b c] (Foo. 1 2 3)] ...)

5:35 _na_ka_na_: if they have names, then its just defrecord right? for inside method bodies one could use $1 .. ?

5:36 (let [{:keys [a b c] (Foo. 1 2 3)]) is not much different

5:36 raek: the user of the tuple would think of it as a positional structure, rather than a map

5:36 sure

5:36 then I have to come up with good names for the field...

5:38 fliebel: morning

5:38 Raynes: I just finished moving the assembla Getting Started wiki pages to Confluence: http://dev.clojure.org/display/doc/Getting+Started

5:39 raek: (inc Raynes)

5:39 sexpbot: ⟹ 4

5:39 * Raynes bows

5:41 ejackson: nice one Raynes

5:41 Raynes: It was nothing, really. Only about an hour of my precious, important time.

5:41 * Raynes files his fingernails.

5:42 Raynes: I just wanted to be able to link to confluence in my book instead of assembla. :>

5:42 ejackson: quick pointer please. how do I monitor for an exception in a case like this (def a (future (/ 1 0)))

5:43 clgv: can the CLR implementation be considered as stable as the JVM one provided both have the same version number (e.g. 1.2)?

5:43 Raynes: Use a thread instead.

5:43 ejackson: a know if I evel a it will throw an exception, but if a is in the code, how do I know that an exception has happend w/o evalling a ? or is that not the true path ?

5:44 Raynes: I'll check it out, thanks

5:44 raek: what?

5:44 clojurebot: what is exceptions

5:45 ejackson: exactly clojurebot - I'm getting exceptions in my code and not sure how to monitor for em

5:45 Raynes: future is satan when it comes to error handling.

5:45 raek: Raynes: no.

5:45 Raynes: raek: Yes.

5:45 ejackson: raek: what do you suggest ?

5:45 _na_ka_na_: ejackson, the above code will throw an exception inside the future and theres no way you can catch it

5:45 Raynes: raek: We had this problem in Irclj because you replaced a thread with a future.

5:45 raek: when you dereference a future, it will throw a certain kind of exception if some exceptio was thrown in the body

5:46 http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#get()

5:46 Raynes: Yes, when you dereference it.

5:46 raek: "ExecutionException - if the computation threw an exception"

5:46 if you want to handle it (e.g. printing the stack trace) you should add code to do so

5:46 Raynes: Futures are great, but not if you're just using them as a way to run something in a new thread.

5:46 raek: (future (try ... (catch Throwable t (.printStackTrace t))))

5:47 Raynes: why not?

5:47 Raynes: I think his example is enough of a reason.

5:47 ejackson: raek: but how to monitor it ? I start up a future in a, if I deref it initally it might give me :pending, which is cool, and then exception later. I don't want to spin over it do it ?

5:48 tomoj: ,@(future (try (/ 1 0) (catch Throwable t (.printStackTrace t))))

5:48 clojurebot: tomoj: Pardon?

5:48 Raynes: Well, I did word that wrong.

5:48 raek: if you dereference it, you will block until it completes or throws

5:48 ejackson: DEREFENCE !

5:48 bloody genius, thanks :)

5:48 rtfm ejackson

5:48 Raynes: Futures are great if you want to run something in a new thread and care about the value.

5:49 raek: or want tot be able to cancel it

5:49 afekz: functional approach - return value even if just "succes"/?

5:49 raek: or check whether it has finished

5:49 afekz: maybe there are problems I haven't yet come across, but it's a wonderful boon for my hacking of little bits of code together

5:49 ejackson: raek and Raynes : thank you both

5:49 afekz: even just launching some heavy crunching things in the REPL (up to CPU core limit)

5:50 _na_ka_na_: raek, didn't get, how will deref help

5:50 Raynes, how will spawn your own thread help here

5:50 Raynes: afekz: If you don't have a meaningful value to return, nil will be returned, and that's fine. If the last thing you do in a function is a side-effect like println, it'll return nil and that'll be your result.

5:51 _na_ka_na_: When the error happens, it just happens.

5:51 afekz: Raynes: in my use cases so far, any side effects will hit the file system

5:51 Raynes: You don't have to "check" to see if it happened.

5:51 raek: thread print the stack trace and die on exceptions

5:51 futures run in some else's thread, so they can''t crash it

5:52 they are built to be able to communicate back how the execution went

5:52 _na_ka_na_: help in which problem?

5:53 _na_ka_na_: I don't quite see how threads or derefing are useful in this case: (def a (some very time consuming thing which can safely happen concurrently))

5:54 by useful I mean if that time consuming thing throws an exception

5:54 afekz: doesn't that block?

5:54 _na_ka_na_: not if you use a future

5:54 afekz: *nod* - I wasn't reading the (future (...)) into your psuedo code - my apologies

5:55 _na_ka_na_: so the problem is how do i deal with the case when the time consuming thing happening concurrently throws an exception

5:55 raek: what do you want to detect?

5:56 ejackson: _na_ka_na_: at some point you're going to need to know what happened in the execution

5:56 so somewhere you'll need to deref the future

5:56 that's going to block

5:56 i guess, dunno really.

5:56 raek: you can also use future-done? to poll it

5:56 ejackson: ,(doc future-done?)

5:56 raek: sone = finished or throwed

5:56 clojurebot: "([f]); Returns true if future f is done"

5:57 raek: *done

5:57 tomoj: I can't think of when I'd want to use that instead of lamina

5:58 ejackson: can you put a watch onto future ?

5:59 raek: (def pool (Executors/newFixedThreadPool 10)) (map deref (.invokeAll (map #(f %) coll))))

5:59 ejackson: tomoj: you're referring to https://github.com/ztellman/lamina ?

6:00 raek: ejackson: no. it would be more logical to add the triggering code in the code running in the other thread, I think

6:00 _na_ka_na_: the only sane approach I can think of is: catch all your exceptions when you start a new thread .. (future (try do-your-thing (catch Exception e handle-it)))

6:00 ejackson: raek: ok, just a random though.

6:00 tomoj: ejackson: yeah, but that wasn't a suggestion, I've just got lamina on the brain and never really understood futures

6:00 _na_ka_na_: define:lamina

6:01 raek: I guess all this depends on how you want to handle the exceptions

6:01 ejackson: tomoj: cool, I always like now toys to play with.

6:01 raek: for a background thread, it makes sense to have a top-level catch-all

6:03 _na_ka_na_: hmm you can even do: (try @(future (/ 1 0)) (catch Exception e :great))

6:04 raek: you could print the stacktrace, do some logging, store the exception in some global variable, etc

6:04 ah, sorry. read it as "hmm what can you even do"

6:05 _na_ka_na_: i got misplaced earlier as I was catching the wrong exception, (try @(future (/ 1 0)) (catch ArithmeticException e :great))

6:05 it throws a java.util.concurrent.ExecutionException

6:05 raek: yes, it wraps the original one

6:06 (try @(future (/ 1 0)) (catch ExecutionException e (throw (.getCause e))))

6:06 _na_ka_na_: hmm nice

6:06 raek: futures can fail in multiple ways, so some mechanism for distinguishing the cases is needed

6:07 _na_ka_na_: why is error handling so hard!

6:08 ejackson: you're telling me :)

6:10 _na_ka_na_: sometime back I wrote some critical piece of biz code .. I handled any exception it threw by mailing it to myself, then I would quickly do some fixes

6:10 usually data fixes

8:16 clgv: is there a shortcut for the cond-expresson for the case when I only want to check values (classic switch-case expression)??

8:16 fliebel: clgv: switch?

8:16 clgv: ,(doc switch)

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

8:16 mrBliss: clgv: case or condp

8:16 clgv: $(doc switch)

8:17 fliebel: &(doc switch)

8:17 sexpbot: java.lang.Exception: Unable to resolve var: switch in this context

8:17 fliebel: I'm sure it's htere somewhere...

8:17 clgv: case looks promising

8:17 mrBliss: for some examples: http://clojuredocs.org/clojure_core/clojure.core/case

8:18 clgv: thx :)

8:18 fliebel: Ah, it's case indeed.

8:18 zmyrgel: hi, could somebody point what I'm doing wrong, I have ref to map and I want to change one key value pair in it

8:18 but when I try to do it the whole ref gets set to nil

8:19 fliebel: zmyrgel: Code?

8:19 zmyrgel: here you go: http://pastebin.com/wtcBM8ZV

8:20 mrBliss: zmyrgel: lose the '@'

8:20 (dosync (alter game-options assoc key value))

8:21 zmyrgel: mrBliss: thanks, that was quick :)

8:38 Raynes: apgwoz: ping

8:50 clgv: what's the possbile error when: (macroexpand-1 '(create-statement expr)) fails with java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol ?

8:55 raek: sounds like something should expand to (defn foo [] ...) but actually becomes (defn foo bar [] ...)

8:55 i.e. the bar symbol cannot be used as an argument vector

8:56 ,(let foo 123)

8:56 clojurebot: java.lang.IllegalArgumentException: let requires a vector for its binding

8:57 raek: ,(defn foo bar [] 123)

8:57 clojurebot: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol

8:58 david`: ,(def fib (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))

8:58 clojurebot: DENIED

8:58 david`: :(

8:59 Raynes: You can't def in either bot, but you can let ##(let [fib (lazy-cat [0 1] (map + (rest fib-seq) fib-seq))] (take 10 fib))

8:59 sexpbot: java.lang.Exception: Unable to resolve symbol: fib-seq in this context

8:59 Raynes: Well, yeah.

8:59 david`: ##(let [fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq))] (take 10 fib-seq))

8:59 sexpbot: java.lang.Exception: Unable to resolve symbol: fib-seq in this context

9:01 raek: a value cannot contain itself. you could make fib-seq as a funciton of zero arguments, though

9:01 (letfn [(fibseq [] ...)] (take 8 (fibseq)))

9:04 ,(letfn [(fib-seq [] (lazy-cat [0 1] (map + (rest (fib-seq)) (fib-seq))))] (take 8 (fib-seq)))

9:04 clojurebot: (0 1 1 2 3 5 8 13)

9:09 clgv: raek: found it. it's a (first expr) during macro expansion time

9:09 I could clearly use something like a "macro expansion stack" for debug purposes...

9:24 if I use a macro in a macro definition, is it expanded during processing the definition provided it has no syntaxquote?

9:24 Chousuke: yes.

9:24 rrc7cz: how can you claim a group in clojars?

9:24 clgv: just to clarify the exact scenario: (defmacro macro2 [x] (macro1 x))

9:25 Chousuke: clgv: yeah, the expansion happens at definition time

9:25 clgv: Chousuke: hmok then I have to analyze why my ported code doesnt do the same as the original ;)

9:26 Chousuke: the code the macro expands to is evaluated and that becomes the code that actually runs at runtime.

9:27 maybe somewhere there you have your mistake :P

9:28 clgv: hm yes. the problem is the original code was nested too much and I tried to simplify. I must have missed a syntax quote level somewhere...

9:32 fliebel: I have a Java project with a build.xml file, can Maven install it into my local repo, so I can use it in Cake?

9:35 clgv: Chousuke: ok, seems I mistook a defn for a defmacro while porting...

9:36 Chousuke: heheh

9:37 fliebel: oh, wait (not= ant maven)

9:37 clgv: I have to get used to the fact that functions can be called during macroexpansion time...

9:38 Chousuke: heh.

9:38 you can do almost anything during macroexpansion

9:38 AFAIK Penumbra does reflection :P

9:39 looks up available OpenGL functions and generates a clojurey wrapper for them.

9:39 clgv: I have to get rid of the C/C++ macro interpretation ;)

9:39 still halfway between this one and the clojure one ;)

9:39 chouser: amalloy_: finger trees are at https://github.com/clojure/data.finger-tree

9:40 Chousuke: chouser: what's the status of that, anyway?

9:40 chouser: good to go

9:41 I'll be releasing 0.0.1 once we've got our new contrib release procedure ducks in a row

9:46 MisterSpeaker: I'm having trouble getting a minimal penumbra project running - I'm getting the same error as reported here: http://groups.google.com/group/penumbra-lib/browse_thread/thread/b3232a81b5bdf930 Can anyone see anything in the stacktrace that might indicate what's wrong?

9:48 fliebel: MisterSpeaker: I'm downloading Penumbra just now. I'll see what it does for me.

9:48 AWizzArd: chouser: what are currently the biggest challenges regarding the FTs?

9:49 technomancy: AWizzArd: judging from questions asked on IRC, I'd say the build.

9:56 fujin: ohai

9:56 danlarkin: fujin: OH HERRO

10:00 AWizzArd: (:

10:08 raek: rrc7cz: I think you simply push the jar with that group in the POM

10:09 at least, that's how I did for my jars in the se.raek group

10:13 chouser: AWizzArd: Clojure team virtual logistics

10:18 AWizzArd: I see.

10:29 ejackson: what is the accepted way of checking the type of function arguments? (instance? ...) ?

10:30 tonyl: (type ...0

10:30 ejackson: should I want to do se even ? If I expect some argument, d, to be a DateTime, should I assert this in a :pre ?

10:30 tonyl: (type ...)

10:30 you can type hinted

10:30 chouser: but type hinting doesn't assert

10:30 tonyl: and if it the argument passed to it it would throw an Exception

10:31 chouser: so, asserting in a :pre is probably best, if you're not comfortable just leaving it open.

10:31 ejackson: well, I don't want to write crappy code, but there's a trade off here :)

10:32 putting type assertions everywhere is ugly and seems to miss some point, but allowing my to call a function on a type that is not supported is also ugly.

10:32 what's the received wisdom here ?

10:32 technomancy: there's the notion of type hints as documentation

10:32 I'm not sure I buy that, but it's an interesting idea

10:32 ejackson: interesting

10:34 thanks for the pointers guys

10:35 fliebel: Hrm, Cake hangs for me on random projects. It seems somehow related to having native deps, or being a complicated project.

10:36 apgwoz: Raynes: pong, sorry was away from this computer

10:54 rrc7cz: what's the standard way of setting a global var for a lib? for example, some lib that's a client of some web service needing an api key. I have *api-key* in the ns of my lib, but I don't support users would be (intern 'mylibns '*api-key* "1234")

10:55 Chousuke: generally, you should avoid depending on such a var. just pass it around as a parameter if possible

10:56 alternatively, you can make it dynamically bindable and then require users do (binding [*api-key* "whatever"] (calls-to-your-code-here))

10:56 rrc7cz: Chousuke: I'd rather force (binding [*api-key* "foo"] (myapicall1) (myapicall2) etc)

10:56 so it's less tedious

10:57 Chousuke: you read my mind :-D

10:57 Chousuke: but if it's at all feasible, it's better to use a parameter.

10:57 rrc7cz: but *api-key* lives in the ns of my lib, so I don't really see why it would be a problem to just have them set it once and forget about it

10:58 Chousuke: global dynamic variables are pretty inflexible :/

10:58 rrc7cz: you should at least hide the *api-key* entirely then

10:58 rrc7cz: Chousuke: I understand, but really it's a one time, read only type thing. Passing it as a param everywhere would really make using the lib ugly

10:58 Chousuke: you mean make it private and have a setter fn?

10:58 Chousuke: provide a function like (init-lib! "apikey")

10:59 rrc7cz: okay that makes sense

10:59 Chousuke: but then it will be impossible to use your library concurrently with different API keys.

10:59 rrc7cz: Chousuke: you could still use (binding)

11:00 Chousuke: perhaps. though provide a macro for that.

11:00 rrc7cz: Chousuke: you'd just have a "default" api key you set with the init fn, then use (binding) to briefly drop into other keys

11:00 Chousuke: in practice, at least for this web service, they will never have multiple api keys, but it's an interesting though

11:02 are the earmuffs appropriate still for this var? I mean, it's private

11:02 mrBliss: I think we use +for-private-vars+

11:03 Chousuke: rrc7cz: yeah, if it can be dynamically bound

11:03 ++ is a CL convention for constants IIRC. it doesn't really make sense in Clojure :)

11:05 mrBliss: Chousuke: and for (def ^:private..) stuff?

11:05 Chousuke: I don't think you need anything

11:05 the metadata is enough :P

11:06 mrBliss: but you don't see the metadata when you're using the var :)

11:06 Chousuke: enforcing "privateness" is usually not very useful anyway. If someone goes and rebinds *api-key* manually, that's not your problem

11:25 fliebel: Is it possible in Cake to set java.library.path and to set a property on Maven? Some idiot put <platform>win32</platform> in his pom file. I'm getting java.lang.UnsatisfiedLinkError.

11:26 Trying to get lwjgl, and ultimately Slick.

11:48 lpetit: Hmmm, instead of trying to make ccw know each and every build system around (cake, lein, maven, gradle, pmaven, und so weiter), what about just contributing "eclipse" plugins to each of these build systems. eg. lein-eclipse, cake-eclipse, et. which would just help create/update eclipse required .project/.classpath files . So the workflow would become : run lein eclipse in your project, import your project in eclipse. period. ?

11:52 technomancy: lpetit: people have been doing "lein pom" and then importing as a maven project; does that work ok?

11:52 I guess it helps it know where the files are but doesn't help with running tasks

11:54 lpetit: technomancy: I have no feedback concerning this case. What I think, though, is that some people are frightened by the m2eclipse plugin. Here I'm advocating a "middle road", more orthogonal. Keep using your favorite build tool. And your favorite IDE.

11:54 technomancy: Until one clear winner emerges, and then I'll provide more integrated support :-p

11:54 technomancy: sure, I think it makes sense

11:55 Raynes: I like the idea.

11:56 * lpetit , despite having made the resolutions on focusing more on the task at hand, is, yet again, on the road of dispersion :)

11:58 lpetit: 'ommon cemerick, why aren't you there when I need you, helping me not deviate from the all maven road ? :-D

11:58 mrBliss: Wouldn't it make more sense to adapt the editor to the build systems instead of the build systems to the editor? Even though there are quite a few build systems now, in general, there will be more editors. But I understand what you'd want to do it this way.

12:00 lpetit: mrBliss: less work. Following the dependency rule "make an artifact only depend on more stable artifacts". And eclipse's .project / .classpath format is (IMHO) more stable than the current build tools ecosystem :)

12:01 ok, out of 3 answers, 2 considered positive. Enough for me starting to yet again spread my energy over more than one task :)

12:04 Huh, seems like lein-eclipse already exists ! http://tux2323.blogspot.com/2010/08/import-clojure-leiningen-project-into.html

12:05 why oh why do people not communicate more ? (me included, of course)

12:06 amalloy: lpetit: i'll send you an email every time i push a commit to one of my projects, just in case you want to use it someday :)

12:07 technomancy: they didn't add it to https://github.com/technomancy/leiningen/wiki/Plugins =(

12:07 lpetit: amalloy: no thanks. I just meant that (unless my memories are leaking), it could have been interesting to have a note of this plugin in the counterclockwise ml, don't you think ?

12:08 and also a note in the lein ml, since it seems that technomancy is also discovering this plugin existence.

12:09 amalloy: lpetit: sure, i agree. but it's fun to make impractical suggestions

12:09 lpetit: amalloy: certainly :)

12:09 technomancy: amalloy: have you tried restarting with extensions off?

12:10 amalloy: technomancy: what

12:12 technomancy: amalloy: impractical suggestions, you know

12:12 Mac System 9 advice.

12:12 lpetit: (rofl)

12:12 must leave, cu

12:12 amalloy: technomancy: jeez, mac system 9. i'm too young for this nonsense :P

12:13 * lpetit should really acknowledge, once and for all, that it is impracticall to emit a broadcast "byebye" in an irc chatroom

12:13 * technomancy reccommends /me &

12:18 gfrlog: ,(println "Testing connection")

12:18 clojurebot: Testing connection

13:02 jkndrkn: do any lein users know if you can access the version number set in the project.clj defproject form within your application?

13:03 technomancy: jkndrkn: only from plugins... but that's a good idea.

13:05 jkndrkn: what do you mean via plugins? is that method something i could exploit for my application? is there simply no way to access that version number at the moment?

13:05 technomancy: I mean plugins (code that runs in lein's process) have access to the version number but code that runs in your project does not

13:06 jkndrkn: ah, ok. thanks for the clarification ^_^

13:12 amalloy: technomancy: is it actually a good idea? it would mean a clojure program that only works if it's built with lein

13:26 signalseeker: ,(println 'test)

13:26 clojurebot: test

13:29 technomancy: amalloy: it would be good to provide it as a System/getProperty

13:29 of course it's up to the app what it wants to do with it

13:31 amalloy: technomancy: yes, i like it as a system property. i didn't even realize you could add system properties :P

14:03 gfrlog: ,(println (partial partial partial partial partial partial))

14:03 clojurebot: #<core$partial$fn__3684 clojure.core$partial$fn__3684@a17e57>

14:13 fogus`away: ,(((((((partial partial partial partial partial partial)))) + 100)) 42)

14:13 clojurebot: 142

14:14 amalloy: fogus`away: i think it's fair to say if you ever have (((((((( in your code you are either an imbecile, or too clever for your own good

14:17 * cemerick greps his projects dir :-P

14:19 amalloy: cemerick: another good indicator is ((constantly

14:20 cemerick: how embarrassing

14:22 amalloy: *chuckle*

14:22 fliebel: How do I set a property on maven from Cake? Some ass thought it was smart to add only Windows natives to a pom file: http://slick.cokeandcode.com/mavenrepo/slick/slick/274/slick-274.pom (project>properties>platform)

14:23 cemerick: fliebel: they're just system properties, -Dfoo=bar

14:24 * cemerick is surprised there's no wikipedia article – or really anything substantive anywhere – about function position.

14:24 fliebel: cemerick: So you mean I should do cake deps -Dplatform=mac?

14:25 cemerick: fliebel: I have no idea how cake works.

14:25 mrBliss: Can anybody explain why they start with a '-D'?

14:25 fliebel: cemerick: I figured I could do -D to mvn, but not how cake handles that.

14:25 cemerick: fliebel: but yeah, that'd be my first thought

14:26 mrBliss: I'm guessing only Gosling et al. know.

14:28 mrBliss: cemerick: ok :)

14:29 S11001001: mrBliss: I'd guess an homage to the C preprocessor.

14:30 Berengal: D for define, if memory serves

14:31 mrBliss: Berengal: that sounds plausible

14:31 Berengal: Does anyone have any experience with introducing clojure in the workplace, or know of any resources dealing with that?

14:33 cemerick: Berengal: I'm in the process of collecting a variety of strategies and related tales for the book.

14:34 The biggest source of leverage is the interop/packaging/distribution story.

14:34 technomancy: Berengal: at the risk of repeating the obvious, workplaces vary widely.

14:35 Berengal: cemerick: I've tried that, and the response has been something like "That's nice, but why bother when Java already interops so well with itself?"

14:35 cemerick: Probably followed by key library availability, and the use of a decent execution environment for those shops that usually use e.g. Ruby.

14:35 amalloy: mrBliss, Berengal: it is indeed D for define, and a carryover from the C preprocessor

14:36 cemerick: Berengal: If there's no recognition of the value of greater degrees of expressivity and therefore developer productivity, then I'm not sure where you can go from there.

14:38 Surely a cost/benefit argument can be made re: productivity and quality improvements due to the lack of (or minimization of) defects due to concurrency, mutable data structures, etc.

14:38 Berengal: cemerick: Eh, there's recognition, but mostly there's a lack of enthusiasm, and management seems to think that two languages means twice as slow

14:40 fliebel: Can someone who knows pom tell me what it's doing with lwjgl-native? lwjgl doesn't even seem to be on Maven.

14:40 lwjgl-native

14:40 woops: http://slick.cokeandcode.com/mavenrepo/slick/slick/274/slick-274.pom

14:41 Berengal: cemerick: When I show people all the nifty things clojure can do (one tactically defined macro reduced a sample project I converted from 1000 to 10 lines of code) they tell me that it's neat and that I should talk to the boss-man. He, in turn, also says it's neat, but nobody knows clojure...

14:43 I've got a chance coming up where I could try to convince them, but it'd be nice if someone could tell me what's worked for them

14:44 cemerick: fliebel: the lwjgl deps are coming from the http://b2s-repo.googlecode.com/svn/trunk/mvn-repo repo

14:45 chouser: Berengal: It's too soon for me to say whether it has worked or not, but my approach has been to not particularly advocate, but to inform and educate

14:45 tantalize the developers with Clojure's abilities, help get them started using it on side or personal projects

14:46 give lunch talks about Clojure if you do that sort of thing at work, or if you can start doing that sort of thing

14:46 fliebel: cemerick: Thanks, where does it say that?

14:46 cemerick: fliebel: it's in the pom -- near the bottom, in the <repositories> section

14:46 chouser: all without necessarily trying to convince anyone they should use it at work, such that you remain a safe and non-confrontational person to talk to

14:46 cemerick: Berengal: if he's business-side (or really, involved in P&L in any way, even in a departmental capacity), boil it down to numbers.

14:47 chouser's strategy being the maximally-constructive long-term strategy for other developers, of course :-)

14:47 chouser: Berengal: with any luck, other devs will start coming to you saying, "I'm trying to do such-and-such and it's a paing, but it would be *so easy* in Clojure" because now they know enough to be able to say that with confidence.

14:47 Berengal: chouser: That's been my approach as well, telling people that it's neat, but it doesn't help much if people don't actually try it at home

14:48 fliebel: cemerick: Thanks!

14:48 chouser: Berengal: well, if your dev team doesn't know Clojure and doesn't *want* to learn, it's probably a poor business decision (and therefore bad for you job and everyone else's) to have it forced on them from above, even if you could convince boss-man.

14:49 seancorfield: Berengal: what i've been doing is creating clojure versions of various pieces of code and write unit tests and commit them alongside the original code

14:49 then i can show people the equivalent clojure for code they already know

14:50 over time, they realize it's not some alien technology that's hard to learn / read :)

14:50 Berengal: chouser: Yes, and therein lies the problem. I need to make them want to learn it. As it stands now, they're caught in the local maxima of knowing Java well without realizing there are even more comfortable spots to be in

14:51 seancorfield: we're about to cut over some key portions of one of our apps to use clojure - i expect to have clojure in production by march

14:51 Berengal: seancorfield: I could try some of that.

14:51 seancorfield: apart from anything else, it's a good learning exercise to port parts of your existing system to clojure

14:51 Berengal: I've also been trying to use it as a Java repl, but most Java code isn't really repl-able

15:06 ztellman: fliebel: you around?

15:06 fliebel: yea

15:07 ztellman: so can you explain to me in more detail what you need to be able to parse?

15:07 fliebel: ztellman: http://www.minecraft.net/docs/NBT.txt

15:08 TAG_Compound is delimited by TAG_end.

15:08 ztellman: oh, and tag_compound can contain a tag_compound

15:08 I see

15:08 clojurebot: Excuse me?

15:08 ztellman: hmm

15:09 fliebel: ztellman: It is for the same reason regex can't parse XML that Gloss can't parse NBT.

15:10 ztellman: fliebel: I'm not completely sure that's true

15:10 or rather, I think it's not completely incompatible with how gloss parses

15:10 fliebel: ztellman: Okay :)

15:11 ztellman: for instance, you can have [ (string :utf-8 :delimiters [0x0]) (string :utf-8 :delimiters [0x0]) ]

15:11 obviously it's the outer delimiter that's the issue

15:12 but reading linearly through the byte stream is basically how it works, the delimiter thing is just a shortcut that delays parsing the bytes

15:12 let me think about this a little

15:13 fliebel: ztellman: Here's my code up to the point where I ran into this: https://gist.github.com/761997

15:13 ztellman: fliebel: ok, thanks

15:14 give me a few days, and I'll either have a solution or call it quits

15:15 fliebel: ztellman: Sure, great! I'm not in a hurry. I was just playing with Gloss, trying to replace the ugly Java parser that exists for NBT.

15:15 ztellman: it's a fun use case

15:16 fliebel: ztellman: In other news, have you ever considered making a message queue? Just because you can... There is Lamina, Aleph and Gloss, should be easy :) If you haven't, I might try that sometime.

15:17 ztellman: fliebel: I'm a few hours' free time away from having one that operates over redis

15:17 as for one from scratch, that's a bigger undertaking

15:18 fliebel: ztellman: You're fantastic! :)

15:18 ztellman: you're welcome to try that, if you like

15:19 ok, got to run, thanks for the clarification

15:19 fliebel: ztellman: I think I'm fine with Redis.

15:19 Okay, bye :) Thanks :)

15:29 bhenry: i have :aot with a namespace and it breaks functionality that worked without :aot. i'm getting classNotFound errors on classes used in only one ns. there are however functions that call functions from that ns in other ns's. what exactly is aot doing?

15:49 S11001001: bhenry: it loads the modules you're compiling with the flag for writing compilations to disk turned on

15:50 bhenry: did you :import the relevant classes?

15:51 bhenry: S11001001: the relevant classes are only used in the class in which they are defined.

15:53 S11001001: great, but...

15:57 raek: bhenry: are you starting the clojure instance in another way, compared to how you did it without AOT?

16:09 bhenry: i got it figured out, but another question...

16:09 never mind i found it.

16:20 arkh: what's a way to take a collection of functions and apply them to a sequence of strings. I'm interested in the first non-nil function response (then the function collection could be applied to the next string)

16:22 S11001001: arkh: some

16:25 arkh: S11001001: that's close to what I'm looking for but I'd like to run the battery of functions against every string in the sequence of strings

16:26 if none of the functions return non-nil then that string is ignored

16:26 I figured something like this already exists somewhere in clojure, I just don't know where yet

16:27 _na_ka_na_: does anyone know if circular namespace dependencies are allowed in 1.3 ?

16:27 mefesto: arkh: maybe this would work? (map #(first (filter (comp not nil?) (map % funcs))) strings)


16:28 ugh sorry, bug in there

16:29 arkh: mefesto: the clojure runtime in my head hadn't caught that yet but I'm not surprised it didn't ; )

16:29 mefesto: (map % funcs) won't do since % will be a string. im useless in the late afternoon :)

16:29 raek: (filter identity (for [s strings] (some #(% s) fns)))

16:31 hrm, perhaps (remove nil? ...) would be better

16:32 technomancy: raek: vote for http://dev.clojure.org/jira/browse/CLJ-450

16:47 sproust: Hello gang; I'm having troubles with swank. I'm trying to use it with my own build of bleeding-edge Clojure. Doesn't work ("Evaluation Aborted"). Does swank-clojure work with 1.3? git comments seem to imply it does... does anyone have a working setup with Clojure-1.3.something and swank-clojure? If so, which version?

16:47 (I'm being careful to use the ELPA version of Slime too.)

16:51 technomancy: sproust: I've heard of error reports using it with 1.3

16:51 sproust: Hi Phil; but... aren't you one of the main developers of it? Are you using with 1.3?

16:51 technomancy: it doesn't actually have developers

16:52 it has ... maintainers

16:52 even that is maybe a stretch

16:52 I am still on 1.2 for everything

16:52 sproust: Oh. I see a commit in the git log from you on dec 21 that says "Keepin' it real with pre-1.3 versions."

16:52 Allright, I'll switch back for this task. Thanks man,

16:53 technomancy: that was actually fixing it for 1.2 and lower

16:53 since someone committed a fix for 1.3 that broke it with older versions

16:56 sproust: I see. This is a new project, I'm dying to move to 1.3, I guess I'll have to wait a bit.

16:56 technomancy: really keen on primitive support or something?

17:01 sproust: Nah, just wanting all the new stuff I've been hearing about.

17:01 I'm a bit surprised you guys at Sonian aren't on the bleeding edge.

17:06 technomancy: email archiving doesn't really involve a lot of fibonnaci calculations, so primitive support isn't really exciting for me.

17:07 the binding changes are good, but not really enabling anything new, just cleaning up stuff in a way that's going to break lots of things... best for us to wait for the dust to settle

18:39 chett: How can I remove an item from a set inside a transaction? I need to do the opposite of (dosync (alter foo conj "bar"))

18:39 qbg: ,(doc disj)

18:39 clojurebot: "([set] [set key] [set key & ks]); disj[oin]. Returns a new set of the same (hashed/sorted) type, that does not contain key(s)."

18:40 chett: qbg: thanks

18:53 fbru02: hey guys what is a good way to generate a fn inside a macro that takes a parameter ?

18:56 raek: fbru02: does the fn or the macro take he parameter?

18:56 fbru02: raek: the fn takes the parameter

18:56 raek: `(fn [x#] (inc x#))

18:56 for example

18:56 ,`(fn [x#] (inc x#))

18:56 clojurebot: (clojure.core/fn [x__1797__auto__] (clojure.core/inc x__1797__auto__))

18:57 fbru02: raek: thanks , i had sth like that, i have to see why it is not working :/ thanks a lot !

18:58 raek: you must use the # suffix, or you end up with a user/x symbol

18:58 which you cannot use as a paramter

19:00 if you try to, you get this error: "CompilerException java.lang.Exception: Can't use qualified name as parameter: user/x"

19:01 fbru02: raek: thankks , also I'm doing sth like `(def (symbol (str ~name "-old")) [x#] (...)) but i sometimes get that the first parameter must be a symbol , why is not casting to symbol with (symbol ..)

19:01 ?

19:01 raek: def is a special form, so it needs the argument to be a symbol in code, not evaluate to one

19:02 in this specific case you need a non-qualified symbol

19:02 and you can use the ~'sym hack

19:02 ,`(def ~'name 1) ;

19:02 clojurebot: DENIED

19:03 raek: in this case, I guess you need something like `(def ~(symbol (str name "-old")) ...), which constructs the symbol at compile-time

19:04 fbru02: raek: will try that ! thanks a bunch !

19:05 raek: np.

19:06 amalloy: raek: since when is ~' a hack?

19:06 raek: fair enough... "hack" might not be great word for it...

19:08 amalloy: one nice use-case for it is something like (defmacro foo [blah] `(defn {:arglists '~'([x])} macfn [x#] (do-stuff-with x#)))

19:10 fbru02: amalloy: what

19:11 amalloy: what's macfn in your prev line?

19:11 amalloy: fbru02: heh, a bug

19:11 fbru02: :P

19:12 amalloy: but in real life it would be the name of a function to define, probably another arg to the foo macro

19:22 david`17: where's the video for stu's talk

19:22 it's not up yet, right?

19:42 fbru02: david`17: i don't think it is up , but is the one i want to see the most

19:48 david`17: fbru02: me too :)

20:07 nathanmarz: I've noticed lein uberjar has been a lot slower since 1.4. Anyone else notice this?

20:08 technomancy: any ideas?

21:14 TakeV: Any good clojure libraries for working with Swing?

21:22 amalloy: TakeV: clojure is itself a good library for working with swing - you get a repl and all the swing classes. if you want something more specific, it's rarely hard to use a java library

21:30 TakeV: amalloy: Ah, this is true. I'm just thinking about a wrapper type of library.

21:50 technomancy: nathanmarz: 1.4.2?

21:50 1.4.0 had some remove-unrelated-class-files logic that could slow it down

22:53 amalloy: so here is an idea, which may be crazy

22:54 my experience has been that (cond (some long expression that might take multiple lines) (something or other) (more stuff)...) can be hard to format in a readable way

22:55 what if cond were willing to treat a two-element vector as if it were two discrete elements?

23:07 https://gist.github.com/777365 is an example of what i have in mind

23:16 seancorfield_: amalloy: i must admit i do find forms like cond a bit hard to read

23:16 the bindings in let makes me feel the same way

23:17 amalloy: seancorfield_: yeah, on occasion that is true

23:17 most other lisps i know require you to wrap each pair with (), which seems a little draconian to me, but having it available as an option might be nice

23:18 cond can use [] for wrapping, and now that you mention it let *could* use (), though i'm less confident about whether this would improve reasability

23:19 cemerick: it seems to me that the elimination of those "extraneous" parens/brackets was quite the insightful break from CL, etc.

23:19 seancorfield_: it's just a bit odd to see a form where alternating elements have alternating meanings :)

23:19 cemerick: once your conditionals are long enough to cause formatting issues, isn't that the time to break them into separate functions?

23:19 seancorfield_: yeah, cemerick, i agree it reduces the noise...

23:20 and, yeah, you're probably right about refactoring into smaller functions

23:21 cemerick: FWIW, it's common for such longer conditionals and/or result forms to simply be started on separate lines, with a blank line between each conditiona/result pair

23:21 amalloy: cemerick: yeah, i've done that in the past. it looks pretty weird all the same

23:21 cemerick: I agree. Thus my refactor-to-helper-fn suggestion. :-)

23:22 amalloy: indeed

23:23 cemerick: That's actually the only place where I reliably use letfn.

23:25 it's bizarre to me that pretty-printing a var elides its name.

23:25 * technomancy is very glad he hasn't known of the existence of http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html before today

23:26 seancorfield_: cemerick: i can see that being a good use of letfn - i assume from your comment that you don't think it has many other good uses?

23:27 cemerick: replaca: is that intentional, BTW?

23:28 seancorfield_: no, it definitely has its niche (the fns all being mutually visible can be handy). I just don't happen to need it much.

23:28 Others seem to use it more than I do. Probably a style thing more than anything else.

23:29 seancorfield_: i haven't developed my own clojure style yet :)

23:29 cemerick: technomancy: sarcasm?

23:29 seancorfield_: you have, even if you don't know it yet ;-)

23:29 seancorfield_: mostly i've been experiementing with clojure but i'm planning to start using it in a production context soon

23:30 cemerick: You work with coldfusion a fair bit, right?

23:30 amalloy: technomancy: Arrays.asList is the one useful thing in that class, and obviously it's not necessary if you have (apply list)

23:30 seancorfield_: i've got buy in from devs and i've raised the subject with management a few times - on monday we'll actually get together to discuss a timeline

23:30 technomancy: cemerick: no, I'm only starting to realize how bad things would have to be in a language for a class like that to be useful

23:30 seancorfield_: cemerick: yeah, been working with cfml since i was at macromedia and we bought allaire :)

23:31 my team of java / c++ devs had to cross-train and rebuild all the e-commerce stuff at macromedia with cfml

23:31 technomancy: that's what happens when the only tool you have is a hammer... er, i mean a class

23:32 cfml has evolved into a pretty cool web scripting language over the years - and there are two full-featured FOSS engines as well as adobe's commercial offering

23:32 * cemerick supposes he's the only one that ends up having to deal with arrays much :-P

23:34 technomancy: just the amount of repetition there is the main thing that makes me cringe

23:35 cemerick: seancorfield_: I've never touched it. It never really broached my consciousness over the years. *shrug*

23:35 Sounds like you've been beating a path for Clojure in it though. :-)

23:35 amalloy: technomancy: the one that's started bothering me since i moved to clojure is the "holder" classes - why should i have to write two hundred lines of code to group 5 objects together into a single entity?

23:39 seancorfield_: cemerick: well, i'm already using scala for some xml heavy lifting and the functional stuff has been a passion of mine since the early 80's

23:39 clojure fits in well with our "dynamic scripting on the jvm" stack so i think it's a good fit

23:41 scala for low-level performance-critical infrastructure, clojure for the general web application model, cfml for the front end templating and high-level mvc stuff

23:47 tomoj: whoa

23:47 I would never have guessed that last one

23:49 Derander: coldfusion? I didn't realize that still existed :-P

23:49 I swear it's like the COBOL of web languages

23:49 reading back log

23:49 seancorfield_: it's the same age as ruby and php :)

23:50 i work mostly with railo which is a FOSS implementation - and a jboss community project

23:50 cemerick: And, amusingly, your everyday life absolutely depends upon systems written in COBOL. ;-)

23:50 Derander: cemerick: I'm aware of this

23:51 * seancorfield_ wonders whether he should own up to porting microfocus cobol to the sparc and motorola 88000 chips?

23:51 seancorfield_: aka Sun COBOL 1.0 (on sparc)

23:51 Enclojed: So I'm a clojure n00b but I've used STM before. I'm curious, if I restrict myself to only using clojure collections and immutable records in the STM, how do I write concisely transform a record within a record within a record during a transaction? Obviously I have to copy the parents and all that, but is there a succinct way to do this?

23:52 cemerick: Enclojed: update-in and assoc-in are very handy for twiddling slots many layers down in a data structure.

23:53 seancorfield_: sounds deliciously hardcore

23:53 * cemerick winces at his own usage of "hardcore"

23:53 amalloy: cemerick: deliciously hardcore? this is a family-friendly channel

23:54 cemerick: aaaaand amalloy's mind is in the gutter, per usual :-P

23:54 Enclojed: cemerick: At the risk of sounding dumb, is it true that update-in works 100% with records?

23:55 seancorfield_: cemerick: my first real job? writing a portable VM for UCSD Pascal... i'm a compiler / runtime guy at heart...

23:55 cemerick: Enclojed: absolutely -- it's just using assoc

23:55 Enclojed: cemerick: Fantastic! Is there somewhere I can learn about how to structure clojure programs using STM in a server/client architecture? I don't see anything in the docs about how to do IO cleanly :(

23:56 amalloy: Enclojed: the way i usually do it is something like (send-message (swap! my-atom some-function-deciding-what-to-say))

23:56 cemerick: Enclojed: IO is a no-go within transactions. Thus the existence of the io! macro.

23:56 amalloy: thus if there's a retry, you don't send any actual messages till the end

23:56 cemerick: Enclojed: using a watcher on key refs to drive write-behind persistence is a good pattern

23:57 Enclojed: cemerick: I was using really sloppy language there, sorry. The model I'm used to (Red Dwarf/Darkstar server does this) allows you to queue up IO to happen after a transaction

23:57 cemerick: does io! send things that way? Or do I have to make my own queue?

23:57 amalloy: Enclojed: io! definitely doesn't do that

23:58 cemerick: ,(doc io!)

23:58 clojurebot: "([& body]); If an io! block occurs in a transaction, throws an IllegalStateException, else runs body in an implicit do. If the first expression in body is a literal string, will use that as the exception message."

23:58 cemerick: io! is a safeguard to ensure that IO isn't accidentally roped into a transaction

23:58 Enclojed: cemerick: Yeah I looked it up... there doesn't seem to be much in the docs about when to use it. I guess it's just for things you don't expect to be transactional?

23:59 cemerick: Enclojed: amalloy's approach of using an agent for post-transaction actions is equally applicable to the problem. Agent sends queue up and aren't released until a transaction is committed; watchers are notified in much the same way.

Logging service provided by n01se.net