#clojure logs

2011-01-12

00:10amalloywhat 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?
00:15hiredmanamalloy: ant
00:15hiredmanthat kind of depends
00:16hiredmanyou can infact upoad your own version of clojure to clojars if you want
00:17hiredmanhttp://clojars.org/org.clojars.hiredman/clojure
00:17hiredmanor just use maven to install it in your local m2
00:18amalloyhiredman: aha, thanks, that's a simpler solution than i expected
00:19hiredmanif you run ant test it runs the tests with the clojure.jar you just compiled
00:19hiredmanso you can just add test cases
00:24amalloyhiredman: deviouser and deviouser!
00:54amalloyhow do folks here feel about having #|...|# common-lisp-like comments?
00:57RaynesTotally for it.
00:58tomojhuh, we have no block comments now that will take non-forms?
00:58tomojI never noticed
00:58Rayneshttp://dev.clojure.org/jira/browse/CLJ-714
01:19bartjfacing a precision issue: is there anyway 0.7 != (float 7/10)
01:24amalloy&(= 0.7 (double 7/10))
01:24sexpbot⟹ true
01:24amalloy&(= 0.7 (float 7/10))
01:24sexpbot⟹ false
01:24amalloybartj: ^
01:25cheezeyso basicallly clojure defaults to doubles? o_O
01:25amalloycheezey: um...yeah, just like every other language in the world [citation needed]
01:26bartjwhy is this!??
01:26bartjI mean why doesn't float work?
01:26amalloybartj: because of precision, just like you said
01:26amalloy0.7<decimal> is not representable precisely in base 2
01:27cheezeybartj: cuz floats are less precise than doubles
01:28amalloy&(Double/toHexString 0.7)
01:28sexpbot⟹ "0x1.6666666666666p-1"
01:29amalloy&(Float/toHexString 0.7)
01:29sexpbot⟹ "0x1.666666p-1"
01:29bartjvoila!
01:29bartjI wanted to know how it gets stored, thanks!
01:31cheezeyamalloy: 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?
01:32amalloycheezey: 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)
01:33bartjamalloy, cheezey thank you!
01:34cheezeyamalloy: when you say you want src to be inthe classpath, you mean the absolute path to src right?
01:35amalloycheezey: yes, although a relative path would probably work if you were sure of what the cwd is
01:39cheezeyhmm. i dunno what the issue is (prretty much same thing as last time)
01:42cheezeyamalloy: 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?
01:43amalloyno
01:43cheezey:x
01:43amalloythe filename is part of the namespace as well
01:43amalloyso you want (ns a), not (ns foo)
01:44amalloyor ns foo.a, if foo's parent is on the classpath
01:51cheezeyamalloy: hm. i dunno why i can't figure this out...
01:56amalloycheezey: 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
02:20tomojcheezey: 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?
02:21tomojor was that someone else
02:21cheezeytomoj: yeah that was me
02:22tomojany particular reason you chose that guide?
02:22cheezeywhat's the alternative? o_O
02:22tomojI recommend trying to get set up with leiningen or cake instead
02:22cheezeytomoj: yeah im using leinigen now
02:23tomojthen you shouldn't have to compile clojure/contrib from source
02:23clojurebotsource is http://github.com/hiredman/clojurebot/tree/master
02:23tomojor use any 'clj' script
02:23cheezeyya, i just switched =P
02:25tomojgood
02:25tomojsingle-segment namespaces (like (ns foo)) are discouraged, by the way
02:26amalloycheezey: so just $ lein new myproject, and it'll set up a skeleton project for you
02:26amalloythen you can see how things are supposed to be organized
02:26cheezeyamalloy: i've built my project, but when i run it, something about main-class manifest
02:26cheezeystill looking stuff up but ify ou know the solution :P
02:40Licensermorning
02:41Scriptormarnin Licenser
03:05LauJensenMorning crew
03:13amalloymornin LauJensen
03:16amalloyhey 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
03:20LauJensendone
03:23amalloysweet. thanks
03:24m1ndvirusIs Clojure similar to CL?
03:25amalloyfor certain values of similar
03:26_na_ka_na_I have a doubt, is a var, just a more flexible atom ?
03:27_na_ka_na_semantically I mean
03:28_na_ka_na_amalloy, why not use #_ for multiline comments?
03:28LauJensenm1ndvirus: not really
03:29amalloy_na_ka_na_: for the same reason you can't use (comment)
03:29m1ndvirusLauJensen: Is it like Scheme?
03:29LauJensenWell, not really
03:29m1ndvirusLauJensen: Arc?
03:29amalloym1ndvirus: keep going till you get to clojure :)
03:30LauJensenI dont know Arc that well, but from what I know, its not like it
03:30m1ndvirusIf you were to describe Clojure's philosophy in a brief phrase, what would it be?
03:30taliosEvening
03:30_na_ka_na_amalloy, you can do (list 1 2 #_" blah blah multiline comment" 3 4)
03:30LauJensenhttp://clojure.org/rationale
03:30m1ndvirustalios: That tells me almost nothing. :P
03:31LauJensenm1ndvirus: slurp that link ^^
03:31m1ndvirusDid so.
03:31amalloy_na_ka_na_: yeah, and you can do the same in perl with <<<, but that doesn't make it a real comment
03:31amalloyand you can't nest those either
03:31taliosm1ndvirus: ok - Glorious evening of cool summer Auckland breeze to you - I hope you and yours are safe, warm, and cuddly. :)
03:32_na_ka_na_amalloy, by real comment you mean ?
03:32amalloy_na_ka_na_: for example i can't include a string in your "comment"
03:32m1ndvirustalios: I felt a warm gust of light wind breeze through my nostrils.
03:33_na_ka_na_amalloy, ya but you can use \" \"
03:33amalloy_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
03: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
03:35amalloy_na_ka_na_: you can't use #_"" to write a comment describing how to use #_"" comments - you have to escape the quotes
03:36amalloyyou can't comment out a chunk of code that's malformed but you want to keep around for now
03:36_na_ka_na_amalloy, doesn't this go with any literal? in java we have /* */ ... now how do i write '*/' in comments?
03:37amalloy_na_ka_na_: the lisp #|...|# comments, as well as my clojure impl, nest
03:39_na_ka_na_amalloy, you mean i can write #| ..comment.. |# .. comment continues ... #| ..comment continues further |# ?
03:39_na_ka_na_so its like a stack
03:39amalloyyou can write #| comment #| more comment |# still comment |# now real code
03:40amalloysee the attached patch for my jira issue - i include a test case for that
03:40_na_ka_na_amalloy, but its the same thing then, who do i write |# inside the comment itself?
03:42amalloywell, 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
03:43_na_ka_na_so equivalent to escaping " inside #""
03:43_na_ka_na_plus editors can provide support for commenting/uncommenting a chunk of code
03:44amalloynot if it's not well-formed
03:45_na_ka_na_this works (list 1 2 #_"(a" 3 4)
03:45amalloy*chuckle* oh, all right
03:46amalloybut you could say the same of any language that allows multi-line strings - why allow multi-line comments?
03: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"
03:47amalloyand requires more escaping
03:47_na_ka_na_yes
03:48amalloyit's also clearer in editors without good syntax highlighting
03:48amalloy|# is the end of a comment, but " is harder to spot
03:50_na_ka_na_I agree, that's why I'm upvoting your patch
03:51ejacksongreetings
03:51amalloythanks for the argument, though. i hadn't realized how good a substitute #_ is
03:51_na_ka_na_I too didn't know, i just use ; for every line
03:52amalloyme too :)
03:53_na_ka_na_I have a doubt, is a var, just a more flexible atom ?
03:55_na_ka_na_alter-var-root & swap! seem similar
03:56amalloy_na_ka_na_: vars have per-thread bindings and an automatic stack/history, and are interned in namespaces; they also deref by default
03:56amalloyi think that's most of the interesting differences
03:57_na_ka_na_so I can use a var inplace of a global (ns-level) atom
03:58amalloyuhhh, i suppose you could. i'm not sure what the concurrency semantics of vars are, but it's probably okay
03:58_na_ka_na_,(doc alter-var-root)
03:58clojurebotDENIED
03:58_na_ka_na_nice clojurebot
03:58amalloy$source alter-var-root
03:58sexpbotalter-var-root is http://is.gd/kBPoN
03:59_na_ka_na_so it also atomically alters the var
04:02_na_ka_na_i cant think why I would want to do (def s (atom x)) instead of just (def s x)
04:03_na_ka_na_plus in 1.3 binding is also multithreaded
04:09tomojhmm.. only one thread can alter-var-root at a time
04:11tomojmultiple threads can swap! at the same time, but if the winner changes the value the rest have to retry anyway
04:15_na_ka_na_tomoj, didn't get what you meant by only one thread can alter-var-root at a time?
04:15_na_ka_na_I can do (def a 0) and then (dotimes [_ 100] (future (alter-var-root #'a inc)))
04:16tomojyeah, and they all block waiting for the previous ones to finish
04:16_na_ka_na_hmm so the difference is that, alter-var-root uses a lock, whereas atom is compare-and-swap ?
04:18tomojsounds right to me
04: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
04:24amalloy_na_ka_na_: a lock will perform better. but atoms won't deadlock
04:25amalloyi guess i might even be wrong about a lock performing better
04:25tomojalso
04:25tomojalter-var-root seems to block readers
04:26tomojwith the atom, you might have lots of retries, but anyone can always get the current value
04:27_na_ka_na_hmm so vars are synchronized objects in java
04:27tomojfor a stupid test where each of 100 swap!/alter-var-root just sleeps for 100ms and incs, they perform almost the same
04:28tomojif 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
04:44TobiasRaedermorning
04:50bartjwhat is the *easiest* way to read command line arguments in Clojure?
04:51Berengal_work_bartj: Require they be valid clojure datastructures, and call read on them
04:51bartjI mean is there a "Perlish" way so that the command line variables are stored in ARGV
04:52bartjor a "Javaish" way where the main method takes arguments
04:52bartjI am looking at this: http://stackoverflow.com/questions/1341154/building-a-clojure-app-with-a-command-line-interface
04:53bartjand when I run the example from the accepted answer, changing the value of "foo" it doesn't get printed
04:54bartjput another way:
04:56bartjwhy doesn't *command-line-args* print anything, even though I pass arguments
04:59_na_ka_na_bartj, $ java -cp lib/clojure-1.2.0.jar clojure.main -r 1 2 3
04:59_na_ka_na_Clojure 1.2.0
04:59_na_ka_na_user=> *command-line-args*
04:59_na_ka_na_("1" "2" "3")
04:59_na_ka_na_user=>
05:00bartjdo I need to give the -r flag?
05:00_na_ka_na_-r is for the repl
05:01_na_ka_na_I think it will work even if you're running a main method
05:02bartjhmm, yes!
05:03bartjI am confused regarding which option to use:
05:03bartjI mean what is the difference b/w
05:03bartj*command-line-args*
05:03bartj(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
05:06_na_ka_na_i guess with-command-line is a useful utility if you're building a CLI app
05:07clgvit seems to do the parsing of *command-line-args* and gives you variables with the given values assigned
05:08clgvso you dont have to do that task yourself
05:09clgvthanks for the link btw :)
05:10RaynesMan, moving wiki pages is real grunt work.
05:14bartjso, using *command-line-ags* is definitely much easier
05:15bartj_na_ka_na_, by app I think you mean "command menus" for naviagation, not a hacky utility ?
05:17_na_ka_na_bartj, by CLI app I meant any command line interface program
05:17bartj_na_ka_na_, ok, thanks for the help
05:17_na_ka_na_bartj, welcome
05:20raekbartj: *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
05:21bartjraek, that makes a lot of sense, thanks!
05:22clgvbartj: if you take that example: java -classpath . cmd_line_demo --foo test --bar 4711 filename
05:22clgv*command-line-args* would be ["-foo" "test" "--bar" "4711" "filename"]
05:22clgvafair 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)
05: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
05:26raekalso, amalloy_ has made a command line option parser: https://github.com/amalloy/clojopts/tree/
05:27bartjits just a small hacky utility; I'll go with *command-line-args*
05:27bartjthanks again everyone
05:31raekI 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?
05:32raekyou could call it deftuple
05:33raek(deftuple Foo [a b c] ...)
05:33clgvwhat is the goal of that? performance? "typesafety" of this deftuple since it can't get more fields/attributes?
05:33raek(Foo. 1 2 3) => #:user.Foo[1 2 3]
05:33_na_ka_na_raek, I think (deftuple Foo 3)
05:33raekI often feel that I want something like haskells ADTs
05:34LauJensenAnd SQL masters in here?
05:34raekthe parts should have names if you want to reference them in method bodies
05:34raekone feature of these tuples would be that they destructure as lists/vectors
05:35raek(let [[a b c] (Foo. 1 2 3)] ...)
05:35_na_ka_na_if they have names, then its just defrecord right? for inside method bodies one could use $1 .. ?
05:36_na_ka_na_(let [{:keys [a b c] (Foo. 1 2 3)]) is not much different
05:36raekthe user of the tuple would think of it as a positional structure, rather than a map
05:36raeksure
05:36raekthen I have to come up with good names for the field...
05:38fliebelmorning
05:38RaynesI just finished moving the assembla Getting Started wiki pages to Confluence: http://dev.clojure.org/display/doc/Getting+Started
05:39raek(inc Raynes)
05:39sexpbot⟹ 4
05:41ejacksonnice one Raynes
05:41RaynesIt was nothing, really. Only about an hour of my precious, important time.
05:42RaynesI just wanted to be able to link to confluence in my book instead of assembla. :>
05:42ejacksonquick pointer please. how do I monitor for an exception in a case like this (def a (future (/ 1 0)))
05:43clgvcan the CLR implementation be considered as stable as the JVM one provided both have the same version number (e.g. 1.2)?
05:43RaynesUse a thread instead.
05:43ejacksona 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 ?
05:44ejacksonRaynes: I'll check it out, thanks
05:44raekwhat?
05:44clojurebotwhat is exceptions
05:45ejacksonexactly clojurebot - I'm getting exceptions in my code and not sure how to monitor for em
05:45Raynesfuture is satan when it comes to error handling.
05:45raekRaynes: no.
05:45Raynesraek: Yes.
05:45ejacksonraek: what do you suggest ?
05:45_na_ka_na_ejackson, the above code will throw an exception inside the future and theres no way you can catch it
05:45Raynesraek: We had this problem in Irclj because you replaced a thread with a future.
05:45raekwhen you dereference a future, it will throw a certain kind of exception if some exceptio was thrown in the body
05:46raekhttp://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#get()
05:46RaynesYes, when you dereference it.
05:46raek"ExecutionException - if the computation threw an exception"
05:46raekif you want to handle it (e.g. printing the stack trace) you should add code to do so
05:46RaynesFutures are great, but not if you're just using them as a way to run something in a new thread.
05:46raek(future (try ... (catch Throwable t (.printStackTrace t))))
05:47raekRaynes: why not?
05:47RaynesI think his example is enough of a reason.
05:47ejacksonraek: 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 ?
05:48tomoj,@(future (try (/ 1 0) (catch Throwable t (.printStackTrace t))))
05:48clojurebottomoj: Pardon?
05:48RaynesWell, I did word that wrong.
05:48raekif you dereference it, you will block until it completes or throws
05:48ejacksonDEREFENCE !
05:48ejacksonbloody genius, thanks :)
05:48ejacksonrtfm ejackson
05:48RaynesFutures are great if you want to run something in a new thread and care about the value.
05:49raekor want tot be able to cancel it
05:49afekzfunctional approach - return value even if just "succes"/?
05:49raekor check whether it has finished
05:49afekzmaybe there are problems I haven't yet come across, but it's a wonderful boon for my hacking of little bits of code together
05:49ejacksonraek and Raynes : thank you both
05:49afekzeven just launching some heavy crunching things in the REPL (up to CPU core limit)
05:50_na_ka_na_raek, didn't get, how will deref help
05:50_na_ka_na_Raynes, how will spawn your own thread help here
05:50Raynesafekz: 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.
05:51Raynes_na_ka_na_: When the error happens, it just happens.
05:51afekzRaynes: in my use cases so far, any side effects will hit the file system
05:51RaynesYou don't have to "check" to see if it happened.
05:51raekthread print the stack trace and die on exceptions
05:51raekfutures run in some else's thread, so they can''t crash it
05:52raekthey are built to be able to communicate back how the execution went
05:52raek_na_ka_na_: help in which problem?
05: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))
05:54_na_ka_na_by useful I mean if that time consuming thing throws an exception
05:54afekzdoesn't that block?
05:54_na_ka_na_not if you use a future
05:54afekz*nod* - I wasn't reading the (future (...)) into your psuedo code - my apologies
05: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
05:55raekwhat do you want to detect?
05:56ejackson_na_ka_na_: at some point you're going to need to know what happened in the execution
05:56ejacksonso somewhere you'll need to deref the future
05:56ejacksonthat's going to block
05:56ejacksoni guess, dunno really.
05:56raekyou can also use future-done? to poll it
05:56ejackson,(doc future-done?)
05:56raeksone = finished or throwed
05:56clojurebot"([f]); Returns true if future f is done"
05:57raek*done
05:57tomojI can't think of when I'd want to use that instead of lamina
05:58ejacksoncan you put a watch onto future ?
05:59raek(def pool (Executors/newFixedThreadPool 10)) (map deref (.invokeAll (map #(f %) coll))))
05:59ejacksontomoj: you're referring to https://github.com/ztellman/lamina ?
06:00raekejackson: no. it would be more logical to add the triggering code in the code running in the other thread, I think
06: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)))
06:00ejacksonraek: ok, just a random though.
06:00tomojejackson: yeah, but that wasn't a suggestion, I've just got lamina on the brain and never really understood futures
06:00_na_ka_na_define:lamina
06:01raekI guess all this depends on how you want to handle the exceptions
06:01ejacksontomoj: cool, I always like now toys to play with.
06:01raekfor a background thread, it makes sense to have a top-level catch-all
06:03_na_ka_na_hmm you can even do: (try @(future (/ 1 0)) (catch Exception e :great))
06:04raekyou could print the stacktrace, do some logging, store the exception in some global variable, etc
06:04raekah, sorry. read it as "hmm what can you even do"
06:05_na_ka_na_i got misplaced earlier as I was catching the wrong exception, (try @(future (/ 1 0)) (catch ArithmeticException e :great))
06:05_na_ka_na_it throws a java.util.concurrent.ExecutionException
06:05raekyes, it wraps the original one
06:06raek(try @(future (/ 1 0)) (catch ExecutionException e (throw (.getCause e))))
06:06_na_ka_na_hmm nice
06:06raekfutures can fail in multiple ways, so some mechanism for distinguishing the cases is needed
06:07_na_ka_na_why is error handling so hard!
06:08ejacksonyou're telling me :)
06: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
06:10_na_ka_na_usually data fixes
08:16clgvis there a shortcut for the cond-expresson for the case when I only want to check values (classic switch-case expression)??
08:16fliebelclgv: switch?
08:16clgv,(doc switch)
08:16clojurebotIt's greek to me.
08:16mrBlissclgv: case or condp
08:16clgv$(doc switch)
08:17fliebel&(doc switch)
08:17sexpbotjava.lang.Exception: Unable to resolve var: switch in this context
08:17fliebelI'm sure it's htere somewhere...
08:17clgvcase looks promising
08:17mrBlissfor some examples: http://clojuredocs.org/clojure_core/clojure.core/case
08:18clgvthx :)
08:18fliebelAh, it's case indeed.
08:18zmyrgelhi, could somebody point what I'm doing wrong, I have ref to map and I want to change one key value pair in it
08:18zmyrgelbut when I try to do it the whole ref gets set to nil
08:19fliebelzmyrgel: Code?
08:19zmyrgelhere you go: http://pastebin.com/wtcBM8ZV
08:20mrBlisszmyrgel: lose the '@'
08:20mrBliss(dosync (alter game-options assoc key value))
08:21zmyrgelmrBliss: thanks, that was quick :)
08:38Raynesapgwoz: ping
08:50clgvwhat'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 ?
08:55raeksounds like something should expand to (defn foo [] ...) but actually becomes (defn foo bar [] ...)
08:55raeki.e. the bar symbol cannot be used as an argument vector
08:56raek,(let foo 123)
08:56clojurebotjava.lang.IllegalArgumentException: let requires a vector for its binding
08:57raek,(defn foo bar [] 123)
08:57clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
08:58david`,(def fib (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
08:58clojurebotDENIED
08:58david`:(
08:59RaynesYou 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))
08:59sexpbotjava.lang.Exception: Unable to resolve symbol: fib-seq in this context
08:59RaynesWell, yeah.
08:59david`##(let [fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq))] (take 10 fib-seq))
08:59sexpbotjava.lang.Exception: Unable to resolve symbol: fib-seq in this context
09:01raeka value cannot contain itself. you could make fib-seq as a funciton of zero arguments, though
09:01raek(letfn [(fibseq [] ...)] (take 8 (fibseq)))
09:04raek,(letfn [(fib-seq [] (lazy-cat [0 1] (map + (rest (fib-seq)) (fib-seq))))] (take 8 (fib-seq)))
09:04clojurebot(0 1 1 2 3 5 8 13)
09:09clgvraek: found it. it's a (first expr) during macro expansion time
09:09clgvI could clearly use something like a "macro expansion stack" for debug purposes...
09:24clgvif I use a macro in a macro definition, is it expanded during processing the definition provided it has no syntaxquote?
09:24Chousukeyes.
09:24rrc7czhow can you claim a group in clojars?
09:24clgvjust to clarify the exact scenario: (defmacro macro2 [x] (macro1 x))
09:25Chousukeclgv: yeah, the expansion happens at definition time
09:25clgvChousuke: hmok then I have to analyze why my ported code doesnt do the same as the original ;)
09:26Chousukethe code the macro expands to is evaluated and that becomes the code that actually runs at runtime.
09:27Chousukemaybe somewhere there you have your mistake :P
09:28clgvhm 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...
09:32fliebelI have a Java project with a build.xml file, can Maven install it into my local repo, so I can use it in Cake?
09:35clgvChousuke: ok, seems I mistook a defn for a defmacro while porting...
09:36Chousukeheheh
09:37fliebeloh, wait (not= ant maven)
09:37clgvI have to get used to the fact that functions can be called during macroexpansion time...
09:38Chousukeheh.
09:38Chousukeyou can do almost anything during macroexpansion
09:38ChousukeAFAIK Penumbra does reflection :P
09:39Chousukelooks up available OpenGL functions and generates a clojurey wrapper for them.
09:39clgvI have to get rid of the C/C++ macro interpretation ;)
09:39clgvstill halfway between this one and the clojure one ;)
09:39chouseramalloy_: finger trees are at https://github.com/clojure/data.finger-tree
09:40Chousukechouser: what's the status of that, anyway?
09:40chousergood to go
09:41chouserI'll be releasing 0.0.1 once we've got our new contrib release procedure ducks in a row
09:46MisterSpeakerI'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?
09:48fliebelMisterSpeaker: I'm downloading Penumbra just now. I'll see what it does for me.
09:48AWizzArdchouser: what are currently the biggest challenges regarding the FTs?
09:49technomancyAWizzArd: judging from questions asked on IRC, I'd say the build.
09:56fujinohai
09:56danlarkinfujin: OH HERRO
10:00AWizzArd(:
10:08raekrrc7cz: I think you simply push the jar with that group in the POM
10:09raekat least, that's how I did for my jars in the se.raek group
10:13chouserAWizzArd: Clojure team virtual logistics
10:18AWizzArdI see.
10:29ejacksonwhat is the accepted way of checking the type of function arguments? (instance? ...) ?
10:30tonyl(type ...0
10:30ejacksonshould I want to do se even ? If I expect some argument, d, to be a DateTime, should I assert this in a :pre ?
10:30tonyl(type ...)
10:30tonylyou can type hinted
10:30chouserbut type hinting doesn't assert
10:30tonyland if it the argument passed to it it would throw an Exception
10:31chouserso, asserting in a :pre is probably best, if you're not comfortable just leaving it open.
10:31ejacksonwell, I don't want to write crappy code, but there's a trade off here :)
10:32ejacksonputting 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:32ejacksonwhat's the received wisdom here ?
10:32technomancythere's the notion of type hints as documentation
10:32technomancyI'm not sure I buy that, but it's an interesting idea
10:32ejacksoninteresting
10:34ejacksonthanks for the pointers guys
10:35fliebelHrm, Cake hangs for me on random projects. It seems somehow related to having native deps, or being a complicated project.
10:36apgwozRaynes: pong, sorry was away from this computer
10:54rrc7czwhat'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:55Chousukegenerally, you should avoid depending on such a var. just pass it around as a parameter if possible
10:56Chousukealternatively, you can make it dynamically bindable and then require users do (binding [*api-key* "whatever"] (calls-to-your-code-here))
10:56rrc7czChousuke: I'd rather force (binding [*api-key* "foo"] (myapicall1) (myapicall2) etc)
10:56rrc7czso it's less tedious
10:57rrc7czChousuke: you read my mind :-D
10:57Chousukebut if it's at all feasible, it's better to use a parameter.
10:57rrc7czbut *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:58Chousukeglobal dynamic variables are pretty inflexible :/
10:58Chousukerrc7cz: you should at least hide the *api-key* entirely then
10:58rrc7czChousuke: 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:58rrc7czChousuke: you mean make it private and have a setter fn?
10:58Chousukeprovide a function like (init-lib! "apikey")
10:59rrc7czokay that makes sense
10:59Chousukebut then it will be impossible to use your library concurrently with different API keys.
10:59rrc7czChousuke: you could still use (binding)
11:00Chousukeperhaps. though provide a macro for that.
11:00rrc7czChousuke: you'd just have a "default" api key you set with the init fn, then use (binding) to briefly drop into other keys
11:00rrc7czChousuke: in practice, at least for this web service, they will never have multiple api keys, but it's an interesting though
11:02rrc7czare the earmuffs appropriate still for this var? I mean, it's private
11:02mrBlissI think we use +for-private-vars+
11:03Chousukerrc7cz: yeah, if it can be dynamically bound
11:03Chousuke++ is a CL convention for constants IIRC. it doesn't really make sense in Clojure :)
11:05mrBlissChousuke: and for (def ^:private..) stuff?
11:05ChousukeI don't think you need anything
11:05Chousukethe metadata is enough :P
11:06mrBlissbut you don't see the metadata when you're using the var :)
11:06Chousukeenforcing "privateness" is usually not very useful anyway. If someone goes and rebinds *api-key* manually, that's not your problem
11:25fliebelIs 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:26fliebelTrying to get lwjgl, and ultimately Slick.
11:48lpetitHmmm, 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:52technomancylpetit: people have been doing "lein pom" and then importing as a maven project; does that work ok?
11:52technomancyI guess it helps it know where the files are but doesn't help with running tasks
11:54lpetittechnomancy: 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:54lpetittechnomancy: Until one clear winner emerges, and then I'll provide more integrated support :-p
11:54technomancysure, I think it makes sense
11:55RaynesI like the idea.
11:58lpetit'ommon cemerick, why aren't you there when I need you, helping me not deviate from the all maven road ? :-D
11:58mrBlissWouldn'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:00lpetitmrBliss: 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:01lpetitok, out of 3 answers, 2 considered positive. Enough for me starting to yet again spread my energy over more than one task :)
12:04lpetitHuh, seems like lein-eclipse already exists ! http://tux2323.blogspot.com/2010/08/import-clojure-leiningen-project-into.html
12:05lpetitwhy oh why do people not communicate more ? (me included, of course)
12:06amalloylpetit: 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:07technomancythey didn't add it to https://github.com/technomancy/leiningen/wiki/Plugins =(
12:07lpetitamalloy: 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:08lpetitand also a note in the lein ml, since it seems that technomancy is also discovering this plugin existence.
12:09amalloylpetit: sure, i agree. but it's fun to make impractical suggestions
12:09lpetitamalloy: certainly :)
12:09technomancyamalloy: have you tried restarting with extensions off?
12:10amalloytechnomancy: what
12:12technomancyamalloy: impractical suggestions, you know
12:12technomancyMac System 9 advice.
12:12lpetit(rofl)
12:12lpetitmust leave, cu
12:12amalloytechnomancy: jeez, mac system 9. i'm too young for this nonsense :P
12:18gfrlog,(println "Testing connection")
12:18clojurebotTesting connection
13:02jkndrkndo any lein users know if you can access the version number set in the project.clj defproject form within your application?
13:03technomancyjkndrkn: only from plugins... but that's a good idea.
13:05jkndrknwhat 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:05technomancyI 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:06jkndrknah, ok. thanks for the clarification ^_^
13:12amalloytechnomancy: is it actually a good idea? it would mean a clojure program that only works if it's built with lein
13:26signalseeker,(println 'test)
13:26clojurebottest
13:29technomancyamalloy: it would be good to provide it as a System/getProperty
13:29technomancyof course it's up to the app what it wants to do with it
13:31amalloytechnomancy: yes, i like it as a system property. i didn't even realize you could add system properties :P
14:03gfrlog,(println (partial partial partial partial partial partial))
14:03clojurebot#<core$partial$fn__3684 clojure.core$partial$fn__3684@a17e57>
14:13fogus`away,(((((((partial partial partial partial partial partial)))) + 100)) 42)
14:13clojurebot142
14:14amalloyfogus`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:19amalloycemerick: another good indicator is ((constantly
14:20cemerickhow embarrassing
14:22amalloy*chuckle*
14:22fliebelHow 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:23cemerickfliebel: they're just system properties, -Dfoo=bar
14:24fliebelcemerick: So you mean I should do cake deps -Dplatform=mac?
14:25cemerickfliebel: I have no idea how cake works.
14:25mrBlissCan anybody explain why they start with a '-D'?
14:25fliebelcemerick: I figured I could do -D to mvn, but not how cake handles that.
14:25cemerickfliebel: but yeah, that'd be my first thought
14:26cemerickmrBliss: I'm guessing only Gosling et al. know.
14:28mrBlisscemerick: ok :)
14:29S11001001mrBliss: I'd guess an homage to the C preprocessor.
14:30BerengalD for define, if memory serves
14:31mrBlissBerengal: that sounds plausible
14:31BerengalDoes anyone have any experience with introducing clojure in the workplace, or know of any resources dealing with that?
14:33cemerickBerengal: I'm in the process of collecting a variety of strategies and related tales for the book.
14:34cemerickThe biggest source of leverage is the interop/packaging/distribution story.
14:34technomancyBerengal: at the risk of repeating the obvious, workplaces vary widely.
14:35Berengalcemerick: 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:35cemerickProbably followed by key library availability, and the use of a decent execution environment for those shops that usually use e.g. Ruby.
14:35amalloymrBliss, Berengal: it is indeed D for define, and a carryover from the C preprocessor
14:36cemerickBerengal: 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:38cemerickSurely 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:38Berengalcemerick: 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:40fliebelCan someone who knows pom tell me what it's doing with lwjgl-native? lwjgl doesn't even seem to be on Maven.
14:40fliebellwjgl-native
14:40fliebelwoops: http://slick.cokeandcode.com/mavenrepo/slick/slick/274/slick-274.pom
14:41Berengalcemerick: 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:43BerengalI'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:44cemerickfliebel: the lwjgl deps are coming from the http://b2s-repo.googlecode.com/svn/trunk/mvn-repo repo
14:45chouserBerengal: 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:45chousertantalize the developers with Clojure's abilities, help get them started using it on side or personal projects
14:46chousergive lunch talks about Clojure if you do that sort of thing at work, or if you can start doing that sort of thing
14:46fliebelcemerick: Thanks, where does it say that?
14:46cemerickfliebel: it's in the pom -- near the bottom, in the <repositories> section
14:46chouserall 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:46cemerickBerengal: 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:47cemerickchouser's strategy being the maximally-constructive long-term strategy for other developers, of course :-)
14:47chouserBerengal: 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:47Berengalchouser: 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:48fliebelcemerick: Thanks!
14:48chouserBerengal: 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:49seancorfieldBerengal: 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:49seancorfieldthen i can show people the equivalent clojure for code they already know
14:50seancorfieldover time, they realize it's not some alien technology that's hard to learn / read :)
14:50Berengalchouser: 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:51seancorfieldwe'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:51Berengalseancorfield: I could try some of that.
14:51seancorfieldapart from anything else, it's a good learning exercise to port parts of your existing system to clojure
14:51BerengalI've also been trying to use it as a Java repl, but most Java code isn't really repl-able
15:06ztellmanfliebel: you around?
15:06fliebelyea
15:07ztellmanso can you explain to me in more detail what you need to be able to parse?
15:07fliebelztellman: http://www.minecraft.net/docs/NBT.txt
15:08fliebelTAG_Compound is delimited by TAG_end.
15:08ztellmanoh, and tag_compound can contain a tag_compound
15:08ztellmanI see
15:08clojurebotExcuse me?
15:08ztellmanhmm
15:09fliebelztellman: It is for the same reason regex can't parse XML that Gloss can't parse NBT.
15:10ztellmanfliebel: I'm not completely sure that's true
15:10ztellmanor rather, I think it's not completely incompatible with how gloss parses
15:10fliebelztellman: Okay :)
15:11ztellmanfor instance, you can have [ (string :utf-8 :delimiters [0x0]) (string :utf-8 :delimiters [0x0]) ]
15:11ztellmanobviously it's the outer delimiter that's the issue
15:12ztellmanbut reading linearly through the byte stream is basically how it works, the delimiter thing is just a shortcut that delays parsing the bytes
15:12ztellmanlet me think about this a little
15:13fliebelztellman: Here's my code up to the point where I ran into this: https://gist.github.com/761997
15:13ztellmanfliebel: ok, thanks
15:14ztellmangive me a few days, and I'll either have a solution or call it quits
15:15fliebelztellman: 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:15ztellmanit's a fun use case
15:16fliebelztellman: 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:17ztellmanfliebel: I'm a few hours' free time away from having one that operates over redis
15:17ztellmanas for one from scratch, that's a bigger undertaking
15:18fliebelztellman: You're fantastic! :)
15:18ztellmanyou're welcome to try that, if you like
15:19ztellmanok, got to run, thanks for the clarification
15:19fliebelztellman: I think I'm fine with Redis.
15:19fliebelOkay, bye :) Thanks :)
15:29bhenryi 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:49S11001001bhenry: it loads the modules you're compiling with the flag for writing compilations to disk turned on
15:50S11001001bhenry: did you :import the relevant classes?
15:51bhenryS11001001: the relevant classes are only used in the class in which they are defined.
15:53S11001001great, but...
15:57raekbhenry: are you starting the clojure instance in another way, compared to how you did it without AOT?
16:09bhenryi got it figured out, but another question...
16:09bhenrynever mind i found it.
16:20arkhwhat'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:22S11001001arkh: some
16:25arkhS11001001: 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:26arkhif none of the functions return non-nil then that string is ignored
16:26arkhI 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:27mefestoarkh: maybe this would work? (map #(first (filter (comp not nil?) (map % funcs))) strings)
16:27mefesto
16:28mefestough sorry, bug in there
16:29arkhmefesto: the clojure runtime in my head hadn't caught that yet but I'm not surprised it didn't ; )
16:29mefesto(map % funcs) won't do since % will be a string. im useless in the late afternoon :)
16:29raek(filter identity (for [s strings] (some #(% s) fns)))
16:31raekhrm, perhaps (remove nil? ...) would be better
16:32technomancyraek: vote for http://dev.clojure.org/jira/browse/CLJ-450
16:47sproustHello 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:47sproust(I'm being careful to use the ELPA version of Slime too.)
16:51technomancysproust: I've heard of error reports using it with 1.3
16:51sproustHi Phil; but... aren't you one of the main developers of it? Are you using with 1.3?
16:51technomancyit doesn't actually have developers
16:52technomancyit has ... maintainers
16:52technomancyeven that is maybe a stretch
16:52technomancyI am still on 1.2 for everything
16:52sproustOh. I see a commit in the git log from you on dec 21 that says "Keepin' it real with pre-1.3 versions."
16:52sproustAllright, I'll switch back for this task. Thanks man,
16:53technomancythat was actually fixing it for 1.2 and lower
16:53technomancysince someone committed a fix for 1.3 that broke it with older versions
16:56sproustI see. This is a new project, I'm dying to move to 1.3, I guess I'll have to wait a bit.
16:56technomancyreally keen on primitive support or something?
17:01sproustNah, just wanting all the new stuff I've been hearing about.
17:01sproustI'm a bit surprised you guys at Sonian aren't on the bleeding edge.
17:06technomancyemail archiving doesn't really involve a lot of fibonnaci calculations, so primitive support isn't really exciting for me.
17:07technomancythe 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:39chettHow can I remove an item from a set inside a transaction? I need to do the opposite of (dosync (alter foo conj "bar"))
18:39qbg,(doc disj)
18:39clojurebot"([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:40chettqbg: thanks
18:53fbru02hey guys what is a good way to generate a fn inside a macro that takes a parameter ?
18:56raekfbru02: does the fn or the macro take he parameter?
18:56fbru02raek: the fn takes the parameter
18:56raek`(fn [x#] (inc x#))
18:56raekfor example
18:56raek,`(fn [x#] (inc x#))
18:56clojurebot(clojure.core/fn [x__1797__auto__] (clojure.core/inc x__1797__auto__))
18:57fbru02raek: thanks , i had sth like that, i have to see why it is not working :/ thanks a lot !
18:58raekyou must use the # suffix, or you end up with a user/x symbol
18:58raekwhich you cannot use as a paramter
19:00raekif you try to, you get this error: "CompilerException java.lang.Exception: Can't use qualified name as parameter: user/x"
19:01fbru02raek: 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:01fbru02?
19:01raekdef is a special form, so it needs the argument to be a symbol in code, not evaluate to one
19:02raekin this specific case you need a non-qualified symbol
19:02raekand you can use the ~'sym hack
19:02raek,`(def ~'name 1) ;
19:02clojurebotDENIED
19:03raekin this case, I guess you need something like `(def ~(symbol (str name "-old")) ...), which constructs the symbol at compile-time
19:04fbru02raek: will try that ! thanks a bunch !
19:05raeknp.
19:06amalloyraek: since when is ~' a hack?
19:06raekfair enough... "hack" might not be great word for it...
19:08amalloyone nice use-case for it is something like (defmacro foo [blah] `(defn {:arglists '~'([x])} macfn [x#] (do-stuff-with x#)))
19:10fbru02amalloy: what
19:11fbru02amalloy: what's macfn in your prev line?
19:11amalloyfbru02: heh, a bug
19:11fbru02:P
19:12amalloybut in real life it would be the name of a function to define, probably another arg to the foo macro
19:22david`17where's the video for stu's talk
19:22david`17it's not up yet, right?
19:42fbru02david`17: i don't think it is up , but is the one i want to see the most
19:48david`17fbru02: me too :)
20:07nathanmarzI've noticed lein uberjar has been a lot slower since 1.4. Anyone else notice this?
20:08nathanmarztechnomancy: any ideas?
21:14TakeVAny good clojure libraries for working with Swing?
21:22amalloyTakeV: 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:30TakeVamalloy: Ah, this is true. I'm just thinking about a wrapper type of library.
21:50technomancynathanmarz: 1.4.2?
21:50technomancy1.4.0 had some remove-unrelated-class-files logic that could slow it down
22:53amalloyso here is an idea, which may be crazy
22:54amalloymy 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:55amalloywhat if cond were willing to treat a two-element vector as if it were two discrete elements?
23:07amalloyhttps://gist.github.com/777365 is an example of what i have in mind
23:16seancorfield_amalloy: i must admit i do find forms like cond a bit hard to read
23:16seancorfield_the bindings in let makes me feel the same way
23:17amalloyseancorfield_: yeah, on occasion that is true
23:17amalloymost 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:18amalloycond 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:19cemerickit seems to me that the elimination of those "extraneous" parens/brackets was quite the insightful break from CL, etc.
23:19seancorfield_it's just a bit odd to see a form where alternating elements have alternating meanings :)
23:19cemerickonce your conditionals are long enough to cause formatting issues, isn't that the time to break them into separate functions?
23:19seancorfield_yeah, cemerick, i agree it reduces the noise...
23:20seancorfield_and, yeah, you're probably right about refactoring into smaller functions
23:21cemerickFWIW, 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:21amalloycemerick: yeah, i've done that in the past. it looks pretty weird all the same
23:21cemerickI agree. Thus my refactor-to-helper-fn suggestion. :-)
23:22amalloyindeed
23:23cemerickThat's actually the only place where I reliably use letfn.
23:25cemerickit's bizarre to me that pretty-printing a var elides its name.
23:26seancorfield_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:27cemerickreplaca: is that intentional, BTW?
23:28cemerickseancorfield_: 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:28cemerickOthers seem to use it more than I do. Probably a style thing more than anything else.
23:29seancorfield_i haven't developed my own clojure style yet :)
23:29cemericktechnomancy: sarcasm?
23:29cemerickseancorfield_: you have, even if you don't know it yet ;-)
23:29seancorfield_mostly i've been experiementing with clojure but i'm planning to start using it in a production context soon
23:30cemerickYou work with coldfusion a fair bit, right?
23:30amalloytechnomancy: Arrays.asList is the one useful thing in that class, and obviously it's not necessary if you have (apply list)
23:30seancorfield_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:30technomancycemerick: 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:30seancorfield_cemerick: yeah, been working with cfml since i was at macromedia and we bought allaire :)
23:31seancorfield_my team of java / c++ devs had to cross-train and rebuild all the e-commerce stuff at macromedia with cfml
23:31seancorfield_technomancy: that's what happens when the only tool you have is a hammer... er, i mean a class
23:32seancorfield_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:34technomancyjust the amount of repetition there is the main thing that makes me cringe
23:35cemerickseancorfield_: I've never touched it. It never really broached my consciousness over the years. *shrug*
23:35cemerickSounds like you've been beating a path for Clojure in it though. :-)
23:35amalloytechnomancy: 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:39seancorfield_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:39seancorfield_clojure fits in well with our "dynamic scripting on the jvm" stack so i think it's a good fit
23:41seancorfield_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:47tomojwhoa
23:47tomojI would never have guessed that last one
23:49Derandercoldfusion? I didn't realize that still existed :-P
23:49DeranderI swear it's like the COBOL of web languages
23:49Deranderreading back log
23:49seancorfield_it's the same age as ruby and php :)
23:50seancorfield_i work mostly with railo which is a FOSS implementation - and a jboss community project
23:50cemerickAnd, amusingly, your everyday life absolutely depends upon systems written in COBOL. ;-)
23:50Derandercemerick: I'm aware of this
23:51seancorfield_aka Sun COBOL 1.0 (on sparc)
23:51EnclojedSo 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:52cemerickEnclojed: update-in and assoc-in are very handy for twiddling slots many layers down in a data structure.
23:53cemerickseancorfield_: sounds deliciously hardcore
23:53amalloycemerick: deliciously hardcore? this is a family-friendly channel
23:54cemerickaaaaand amalloy's mind is in the gutter, per usual :-P
23:54Enclojedcemerick: At the risk of sounding dumb, is it true that update-in works 100% with records?
23:55seancorfield_cemerick: my first real job? writing a portable VM for UCSD Pascal... i'm a compiler / runtime guy at heart...
23:55cemerickEnclojed: absolutely -- it's just using assoc
23:55Enclojedcemerick: 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:56amalloyEnclojed: the way i usually do it is something like (send-message (swap! my-atom some-function-deciding-what-to-say))
23:56cemerickEnclojed: IO is a no-go within transactions. Thus the existence of the io! macro.
23:56amalloythus if there's a retry, you don't send any actual messages till the end
23:56cemerickEnclojed: using a watcher on key refs to drive write-behind persistence is a good pattern
23:57Enclojedcemerick: 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:57Enclojedcemerick: does io! send things that way? Or do I have to make my own queue?
23:57amalloyEnclojed: io! definitely doesn't do that
23:58cemerick,(doc io!)
23:58clojurebot"([& 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:58cemerickio! is a safeguard to ensure that IO isn't accidentally roped into a transaction
23:58Enclojedcemerick: 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:59cemerickEnclojed: 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.