2008-11-28
| 00:13 | dlonki | (dorun (for (for ...)))? |
| 00:27 | danlei | dlonki: compare (def x (for [i (range 5)] (do (print i) i))) to (def x (dorun (for [i (range 5)] (do (print i) i)))), and (def x (doall ... |
| 01:00 | dlonki | i see |
| 01:13 | dlonki | anyone good with matlab? is its code fast enough ti use for real apps or is matlab only for use in prototyping? |
| 02:29 | danlei | � |
| 03:54 | Lau_of_DK | Yyoo :) |
| 05:19 | AWizzArd | Moin |
| 05:24 | Lau_of_DK | Ola |
| 07:20 | Lau_of_DK | Hey heey =) |
| 07:29 | pdoubleya | Lau_of_DK: hey |
| 07:30 | pdoubleya | where is the . macro defined in the clojure clj files |
| 07:31 | lvijay | i think . is a built-in |
| 07:31 | lvijay | .. is the macro |
| 07:32 | lvijay | . is defined in java |
| 07:32 | pdoubleya | lvijay: ah, ok |
| 07:32 | pdoubleya | wanted to see what it looked like :) |
| 07:34 | lvijay | if you're interested in its java implementation you should look at clojure.lang.Compiler |
| 07:35 | pdoubleya | is Compiler used just for AOT, or for the interpreter as well? (no class Interpreter) |
| 07:36 | Lau_of_DK | (doc .) |
| 07:36 | clojurebot | excusez-moi |
| 07:37 | pdoubleya | Lau_of_DK: thx |
| 07:38 | lvijay | Compile has AOT |
| 07:40 | lvijay | i haven't looked into the AOT code yet |
| 07:40 | lvijay | I know that Compiler is used to parse the clojure forms because I was hacking on it yesterday |
| 07:41 | pdoubleya | lvijay: did it survive the hacking? :) |
| 07:42 | lvijay | that's up to Rich and the others that decide upon Clojure's syntax |
| 07:42 | lvijay | i made a suggestion and submitted a patch. Rich decides if it goes thru :-) |
| 07:43 | pdoubleya | nice to see people working on it... |
| 07:53 | lvijay | newbie question: how do I refer to a class that is not in the current namespace without importing it? |
| 07:53 | lvijay | user=> java.util/Collection |
| 07:53 | lvijay | java.lang.ClassNotFoundException: java.util (NO_SOURCE_FILE:0) |
| 07:56 | Lau_of_DK | like that |
| 07:57 | Lau_of_DK | (java.util/Collection. x y z) |
| 07:58 | Lau_of_DK | user> (javax.swing.JOptionPane/showMessageDialog nil "Its working") |
| 07:58 | Lau_of_DK | nil |
| 07:58 | Lau_of_DK | |
| 08:02 | lvijay | here's my problem: |
| 08:02 | lvijay | user=> (try (java.net/URL. "http://www.google.com/") (catch java.net/MalformedURLException e (println e))) |
| 08:02 | lvijay | java.lang.IllegalArgumentException: Unable to resolve classname: java.net/MalformedURLException (NO_SOURCE_FILE:2) |
| 08:04 | hoeck | lvijay: "/" is for static member and method access, and for accessing stuff in namespaces |
| 08:04 | Lau_of_DK | java.net does not exist |
| 08:05 | lvijay | ok |
| 08:05 | hoeck | java.net is a package, not a class |
| 08:06 | hoeck | you probably want (java.net.URL. "http://...") |
| 08:06 | Lau_of_DK | exactly hoeck :) |
| 08:06 | Lau_of_DK | You literally took the words out of my ERC :) |
| 08:06 | lvijay | ah |
| 08:07 | hoeck | lvijay: and java.net.MalformedURLException |
| 08:07 | lvijay | I mixed up static references and package references |
| 08:07 | lvijay | the above worked |
| 08:07 | hoeck | Lau_of_DK: you need better auto-completion then :) |
| 08:08 | lvijay | thanks hoeck and Lau_of_DK |
| 08:10 | Lau_of_DK | nps |
| 08:10 | Lau_of_DK | hoeck: Ive got dabbrav-expand, what are you using? :) |
| 08:11 | hoeck | currently mibbit, but i love dabbrev-expand too |
| 08:14 | Lau_of_DK | k, never heard of mibbit |
| 08:15 | hoeck | http://www.mibbit.com/ ajax irc client, very useful at work :) |
| 08:17 | lvijay | hoeck: that's useful. i'm currently using chatzilla. i'm new to clojure and IRC |
| 08:18 | Lau_of_DK | hoeck: okay, but you realize that dabbrev-expand is not an irc client right? :) |
| 08:18 | hoeck | so was I'am about 3 months ago, i noticed mibbit in someones quit message |
| 08:19 | mibbit_test | uuuh, so pretty |
| 08:19 | mibbit_test | :) |
| 08:19 | hoeck | Lau_of_DK: yeah, its not capable of interpreting elisp, so no chance to dabbrev-expand something here :) |
| 08:19 | Lau_of_DK | lvijay: If you code in emacs, chat in emacs |
| 08:20 | lvijay | i code in emacs |
| 08:20 | lvijay | but is erc setup easy in emacsw32? |
| 08:20 | Lau_of_DK | :) then you know what to do |
| 08:20 | Lau_of_DK | dunno, probably like linux, emacs is emacs right? |
| 08:20 | pdoubleya | noobee question: learning clojure, is there a rule of thumb for when I don't need parens? e.g. (.substring "hello" 1 5) works, don't need parens around 1 5 altho i thought i would... |
| 08:20 | hoeck | Lau_of_DK: but (at least my) emacs hangs when erc looses the irc connection |
| 08:21 | Lau_of_DK | hoeck: Mine too, so the trick is not to loose the connection :) |
| 08:21 | Lau_of_DK | pdoubleya: () = evaluation |
| 08:21 | pdoubleya | Lau_of_DK: hmm ok, so it doesn't mean "a list of ..." |
| 08:21 | Lau_of_DK | user> (def f (fn [x] (+ x 2))) |
| 08:21 | Lau_of_DK | #'user/f |
| 08:21 | Lau_of_DK | user> f |
| 08:21 | Lau_of_DK | #<user$f__1305 user$f__1305@2b2cf8> |
| 08:21 | Lau_of_DK | user> (f 2) |
| 08:22 | Lau_of_DK | 4 |
| 08:22 | Lau_of_DK | |
| 08:22 | lvijay | pdoubleya: do you know python? |
| 08:22 | pdoubleya | lvijay: no |
| 08:23 | lvijay | ok |
| 08:23 | Lau_of_DK | lvijay: Its not allowed to speak about Python in the presence of intelligent people, please respect the universal law |
| 08:23 | lvijay | :-) |
| 08:24 | pdoubleya | Lau_of_DK: thx |
| 08:24 | lvijay | Lau_of_DK: i guess that explains why i didn't get that memo. too busy py***ning |
| 08:28 | jdz | hello people! |
| 08:30 | hoeck | jdz: hello! |
| 08:32 | jdz | i assume the compilation stuff is supposed to be working? |
| 08:32 | jdz | i am having troubles with getting the example to work... |
| 08:33 | hoeck | jdz: do you mean :genclass? |
| 08:34 | Lau_of_DK | Catch all ya'll later |
| 08:34 | lisppaste8 | jdz pasted "compilation problems" at http://paste.lisp.org/display/71165 |
| 08:46 | hoeck | jdz: have you set your classpath to include "./classes" ? |
| 08:47 | hoeck | jdz: looks like foo.clj gets compiled successfully but then clojure can't load the generated .class file |
| 08:48 | hoeck | jdz: i get exactly the same error as you when ommitting the -cp ./classes at startup |
| 08:50 | jdz | hoeck: hmm, good point. |
| 08:50 | jdz | which means clojure is trying to load the class as well? |
| 08:51 | jdz | *classes |
| 08:51 | jdz | compiled files in short :) |
| 08:51 | hoeck | yes, it seems so, compile -> load .class |
| 08:53 | jdz | hmm, now i get java.lang.ExceptionInInitializerError |
| 08:53 | jdz | hoeck: compilation works for you? |
| 08:53 | jdz | if yes i'll bang at it until it works for me, too :) |
| 08:54 | hoeck | yes, it works here |
| 08:59 | jdz | yay, it works |
| 08:59 | jdz | i think the problem was with "classes" directory not existing before starting clojure |
| 09:06 | jdz | one question: what does it mean if the function name starts with a dash (like -main)? |
| 09:07 | hoeck | jdz: its for use with :genclass, specifies the method to implement in this function |
| 09:08 | hoeck | and "main" or "-main" is for a static public main method in the generated namespace class |
| 09:08 | jdz | oh, found documentation in gen-class |
| 09:09 | jdz | hoeck: "main" without the dash won't work, will it? |
| 09:09 | hoeck | compilation docs are pretty up to date now, you may want to read there too: http://clojure.org/compilation |
| 09:10 | jdz | yes, i think i will have to read it from start to end (i just now realized that the dash prefix is explained there, too) |
| 09:10 | hoeck | jdz: it has to be -main now |
| 09:11 | jdz | hoeck: thanks for help! |
| 09:11 | hoeck | jdz: np |
| 11:29 | freddy_d | hello |
| 11:30 | freddy_d | anyone here? |
| 11:31 | freddy_d | I'm trying to figure out how to generate a Java class stub from Clojure to do the bridge, and having some trouble |
| 11:34 | blackdog | freddy_d, the only trouble i had was not having the classes directory in the classpath |
| 11:34 | freddy_d | blackdog: any chance you could point me to some docs? |
| 11:35 | blackdog | rich did put new docs on the site a couple of days ago |
| 11:35 | blackdog | othre than that i worked from this http://paste.lisp.org/display/70665 |
| 11:35 | freddy_d | basically I want to generate a.b.c.MyBean, with one method that returns MyClass |
| 11:36 | blackdog | so you want a a.b.c.MyBean namespace in clojure then |
| 11:37 | freddy_d | yes, I want to implement that one method in clojure |
| 11:37 | freddy_d | but I want the Java framework to "see" it from Java bytecode |
| 11:38 | freddy_d | (hopefully I'm making some sense) |
| 11:38 | blackdog | yes using (ns (:genclass///00 is the way to go then |
| 11:38 | blackdog | once you've defined your class in a clojure ns |
| 11:39 | blackdog | you compile it with (compile a.b.c.MyBean) |
| 11:39 | blackdog | http://clojure.org/compilation |
| 11:40 | freddy_d | blackdog: thanks for the pointers, I'll try it out |
| 11:41 | blackdog | k |
| 11:47 | freddy_d | blackdog: apologies, I'm a total newbie. why, in your pasted example, is it e.g. (defn- -mymax and not (defn mymax ? |
| 11:48 | blackdog | not sure, i think it's just convention so that clojure can find the methods |
| 11:48 | blackdog | as opposed to an internal function |
| 11:48 | blackdog | rich did mention something about it on the group if you do a search |
| 13:49 | danlei | b |
| 14:16 | sdfsf | is there no way to comment out a section in slime? |
| 14:37 | grkz | sdfsf: mark the region (go to start, C-space, go to end) and then M-; |
| 14:39 | peter_12 | I'm curious how the Clojure folks approach the realm where OOP ORM's are commonly used for CRUD DB operations. |
| 14:39 | peter_12 | I don't like ORM's like Rails' ActiveRecord. All that imperative stuff is a real headache. |
| 14:40 | blackdog | rhickey, is mostly down on ORM i believe |
| 14:41 | peter_12 | "down on" = ? |
| 14:41 | blackdog | he doesn't like it |
| 14:41 | peter_12 | ahh |
| 14:41 | peter_12 | the same for me |
| 14:41 | blackdog | so there would be nothing in core for it |
| 14:41 | peter_12 | so what is the general approach to mutating a database? |
| 14:41 | blackdog | have a look at clojure.contrin.sql |
| 14:42 | blackdog | have a look at clojure.contrib.sql |
| 14:42 | peter_12 | blackdog: ok. Thanks |
| 14:42 | blackdog | and you'll find resultset-seq in core.clj |
| 14:42 | peter_12 | ahh that would be for SELECT |
| 14:42 | peter_12 | That is the easy case |
| 14:42 | peter_12 | DELETE is pretty easy too |
| 14:43 | peter_12 | it is UPDATE and INSERT that are the tricky ones |
| 14:43 | peter_12 | what should happen if failure etc |
| 14:43 | blackdog | the c.c.sql takes care of that |
| 14:43 | peter_12 | ok |
| 14:43 | blackdog | it has a (transaction) |
| 14:43 | freddy_d | blackdog: it's all good now, I managed to compile .clj to java, scripted it with Ant, and Stripes web framework picks it up. Very nice. :) |
| 14:43 | blackdog | cool! |
| 14:44 | freddy_d | thanks for your help |
| 14:44 | freddy_d | would the Clojure community be interested in the Stripes/Clojure integration? or does Clojure already have its own web framework? |
| 14:44 | blackdog | yw, i usually defer to Chouser, rhickey and more knowedable folks but i think they're on holiday :P |
| 14:45 | freddy_d | hehe |
| 14:45 | blackdog | Pupeno, has someting called compojure |
| 14:45 | blackdog | and AWizzard is working on rife integration |
| 14:50 | peter_12 | blackdog: looking at clojure.contrib.sql, it seems like that is dealing with one level of abstraction lower than I am interested in. I'm interested in how clojure folks might handle validation of data before attempting a db insert |
| 14:51 | peter_12 | and then if there are errors how to get that back to the controller and view, in a web app, for example |
| 14:52 | blackdog | well i guess your app takes care of that, afaik there's no work on web stuff apart from compojure in terms of framework |
| 14:53 | peter_12 | yeah, the app takes care of that, I was just wondering if there was a general attitude of how that should best be done. I don't like, and have never liked, how Rails does that. |
| 14:54 | peter_12 | it isn't really a web-specific issue but that is my current application |
| 14:54 | blackdog | i'm not a lisper so I don't have a good idea of how they accomplish such stuff in CL etc |
| 14:55 | peter_12 | I may ask the Common Lisp and Scheme folks what they do |
| 15:03 | Pupeno | blackdog: ? |
| 15:03 | blackdog | hello |
| 15:09 | freddy_d | blackdog: interesting. well, a Stripes/Clojure integration might still be useful. |
| 15:11 | blackdog | given the number of java web frameworks i'm sure we;ll see quite a few |
| 15:11 | blackdog | wrappers |
| 15:12 | ryrunfrnf | anyone good with common lisp? im translating pg ansi cl raytracer to clojure and wow clojure is so much cleaner and more elegant than cl. |
| 15:12 | ryrunfrnf | but what is the eq od do in cl? |
| 15:16 | gnuvince | ryrunfrnf: eq od do? |
| 15:16 | gnuvince | equivalent of do? |
| 15:17 | gnuvince | ryrunfrnf: look at loop/recur |
| 15:55 | kotarak | Say I have a gen-class: (ns foo.bar.Baz (:gen-class ...)). Can I refer to Baz directly in the source file? |
| 16:26 | sdfsf | who is albert cordona? |
| 16:30 | gnuvince | How do I get the absolute value of a number? |
| 16:31 | kotarak | Math/abs maybe? |
| 16:32 | gnuvince | Bingo |
| 16:32 | gnuvince | thanks |
| 16:32 | gnuvince | I was trying (.abs -3) |
| 16:32 | kotarak | gnuvince: that would be too easy. ;) |
| 16:32 | Chouser | (.abs -3M) works |
| 17:01 | AWizzArd | Chouser: how can it work? Is it because nM is treated specifically by the reader and is some kind of postfix reader macro which translates into (new BigDecimal "n") ? |
| 17:10 | sdfsf | anyone use the Fiji/ImageJ package? |
| 17:10 | sdfsf | i want to write apps in clojrue as normal with it |
| 17:10 | sdfsf | is that possible? |
| 17:20 | AWizzArd | sdfsf: yes, Clojure is good to write normal and not so normal apps with it. |
| 17:21 | AWizzArd | From todays perspective Clojure has the potential to make it easier to write non-normal apps (namely those that make use of multiple cores in CPUs). |
| 17:45 | Chouser | AWizzArd: yep. (class -3M) -> java.math.BigDecimal |
| 17:45 | Chouser | BigDecimal has an 'abs' method. |
| 17:51 | AWizzArd | yes, this I understand |
| 18:14 | ryrunfrnf | why doesnt errors report the linenumberwhere the error is ? |
| 18:14 | ryrunfrnf | really annoying |
| 18:38 | AWizzArd | because in Lisp programming is not string editing |
| 18:39 | blackdog | AWizzArd, did you have any luck with the interation |
| 18:39 | AWizzArd | you are doing tree editing |
| 18:39 | blackdog | AWizzArd, did you have any luck with the integration |
| 18:39 | AWizzArd | blackdog: did not continue with it yet, but I will have a try tomorrow |
| 18:39 | AWizzArd | I will use your example and see how far I get with it |
| 18:40 | blackdog | i didnt try compiling it or anything, but it's close :P |
| 18:43 | AWizzArd | If I use purely java code from within Clojure the resulting .class file should be more or less exactly the same as if I had compiled it from a .java source. The clojure.jar would not be needed in that case. |
| 18:43 | ryrunfrnf | java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol (NO_SOURCE_FILE:1) |
| 18:43 | ryrunfrnf | is it now allowed to do: let [x blah c x]? |
| 18:44 | ryrunfrnf | what exactly does clojure check when compiling? |
| 18:44 | blackdog | well you;ll get lot's of class files not just one, |
| 18:44 | AWizzArd | But if I use any Clojure functionality I will have to use the clojure.jar and find a way how to start Jetty so that it will know about that as well. |
| 18:44 | blackdog | you get a class for each function and namespace |
| 18:45 | blackdog | and I'll be impressed if you can get away without clojure.jar |
| 18:45 | blackdog | don't know |
| 18:46 | hiredman | ryrunfrnf: sounds like somewhere (seq ...) is getting called on something that seq doesn't know what to do with |
| 18:46 | hiredman | do you do an destructering? |
| 18:51 | ryrunfrnf | meh, do youi guys have constant problems with getting stuck forever on dumb details? |
| 18:52 | ryrunfrnf | like so often it is some really small stupid detail that is right ther ein your face and yous till miss it |
| 18:52 | ryrunfrnf | i was using (defn f (params) instead of [params]... |
| 18:53 | Aisling | I used to work as a tutor in the lab at my university and I saw lots of people doing things like that. |
| 18:53 | Aisling | It's not just you. Attention to detail helps but still you'll run into these errors. |
| 18:54 | hiredman | well |
| 18:54 | Aisling | Syntax support in your editor can help with this. |
| 18:55 | hiredman | besides starting to write my lisp in ruby, and watching the mit sicp videos, I don't have previous lisp experience, so I don't automatically put parens everywhere :P |
| 19:14 | ryrunfrnf | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number (NO_SOURCE_FILE:2) |
| 19:14 | ryrunfrnf | (let [n (minroot (+ (sq xr) (sq yr) (sq zr)))] |
| 19:19 | hiredman | clojurebot: cheesecake is delicious. |
| 19:19 | clojurebot | Roger. |
| 19:33 | ryrunfrnf | why os destructuring slower than first/rest? |
| 19:38 | gnuvince_ | ryrunfrnf: destructuring has more bells and whistles |
| 19:38 | gnuvince_ | > (let [[x y & z :as all] [1 2 3 4]] [x y z all]) |
| 19:38 | gnuvince_ | [1 2 (3 4) [1 2 3 4]] |
| 19:44 | ryrunfrnf | hmm when doign a raytracer |
| 19:44 | ryrunfrnf | that must be perfect for multimethods right? |
| 19:44 | ryrunfrnf | now i seee their advantage |
| 19:44 | ryrunfrnf | have amethod intersect |
| 19:44 | ryrunfrnf | and specialize on the thing its calle don |
| 19:51 | ryrunfrnf | god clojure is sooooo much cleaner than common lisp |
| 19:53 | gnuvince_ | :) |
| 20:29 | ryrunfrnf | is it impossible to set swank/slime-intendation to 4 chars always? |
| 20:39 | ryrunfrnf | java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :shape (NO_SOURCE_FILE:0) |
| 20:42 | ryrunfrnf | (intersect sph [10 20 30] 30 40 50) |
| 20:42 | ryrunfrnf | (defmethod intersect :Sphere [sphere point xr yr zr] |
| 20:42 | ryrunfrnf | (defn sphere-intersect [sphere point xr yr zr] |
| 20:42 | ryrunfrnf | wtf? |
| 20:43 | hiredman | ryrunfrnf: all the args to a multimethod get passed to the dispatch function |
| 20:43 | hiredman | so what happens there is (:Sphere sphere poit xr yr xr) |
| 20:43 | hiredman | which, uh, no? |
| 20:44 | hiredman | wait |
| 20:44 | hiredman | the is defmethod |
| 20:44 | hiredman | not defmulti |
| 20:45 | ryrunfrnf | so i want to refer to the sphere itself, how do i? |
| 20:46 | ryrunfrnf | (defmethod area :Rect [r] |
| 20:46 | ryrunfrnf | (* (:wd r) (:ht r))) |
| 20:46 | ryrunfrnf | hes assing the rect itself |
| 20:46 | hiredman | what does your defmulti look like? |
| 20:47 | ryrunfrnf | (defmulti intersect :shape) |
| 20:48 | lisppaste8 | andjnsd pasted "defmulti" at http://paste.lisp.org/display/71202 |
| 20:51 | ryrunfrnf | (defmethod intersect :Sphere [sphere a] |
| 20:51 | ryrunfrnf | (+ (:x sphere) a)) |
| 20:51 | ryrunfrnf | works |
| 20:52 | hiredman | so |
| 20:52 | hiredman | yeah |
| 20:53 | hiredman | you are using a keyword as a dispatch function |
| 20:53 | hiredman | but that only works if you have one arg |
| 20:53 | ryrunfrnf | isnt ricks example? |
| 20:53 | hiredman | yeah it is |
| 20:53 | hiredman | but he only dispatches on one param |
| 20:53 | ryrunfrnf | ok |
| 20:54 | ryrunfrnf | so how should i change it? |
| 20:54 | ryrunfrnf | how do irefer to the sphere inside its defmethod? :Sphere? |
| 20:55 | hiredman | is the first argument always going to be hash with a :Sphere keyword? |
| 20:55 | ryrunfrnf | it is going to be a :shape |
| 20:55 | ryrunfrnf | hash-map |
| 20:55 | ryrunfrnf | sphere, cube etc |
| 20:55 | ryrunfrnf | it is for a raytracer |
| 20:56 | hiredman | (doc defstruct) |
| 20:56 | clojurebot | Same as (def name (create-struct keys...)); arglists ([name & keys]) |
| 20:56 | hiredman | btw |
| 20:56 | ryrunfrnf | yes |
| 20:56 | ryrunfrnf | but isnt this pretty much was multimethods are for? |
| 20:56 | ryrunfrnf | hvaing an intersect functiona nd dispathicng on the type |
| 20:56 | ryrunfrnf | of :shape? |
| 20:57 | ryrunfrnf | (defmethod intersect :Sphere [a] |
| 20:57 | ryrunfrnf | (+ (:x :Sphere) a)) |
| 20:57 | hiredman | so replace :shape in the defmulti with (fn [& x] (:shape (first x))) |
| 20:57 | ryrunfrnf | doesnt work |
| 20:57 | ryrunfrnf | i dont get how to use them then |
| 20:57 | hiredman | ryrunfrnf: you don't seem to understand how dispatch functions work |
| 20:57 | ryrunfrnf | correct |
| 20:58 | hiredman | that is what multimethods are for, you just are passing more then one arg, but using a dispatch function that only takes one arg |
| 20:58 | hiredman | keywords in clojure are functions of maps |
| 20:58 | ryrunfrnf | which is the dispathc function? defmulti? |
| 20:58 | hiredman | ryrunfrnf: you are using :shape as a dispatch function |
| 20:58 | hiredman | the keyword :shape |
| 20:59 | ryrunfrnf | yes |
| 20:59 | ryrunfrnf | what should i use? |
| 20:59 | AWizzArd | ryrunfrnf: have a look at this examplefor the generality of multimethods: http://paste.lisp.org/display/68846 |
| 20:59 | hiredman | a function that can take as many args as you pass |
| 21:00 | hiredman | the dispatch function needs to have the same arity as the method it dispatches to |
| 21:00 | hiredman | or something like that |
| 21:01 | hiredman | a keyword has an arity of 1 |
| 21:01 | hiredman | your method as an arity of more then 1 |
| 21:01 | hiredman | *boom* |
| 21:06 | ryrunfrnf | then i dont get what defmulti is for |
| 21:06 | hiredman | then don't use it |
| 21:08 | hiredman | clojurebot: where are you? |
| 21:08 | clojurebot | http://gist.github.com/27733 |
| 21:08 | hiredman | I use multimethods there |
| 21:09 | AWizzArd | ryrunfrnf: defmulti takes a function |
| 21:10 | AWizzArd | when you say (defmulti foo my-fun) then my-fun gets called with the arguments that you gave to the call of foo |
| 21:10 | AWizzArd | if you say (foo 1 2 3) then Clojure will do (my-fun 1 2 3) for you |
| 21:10 | AWizzArd | my-fun yields a result |
| 21:11 | AWizzArd | then Clojure goes through all (defmethod foo)'s to see if one of them was done for this result |
| 21:11 | AWizzArd | look at http://paste.lisp.org/display/68846 |
| 21:11 | AWizzArd | there is the call (foo 2 4) |
| 21:11 | AWizzArd | Clojure secretly calls my fn from above |
| 21:12 | AWizzArd | This fn takes either 1 arg or 2. As I gave two we need to look into that branch. It simply adds both numbers. So, (foo 2 4) will yield 6. |
| 21:12 | AWizzArd | There exists a method foo for 6 |
| 21:13 | AWizzArd | it gets both original arguments that were given, which were 2 and 4, and then passes them to the respective defmethod foo, which will multiply it's args |
| 21:14 | AWizzArd | Clear now? |
| 21:17 | ryrunfrnf | no |
| 21:18 | ryrunfrnf | (classes-of int int) would be clear |
| 21:18 | hiredman | ... |
| 21:18 | ryrunfrnf | i want to write a method intersect that takes an abstract shape and then dispatches to the correect shape-method |
| 21:19 | AWizzArd | what exactly is unclear in this example? |
| 21:19 | hiredman | ryrunfrnf: you are not going to be able to use a keyword as a dispatch, because your methods take more then one arg |
| 21:20 | hiredman | your best bet is to write a dispatch function that takes a variable number of args |
| 21:20 | ryrunfrnf | ok i see |
| 21:20 | AWizzArd | you can pass keywords to defmulti btw, because they are treated asfunctions |
| 21:20 | hiredman | and uses the keyword to determine the :shape of the first argument |
| 21:20 | AWizzArd | (:my-key my-hashtable) ==> value for key |
| 21:21 | jeremy___ | ok here's a newbie question: Here's a function my-sum that take a list of numbers and adds them together: (defn my-sum [x] |
| 21:21 | jeremy___ | (+ ~@x)) |
| 21:22 | hiredman | no |
| 21:22 | jeremy___ | I get a ClassCastException when I run (my-sum `(1 2 3)) |
| 21:22 | hiredman | yeah |
| 21:22 | hiredman | you do |
| 21:22 | hiredman | ok |
| 21:22 | jeremy___ | what am I doing wrong? |
| 21:22 | hiredman | a lot |
| 21:22 | hiredman | ~ is unquote |
| 21:22 | hiredman | mostly only used in macros |
| 21:23 | AWizzArd | you can use ~ or ~@ only inside a backquote expression. Your (+ ~@x) is just a plain list |
| 21:24 | AWizzArd | try instead (defn my-sum [x] `(+ ~@x)) |
| 21:24 | AWizzArd | when you then (my-sum `(1 2 3)) ==> (+ 1 2 3) |
| 21:24 | hiredman | (doc apply) |
| 21:24 | clojurebot | Applies fn f to the argument list formed by prepending args to argseq.; arglists ([f args* argseq]) |
| 21:25 | jeremy___ | ah thanks it's starting to make sense |
| 21:26 | AWizzArd | This is used to contstruct lists. Lists are data. Data is code. So the backquote and ~ as well as ~@ are very often used to create code. |
| 21:26 | ryrunfrnf | int he examples oyu posted both defmulti and defmethod contains information on implementation |
| 21:26 | ryrunfrnf | they seem intertwined, thats what is confusing me |
| 21:27 | AWizzArd | Note however that you can write all programs without `, ~ and ~@. They are just shortcuts to plain function calls. |
| 21:27 | AWizzArd | ryrunfrnf: You could have a (defn my-count [obj] (count obj)). And then you do (defmulti foo my-count). |
| 21:28 | AWizzArd | this means that now all calls in the form of (foo ...) will in secretly be (my-count ...) |
| 21:28 | ryrunfrnf | so whats the point then? |
| 21:28 | AWizzArd | example: (foo [1 2 3]) === (my-count [1 2 3]) ==> 3 |
| 21:28 | AWizzArd | but without defmethods it would be pointless |
| 21:29 | AWizzArd | now we put in a method: (defmethod foo 3 [arg] (println "Hello")) |
| 21:29 | ryrunfrnf | I thought it worked like: declare a function name and what it takes. then declare a bunch of methods to call depending on the type |
| 21:29 | AWizzArd | We said the call (foo [1 2 3]) ==> 3. There exists a (defmethod foo 3 ...) |
| 21:30 | AWizzArd | the 3 in the (defmethod ..) is the one that was the result of the call to (foo [1 2 3]) which under the hood was really a call to my-count. |
| 21:30 | AWizzArd | What now happens is: put the original argument to foo (it was [1 2 3]) to this method |
| 21:30 | arohner | what is the value of clojure.core.test? |
| 21:30 | AWizzArd | in this method it is called arg. We could have called it peter. The body of the method is (println "Hello") |
| 21:31 | AWizzArd | So, (foo [1 2 3]) will print Hello |
| 21:31 | arohner | it's slightly annoying that the test function expects failures to throw exceptions, yet it does nothing to catch & report them |
| 21:31 | ryrunfrnf | Like I thought it worked kind of liek inherited methods so i could do Obj.method and dont do inthe function If obj == type then blah else blahaba |
| 21:31 | AWizzArd | that was the old school dispatching, as most languages do |
| 21:31 | AWizzArd | this is the plain old type dispatch |
| 21:31 | hiredman | you can do that sort of thing |
| 21:31 | AWizzArd | but in Clojure you are not bound to that |
| 21:32 | AWizzArd | This is just a subset of what Clojures methods can do |
| 21:32 | hiredman | yeah |
| 21:32 | AWizzArd | you can dispatch for example on the number of elements in your argument, as we just did in the my-count example |
| 21:32 | AWizzArd | so no longer the type of the argument is important |
| 21:32 | AWizzArd | but only how many elements it contains |
| 21:33 | hiredman | you can dispatch on just about anything |
| 21:33 | hiredman | because the dispatcher is just another function |
| 21:33 | AWizzArd | add a (defmethod foo 5 [ryrun] (reverse ryrun)) |
| 21:33 | AWizzArd | now you can say: (foo "Hello") |
| 21:33 | AWizzArd | and see what happens |
| 21:34 | ryrunfrnf | but i want a funiton intersect so i should have one defmulti and sveral defmethods? |
| 21:34 | hiredman | yes |
| 21:34 | AWizzArd | ryrunfrnf: first you should understand in detail how it works. I think these examples were pretty obvious. If not, what exactly puzzles you? |
| 21:34 | hiredman | but you will need slightly more complicated dispatch function because you are using more then one argument |
| 21:41 | AWizzArd | ryrunfrnf: in other languages a defmulti always looks basically the same. It is always something like: (defmulti name class) |
| 21:42 | AWizzArd | where (class obj) returns the type of that object |
| 21:42 | AWizzArd | you can not simply replace class with your own function |
| 21:43 | ryrunfrnf | but i dont get the 6 and the \H |
| 21:43 | ryrunfrnf | wtf are those names of the methods? |
| 21:43 | ryrunfrnf | if it is a 6 then do this? |
| 21:44 | hiredman | those are return values of the dispatch function |
| 21:44 | hiredman | if the dispatch function returns 6 then do this method |
| 21:45 | hiredman | which method is run is the result of what the dispatch function outputs |
| 21:45 | AWizzArd | ryrunfrnf: okay, so your problem lies in the (fn) which is passed to defmulti |
| 21:45 | AWizzArd | in Clojure a function can have many parameter lists and bodies |
| 21:46 | AWizzArd | The anon function that I passed to defmulti is such an example. It has the parameter collection and the body (first collection) |
| 21:46 | AWizzArd | If this function is called with just one arg then this branch of the fn is used |
| 21:47 | AWizzArd | Now the fn has a second branch. One that has two parameters. If we pass in two args they will be added. |
| 21:47 | ryrunfrnf | but why are they instances of a somehting instead foa type? |
| 21:47 | ryrunfrnf | if u make a general speci it should be diosptache dona type |
| 21:47 | ryrunfrnf | not an isntanc eof the type |
| 21:47 | AWizzArd | try (defn blah [x] (first x) [x y] (+ y x)) and call blah |
| 21:48 | AWizzArd | try calling blah with one arg and with two |
| 21:48 | hiredman | AWizzArd: I think you may be missing some parens |
| 21:48 | AWizzArd | oki right |
| 21:49 | AWizzArd | parens around [x] (first x) and also around the second guy |
| 21:49 | hiredman | and the (first ...) is kind of pointless |
| 21:49 | AWizzArd | hiredman: why? |
| 21:49 | hiredman | AWizzArd: well I guess it depends |
| 21:49 | AWizzArd | (blah (range 8 24)) |
| 21:49 | ryrunfrnf | i thin i see a little now |
| 21:49 | hiredman | I just assumed that since the [x y] form uses (+ ) |
| 21:49 | AWizzArd | but also (blah 10 5) |
| 21:50 | hiredman | anyway |
| 21:50 | hiredman | whatev |
| 21:50 | AWizzArd | ryrunfrnf: when you understand blah just do in my example at http://paste.lisp.org/display/68846 a replacement of the defmulti. (defmulti foo blah) |
| 21:51 | AWizzArd | when we call (foo "Hello World") then foo gets only one arg. This means we go into the branch 1 of blah. This simply returns the first element of the collection. |
| 21:52 | AWizzArd | A string is a collecting. The first element of "Hello World" is the char \H |
| 21:52 | hiredman | clojurebot: multimethods? |
| 21:52 | clojurebot | multimethods seperate the 20% from the 80% |
| 21:52 | AWizzArd | How can one teach the clojurebot new things? |
| 21:53 | hiredman | clojurebot: a is b |
| 21:53 | clojurebot | c'est bon! |
| 21:53 | hiredman | clojurebot: a? |
| 21:53 | clojurebot | a is b |
| 21:53 | hiredman | clojurebot: a is also c |
| 21:54 | clojurebot | Ack. Ack. |
| 21:54 | hiredman | clojurebot: a? |
| 21:54 | clojurebot | a is c |
| 21:54 | hiredman | clojurebot: a? |
| 21:54 | clojurebot | a is b |
| 21:55 | AWizzArd | clojurebot: multimethods is also what separates the boy from the man. |
| 21:55 | clojurebot | c'est bon! |
| 21:55 | rottcodd | clojurebot: b? |
| 21:55 | clojurebot | excusez-moi |
| 21:56 | ryrunfrnf | if i want to pass 5 args and dispatch on the ttype oa the first? |
| 21:56 | ryrunfrnf | (defmulti intersect (fn [a b c d e] |
| 21:56 | ryrunfrnf | (class a))) ? |
| 21:57 | hiredman | uh |
| 21:57 | hiredman | you most likely don't want to use (class ...) |
| 21:57 | hiredman | but that is the general idea |
| 21:57 | AWizzArd | this fn looks like a function that takes 5 arguments and returns the class of the first (while it ignores the other 4) |
| 21:58 | jeremy___ | Here's another newbie question: Is there a way to force floating points when I run (/ 1 2 3 4) besides making one of the args a decimal (e.g 2.0)? |
| 21:58 | hiredman | (doc float) |
| 21:58 | clojurebot | Coerce to float; arglists ([x]) |
| 21:58 | AWizzArd | (float (/ 1 2 3 4)) |
| 21:58 | hiredman | clojurebot: botsnack |
| 21:58 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 21:58 | AWizzArd | (/ 1 2 3 4.0) |
| 21:59 | jeremy___ | ah thanks I overlooked that on the API page. |
| 21:59 | ryrunfrnf | so if i want to dispatch on a type i should have a defstrcut not a function calle dpshere? |
| 22:00 | AWizzArd | a defstruct is done for optimization,it will not create types |
| 22:00 | AWizzArd | structs are simple hashtables |
| 22:01 | AWizzArd | but they don't use up RAM for (some) of their keys |
| 22:02 | ryrunfrnf | oh my |
| 22:02 | ryrunfrnf | god |
| 22:02 | ryrunfrnf | so i cant disptach on something called a sphere? |
| 22:02 | hiredman | YOU CAN DISPATCH ON WHATEVER YOU WANT |
| 22:02 | ryrunfrnf | becaus eif i d struct sphere it passes back a ahsh howthe f doi matcht hat? |
| 22:02 | AWizzArd | if you have a (defstruct person :name :street :age :telephone) and want to do it for New York, then you would have 18 million instances or something like that. If it were a hashtable then all 18 mio entries would consume space for the keys :name :street :age :telephone. |
| 22:02 | hiredman | JUST WRITE THE RIGHT FUNCTION |
| 22:03 | ryrunfrnf | yes but since all :shapes will use hashmaps how do i differ them? |
| 22:03 | hiredman | you could even dispatch on time of day |
| 22:03 | AWizzArd | in a structure map only one time the keys need to be stored. |
| 22:03 | AWizzArd | ryrunfrnf: you will manually have to put some key/value into the hashtable |
| 22:03 | hiredman | ryrunfrnf: you have a key {:shape :sphere} |
| 22:03 | AWizzArd | (defstruct person :name :age) |
| 22:03 | hiredman | and you have a function that returns the value of that key of the hash |
| 22:04 | AWizzArd | (defn make-person [n a] (assoc (struct person n a) :type :person) |
| 22:04 | AWizzArd | now each instance of your hashtable will also have the key/value pair {:type :person} |
| 22:06 | SimonAdameit | Good evening |
| 22:07 | AWizzArd | Moin Simon |
| 22:13 | lisppaste8 | blarf pasted "im dying of frustration" at http://paste.lisp.org/display/71210 |
| 22:13 | hiredman | man, I wonder who blarf is |
| 22:13 | hiredman | ok |
| 22:14 | hiredman | NO |
| 22:14 | hiredman | no no |
| 22:14 | hiredman | no |
| 22:14 | hiredman | no |
| 22:14 | albino | that's a lot of 'no's |
| 22:14 | hiredman | see, here you have one thing you are passing, the hash |
| 22:14 | hiredman | so your dispatch function should take one value |
| 22:15 | hiredman | I think you will be better off if you have your dispatch function take a variable number of args |
| 22:16 | ryrunfrnf | but it takes a sphere a point and 3 coordinates |
| 22:17 | hiredman | ryal all of which are in the hash |
| 22:17 | hiredman | the hash is one "thing" |
| 22:17 | gnuvince_ | Does clojure have a divmod function? |
| 22:17 | hiredman | object, datastructure, thing |
| 22:18 | hiredman | (doc rem) |
| 22:18 | clojurebot | remainder of dividing numerator by denominator.; arglists ([num div]) |
| 22:18 | ryrunfrnf | but which is thet dispatch function? defmethods? |
| 22:18 | hiredman | no |
| 22:18 | SimonAdameit | Using swank-clojure I get the following error: "Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Repl" |
| 22:18 | gnuvince_ | hiredman: that's only the second part :) |
| 22:18 | hiredman | the dispatch function is the function you pass to defmulti |
| 22:19 | hiredman | gnuvince_: well I don't know what divmod is |
| 22:19 | hiredman | so I guessed |
| 22:19 | SimonAdameit | Alot of people seem to have gotten that, but the tip to fully qualify the clojure jar path that I found in the google group did not work |
| 22:19 | SimonAdameit | Any Idea how to fix this? |
| 22:19 | gnuvince_ | hiredman: (divmod 3 2) => (1 1) |
| 22:20 | gnuvince_ | hiredman: basically, it'd be: (defn divmod [m n] [(quot m n) (rem m n)]) |
| 22:20 | hiredman | ok |
| 22:20 | AWizzArd | SimonAdameit: do you use the newest versions? |
| 22:21 | hiredman | clojurebot: emacs? |
| 22:21 | clojurebot | emacs is hard, lets go shopping! |
| 22:21 | SimonAdameit | AWizzArd: for slime, swank-clojure and clojure yes |
| 22:21 | SimonAdameit | and emacs 22 |
| 22:22 | AWizzArd | I have the same, for me it works |
| 22:22 | SimonAdameit | could you paste the relevant .emacs parts, maybe I could try yours |
| 22:22 | AWizzArd | oki |
| 22:23 | ryrunfrnf | but isnt the defmethod that has a value of what the defmulti retuns called? |
| 22:23 | ryrunfrnf | defmulti intersect retuns :shape a whc should be :Sphere |
| 22:23 | ryrunfrnf | then defmethid intersect :Sphere is called? |
| 22:24 | lisppaste8 | rte annotated #71210 with "multis" at http://paste.lisp.org/display/71210#1 |
| 22:24 | hiredman | that should work |
| 22:25 | hiredman | and could you use your own nick when you paste stuff? |
| 22:26 | SimonAdameit | AWizzArd: Yay, got it working to |
| 22:27 | SimonAdameit | It actually was a "stupid" error in specifying the wrong path :) |
| 22:27 | ryrunfrnf | yes but it doesnt |
| 22:28 | hiredman | what is the error |
| 22:28 | lisppaste8 | AWizzArd pasted "Example emacs config for Clojure+slime" at http://paste.lisp.org/display/71211 |
| 22:28 | AWizzArd | oki |
| 22:28 | hiredman | ryrunfrnf: paste the whole thing again |
| 22:28 | hiredman | uh |
| 22:28 | hiredman | yeah |
| 22:28 | hiredman | you are missing parens |
| 22:29 | hiredman | inside the fn, you need (:shape a) |
| 22:30 | ryrunfrnf | wow so annoying |
| 22:30 | ryrunfrnf | now it works |
| 22:30 | ryrunfrnf | hehe sorry guys |
| 22:30 | AWizzArd | I think you don't need these 5 args for defmultis dispatch fn |
| 22:31 | AWizzArd | try (defmulti intersect :shape) |
| 22:31 | hiredman | AWizzArd: ssh it's working, back away slowlyr |
| 22:31 | AWizzArd | *g* |
| 22:31 | hiredman | AWizzArd: he passes more then one arg |
| 22:31 | hiredman | not just the hash |
| 22:31 | hiredman | keywords are functions of arity 1 |
| 22:31 | hiredman | so they blow up |
| 22:31 | hiredman | which is how this whole thing started |
| 22:32 | AWizzArd | wow |
| 22:32 | AWizzArd | well, you could need a calm-down-tea for tonight hire ;-) |
| 22:32 | AWizzArd | it was a moving theme |
| 22:32 | hiredman | huh |
| 22:33 | Chouser | keywords can take 2 args (not found) |
| 22:33 | hiredman | Chouser: just noticed that |
| 22:34 | hiredman | the point is, he is passing to many args to dispatch via a keyword, so cargo culting the examples doesn't work |
| 22:36 | sdfsf | the intersect function takes 5 args |
| 22:37 | sdfsf | a sphere a point and 3 coordinates |
| 22:37 | sdfsf | so i need to pass everala rgs aight? |
| 22:38 | sdfsf | i should do porn instead |
| 22:46 | AWizzArd | sdfsf: if this data is already inside the hashtable then you would only have to pass this one arg, namely the hashtable |
| 23:19 | matzero | hello is this working? |
| 23:19 | matzero | microphone check 1 check 2 |
| 23:20 | sdfsf | anyone seen matzero lately? i never se him around here |
| 23:21 | matzero | lol |
| 23:21 | matzero | cool thanks for the ping back |