#clojure logs

2011-05-22

00:57dsantiagoIs there any way to use deftest to define a test, and then alter the metadata on the test function so that when a fixture you specify is run, it can access that metadata from the function passed in?
00:58dsantiagoI can't seem to make it work using alter-meta! on the value in the test's var, or vary-meta on the symbol passed to deftest.
00:58dsantiagoMight be doing something stupid here.
01:05desertman_hi, i am trying to use the sql library , i have mysql running on port 3306 , however i get No suitable driver found error , https://gist.github.com/985192
01:08symboledesertman_: I've never used that library, but I suspect you need the actual driver in the classpath.
01:09desertman_ok
01:11symboledesertman_: http://clojars.org/mysql/mysql-connector-java
01:14desertman_symbole : cool
01:15desertman_thanks
01:15symboleNp.
02:08seancorfielddesertman_: if you're using leiningen, add this to your project dependencies: [mysql/mysql-connector-java "5.1.6"]
02:08seancorfieldyeah, what symbole said :)
02:09seancorfield(dangers of catching up on irc late at night)
02:23zakwilsonUsing ClojureQL, I want to do something like (select (table db :items) (apply sql-or (map (partial like :longdesc) ["foo" "bar"]))) and get sql like "select * from items where longdesc like 'foo' or longdesc like 'bar'", but I'm not getting anything of the sort.
02:26zakwilsonOh, I see. I should be using or, not sql-or.
06:48robonobois slurp lazy?
06:48robonoboor do i have to use slurp* from duck-streams for that?
10:36a_robbinsTrying to setup lein so that 'lein repl' will automatically load and then activate a given namespace. :repl-init will load all the code from my file, but it doesn't switch my active namespace to that file, so I still need to call '(in-ns namespace-name) once I start. Any ideas?
10:47TimMca_robbins: Let me check one of my projects...
10:48TimMca_robbins: Try having a :main
10:48a_robbinsTimMc: What would I put in it?
10:49a_robbins(in-ns 'namespace) ?
10:49TimMchttps://github.com/timmc/CS4300-HW3/blob/master/project.clj
10:49TimMcSo, in project.clj, :main mynamespace
10:50TimMcI think it's intended for when you want a runnable JAR, but it definitely does what you want as well.
10:51a_robbinsYeah, that does do what I need. I also don't need :repl-init when I am using it
10:51a_robbinsI guess :repl-init is for other stuff that you'd like to load, iff you are on the repl
10:52a_robbinsTimMc: thanks!
10:54TimMcnp
10:58a_robbinsTimMc: So, after messing with it a little more, I guess I see a use case for :repl-init. I'm working on an appengine-magic project, so any time I start the repl I want 1)To load my core namespace, 2) to activate it and 3) to start the dev server. :main handles 1 and 2, but :repl-init can be pointed to a script that makes 3 happen. That way it'll only start if I'm at the repl, and not up on app engine
10:59TimMcYeah, that sounds reasonable. I haven't used :repl-init for any projects so far.
11:18thorwiltechnomancy: hi! if it is normal that "lein plugin install swank-clojure 1.3.1" seems to hang for minutes until it finally prints something, then please consider to add a warning about that
11:21thorwiltechnomancy: btw, what's not clear to me is the interplay or lack thereof with an already installed slime and paredit
11:22a_robbinsthorwil: I think maven is down right now. That seems to be hanging a lot of lein commands
11:24thorwiloh, i would have expected an all or nothing, but "lein plugin install swank-clojure 1.3.1" took like 10 minutes to complete here. well, glad it worked, after all :)
11:29a_robbinsthorwil: Yeah, maybe the server is responding to requests very, very slowly? http://repo1.maven.org/maven2/
11:31technomancythorwil: yeah, stuff in jack-in completely overrides anything that's already there right now
11:31technomancythere's room for some subtlety to be added in for sure
11:31technomancyplus it should tell you what it's bootstrapping; right now it's only slime and slime-repl
11:33technomancya_robbins: actually that's a bug; repl-init is supposed to set the initial ns
11:33technomancyit's just that I never use the repl task, so I did't notice
11:33thorwilinstalling clojure-mode via elpa led to a complaint about a paredit reference
11:34a_robbinstechnomancy: oh, good to know. Also, is there any easy way to switch leiningen to use the uk maven mirror for now? I'm hoping for some kind of global maven-url setting.
11:34thorwilclojure-jack-in briefly tells me that it exited with abnormal status
11:35thorwil"exited abnormally with code 1"
11:37a_robbinstechnomancy: or, instead of giving maven a new url, dropping it from the lookup list for a little while. Many of my lein commands just hang at '[INFO] artifact org.clojure:clojure: checking for updates from central'
11:39robonobois there a way to pass all :keys from a function to another function?
11:42thorwilrobonobo: what do you mean with :keys from a function?
11:43robonobowhen you have a general function (defn foo [x & {:keys [y z]}] ...)
11:43robonoboand a helper-function that sets x to some value
11:44robonobo(defn foo-handy [& {:keys [y z]}] (foo x :y y :z z))
11:44robonobois there a way to do that shorter?
11:45technomancythorwil: there's also a bug where it'll get confused if there are multiple versions of swank in ~/.lein/plugins
11:45technomancypossibly fixed in clojure-mode 1.9.1, but it's something to look for
11:46thorwiltechnomancy: swank-clojure-1.3.1.jar is the only content of ~/.lein/plugins here
11:47technomancya_robbins: you can try :omit-default-repositories true and then add in :repositories {"mvn-uk" "http:[...]"} I think
11:47technomancyhaven't tried it myself
11:47thorwilrobonobo: i'm not sure what you are trying to do, but have you considered using partial?
11:47robonobothorwil: i'll look into that
11:47robonobothanks
11:48technomancythorwil: hm; hard to say what's going on. you might get more detailed output from regular lein swank
11:48a_robbinsrobonobo: maybe you should do the destructuring inside the helper function instead of in the outer function?
11:49a_robbinsrobonobo: If you are pulling it apart to get the keys, and then wanting to put the keys back together to pass them, maybe they don't need to be pulled apart?
11:50robonobowait, can i just do (defn foo-hany [& opts] (apply foo x-default opts))?
11:50technomancyhuh; the CLU language introduced iterators. that must be why they named the villain in Tron Legacy after it.
11:52a_robbinsrobonobo: I think this would do what you want: (defn foo-hany [& opts] (apply foo (merge x-default opts)))
11:52a_robbinsrobonobo: actually, I think you could drop the apply
11:53robonobowhy not just (apply foo x-default opts) ?
11:55Vinzent(apply foo x-default opts) is ok, you can also (def foo-helper (partial foo x-default))
11:55a_robbinsrobonobo: It depends on how foo works I guess. My version used a hashmap to track all the different options, which would be destructured inside foo.
11:57robonobook, it works now
11:57robonobothanks guys
12:00thorwiltechnomancy: indeed: http://paste.pocoo.org/show/393172/
12:01thorwiltechnomancy: the referenced file: http://paste.pocoo.org/show/393173/
12:05technomancythorwil: yeah, gotta make that more exposed from emacs.
12:06Vinzentin enlive, I had some troubles when i tried to deftemplate\defsnippet with filename from the fn (e.g. (deftemplate foo (path "file.html") ...)): snippets was always returning empty seq (like no metched segments found), but no NullPointerException was thrown (like when file not found on cp)
12:07VinzentHave anyone encountered similar problems?
12:07thorwiltechnomancy: any idea what the problem at hand is? could it be an appengine-magic swank 1.3.1 incompatibility?
12:10thorwilVinzent: where does the (path) from come from? use just the path in quotes, with the templates in resources
12:15Vinzentthorwil, (defn path [filename] (str "long/path/to/templates/dir" filename)) just for shorteness
12:16thorwilVinzent: deftemplate is a macro and you would have to use eval, or something
12:18thorwilor wrap it in your own macro, just for assembling that path
12:19thorwilthen again, I would expect a NullPointerException if that is the problem, so maybe i'm talking bs
12:22Vinzentthorwil, lol, it's much easier: by distraction, I forget to add filename to the str form
12:23thorwilheh
12:25no_mindanyone used clojure.contrib.find-namepspaces ? I cannot figure out the input params for find-namespaces-in-dir ? If I pass a string as dir name, it says it needs java.io.File
12:26Vinzentso i've passed path to directory to the deftemplate; funny that it was working and returns something like "<html><body>layout.html\npost.html\n etc :)
12:29Vinzentno_mind, then you should pass java.io.File
12:30Vinzent(find-namespaces-in-dir (java.io.File. "src")) works fine for me
12:31no_mindI get an error ava.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn
12:31raekno_mind: sounds you are missing the last dot... :)
12:31Vinzentno_mind, note dot in the end of the class name
12:31no_mindk
12:57VinzentWith appengine-magic I have to recompile whole program after changes made; why? I'm passing var to the def-appengine-app
14:34thorwilawesome. so i had a working setup, but wanted to try http://technomancy.us/149 to have something repeatable, a way to recommend to others. somehow doesn't work with my appengine-magic project.
14:34thorwili got rid of the lein swank plugin and rolled back my entire .emacs and .emacs.d
14:35thorwiland still get the same error
14:36thorwiljava.lang.NullPointerException (init_repl.clj:0)
14:36thorwilhttp://paste.pocoo.org/show/393173/
14:51thorwilif i remove the init-script from project.clj to do things manually, (ae/serve tlog-app) leads to "java.lang.NullPointerException (NO_SOURCE_FILE:0)"
15:04raekthorwil: can you post the complete stacktrace?
15:04thorwilraek: java.lang.NullPointerException (NO_SOURCE_FILE:0) is all it says now
15:05raekin the repl?
15:05thorwilyes
15:05raektry (.printStackTrace *e)
15:07thorwilhttp://paste.pocoo.org/show/393270/
15:08zakwilsonSo I dove head first in to ClojureQL last night, and my first impression is that it is amazing and wonderful. All query languages should be like that.
15:11raekthorwil: no old files in classes/ lying around or something?
15:11raekthe NPE from the java.io.File constructor seems suspicious
15:12thorwilraek: removing everything in classes is the solution. thank you!
15:13thorwilnow ofcourse i have to wonder if the new setup would have worked after clearing classes, too :/
16:17polypus~ping
16:17clojurebotPONG!
16:27duncanmtechnomancy: how did you install emacs24 on your ubuntu laptop?
16:41amalloyduncanm: sudo apt-get install emacs-snapshot probably works, and building it from source isn't that hard either
16:42amalloydo a little research, though; i'm not 100% sure snapshot is 24
16:46technomancyduncanm: I built from the github mirror. pretty easy to do.
16:47technomancyI dimly recall the -snapshot package having lost its maintainer and being stuck in the past
16:47technomancyyou can use it for its build-deps though
16:48duncanmamalloy: yeah, it's no longer up to date
16:48duncanmtechnomancy: thanks
17:02CozeyHello. I'm not sure if i got it right: is it possible to make a class hierarchy with defrecord? Or otherwise how do I provide just one implementation for a protocol P, implemented by Parent class and its Descendants?
17:03Cozeyshould I use a multimethod for this? It seemed to me that defrecord is not to be used with multimethods... is it?
17:13technomancyhow many clojure libraries are there with native components?
17:13technomancyI only know of three: penumbra, serial-port, and the arduino one
17:25dnolentechnomancy: overtone.
17:28amalloyCozey: building a class hierarchy feels like the wrong way to approach the problem. if you only want one implementation, just define it as a plain function that takes a Parent object as its first arg
17:30Cozeyok. on the other hand - is it a good practice to use protocols with multimethods?
17:30Cozeyor should one use (extend.. )
17:31Cozeybut then - this only extends one type, and not the whole hierarchy
17:31Cozeysay I'd like to have a method (save-to-db ) for a hierarchy of records like Person, Order, etc.
17:31technomancydnolen: thanks
17:31Cozeywhat would be the Clojure approach to this?
17:32CozeyI'm a little lost in the 'function only multimethod' and protocols/record/types new speedy paradigms
17:38dnolenCozey: you can compose default implementations w/ function maps and extend-type.
17:38Cozeyextend-type applies to records, not just types
17:38dnolenCozey: however for I/O bound stuff like saving to a db, multimethods are fast enough.
17:39dnolenCozey: yes.
17:42Cozeythanks; so this means a class generated by defrecord will always get an implementation from a protocol it implements or from it's definition; inheritance between records is not used to implement polymorphism? And the way to write an implementation of a protocol is to extend on a specific type (how to extend many types implementing one protocol?)
17:43dnolenCozey: Clojure adopts the stance "inheritance considered harmful"
17:46Cozeyok. so I use multimethods - and this way can give a different implementation for different part of some hierarchy - is there a way to achieve the same using the 'optimized' methods defined with defrecord/deftype?
17:48dnolenCozey: extend-type can take a map filled /w fns, these are composable - they are just maps.
17:48Cozeywhat's the semantics of (extend nil Proto ... ) - with nil instead of type ?
17:49CozeyI'd love to see an example
17:49dnolenCozey: allows adding custom dispatch for nil value.
17:49dnolenquite useful.
17:50Cozeybut how do I extend a set of records this way?
17:52CozeySay I have a (defprotocol Sleep (sleep [this] ... )) and then I have (defrecord Animal) (defrecord Person), (defrecord Vampire) - how do I specify an implementation of sleep, which would work with animals, persons and vampires?
17:52Cozeyor should I just use a normal method hinted with ^Sleep (I could do that?)
18:25dnolenCozey: 2 ways to accomplish the same thing, https://gist.github.com/985965, https://gist.github.com/985967. I recommend getting comfortable w/ the later first.
18:28CozeyAh! Thank You so much
18:28Cozeyjust one more question - how about a defmulti on a protocol ?
18:36dnolenCozey: I think initially it's wise to consider multimethods and deftype/record/protocols as two completely distinct systems. It may seem like they overlap in functionality, but certain types of performant programs are simply not possible w/ multimethods.
18:36Cozeyok - in which case the 'sleep-shared' pattern is to be used
18:37Cozeyenough of dissecting this problem! Thank You for the examples on gist :-)
18:40dnolenCozey: No in the highest perf situation sleep-shared is also a not an insignificant perf hit. You simply just have to reimplement the function for each type (or macro it away). This is a good thing, inheritance just causes too many bigger problems compared to this inconvenience.
18:42Cozeyok, btw: is there a predicate to test if a record implements a protocol?
18:42dnolenCozey: I do have some hope that invokeDynamic can allow for objects to be cleanly composed via delegation, but this a ways off.
18:43dnolen,(doc satisfies?)
18:43clojurebot"([protocol x]); Returns true if x satisfies the protocol"
18:43CozeyIt says that defprotocol creates an interface as well - but the Foo protocol is actually some structure
18:43Cozeycool
21:16no_mindis there a library for parsing config files in clojure ?
21:18amalloyno_mind: well, clojure is such a library, if you store your config files as clojure data structures
21:18amalloyif you have a specific config format in mind, now's the time to say so :)
21:19no_mindyes, ini files
21:19no_mindstoring config in clojure files is not an option when your app is going tobe installed and maintained by sys admins,
21:34no_mindusing find-namespaces/find-namespaces-in-dir I can find out which namespaces exists in a given dir. But how do I load selective namespaces from the result of find-namespaces-in-dir ?
22:02mefestono_mind: for parsing ini files you could use [commons-configuration/commons-configuration "1.6"] http://commons.apache.org/configuration/
22:39desertmenhi, i'm learning leiningen, if i created a project , whats the best way to run and test it. One tutorial has you compile it into a jar and run it from java everytime. Is that the best way, or can you run it from leiningen?
22:42offby1I'd do "lein --help" and see if it says anything about testing
22:45amalloydesertmen: it wouldn't be a bad idea to define actual *tests*, which you can run easily with "lein test" without requiring interaction
22:45amalloybut you can also define a :main namespace in project.clj, which i believe is what lein run calls
22:46desertmenok thanks
22:56no_mindOk someone needs to tell me how to do this. I have a directory with bunch of .clj files. I want to selectively load the namespaces from those files. How do I do this ?
23:24desertmenhi, i (noob) am having some problem getting this sql connector example going -> https://gist.github.com/986166
23:26alandipertdesertmen: looks like you need to add clojure.contrib.sql to your dependencies in project.clj
23:26wolfjbhow do I alter the value of a local variable?
23:26amalloyalandipert: just clojure.contrib
23:27amalloywolfjb: don't
23:27wolfjbok, then how do I read a file in a loop?
23:27desertmenok, thanks
23:27wolfjbI want to read n bytes until there aren't any more
23:28wolfjbusually, I'd say while ((count = in.read(...)) != -1)
23:28wolfjbbut I would need to modify count in that case each time through the loop
23:29wolfjbif I shouldn't modify a local variable, is there a better way to read a file?
23:29amalloywolfjb: you don't need to modify it at all. a straightforward translation would be to create a new count variable at each iteration of your imperative loop
23:30amalloyeg, (loop [] (let [count (...)] (when-not (= count -1) ...)))
23:30wolfjbah
23:30wolfjbwonderful
23:31amalloywolfjb: a nicer solution would depend on what you're actually doing with the bytes you read
23:31wolfjbso, is loop like the common lisp loop then?
23:31amalloyno, not at all
23:31wolfjbI'm zipping a file
23:31wolfjbthis is "library" code in a larger project
23:32amalloyloop is just a nicer syntax around defining an anonymous function that calls itself recursively and "looks" more imperative
23:32wolfjbI'm using java.util.zip.ZipOutputStream and calling write(bytes, 0, count)
23:34wolfjbI'm rewriting some old common lisp code I have as an exercise to learn clojure
23:34amalloyokay. if you just want side effects based on the current chunk of bytes, loop/recur is probably a fine solution
23:35wolfjbwish there was a book to read, the 'Clojure In Action' I guess is still forth-coming
23:35amalloywolfjb: there are several clojure books
23:35wolfjb?
23:36amalloythe Joy of Clojure comes highly recommended and is also recent, which matters for a young language
23:36wolfjbmust have missed them MEAP only had a couple and they look like they are still being written
23:36amalloynah, JoC hit shelves a month or two ago
23:36wolfjbah, cool!
23:37wolfjbmissed it then, I'll have to go find it
23:37wolfjbwow, april 4! that is pretty recent
23:38amalloy(let [buf (byte-array 1024)] (loop [] (when-not (= -1 (.read in-stream buf 1024))) (.write out buf) (recur)))) ; a rough sketch
23:38amalloyi guess not a very good sketch, since it doesn't pass a size to .write
23:41ataggart,(doc clojure.java.io/copy)
23:41clojurebot"([input output & opts]); Copies input to output. Returns nil or throws IOException. Input may be an InputStream, Reader, File, byte[], or String. Output may be an OutputStream, Writer, or File. Options are key/value pairs and may be one of :buffer-size buffer size to use, default is 1024. :encoding encoding to use if converting between byte and char streams. Does not close any streams except thos...
23:42amalloy(inc ataggart)
23:42sexpbot⟹ 1
23:42wolfjb(loop [count (.read in buf 1024) (when-not (= -1 count) (.write out buf count)(recur) ?
23:42amalloynnnooooo, you've gotten the syntax there wrong in several ways
23:43amalloyshould probably look up how to use loop/recur
23:43wolfjb:-)
23:43wolfjbthanks, I'll look
23:43amalloythe general structure is (loop [loop-var init-value] (recur next-value))
23:47amalloyataggart: fwiw, sexpbot gists instead of truncating: ##(doc clojure.java.io.copy)
23:47sexpbotjava.lang.Exception: Unable to resolve var: clojure.java.io.copy in this context
23:48wolfjbhmm... that copy thing looks cool
23:48amalloy&(doc clojure.java.io/copy)
23:48sexpbot⟹ "([input output & opts]); Copies input to output. Returns nil or throws IOException. Input may be an InputStream, Reader, File, byte[], or String. Output may be an OutputStream, Writer, or File. Options are key/value pairs and may be one of :buffer-size buffer size t... http://gist.github.com/986197
23:48ataggart##(doc clojure.java.io/copy)
23:48ataggartnice
23:48sexpbot⟹ "([input output & opts]); Copies input to output. Returns nil or throws IOException. Input may be an InputStream, Reader, File, byte[], or String. Output may be an OutputStream, Writer, or File. Options are key/value pairs and may be one of :buffer-size buffer size t... http://gist.github.com/986198
23:49wolfjb(let [in (new BufferedInputStream (new FileInputStream fileName) 1024)] (clojure.java.io/copy in out) (.close in))
23:49wolfjbmuch cleaner than what I was trying
23:50wolfjb-- assuming that would work and I didn't goof it up :-)
23:50amalloywolfjb: (Foo. x) is a more usual way to write (new Foo x)
23:51amalloyand yeah, it looks like it should work
23:51wolfjbah
23:51wolfjbyou'd think I hadn't read a thing, but really I have! I promise!
23:51wolfjb:-D
23:51ataggartand you can drop all that and replace it with clojure.java.io/file
23:52amalloy&(doc clojure.java.io/file)
23:52sexpbot⟹ "([arg] [parent child] [parent child & more]); Returns a java.io.File, passing each arg to as-file. Multiple-arg versions treat the first argument as parent and subsequent args as children relative to the parent."
23:52ataggartgah, I mean input-stream
23:52amalloy&(doc clojure.java.io/input-stream)
23:52sexpbot⟹ "([x & opts]); Attempts to coerce its argument into an open java.io.InputStream. Default implementations always return a java.io.BufferedInputStream. Default implementations are defined for OutputStream, File, URI, URL, Socket, byte array, and String arguments. If th... http://gist.github.com/986202
23:53ataggarte.g., (with-open [in (input-stream "foo.txt")] ...)
23:53amalloyor (doto (input-stream filename) (copy out) (.close))
23:53ataggartexcept manually handling the close is dumb
23:53amalloyataggart: i should get to know clojure.java.io better
23:53ataggart:)
23:54ataggartya they did good work in there
23:55amalloyataggart: yes, i like the with-open version better. but only a little, and i do like a chance to introduce doto
23:56ataggartthe problem with the doto is what happens if an exception is thrown
23:56amalloyyes, all right. my version is horrible
23:56ataggartheh
23:56amalloybut it has doto!
23:56ataggartdoto is mutation is bad
23:57amalloy*eyeroll* it's well-labeled and cleanly-written mutation
23:58wolfjbheh, I thought doto was a typo
23:58ataggartdoto is lovely when having to deal with javaland, e.g., swing
23:59amalloyyour with-open version does exactly as much mutating, but hides it. mind you, it does the mutating better than i did, but you can't really frown on mutation when recommending with-out
23:59ataggartthough it's been about a decade since I wrote any swing
23:59amalloywolfjb: ##(macroexpand '(doto (+ 1 3) println))
23:59sexpbot⟹ (let* [G__14616 (+ 1 3)] (println G__14616) G__14616)