#clojure logs

2011-02-13

00:02_Vi(defmacro qqq [] '(method-name [this] "qqq")) (reify Qqq (qqq)) ;; NullPointerException How to use macros inside reify/defobject?
00:08_ViIn general, how to feed output of my macros to a system macros (without of writing a wrapper).
00:08_Vis/\./?/
00:08sexpbot<_Vi> In general, how to feed output of my macros to a system macros (without of writing a wrapper)?
00:12_ViHow to make my macros stronger than usual macros and expand before usual macros see it?
00:28_Vi(deftype Qqq [var1] ...) ;; How to mention "var1" in macro? It says it not found in the namespace. Also referring it by #' fails.
00:40jkdufairhow would i evaluate a string representation of a class name to a class
00:42incandenza(Class/forName "...") perhaps
00:44jkdufairthank you!
00:44incandenzanp
00:54alex_boisvertn00b question: I want call "max" on a list
00:54alex_boisverte.g.
00:54alex_boisvert (def xs [ 1 2 3])
00:54alex_boisvert (max xs) ; doesn't work, need to splat the list; don't know how ..
00:54brandnewmathclj
00:54gregh(apply max xs)
00:54brandnewmath...doh, sorry
00:55alex_boisvertgregh: ah, ok, thanks!
03:59kumarshantanuis there a shorter way to transform keys in a map than this? -- (zipmap (map transform-fn (keys m)) (vals m))
04:00brehaut(into {} (map (fn [[k v]] [(transform k) v]) m))
04:02replaca(into {} (for [[k v] m] [(transform k) v])
04:02replacaby a few chars :)
04:04kumarshantanuberhaut: replace: which is supposed to be faster?
04:04replacakumarshantanu: dunno. I think they're about the same
04:04brehaut((comp (partial into {}) (partial map (juxt (comp inc first) (comp transform-fn second)))) m)
04:05replacabrehaut: now you're just being whacky!
04:05brehautchurch of point free!
04:06replacayeah, in haskell it would be beautiful :)
04:06brehautyeah sadly not so much here
04:07Scriptorhaskell, in theory at least, curries every function call, so it's natural :)
04:08brehauti think that map is a tiny bit faster than for but the difference is less important than the readability
04:09brehautkumarshantanu: if you really need to know how fast something is
04:09brehautuse time and dotimes
04:09kumarshantanubrehaut: replaca: i am writing a function to do this, so i guess i will go for performance
04:09replacano - I'd love to see a syntax that combined what was beautiful in clojure with what was beautiful in haskell. Rich made some compelling arguments one night about why he though it wasn't possible
04:09brehautkumarshantanu: that is basicly entirely the wrong answer
04:09replacakumarshantanu: I'm with brehaut on this one :)
04:10replacaunless it's in an inner loop, the difference won't matter
04:10brehautkumarshantanu: hard numbers and real stats after profiling, or use the nice code
04:10kumarshantanuyou guys mean i should prefer readability even if i am wrapping this inside a function?
04:10replacayup
04:10brehautabsolutely
04:11replacain 6 months when you look at your code again to debug it, the quickness that you can absorb it with would be most important
04:11kumarshantanuhmm
04:11replacaif it were a 2x difference, then performance *might* be the deciding issue
04:12kumarshantanui meant to say -- i am writing a function 'map-keys' that will do just this -- but yeah readability is a bigger gain since the perf difference will be tiny
04:12replacabut unless it's in an inner loop, it's unlikely to make more than a couple tenths of a percent difference in your runtime.
04:13kumarshantanui agree
04:13replacaI found "for" to be very unreadable when I came to Clojure, but it's long since been second nature
04:14brehautreplaca: where did you come from?
04:14replacaeverywhere :)
04:14brehauthaha
04:15replacaof course I'd used list comprehension in Python before but something about the difference in the form blocked the mapping in my brain for a couple of months
04:15brehautkumarshantanu: heres a question: why do you think there is no map-keys in the standard lib?
04:15replacamap is the same as most every language that has it (esp. CL), so it was easy
04:16brehautreplaca: huh thats really interesting
04:17replacayeah, dunno why. It seems so obvious now that the block is broken
04:20LauJensenMorning guys
04:20brehautMorning Lau
04:22Scriptormorning LauJensen
05:25_ulisesmorning
05:29_ulisesanybody doing hadoop stuff with clojure? anybody got any recommendations regarding which libs to use, etc.?
05:32LauJensen_ulises: I blogged about one lib, 1) http://bestinclass.dk/index.clj/2010/01/hadoop-installation.html 2) http://bestinclass.dk/index.clj/2010/01/hadoop-feeding-reddit-to-hadoop.html
05:33_ulisesthanks LauJensen :)
05:33_ulisesI was just trying to run the examples of the clojure-hadoop lib (alex ott's fork) but I get weird errors unfortunately, will read your posts, ta
05:39cpfr_ulises, cascalog
05:39_ulisescpfr: I did see that one, however I want to do plain hadoop for the moment but thanks anyway
06:09_ulisesis any of the clojure-hadoop libs on clojars the preferred one? according to LauJensen's post they are broken?
06:10cpfri used stuart's lib
06:25_ulisesright, I tried one of the forks but it didn't quite work for me; perhaps I should try Stuart's lib then
07:14xkbhello
07:14xkbIs anyone here using clj-oauth with delicious?
08:16bultersg'day all
08:48_ulisesdoes anybody know how I can pass -XmxNNN to lein swank?
08:50_ulisesah, found it, nm
08:54Dranik_ulises, how did you manage that?
08:54_ulisesDranik: JVM_OPTS=-Xmx1024M lein swank
08:55_ulisesfrom https://github.com/technomancy/leiningen/blob/stable/resources/script-template
08:55Dranikthanks
08:56_ulisesnp
09:12_uliseshrm, I'm having a hard time making this clojure-hadoop thing work. If I run from the repl (run job) (where job was defined with defjob as per the wordcount examples) the jobs run fine, but the minute I try running a job from the command line with java -cp it all blows up, anybody got experience with this lib and is willing to give me a hand? :)
09:15raekis there any documentation for the contract of the .equiv method of clojure.lang.IPersistentCollection?
09:48khaliGis there a way to wrap a var on a struct?
09:55khaliGdont know if my last message went through but i'm wondering if it's possible to wrap a Var on a struct. Otherwise i'm guessing you'd have to use an atom and access the fields in a sync block thing.
09:57Cozeyis there something like (get-in ) but for vectors as well?
09:59opqdonutget-in works for vectors
09:59opqdonut,(get-in [[0 1 2] [3 4 5]] [1 1])
09:59clojurebot4
10:03raekkhaliG: what do you mean by "wrap a Var on a struct"?
10:03raekcould you give an example on what you want to do?
10:04khaliGi mean (ref <a-struct>)
10:04Chousukeand?
10:04Chousukethat works just fine
10:04Chousukethough in most use cases you'll probably want a record instead of a struct
10:05khaliGok
10:06Chousukethough I'm suspicious now. are you sure you need refs at all?
10:07Chousukeusing refs just because you think you need to mutate something is usually wrong :)
10:07khaliGit's possible i'm wrong :)
10:07Chousukethat is, there might be a solution that doesn't require mutation at all
10:07Chousukeand you should prefer those
10:08ChousukeThe less "mutable" elements your design contains, the easier life will be.
10:08Chousukehmm, fewer*
10:08khaliGunderstood, though i dont know if i could do this without mutation, i'm accumulating some values
10:09Chousukereduce?
10:09raeksounds like a job for reduce
10:09Chousukeyour accumulator does not have to be mutable
10:11khaliGyea let me think but my gut feelign is it's not possible to do without mutation here
10:11Chousukedescribe what you're trying to do and maybe we can help
10:12khaliGOk. i have an exercise model which consists of tables of values for each exercise (sets, reps weight etc), and a workout model which consists of exercises and a few other datums. The data is entered by the user via a Swing UI, and i store the imputs in clojure structs and vectors
10:13khaliGcould i do away with mutation or do i need to provide more information?
10:13Chousukeso you need to update the models?
10:13khaliGcorrect
10:13Chousukeright, for that part, you'll need a ref or something
10:14Chousukebut that's only for the final storing of the updated value
10:14Chousukemost of the related code you can write without mutation
10:14khaliGyes i have written it that way :)
10:14Chousukesounds like you're on the right track then
10:15khaliGatm i have this call (send data conj model) which would work fine if data was a vector, but its not a struct and that's where i got stuck
10:15Chousukeyou can use update-in
10:15khaliGit worked fine before though as long as my data was in that vector (data)
10:15khaliGooh, let me read about update-in
10:15Chousuke(send data update-in [:key] conj whatever)
10:15khaliGthat sounds perfect!
10:16ChousukeI like the chaining aspect of update functions
10:17khaliGi was unwittingly seeking somethign like that, now that've mentioned it
10:17Chousukethere's also assoc-in
10:17khaliGthank you
10:21bulterswhat's the current-easiest-way of doing the whole emacs-clojure-repl dance these days?
10:21bultersI keep losing track of which guide to read ;-)
10:22khaliGbulters, on which platform?
10:22bultersos x
10:23khaliGnot sure about os x, but linux was painless using the emacs package installer thing. i had problems on windows though
10:24_ulisesbulters: do you mean installing or running/devving?
10:24bulters_ulises: well, already got clojure installed (via leiningen)
10:25_ulisesI usually add swank-clojure to my :dev-dependencies
10:25_ulisesand I just discovered a super-neat trick of leiningen, which is to have a checkouts/ dir in your project with symlinks to other projects you're hacking in parallel
10:26_ulisesleiningen picks those up automatically so you don't need to restart your swank server, etc. etc.
10:26bultersAnd I guess installing the swank-clojure and slime packages might help as well...
10:27_ulisesyup, that's how I do it. I've tried eclipse but I'm sort of used to using emacs in my daily routine so...
10:27khaliGpretty much, and then you start swank in your clojure project, and M-x slime-connect in emacs
10:27bulters_ulises: you add them as git (or s/ by your favorite scm) submodules?
10:27_ulisesbulters: atm I'm issuing lein jar as I'm testing launching my app through java
10:27_ulisesand that rebuilds the dependencies, etc.
10:29bulterscool
10:30_ulisesif I have an fn [ args ] how can I detect if args is iterable/seqable? say I can either pass it a map or an fn?
10:30_ulisesthere's fn? for that, but for maps?
10:31bultersoh this is nice... :D thanks for the quick pointer...
10:31_ulises,(doc map?)
10:31clojurebot"([x]); Return true if x implements IPersistentMap"
10:31_ulisesbleh
10:31_ulisesbulters: sure, np :)
10:41rlbI was looking at the tutorial posted here the other day (http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html), and for some reason, the POST handler isn't receiving any form arguments. They're {}. Any idea what I might be doing wrong?
11:05raekbulters: install clojure-mode, slime, slime-repl in emacs with package.el, :dev-dependencies [[swank-clojure "1.2.1"]] in project.clj, lein deps, lein swank and then M-x slime-connect from emacs
11:06raekmost importantly: do not use the deprecated swank-clojure _emacs_ package
11:07khaliGhm so don't install swank-clojure at all?
11:07khaliGi've got 1.1.0 installed
11:07raekbulters: using technomancy's clojure-starter-kit gives you package.el with correct settings. see the docs on http://github.com/technomancy/swank-clojure/
11:07raekkhaliG: the clojure lib or the emacs package?
11:07khaliGemacs package
11:07raekno.
11:07khaliGoops, okay
11:07raekit is from pre-leiningen ties
11:07raek*times
11:08raekuse durendal (another project of technomancy's) if you want a quick way of launching the swank server from emacs
11:48bultersraek: thanks, I've tried the starter kit; but decided to roll my own... part of the emacs learning process :P
11:51bultersdurendal looks nice though...
12:27xkbIs anyone here using clj-oauth with delicious-api?
12:28xkbor anything requiring Authentication headers
12:34thorwili'm trying to follow https://github.com/gcv/appengine-magic#readme. but how do i get into my applications core namespace on the repl?
12:35raekthorwil: you mean something like (in-ns 'the-namespace)?
12:36thorwili guess with in-ns, but the right argument to not trigger a no-source eludes me
12:36raek(C-c M-p in emacs)
12:36raekah, you need to load it first (require 'the-namespace)
12:36raek(C-c C-k in emacs)
12:37raek(doto 'the-namespace require in-ns) is a nice combo
12:37thorwilah, not sure what "lein repl" does or doesn't, in that regard
12:37thorwilbut i was also missing the '
12:37raekall it does is to launch clojure with the correct classpath. it does not load any namespaces except clojure.core
12:38raekyeah, they are functions, so you have to quote the symbol.
12:38raek(unlike the corresponding :require and :use features of 'ns')
12:38thorwili know in principal, but i'm just starting with my first lisp here ;)
12:39thorwilthanks!
12:39raeknp.
12:40xkbaargh again wrong signature.. hmm oauth is bleh
12:40raekxkb: have you tried asking at the clojure or clojure-web-dev google groups?
12:43xkbraek: not yet, will keep on tinkering for about 1 hour. And if that fails, Ill ask :)
12:43xkbthe fault is prob. in the encoding of the uri/params
12:45raekring has some utility functions for param encoding in uris
12:45khaliGaw, slurp/spit wont work with Java Dates? :/
12:46raekkhaliG: they operate on strings
12:46khaliGk
12:46raekso you need to do the string <-> date conversion yourself
12:46khaliGunderstood
12:46khaliGits the only object remaining which isn't a readable string afaik
12:47khaliG(in my code i mean)
12:47raekfor clojure data structure, you can just use read-string and pr-str
12:48khaliGnice
12:48raekspit will call str (which corresponds to java's toString method) on its argument, which does not work for all kinds of data
12:49khaliGseems Date has a toString method
12:49khaliGbut i can't see a fromString
12:49raek,(str (lazy-seq [1 2 3]))
12:49clojurebot"clojure.lang.LazySeq@7861"
12:49raek,(pr-str (lazy-seq [1 2 3]))
12:49clojurebot"(1 2 3)"
12:50khaliGmaybe i can use a different time structure, lets see if there are any clojure libs for that
12:50raekkhaliG: Joda time is a much better lib for working with dates in java. the clojure port is called clj-time
12:50khaliGoh nice!
12:52khaliGhm perhaps i can just write my dates as longs and then read them back
12:53khaliGi'd rather not do any sort of marshalling though
12:53khaliGi'll explore jodatime
12:53khaliGthanks raek
12:53raekyeah, milliseconds since the epoch (in UTC time) as a long is a pretty universal representation
13:35khaliGi love how i'll make a change to a running swing program, move to restart it after making a change and realising i just need to recompile the changed method
13:46pppaulhey, i'm getting an error with spit
13:46pppauljava.lang.Exception: Cannot change an open stream to append mode.'
13:46pppauli'm using conrtib/append-spit
13:53raekpppaul: is the file writable? also, you can use spit from clojure core since 1.2: (spit "file.txt" the-string :append true)
13:53pppauloh, thanks
13:53pppaulthat's much cleaner
13:53pppaulspit is making the file
13:54pppauli'll change my code to your suggestion
13:56pppauli don't get the error now
14:53thorwilis that normal that the repl in emacs doesn't react anymore after i started a jetty server (via appengine-magic)?
14:56rlbIt looks like none of the :input parameters from the example are making it to the POST handler. Can I get jetty (or clojure) to be more verbose wrt the actual POST?
14:56rlbs/clojure/compojure/
14:56sexpbot<rlb> It looks like none of the :input parameters from the example are making it to the POST handler. Can I get jetty (or compojure) to be more verbose wrt the actual POST?
15:06brehautrlb is there a logging middleware you could use?
15:13bobowhat is a good way to do something that should run every 5sek in clojure? should i use executors and such from java?
15:15brehaut(doto (Thread. (fn [] (while true (let [t (calc time now)] (do-action) (Thread/sleep (- 5000 (- now t))))))) .start)
15:15brehautpretty blunt
15:16brehauti guess you could use an agent
15:16brehautinstead of an explicit thread
15:17boboThread feels very blunt, then exexutors feels nicer
15:20brehaut(defn tick (agent nil)) (defn act [v] (do-something) (Thread/sleep 5000) (send tick act))
15:20brehautthats with agents and minus the math to make it a bit more precise
15:20raekbobo: there is a executor class for scheduling repeating tasks
15:21raekhttp://download.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html
15:22raekhttp://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newScheduledThreadPool(int)
15:22raekbobo: also, cron4j works wonderfully when you need to schedule tasks as you would with unix cron
15:23rlbbrehaut: don't know -- I was just trying the example posted here the other day. I'm not all that familiar with compojure/hiccup/ring/etc. yet.
15:24rlbthe POST comes in, but :params is {}.
15:25raekthorwil: I don't know exactly how appengine-magic starts the jetty server, but if you start jetty manually, you can give it the :join? false option to not block until the server is shut down
15:27raekcron4j example (I just love how simple it is):
15:27raek(defonce scheduler (doto (it.sauronsoftware.cron4j.Scheduler.) (.schedule "30 16 * * 1-5" #'my-fn) (.start)))
15:28raekthis executes my-fn 4:30 PM every monday-friday
15:28boboraek: yeh i know they ar ein java :-) just thought if there was something nice in clojure. but il use the java stuff then
15:28brehautrlb: what middleware do you have running?
15:29_ViWhy when I issue "(ns ...)" in REPL I lose access to "doc" function?
15:29rlbbrehaut: ring.adapter.jetty? Starting it like this: (run-jetty #'main/app {:port 8080})
15:29brehautrlb thats your adapter rather than middleware
15:29replacaraek: do you have the leiningen :depends line for cron4j handy?
15:30brehauti dont know of compojure automatically includes ring.middleware.params or similar
15:30rlbbrehaut: Other than that, just using compojure and hiccup. See here:
15:30brehauthiccup isnt relevant here
15:30rlbhttp://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html
15:31raekbobo: well, I made a library that does some of these stuff (not the Scheduled vareity of executors though) by some pretty redundant functions: https://github.com/raek/lcug-concurrency/blob/master/src/se/raek/lcug/concurrency.clj#L208
15:31rlbI adjusted the POST handler like this: (POST "/" x (prn x) ...)
15:31raekreplaca: I found this: [org.clojars.ghoseb/cron4j "2.2.1"]
15:31rlbso I could see x, and I can see that params is {}
15:32boboraek: il take a look!
15:32raekiirc, it wasn't in the maven repo, but someone had pushed it to clojars
15:32rlb(on stdout)
15:32rlbI just wondered if that example might be stale somehow, i.e. the form set up wrong or whatever...
15:32raekbobo: basically, all the fns look like this: (defn submit [exe task] (.submit exe task))
15:33brehautrlb im not an expert on compojure sorry
15:33raekI'm thinking about generating clojure/autodoc-style docs from javadocs
15:33raekso that people don't miss what's directly usable from java...
15:34raekbobo: also, did you see my post re executors in clojure?
15:34brehautraek: that would be handy for the not-from-java people like me
15:34boboraek: i dont think i did?
15:34raekhttp://blog.raek.se/2011/01/24/executors-in-clojure/
15:35rlbbrehaut: np, and thanks.
15:37brehautrlb may i suggest putting together a simple middleware to print out the entire request before it goes into compojure?
15:37brehautthere is an example in the tutorial you are working through that shows how to install ring middleware with compojure
15:38brehautyour middleware will be approximately (defn log-request [handler] (fn [req] (prn req) (handler req)))
15:53mreynoldsnewb question : I'm doing (doseq (keys map) ...) and I'm getting this error : error: java.lang.IllegalArgumentException: doseq requires a vector for its binding (core.clj:12)
15:53mreynoldsDo I have to wrap the returned seq in a vector (or convert it?)?
15:54opqdonut(doseq [k (keys map)] ...)
15:54opqdonutnow the variable k will get bound to each key of the map in turn
15:54mreynoldsduh
15:54mreynoldsThanks
15:59thorwilraek: seems :join? did the trick. strange how without, some operations work and other just hang there. thanks!
16:00rlbbrehaut: ok, thanks again.
16:15rlbbrehaut: post prints as {... "application/x-www-form-urlencoded" ... :body #<Input org.mortbay.jetty.HttpParser$Input@5f4f5a31>}
16:18brehautrlb can you put the ring.middleware.params/wrap-params middleware in before your logging middleware?
16:23rlbbrehaut: like this? (def app (-> #'handler (wrap-params) (log-request)))
16:23rlb
16:24brehautswap wrap-params and log-request
16:24shortlordare there any simple RPC frameworks for clojure? (I just need something to call clojure functions remotely on client and server)
16:25brehautshortlord: what kind of RPC?
16:25raekrlb: the last middleware will be the one that sees the request first and the response last
16:25raekmoustache reverses this in its syntax
16:26raek...since it becomes the outermost wrapping middleware
16:27brehautshortlord: if its not for real work then i have an xml-rpc library that works with ring and provides both sides of the rpc stack, but i dont like xml-rpc and wouldnt recommend it for a real world system
16:27shortlordbrehaut: I have an application that I need to split into a server and a client that renders the server contents and calls some server functions depending on user input. Nothing fancy, simply calling clojure functions remotely (both client and server are clojure-based) would be enough (similar to java RMI)
16:28technomancyshortlord: try clojure.contrib.server-socket/socket-repl
16:28shortlordbrehaut: priority is not performance, but fast and easy integration into existing non-distributed code
16:28technomancythough I guess you would rather have socket-rep
16:28rlbbrehaut, raek: thanks - that fixed it. I was starting with the first example on that page, and it doesn't use middleware (wrap-params, etc.).
16:29brehautshortlord: github.com/brehaut/necessary-evil
16:29brehautif technomancy's solution doesnt work for you
16:29brehautshortlord: but i wouldnt recommend it
16:30shortlordbrehaut: ok, thx a lot
16:31shortlordI've thought about using a simple remote repl, but it would be quite insecure to pass any kind of string and evaluate it. So I guess I would have to build a custom check that only allows the execution of predefined functions, right? Does something like that already exist?
16:32brehautshortlord: if you use a repl yeah you'd have restrict it somehow. cljail might help there
16:33brehautyou need to explicitly expose functions with necessary-evil
16:35shortlordbrehaut: searching for cljail does not give me any results, do you mean clj-sandbox?
16:35brehautshortlord: honestly im not sure. whatever raynes and amalloy's project is called
16:36brehauthttps://github.com/Raynes/clojail
16:38mreynoldsMore newbness : What's the idiomatic way to lookup data from nested maps? Like {:a {:b "b" :c "c"}}, where I want to get :c's value.
16:39brehaut,(get-in [:a :c] {:a {:b "b" :c "c"}})
16:39clojurebotnil
16:39raekmaking a custom interpreter for a limited command set (possibly using the clojure reader) sound much more secure
16:39shortlordbrehaut: cool, thx a lot for the link
16:40mreynoldsnice, thanks!
16:40brehaut,(get-in {:a {:b "b" :c "c"}} [:a :b])
16:40clojurebot"b"
16:40brehautmreynolds: if i got it round the right way :P
16:40mreynoldsbrehaut: No worries, I'm still mapping out functions, so just having the pointer is good enough
16:40brehautmreynolds: its part of a family including assoc-in and update-in
16:41brehautmreynolds: clojuredocs.org/quickref/Clojure%20Core
16:41mreynoldsbrehaut: I'll go check those out. I bought clojure in action and joy of clojure and I've been piece-meal making my way through them.
16:44mreynoldsbrehaut: I sort of wish the clojure docs would have an alternate structure similar to how the code is laid out. I find myself looking at the source often and seeing the functions that are "similar" to that function (as you mentioned, assoc-in and update-in are right next to each other), but aren't in the docs
16:47brehautmreynolds: projects using marginalia have that
16:47mreynoldsbrehaut: Haven't used that yet, I'll go look at it
17:14mreynoldsSimilar question : I'm building a data structure to allow people to specify files to "watch" in special ways. I was building nested data structures ({:stuff {:type "dir", :other-type "otherdir}}) and get-in let me get those nested pieces of data easily. I now want to, basically, walk the data structure, looking at the "dir"s and replace them with actual File objects. I thought about doing this with zippers, but I wanted to ask
17:16chouserzippers would work
17:17chousermreynolds: you might also try clojure.walk
17:17mreynoldschouser: I'll look at both, thanks for the pointers
17:18mreynoldschouser: Walk looks pretty damned perfect
17:18mreynoldschouser: Thanks
17:18chousernp
18:00replacaraek: belated thank you!
18:03rata_hi
18:07aleksanderhi
18:09michaeljaakahi
18:09michaeljaakais there anyone live?
18:10brehautmichaeljaaka: probably
18:10michaeljaaka:) thanks, I thought that i have something wrong configuration
18:10michaeljaakano welcome message, no activity messages
18:10michaeljaakaetc.
18:48_ViIs there somewhere official use case lists for Atoms, Agents and Refs? E.g. a task where only Atom suits (but not Agent or Ref), a task for Agent...
18:50jacortinas_Vi: afraid not, but that would be pretty awesome resource
18:52_ViFor example logging somewhere from multiple threads. Agents are OK, but atoms and refs are likely not.
19:08gfrlogI wonder if agents are implemented with atoms
19:26_ViWhy "alter" and "send" do not end with exclamation point, but "swap!" does?
19:27pdk`it's just a typical little idiosyncracy i guess
19:27_ViHaving trailing "!" makes feeling of some unsafety.
19:28pdk`i dunno why there can't just be some sort of update! function that works on refs/atoms/agents all alike
19:28Chousukealter and send are safe in dosync
19:28pdk`maybe have a keyword arg for it when you need send-off style behavior or something
19:28Chousukeswap! isn't
19:29_ViWhen I writing my own functions, when should I finish their names with "!"? Is there some convention there?
19:31pdk`! implies that the function is destructive or carries side effects beyond returning a value
19:32pdk`it's an old convention from scheme where the functions that did destructive stuff with lists had !
19:32pdk`and since refs/agents/atoms are the only mutable forms of data you'll be working with often in clojure outside of java interop well
19:33_Vipdk`, For example, should some "printDebugLog" be "printDebugLog!"?
19:33pdk`it doesn't seem necessary there
19:33pdk`though note that lisp function naming convention would favor print-debug-log over printDebugLog
19:34Chousukewell actually
19:34_ViIs the rule like "put ! if it have side effects and it is not obvious"?
19:34Chousukethe convention is to use ! if the function is unsafe in dosync and it's not obvious
19:34pdk`you'd be fine with that route i think
19:35pdk`in scheme ! was basically a warning that the function you were using could modify the list you passed to it in-place without any other advance warning
19:35Chousukeeg. spit etc. are unsafe, but it's obvious so there is no bang
19:35_Vi(BTW should it be "unsafely-check-some-condition?!" or "unsafely-check-some-condition!?")
19:35pdk`and in clojure none of the basic data structures are mutable outside of storing them in refs/agents/atoms
19:36Chousukebut swap! has the bang because you might not think that it's unsafe in dosync forms
19:36Chousuke_Vi: have two functions? :P
19:36Chousuke(predicate? (some-unsafe-stuff!))
19:37_ViChousuke, Means the "predicate" with side effects.
19:37Chousukepredicates shouldn't have side-effects :/
19:37pdk`the idea he's getting at is to have a function that does the unsafe stuff and returns some value
19:37pdk`then checking that value against a safe predicate
19:38_ViAlso: Should I consider the function side effects free if it actually have debug-only side effects (such as printing in some log or incrementing statistics counter)?
19:38Chousukeno
19:39Chousukeunless you can disable that behaviour in production code
19:39_ViFor example, when debugging is switched off (release version) it becomes truly side-effects-free.
19:40Chousukeyou'll get some funky debug output if you use such functions in transactions though :)
19:40dnolen_Vi: ! is really to indicate changing a "place" in a way that that doesn't specify any "time management" strategy. alter doesn't need it, they are inside dosync. agents imply uncoordinated concurrency.
19:41Chousukedosync handles sends specially, which is why send doesn't have the bang
19:43pdk`i wouldn't bother if it doesn't change anything that's relevant to an outside caller of the function
19:43pdk`if it's closed over some counter that's just there for debugging and doesn't affect the behavior of any functions or modify other outside state then whatever basically
19:46Chousukewell, yeah.
19:46Chousukeas long as the side-effect is inconsequential to the program it's fine I guess :P
19:47_ViChousuke, So I can add "invocation counter" statistics without fear being bad guy.
19:47_Vis/fear/fear of/
19:47sexpbot<_Vi> Chousuke, So I can add "invocation counter" statistics without fear of being bad guy.
19:48Chousuke_Vi: it's just a bit dirty, but I guess you can.
19:48Chousuke_Vi: at least use a macro or something you can easily disable :)
19:49Chousukethen when you ship a release version, just define the macro to return nil or something :P
19:49Chousukein essence making it a comment
19:55_ViWhat should I do if I want to have a macro that expands in two (or more) forms? (and I cannot use "(do ...)" because of it is not a code)
19:56brehaut_Vi, use do
19:56_Vibrehaut, This is not a code. It is either data or some internals of "reify" or "let" or whatever.
19:57brehautthen use functions
19:58_ViThe only not-so-nice solution I see is to wrap containing for in macros that will handle this duplication.
19:59johnhunterhi, I have a noob question
19:59brehautjohnhunter: you are welcome to ask it
20:00johnhunterthanks, i am writing a swing app, and i want in a text field to let the user write some clojure code - a dsl if you will
20:00johnhunterwhen I get the text, i call (eval text)
20:01johnhunterit seems eval runs from the clojure.core namespace, not my app's namespace
20:01johnhunterso none of my def'd data values are found
20:01_Vijohnhunter, Example:
20:01_Vi(eval (read (java.io.PushbackReader. (java.io.StringReader. "(+ 4 5)"))))
20:02johnhunteryes, thanks, that is roughly what i am doing, and it works for (+ 4 5)
20:02brehautjohnhunter: there is a with-ns function defined somewhere
20:03johnhunteroh.. let me look that one up
20:03brehautjust cant workout where 'somewhere' is
20:04johnhunterhttp://richhickey.github.com/clojure-contrib/with-ns-api.html
20:04brehautthat would be it
20:07johnhunterthe only thing is eval seems to start from clojure.core, and it knows nothing about with-ns from contrib
20:07johnhunteri'm very fuzzy on all this namespace stuff
20:07brehauti would have assumed that (with-ns namespace (eval ...)) would have fixed that?
20:07brehautalternatively
20:08johnhunteroh, i think you might be right... i just have to include that contrib in my main app
20:08johnhunteri'll try that, thanks
20:08brehaut(eval (concat (list with-ns namespace exp)))
20:08brehautwait madenes
20:08brehaut(eval (list 'with-ns namespace exp))
20:09philipoclojure
20:18johnhunterit doesn't seem to resolve with-ns shouldn't i get it by including clojure-contrib in my project.clj like ... :dependencies [[org.clojure/clojure "1.2.0"]
20:18johnhunter [org.clojure/clojure-contrib "1.2.0"]]
20:18brehauthave you got a use or require in your ns?
20:18johnhunter:require
20:20johnhunterhow do i check if it is in clojure.contrib 1.2?
20:20brehautare you referencing with-ns with the fully qualified project?
20:20brehautit is
20:21johnhunternope, just (with-ns myns.core (eval ....)
20:21brehautthere you go then; with a require you need to qualify any functions in that namespace
20:21brehautso if you have bare require, you need clojure.contrib.with-ns/with-ns
20:21brehautif you have an :as require
20:22johnhunterah...
20:22brehaut(eg (:require [clojure.contrib.with-ns :as with-ns]))
20:22brehautyou do just with-ns/with-ns
20:22johnhunterand what if i just want to call (with-ns ... ?
20:22johnhunter:use ?
20:22brehautuse use
20:23brehautIMO - dunno if its considered idiomatic - you should prefer requires to uses, and if you do decided to use a use, you should qualify all the imports with only
20:23johnhunterok, for some reason this namespace stuff won't stick in my brain
20:23brehauteg (:use [clojure.contrib.with-ns :only [with-ns]])
20:25brehauti generally use aliased requires except for some operators or forms that are cleaner (and clear where they from) when used
20:43gfrlogbrehaut: now that I've waited a day, do I get to hear what you were thinking of?
20:43brehautdeclare
20:43brehautperhaps with a with-ns ?
20:43gfrlogyes, I think that would do it
20:44gfrlogI tried it with a fully qualified symbol but I don't think that works
20:44brehauthowever, given ive had a day, i think that probably i was wrong given your requirement to declare something in another ns
20:44gfrlogwrong how?
20:44gfrlogthat hiredman wasn't thinking of that?
20:44brehautthat it might not work?
20:44brehautboth
20:45gfrlogI'll see if it works...
20:45brehauthiredman is much better at this than i am
20:45brehautabsolutely worth a shot
20:45gfrlogdo you think either you or him were suggesting that it's better code than my eval version? Or just that eval isn't strictly necessary?
20:46brehautusing eval is a fairly good sign somethings been overlooked
20:46brehautits more of an implementation tool than a usage tool
20:46gfrlogso you prefer several lines of non-eval code over one line of eval code?
20:46brehautyeah typically
20:47brehautim not convinced you should need to fire up the compiler for small things
20:47brehautthose couple of lines could be abstracted to declare-with-ns or soemthing and become a library function
20:47tomojhow do you avoid eval?
20:47gfrlogthat's a good point
20:48gfrlogtomoj: apparently by using with-ns and declare
20:48gfrlogbut actually I'm sure that wildly depends on what you're using it for
20:48brehauttomoj: thats a guess on my part. i think hiredman was sure of a good way to do it though
20:48gfrlog,(eval "2893")
20:48clojurebotDENIED
20:48gfrlog,(Integer. "2893")
20:48clojurebot2893
20:49brehautyeah your not going to get to execute arbitrary code in the bots
20:49gfrlog(eval '(println "DENIED"))
20:49gfrlog,(eval '(println "DENIED"))
20:49clojurebotDENIED
20:49brehauthaha
20:49tomojthere were ways with sexpbot recently
20:50tomojthere may still be
20:50gfrlogbrehaut: I had not thought of what I was doing as "firing up the compiler" until you put it that way
20:51gfrlognow I am a better man
20:51brehautbbs coffee
20:52tomojhow would either of with-ns or declare help?
20:54gfrlogtomoj: that was specific to my case
20:55gfrlogfor your question, you have to show how you're using eval first
20:55tomojI believe I remeber your case
20:55gfrlogokay, well for my case...
20:55tomojand don't see how it would help
20:55gfrloghe thought that the specific var whose value I wanted to execute could be created before the library is loaded
20:56gfrlogby... (with-ns 'my.namespace (declare go))
20:56gfrlogI just tried that on my code and got strange results
20:57tomojI didn't actually remember your case
20:57gfrlogso apparently it doesn't do the same thing as ((var-get (find-var 'my.namespace/go)))
20:57tomojsince you were talking about eval too I thought you were the one eval'ing gui input
20:57gfrlogoh, no
20:57gfrlogmy case is from yesterday
20:57gfrlogI have a program where most of the code is loaded at runtime
20:58gfrlogthe entry point to that code is where I call (my.namespace/go)
20:58gfrlogbut the compiler won't let me do that since it doesn't know about the namespace yet
20:58gfrlogso I was doing (eval '(my.namespace/go))
20:58gfrlogwhich worked just fine
20:58gfrlogbut offended everybody's sense of decency
20:58tomojright, I see
20:59gfrlogI'm still doing the (find-var) thing
21:04rata_gfrlog: I think it's not the compiler that doesn't know about the namespace
21:04gfrlograta_ my being wrong would not surprise me, as the whole issue of the clojure compiler gets me fogged up -- what would you say that it is?
21:05rata_the evaluator
21:05rata_(if that's the name for what executes your code at runtime)
21:05gfrloghmm
21:06gfrlogbut my code should work at the time it's evaluated
21:06rata_and I thought yesterday hiredman was referring to the (intern ns name) fn
21:06gfrlog,(doc intern)
21:06clojurebotDENIED
21:06gfrlogew
21:06rata_do you get your error when compiling your code?
21:06gfrlog"lein compile" you mean?
21:06rata_~(doc intern)
21:06clojurebotgitdoc is http://github.com/Lau-of-DK/gitdoc/tree/master
21:07rata_gfrlog: for example... or (compile ...)
21:07gfrlogI'll try lein compile
21:07rata_or C-c C-k en slime
21:09gfrlograta_ my religion doesn't permit me to use slime
21:09rata_ok np
21:09gfrlograta_: lein compile gives the expected ClassNotFoundException
21:09rata_ok, so it's the compiler effectively
21:09rata_my fault
21:10gfrlognp
21:11gfrlograta_: when I try intern at the repl using symbols, it complains that the not-yet-existing namespace isn't found
21:11rata_then intern won't solve the problem either
21:11gfrlogI don't see it as a problem. Just a mystery of what hiredman was thinking of.
21:12rata_intern is a fn so it won't solve anything at compile-time I think
21:12gfrlogvar-get and find-var are both fns, I assume, and they sufficed
21:14rata_yes, but you use them to not have to evaluate the symbol... you give the symbol quoted
21:15rata_(is that proper english?)
21:15gfrlogright -- you're hoping to find something that allows the symbol unquoted?
21:15rata_yes
21:15gfrlogsure looked like english to me
21:15gfrlogyeah, I guess a macro could work that out pretty easily. I guess then you're looking for an existing macro in clojure.core or something?
21:18rata_when I compile code that mentions a non-existent var or a non-existent namespace, it doesn't give me a ClassNotFoundException
21:19gfrlog,(why.wont.this/work?)
21:19clojurebotjava.lang.ClassNotFoundException: why.wont.this
21:19gfrloglike that?
21:20rata_hmmm strange I don't get that
21:20rata_perhaps an slime thing, but I don't think so
21:22rata_aha... I have tried with something like (a/b) but not (a.b/c)
21:22gfrlog,(a/b)
21:22clojurebotjava.lang.Exception: No such namespace: a
21:22gfrlogyeah
21:22gfrlogI get results based on that too
21:23rata_so I think the problem is the namespace, not the var
21:25gfrlog,(clojure.core/rata_)
21:25clojurebotjava.lang.Exception: No such var: clojure.core/rata_
21:25gfrlogso you think that would compile?
21:26gfrlog(but not eval of course)
21:26rata_no, but that gives another error
21:26rata_java.lang.Exception
21:26gfrlogeven at compilation?
21:27rata_yes
21:28rata_I have just compiled it and gave me that error
21:28gfrlogthis is an interesting contrast to other dynamic languages
21:28gfrlogruby will let you call whatever made up function you want and doesn't object until it executes
21:29rata_perhaps the solution is (refer ...)
21:29rata_have you tried that?
21:29rata_(refer your.ns)
21:29gfrlog,(doc refer)
21:29clojurebot"([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol ...
21:30gfrlog,(refer rata.gfrlog)
21:30clojurebotjava.lang.ClassNotFoundException: rata.gfrlog
21:30gfrlogso I'd probably get that?
21:31rata_yes =(
21:31rata_,(doc load-string)
21:31clojurebotDENIED
21:33rata_I'm reading here http://clojure.org/Namespaces
21:33rata_,(resolve a.b)
21:33clojurebotjava.lang.ClassNotFoundException: a.b
21:34rata_,(create-ns a.b)
21:34clojurebotjava.lang.ClassNotFoundException: a.b
21:34rata_,(create-ns 'a.b)
21:34clojurebot#<Namespace a.b>
21:34rata_haaa
21:34rata_,(resolve 'a.b)
21:34clojurebotjava.lang.ClassNotFoundException: a.b
21:34gfrlogclojurebot probably resets state every time
21:35rata_yes... just checking if the absence of the quote was significant before
21:35rata_gfrlog: try (create-ns 'your.ns)
21:36gfrlogokay
21:39gfrlograta_: still get the classNotFoundException
21:39gfrlogyes, am quoting the ns name in create-ns
21:40rata_and you get the exception at the create-ns line or at the other line?
21:40gfrlogthe other line
21:40gfrlogafter create-ns
21:43rata_mmmm strange... I don't get that
21:43rata_(do (create-ns 'b.c) (b.c/a)) works for me
21:43rata_*compiles for me
21:43gfrlogmaybe slime is "ruby mode"
21:44rata_hahaha could be
21:44gfrlogclojure: everything is dynamic at runtime, unless you do anything the normal way
21:46rata_load-string isn't at all normal I think
21:46gfrlognope
21:46gfrlogbut calling functions using symbols literals is
21:47rata_gfrlog: putting (create-ns a.b) (a.b/c) in a file and then executing that from the command line gives me a java.lang.Exception, not the ClassNotFoundException
21:47rata_the problem here is load-string
21:47gfrlogbut the error happens before I ever use load-string
21:49rata_what?? then why are you calling something you haven't loaded yet?
21:50gfrlogthe code doesn't get executed until the lib is loaded
21:50gfrlogbut the code offends the compiler before the lib is loaded
21:52gfrlog(defmacro lenient-compiler [& forms] `(eval (do ~@forms)))
21:52gfrlogwhoops
21:52gfrlog(defmacro lenient-compiler [& forms] `(eval '(do ~@forms)))
21:52gfrlogthere we go
21:52rata_and did you put the create-ns thing before the offending code?
21:52gfrlogyes I did
21:52gfrlogyou can imagine why it wouldn't make a difference:
21:53gfrlogthe compiler doesn't execute create-ns
21:53gfrlogso it doesn't know whether or not it will actually result in the relevant namespace being created
21:53gfrlogall it knows is it still hasn't heard of that namespace
21:54rata_mmmm but for some reason when I execute (create-ns 'a.b) (a.b/c) it doesn't say anymore ClassNotFound
21:55gfrlogwhat context are you executing them in?
21:55rata_did you put it at the beginning of the file, after the ns macro?
21:55gfrlogno, just before the relevant statement
21:55rata_that's the whole file (create-ns 'a.b) (a.b/c)
21:55gfrlogdoes the second line in isolation still throw an error?
21:55rata_vim asdf.clj, put that, then execute
21:55gfrloghow do I "execute" it?
21:56gfrlogshould I still call it asdf.clj if I use a dvorak keyboard?
21:56rata_java -cp clojure.jar clojure.main asdf.clj
21:57rata_gfrlog: yes, asdf is a beautiful combination of letters =P
21:57rata_when I put the second line alone it gives a ClassNotFoundException
21:57gfrloglesse
21:57gfrloglesee
21:57gfrloglet's see
21:58gfrlogso I get "no such var" -- which is what you get too?
22:00rata_yes
22:00gfrlogclojure is weird.
22:02gfrlogclojurebot: were you developed in a hammock?
22:02clojurebotPardon?
22:10rata_gfrlog: well... a little step, but too little I think
22:10gfrlogwhat step?
22:11rata_to get a "no such var" instead of a ClassNotFound
22:11gfrlogwell presumably the "no such var" is a runtime error rather than compile time
22:11gfrlogso in my context it wouldn't get thrown, since by runtime the var actually would exist
22:11rata_then try it
22:11gfrlogwell I did and it doesn't compile
22:11gfrlogthat's the whole weird thing about it
22:12rata_=(
22:12rata_yes weird
22:12gfrlogtry executing your file with a (ns) at the top
22:12gfrlogfor a different ns
22:12rata_ok
22:13rata_no such var
22:14gfrlogthen add (load-string "(ns a.b) (defn c [] nil)") on the second line
22:24rata_gfrlog: works fine =)
22:24gfrlogclojure-version?
22:24gfrlogwait that shouldn't matter
22:24rata_1.2
22:24gfrlogme too
22:25rata_but it works without create-ns too
22:25gfrlogah
22:25gfrlogso we're all confused now
22:26gfrlogI think clojure probably has about 7 different ways it can execute your code
22:27rata_no... the thing is when you load-string, the namespace becomes available
22:27rata_and the var too
22:27gfrlogoooh I know
22:27gfrlogput both the load-string and the (a.b/c) in separate functions
22:28gfrlogthen after they've both been defined, call them in order
22:28rata_for example (ns d) (load-string "(ns a.b) (declare c)") (defn e [] (a.b/c)) (load-string "(ns a.b) (defn c [] nil)") (e)
22:28rata_works
22:29gfrlogwhat about without the first load-string?
22:30rata_it doesn't compile... that load-string is required
22:32gfrlogthat's strange
22:33gfrlogI guess the statements are executed in some sense
22:33rata_yeah
22:33gfrlogif you delayed execution of the load-string statement until after (defn e...) had been processed, it probably wouldn't work
22:34gfrloganyhow, I gotta drop out for the night
22:34gfrlogthx for the sleuthin
22:34rata_ok
22:34rata_good night
22:53mreynoldsMore newbism : I'm trying to create a configuration file for my app, but I like the idea of having it be code (a la, most of the time it's convention, but if I need to, I can write an anonymous function). I've looked at leiningen's implementation and it seems... hard due to the limitations of load-file. Is there a better/simpler way of doing this? I'm about to start down the road of building a DSL, but that seems complex as wel
22:54brehautthe simplest way is just to have a settings namespace
22:55brehautif it doesnt need to be reloaded while the program is running its by far the easiest
22:55mreynoldsbrehaut: It doesn't. Can you give me more details for that? Is that just a matter of me including a namespace that is defined separately?
22:56brehautyeah its just like any other clojure file in your project
22:56brehauti have as myproject.settings
22:56brehautand i def the settings to be clojure structures
22:56mreynoldsbrehaut: Ahh, heh. I've yet to actually use more than one ns (still learning). I'll dork around with that. Thanks!
23:34chouserwow, lazy-test's failure reports are *so much nicer* than clojure.test's.
23:35chousersexpbot: tell stuartsierra