2011-05-08
| 01:03 | TheMoonMaster | STM is amazing. |
| 04:20 | kzar | Can you perform dynamic method calls without creating a macro? |
| 04:41 | thorwil | kzar: do you mean somehow arriving at the name of a function as a string, then call it? |
| 04:43 | kzar | thorwil: Well I have my keyword :insert , I've changed it to the symbol .insert fine. But then when I call it (thing-containing-.insert object) it doesn't work. I (sort of) get why, the dot form is evaluated at compile time so I'm going about it the wrong way? |
| 04:46 | thorwil | no idea how the java-interop might screw you there. i mean, with foo.method, i don't know if that shouldn't be though of as one symbol |
| 04:47 | thorwil | guess an alternative to a macro might be eval |
| 05:07 | raek | kzar: (clojure.lang.Reflector/invokeInstanceMethod object "method name" (to-array [arg1 arg2 ...])) |
| 05:13 | raek | kzar: Also, if you do want to use a macro, it's probably easier to generate (. object method arg1 arg2 ...) rather than (.method object arg1 arg2 ...). The latter is syntactic sugar for humans. |
| 05:17 | kzar | raek: Ah right, actually which approach is more idiomatic? |
| 05:18 | raek | kzar: I would say that if you know the method name at compile time, there is no good reson to not generate (. object method ...) with a macro |
| 05:19 | raek | that will be compiled into a invokevirtual JVM bytecode instruction |
| 05:20 | raek | a reflective call will be far mor slower, but sometimes you simply do not know class+method until at runtume |
| 05:22 | kzar | Hmm if I'm honest I'm not sure if I do know the method name at compile time or not. I've got a bunch of actions for google calendar and for each one I have to call one of 4 methods, either .insert .update .query or .delete . So I could have a switch to say if it's type is :insert then do (.insert ....) for each of the 4 but I figured that was ugly |
| 05:24 | raek | kzar: so you want to be able to do someting like (foo :insert obj ...)? |
| 05:25 | kzar | raek: Yea pretty much I guess |
| 05:27 | thorwil | my first mail to the enlive group didn't go through for 2 days, then when i mailed again, both copies arrived immediately. now a reply on the second of them send about 11 hours ago did not appear so far :/ |
| 05:27 | kzar | raek: I think I'm just going to use a case statement on the type keyword and make it easier on myself |
| 05:27 | raek | (case action :insert (.insert ...), :update (.update ...), :query (.query ...), :delete (.delete ...)) |
| 05:27 | kzar | raek: Yep exactly! I'll try and be clever another day |
| 05:28 | kzar | raek: You see what I mean though, it feels like you should be able to go from :insert to (.insert object ..) |
| 05:28 | raek | if all the cases follow exactly the same pattern, it would be quite simple to do a (actions action [:insert :update :query :delete]) macro that expands to this |
| 05:29 | raek | kzar: any reason you don't want four separate defns? |
| 05:29 | kzar | how do you mean? |
| 05:30 | raek | (defn insert-fn [...] (.insert ...)) (defn update-fn [...] (.update ...)) etc |
| 05:31 | kzar | I guess because I've got a seq of actions and I don't know that they will all be the same type. I wanted to map over them running the same function |
| 05:31 | raek | kzar: how are you going to call the function that contains this case expression? always with a variable containing a unknown keyword or do you know the keyword? |
| 05:32 | kzar | raek: Just with a map, I could check the type of action in the mapping function though for sure |
| 05:34 | raek | something like this maybe? (def fn-map {:insert #'insert-fn, :update #'update-fn}) (map #((fn-map %1) %2) actions args) |
| 05:35 | raek | this is one way that closely fits the "to go from :insert to (.insert object ..)" description |
| 05:36 | raek | the case way would be fine too, I guess |
| 05:37 | kzar | raek: How about this, I map over the list of actions with a macro that generates the method calling code |
| 05:39 | raek | kzar: sounds good |
| 05:40 | raek | given that the method name is the only difference between the calls, of course |
| 05:40 | kzar | heh yea I'm hoping it is, if it turns out that's not the case I'll go back to using a function with a case statement me-thinks! |
| 05:44 | kzar | raek: Thanks for the ideas anyway, that was a puzzler |
| 11:12 | bartj | er, anyone with a machine learning background here ? |
| 11:22 | jamesswift | hey folks. question for those who have written some web apps in clojure. preferably with ring etc. |
| 11:25 | jamesswift | I am running my app with jetty as usual and then reverse proxying with apache. but was wondering what is the best strategy for dealing with the fact that the absolute path can be changed. issues include adjusting the routes (currently I do (str *prefix* "/my-route") and also I'm using enlive for templating, this brings problems where I need to reference css and js files. Usually one would keep a common css file in something like |
| 11:25 | jamesswift | "/css/" |
| 11:28 | jamesswift | So basically just wondering what solutions others have come up with to make this painless? |
| 11:33 | gfrlog | jamesswift: your *prefix* is the path with hostname? |
| 11:34 | gfrlog | (I just arrived, so I'm reading your comments from http://clojure-log.n01se.net/ and might be missing some) |
| 11:38 | jamesswift | gfrlog: i wrote a little wrapper which checks the incoming request to see if it's being x-forwarded and if so use binding to change *prefix* to the reverse proxy path I've set up in apache. if it's not being forwarded it remains an empty string. |
| 11:39 | jamesswift | gfrlog: all the comments are there. i probably should expand on the issue a bit. |
| 11:40 | jamesswift | gfrlog: i actually made a mistake in describing, sorry. apache reverse proxies don't change the uri so i don't change the route but i do have to change and redirects. so the *prefix* is only prepended to redirect URIs and not routes as I mentioned before. |
| 11:41 | jamesswift | gfrlog: i'll write up a code sample and pastebin it. back in 5 mins |
| 11:41 | gfrlog | jamesswift: apache is adding a prefix to your path? like a sub-uri? |
| 11:47 | jamesswift | gfrlog: Here is an example https://gist.github.com/46bd4b12e078864ccae0 |
| 11:48 | gfrlog | I think if you have to have a path prefix, that might be essentially how to handle it. The only way I can think of to make it nicer is to create a url function so you aren't repeating (str *prefix* ...) everywhere. |
| 11:48 | jamesswift | gfrlog: I'm using mod_proxy so that I have my clojure app hosted at http://examplecom/some-virt-path but really it's running on localhost:8080 for example so Apache reverse proxies /some-virt-path to localhost:8080 without changing the uri path in the headers |
| 11:49 | gfrlog | when I was doing rails I started using subdomains instead of sub-URI's precisely in order to avoid this headache |
| 11:50 | gfrlog | subdomains are transparent since you don't have to include them in the links etc. |
| 11:50 | jamesswift | gfrlog: yeah that's the only strategy I can think of too. pity. the main headache comes with having to rewrite urls in the template pages that reference common stuff like css. |
| 11:51 | jamesswift | gfrlog: the apache docs do mention a third party mod which can rewrite urls in the response html but that feels wrong |
| 11:51 | gfrlog | jamesswift: I usually find myself creating a helper function for writing urls anyhow, so if you're used to that it's not that bad |
| 11:51 | gfrlog | jamesswift: I agree that's ugly |
| 11:53 | jamesswift | gfrlog: i suspect a rule at the top of every enlive template that matches all href and src values starting with '/' might be the simplest solution right now. |
| 11:53 | gfrlog | jamesswift: I use the helper function for when some resource's ID is going into the url, so I'm not messing with (str) or (format) |
| 11:53 | jamesswift | gfrlog: makes sense |
| 13:13 | dnolen | fascinating GHC 7 uses constraint solving for type inference, http://research.microsoft.com/en-us/um/people/simonpj/papers/constraints/index.htm, CHR lead co-wrote the paper. |
| 14:31 | fliebel | dnolen: oh, nice, so Haskel is an example of these 'al la carte' type systems? |
| 14:33 | dnolen | fliebel: no. |
| 14:33 | fliebel | dnolen: Okay, then what is the type system about? |
| 14:34 | dnolen | fliebel: the paper is how generalized let creates problems for type inference and their new (even controversial) approach, it's a big break from HM style type-inference. |
| 14:43 | dnolen | fliebel: it's yet another reason I would like to see an efficient constraint solver implementation added to core.logic. interestingly enough, efficient predicate dispatch might be useful here... |
| 14:44 | fliebel | i see… |
| 14:44 | Ramblurr | is there a function that is the opposite of 'take', i.e, get the _last_ n items in a coll? |
| 14:45 | Ramblurr | something like (drop (- (count coll) n)) coll) |
| 14:45 | kzar | Ramblurr: might be a better way but you could reverse it and then take the n items |
| 14:45 | Ramblurr | oh jebus, there is a take-last |
| 14:46 | kzar | ah cool, didn't know that :) |
| 14:46 | dnolen | fliebel: maybe next year Clojure will have state-of-the-art optional static typing ... |
| 14:46 | Ramblurr | kzar: yea, found it via clojuredocs.org's "See Other" feature |
| 14:47 | fliebel | that'd be awesome, but how deep do you need to dig into clojure for that? or is it just a lot of typehints? |
| 14:49 | dnolen | fliebel: would need some kind of hook into data produced by the compiler, but it would be a very loose coupling. |
| 14:49 | fliebel | S I guess that's "waiting on the new compiler", together with some other cool stuff. |
| 15:14 | fliebel | Why does if-let not support multiple bindings? So that all bindings have an 'and' relation, with 'or' still being usable to let the first truthy case. (if-let [x true y (or false true)] [x y]) > true true |
| 15:39 | KineticShampoo | Hello |
| 15:39 | odyssomay | hello |
| 16:30 | KineticShampoo | Can someone explain what a 'higher order function' is in layman terms? |
| 16:30 | KineticShampoo | I found the term while searching for college assignments on Clojure to practice on. |
| 16:30 | KineticShampoo | http://www.cis.upenn.edu/~matuszek/cis554-2010/Assignments/clojure-01-exercises.html |
| 16:31 | KineticShampoo | ie "You don't need higher order functions" |
| 16:31 | Thorn | a function which acts on functions |
| 16:31 | kzar | KineticShampoo: It's a function that takes functions as arguments or returns functions |
| 16:32 | fliebel | &(partial + 1) |
| 16:32 | sexpbot | ⟹ #<core$partial$fn__3678 clojure.core$partial$fn__3678@27291d> |
| 16:32 | KineticShampoo | kzar: Thanks! That's a simple explanation. :) So the function uses the returns values of another function, correct? |
| 16:32 | fliebel | In this case, partial takes a function, and returns a new function with the supplied args already provided. |
| 16:33 | fliebel | &((partial + 1) 1) |
| 16:33 | sexpbot | ⟹ 2 |
| 16:33 | kzar | (defn example [f num] (f num 10)) (example * 5) = 50 (example + 5) = 15 |
| 16:34 | kzar | KineticShampoo: Yea it's all dead handy, partial is great too |
| 16:35 | Thorn | KineticShampoo: not just one that uses return values of another function. that would make most every C function higher order lol |
| 16:35 | fliebel | It's these kind of things that help writing a DSL, macros are pretty meh for most things ;) |
| 16:35 | Thorn | KineticShampoo: (defn f [a] (a 3 4)) (f +) ; takes a function (+) as an argument and applies it to 3 and 4 |
| 16:39 | Thorn | or: (defn make-adder [b] (fn [a] (+ a b))) ((make-adder 3) 7) |
| 16:43 | KineticShampoo | When I first tried Clojure on a VM I used Eclipse and I remember it having a plugin that I assume automatically installed everything for me. |
| 16:43 | KineticShampoo | Now I installed Ubuntu 11.04 and want to use Geany as my editor. So without Eclipse, how can I install Clojure? Googling has lead me to believe that the only way is to git pull from the repo on github. |
| 16:44 | maacl | This https://gist.github.com/961679 solves http://www.4clojure.com/problem/62 at my REPL but 4clojure claims wrong no. of args to comp - any ideas? |
| 16:44 | pdk` | you just need to have the two jars for clojure and clojure-contrib |
| 16:45 | pdk` | have them in your classpath and you're golden |
| 16:45 | fliebel | KineticShampoo: Have a look at Leiningen too |
| 16:45 | KineticShampoo | Is this the standard way? |
| 16:46 | fliebel | Most people use lein or cake. managing the classpath and jars yourself is uncool imo. |
| 16:47 | Thorn | maven it standard in the java world, but it downloads half of the internet on the first run |
| 16:48 | fliebel | And a tenth of the internet on each subsequent run |
| 16:49 | Thorn | *is |
| 16:55 | fliebel | Why does if-let let into a temp var and then in the truth case into the real var? Does it hurt anyone to let it right away? |
| 16:56 | fliebel | when-let is even weirder, since there is no false case. |
| 16:58 | kzar | I have (:import [java.net URL]) in my ns declaration and it was working fine until I had to restart my Clojure process. It's giving me "Unable to resolve clasname: URL" now though :o any ideas? |
| 17:05 | maacl | Has previous versions of Clojure had issues with (apply comp '()) ? |
| 17:08 | fliebel | &(comp) |
| 17:08 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$comp |
| 17:09 | fliebel | maacl: What issues? |
| 17:09 | maacl | &(apply comp '()) |
| 17:09 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$comp |
| 17:10 | fliebel | &(apply comp identity '()) ; this *might* be what you want |
| 17:10 | sexpbot | ⟹ #<core$identity clojure.core$identity@1c22e0d> |
| 17:11 | maacl | It evals fine at my REPL using 1.3.0-alpha5 |
| 17:11 | fliebel | maacl: What does it do? |
| 17:12 | fliebel | Oh, i see, just what I just typed. |
| 17:12 | fliebel | it returns identity |
| 17:12 | maacl | yes |
| 17:12 | brehaut | ,() |
| 17:12 | clojurebot | () |
| 17:13 | brehaut | fliebel: you dont need to quote the empty list |
| 17:13 | fliebel | brehaut: Oh, nice to know :) |
| 17:13 | brehaut | i keep forgetting too :) |
| 17:13 | maacl | So the behavior must have changed at some point? |
| 17:14 | fliebel | maacl: yes, it must, unless we got all rolled up in a time continuum. |
| 17:14 | fliebel | But my identity hack works around it, if you must support both. |
| 17:14 | maacl | fliebel: well, you never know |
| 17:15 | maacl | fliebel: yes, thanks |
| 17:25 | KineticShampoo | hm. |
| 17:29 | gfrlog | KineticShampoo: yep. |
| 17:33 | ekoontz | hey, question about mapcat.. |
| 17:33 | ekoontz | https://gist.github.com/961694 |
| 17:34 | ekoontz | how would i do that if i wanted to pass an additional param to cook-kids |
| 17:37 | tomoj | mapcat is just like map in that way ##(mapcat #(list %1 %2) [1 2 3] [4 5 6]) |
| 17:37 | sexpbot | ⟹ (1 4 2 5 3 6) |
| 17:37 | ekoontz | ##(mapcat #(list %1 %2) [1 2 3] [4 5 6]) |
| 17:37 | sexpbot | ⟹ (1 4 2 5 3 6) |
| 17:37 | ekoontz | thanks a lot tomoj :) |
| 17:37 | ekoontz | makes sense..the googles they did nothing |
| 17:39 | ekoontz | *cool-kids not cook-kids lol |
| 17:40 | KineticShampoo | ##mapcat #(list %1 %2) [1 2 3] [4 5] [6] [7 8 9]) |
| 17:40 | KineticShampoo | ##mapcat #(list %1 %2 %3 %4) [1 2 3] [4 5] [6] [7 8 9]) |
| 17:41 | ekoontz | thanks KineticShampoo |
| 17:43 | tomoj | of course #(list %1 %2) is a bit silly |
| 17:43 | brehaut | ekoontz: also if you are using mapcat it may be that for would be cleaner |
| 17:44 | ekoontz | brehaut: i see, thanks, tho it took me a while to parse your sentence :) |
| 17:45 | brehaut | ekoontz: sorry about that, i should have quoted the funs. i cant get to your gist at the moment so i dont know if its relevant, but 'for' is list comprehensions, which is just sugar over the list monad and mapcat is bind in the list monad |
| 17:46 | ekoontz | i am still strugging with the clojure syntax |
| 17:46 | ekoontz | use to (mapcar #'(lambda(x) ...) |
| 17:46 | ekoontz | *used |
| 17:47 | tomoj | was your example just for playing around with mapcat? |
| 17:48 | ekoontz | yeah let me try pastebin |
| 17:49 | ekoontz | sorry having pastebin problems too lol |
| 17:49 | brehaut | my internet is just extremely slow ATM |
| 17:49 | brehaut | i cant get to anything ;) |
| 17:49 | ekoontz | http://pastebin.com/FGAaq1uc |
| 17:49 | ekoontz | are we in the same cafe? ;) |
| 17:51 | tomoj | example seems strange for mapcat |
| 17:52 | raek | ekoontz: #' means something else in clojure. functions and variables share the same namespace. |
| 17:53 | ekoontz | there's no #'lambda i guess right |
| 17:53 | raek | just use fn |
| 17:53 | raek | ,(map (fn [x] (inc x)) [1 2 3]) |
| 17:53 | clojurebot | (2 3 4) |
| 17:53 | brehaut | ekoontz: heres the correspondence: (for [a (range 3) b [:a :c]] [a b]) => (m-bind (range 3) (fn [a] (m-bind [:a :c] (fn [b] (m-return [a b]))))) => (mapcat (fn [a] (mapcat (fn [b] [[a b]]) [:a :c])) (range 3)) |
| 17:53 | raek | ,(map inc [1 2 3]) |
| 17:53 | clojurebot | (2 3 4) |
| 17:54 | brehaut | (m-bind and mapcat take their args in reverse order) |
| 17:54 | ekoontz | thanks raek |
| 17:54 | ekoontz | ok..that makse sense |
| 17:54 | ekoontz | makes* |
| 17:55 | raek | ekoontz: your cool-kids example can also be written as (for [kid '(kurt bob tony), :when (= kid 'kurt)] kid) |
| 17:55 | brehaut | ekoontz: the middle form is very slightly pseudocode; it makes use of forms from the clojure.contrib.monads library |
| 17:55 | tomoj | but why? |
| 17:56 | ekoontz | brehaut: the middle form..? |
| 17:57 | brehaut | in the big block of nonsense i pasted above |
| 17:57 | ekoontz | like..never heard of (m-bind) before.. |
| 17:59 | brehaut | ekoontz: thats 'just' monads stuff; im only using it to demonstrate the corrospondence; mapcat is fairly rare in clojure code because for is cleaner |
| 17:59 | brehaut | (most of the time) |
| 17:59 | brehaut | ekoontz: m-bind is a abstraction over function application |
| 17:59 | ekoontz | the word 'monads' scares me |
| 17:59 | brehaut | yeesh s/is a/is just an/ |
| 18:00 | tomoj | ekoontz: so would you use mapcat or for to do exactly what your example does? |
| 18:00 | ekoontz | i keep hearing about it and still don't understanding it |
| 18:00 | ekoontz | i would use mapcat personally |
| 18:00 | tomoj | (that's a yes/no, not a mapcat/for question) |
| 18:00 | ekoontz | maybe because i don't know (for) |
| 18:01 | tomoj | how about ##(filter '#{kurt} '[kurt bob tony]) |
| 18:01 | sexpbot | ⟹ (kurt) |
| 18:01 | tomoj | I don't know whether the example was contrived for mapcat or whether that way was unknown |
| 18:01 | ekoontz | haven't heard of (filter) either |
| 18:01 | ekoontz | but it seems very intuitive :) |
| 18:02 | ekoontz | well i want to pass another param to the filtering function |
| 18:04 | gfrlog | ekoontz: you want to pass the first param or the second? |
| 18:35 | gfrlog | $findfn [7,8,9,10] 9 2 |
| 18:35 | sexpbot | [] |
| 18:35 | gfrlog | $findfn 9 [7,8,9,10] 2 |
| 18:35 | sexpbot | [] |
| 18:36 | gfrlog | :-| |
| 18:48 | gfrlog | $findfn [4,5,6] 5 |
| 18:48 | sexpbot | [clojure.core/second clojure.core/fnext] |
| 20:22 | sritchie | hey all -- is it possible class call some method other than -main inside of a namespace, when running java -jar my-standalone.jar my.ns arg1 arg2 |
| 20:23 | sritchie | java -jar my-standalone.jar my.ns method-name arg1 arg2, for example/ |
| 20:25 | tomoj | I don't think so, but you can have -main decide to call other functions |
| 20:26 | tomoj | `man java` says it looks for public static void main(String[] args) and that's it |
| 20:30 | sritchie | tomoj: that makes sense, I could get the same behavior by using the first argument as input to case |
| 20:31 | sritchie | thanks |
| 20:32 | tomoj | guess the problem is if you want to support passing a method-name and not, how do you tell whether it's method-name or arg1? |
| 20:35 | gfrlog | his default case would decide that it's arg1? |
| 20:40 | tomoj | sure, but if you ever want to pass an arg1 that happens to have the same name as some function in the namespace.. |
| 20:40 | gfrlog | no way out of that |
| 21:28 | KineticShampoo | FINALLY! |
| 21:29 | KineticShampoo | Finished this project tasks I had with my school software. |
| 21:29 | KineticShampoo | Now I can focus on some Clojure. Problem is I don't really know what to make with the language. Any beginner exercises you would recommend? Something to get me thinking in Clojure? |
| 21:29 | gfrlog | man some folk just set up a site for exactly that |
| 21:29 | gfrlog | it probably had a catchy name too |
| 21:30 | gfrlog | one sec I can find it... |
| 21:30 | KineticShampoo | Google? |
| 21:30 | gfrlog | wouldn't know what to google for |
| 21:30 | KineticShampoo | If you say Google I'll slap you. No matter how many proxies you're behind. |
| 21:30 | gfrlog | 4clojure |
| 21:30 | KineticShampoo | :D |
| 21:30 | KineticShampoo | Oh yeah, that's Raynes site. |
| 21:30 | gfrlog | right |
| 21:31 | gfrlog | not what you're looking for? |
| 21:31 | KineticShampoo | I used it, but while I can solve some of the problems I don't feel I'm learning; if that makes sense. |
| 21:31 | gfrlog | okay -- project euler then? |
| 21:31 | gfrlog | unless you hate math |
| 21:31 | KineticShampoo | I'm looking for a concrete assignment. The type you would get during first or second year Uni. (Yes I hate math! :D) |
| 21:32 | KineticShampoo | Is there something like Codingbat, but for Clojure? |
| 21:32 | gfrlog | I'm out of ideas. Best I can offer at this point is to think up something for you myself :) |
| 21:33 | KineticShampoo | Shoot for it. :) |
| 21:33 | KineticShampoo | Better yet, what book do you recommend for someone new? |
| 21:33 | gfrlog | okay. Write a web app that will make millions of dollars simply by virtue of the fact that it is deployed at the domain lolwaffle.com. I'll contribute the domain name and we can split the profits. |
| 21:34 | KineticShampoo | Can I use a visual basic gooey? |
| 21:34 | TheMoonMaster | Woah woah waoh, we aren't tracking IP's |
| 21:34 | gfrlog | huh? |
| 21:34 | tomoj | :D |
| 21:35 | TheMoonMaster | http://www.youtube.com/watch?v=hkDD03yeLnU |
| 21:35 | gfrlog | oh wait right |
| 21:35 | gfrlog | I should've caught that |
| 21:36 | gfrlog | KineticShampoo: my estimate is that the total number of clojure books is between two and three, inclusive. |
| 21:36 | TheMoonMaster | Macros are odd |
| 21:36 | gfrlog | TheMoonMaster: yep |
| 21:36 | KineticShampoo | LOL |
| 21:36 | TheMoonMaster | KineticShampoo: I'm reading Programming Clojure |
| 21:36 | KineticShampoo | Seriously? Only two books!? |
| 21:36 | gfrlog | KineticShampoo: I've only read one of them. |
| 21:37 | TheMoonMaster | http://pragprog.com/titles/shcloj/programming-clojure |
| 21:37 | gfrlog | KineticShampoo: ^ that was the one I read |
| 21:37 | TheMoonMaster | That is the only good one I know of. |
| 21:37 | gfrlog | it was like two years ago. I liked it. |
| 21:38 | KineticShampoo | I wish Raynes would hurry up with his book. It has a kiddie cover, it seems to be a good fit for newbies. Hehehehe |
| 21:38 | TheMoonMaster | In the beginning it does fairly well teaching the concepts, but at concurrency and macros it starts to fall behind imo. |
| 21:39 | gfrlog | TheMoonMaster: it sure taught me to avoid macros :) |
| 21:39 | TheMoonMaster | gfrlog: Yeah, prevent the whole, what the hell did I just code mentality... |
| 21:39 | gfrlog | I think only in the last six months or so have I started using macros goodly |
| 21:39 | tomoj | goodly! <3 |
| 21:39 | TheMoonMaster | I really don't have much to program due to lack of creativity in that field, but clojure is nice so far. |
| 21:40 | TheMoonMaster | I mostly do web development, and unfortunately I don't like clojure for web stuff as much as I like Ruby for it. |
| 21:40 | gfrlog | TheMoonMaster: help KineticShampoo and you two can split his half of the million |
| 21:40 | TheMoonMaster | gfrlog: Sorry, but it would end up being made in rails. |
| 21:41 | gfrlog | but OOP is so sticky |
| 21:41 | tomoj | maybe the frontend |
| 21:41 | TheMoonMaster | Ruby OOP is nice. |
| 21:41 | tomoj | you want to write the entire backend in rails too? are you doing anything interesting? :) |
| 21:41 | KineticShampoo | Does Clojure have classes? Or just lists and maps? |
| 21:41 | gfrlog | KineticShampoo: it has some differenter things. It also has the plain java classes if you need them for something awkward |
| 21:42 | tomoj | oh, I didn't read the backlog, you don't have to do anything interesting with that domain name |
| 21:42 | gfrlog | tomoj: what do I need to do then, just add adsense? |
| 21:42 | TheMoonMaster | Haha, I can't thing of anything to do with lolwaffle.com |
| 21:43 | tomoj | I dunno, it was your idea? |
| 21:43 | gfrlog | as best I can tell |
| 21:45 | gfrlog | KineticShampoo: now that I think about it, there are probably like six or eight different parts of clojure that could be given as an answer to that question, depending on what you mean by "classes" |
| 21:46 | KineticShampoo | I mean them in the traditional POJO/POCO class context. |
| 21:47 | gfrlog | as I understand it, the clojure complaint about Java OOP is that it's a pile of different concepts mashed together when you'd prefer to have them separately and take only what you need |
| 21:47 | gfrlog | so for example some java classes (Utils?) are just collections of related methods. That's what clojure namespaces do |
| 21:48 | Raynes | KineticShampoo: Man, I wish I'd hurry up with my book more than you do. |
| 21:48 | gfrlog | if I were good at explaining this stuff, I would go on to list several other concepts. But it is too humid. |
| 21:49 | KineticShampoo | Raynes get to it! Stop trolling around the F# forums. |
| 21:49 | gfrlog | Raynes: I wish for more wishes |
| 21:49 | TheMoonMaster | Just saying, I hate macros right now. |
| 21:50 | Raynes | I've been trolling F# forums? :o |
| 21:50 | gfrlog | TheMoonMaster: what're you doing? |
| 21:50 | tomoj | I really like clojure's not having arbitrary object hierarchies built up between me and the data because I almost always know how to just get the damn data |
| 21:50 | Clinteger | Raynes you’re not done with that yet? D: |
| 21:50 | Raynes | I sure wish somebody would have told me this. |
| 21:50 | TheMoonMaster | gfrlog: Reading the macros chapter, wrapping my head around this isn't easy. |
| 21:50 | Raynes | Clinteger: Man, it takes time to write a book. |
| 21:50 | Clinteger | it’s ok :p i’m only joking, you’re busier than me and i’d still be writing chapter 1 :) |
| 21:50 | gfrlog | TheMoonMaster: oh. well then. Let me try putting it this way. |
| 21:51 | KineticShampoo | Free copies for DIC members with over 500 karma? :D |
| 21:51 | gfrlog | TheMoonMaster: a macro is a function that takes code and messes with it and outputs some other code |
| 21:51 | KineticShampoo | *wink wink nudge nudge* |
| 21:51 | TheMoonMaster | Yeah, I get that much |
| 21:52 | Raynes | KineticShampoo: Not a chance. I'll probably give away a few copies with some sort of contest though. |
| 21:52 | gfrlog | TheMoonMaster: okay. Well then, I already understand macros, so why on earth does that not lead directly to you understanding them? |
| 21:52 | TheMoonMaster | lol |
| 21:52 | gfrlog | TheMoonMaster: it seems so easy!!! |
| 21:53 | TheMoonMaster | Haha, this book just doesn't teach it in a way I understand easily I suppose. |
| 21:53 | TheMoonMaster | I'll get it eventually. |
| 21:54 | gfrlog | (defmacro with-clojure [& forms] `(do ~@forms)) |
| 21:54 | TheMoonMaster | I do like the way Clojure does java integration though, that is pretty sweet. |
| 21:55 | TheMoonMaster | I have no idea what `(do ~@forms) even does |
| 21:56 | gfrlog | it does something like (cons 'do forms) |
| 21:56 | TheMoonMaster | I don't understand what `do does either. |
| 21:57 | TheMoonMaster | Sorry, I am super new to clojure |
| 21:58 | gfrlog | that's funny cause 'super' and 'new' are both keywords in Java |
| 21:58 | TheMoonMaster | Ohhhhhh, so the ` quotes the whole thing, and the ~ evaluates that and doesn't quote it! |
| 21:58 | TheMoonMaster | Haha, to be honest I really don't do much JAva |
| 21:59 | TheMoonMaster | I did Java for like a week last year for my AP CS exam in high school. |
| 21:59 | gfrlog | TheMoonMaster: yeah basically. There's an obvious and a subtle difference between ' and ` |
| 22:00 | gfrlog | by which I mean not that the difference is both subtle and obvious, but that there are two differences, and one is subtle and the other is obvious |
| 22:00 | TheMoonMaster | Haha yeah |
| 22:00 | gfrlog | and the fact that they are two different characters is not either of them |
| 22:01 | gfrlog | the obvious difference is that ` allows unquoting, which you just observed |
| 22:01 | gfrlog | the subtle one has to do with qualifying symbols, and I refuse to elaborate due to cognitive limitations |
| 22:01 | TheMoonMaster | lol alright |
| 22:02 | gfrlog | ` is used most often in macros because unquoting is so convenient |
| 22:02 | gfrlog | but you can use it anywhere |
| 22:02 | gfrlog | ,`(I have ~(+ 3 4) piles of functions) |
| 22:02 | clojurebot | (sandbox/I sandbox/have 7 sandbox/piles sandbox/of sandbox/functions) |
| 22:02 | TheMoonMaster | Idiomatically do you use ` much outside of macros? |
| 22:02 | gfrlog | I don't think I ever have |
| 22:03 | gfrlog | nor seen it |
| 22:03 | TheMoonMaster | Didn't think so. |
| 22:03 | gfrlog | probably because of that obnoxious subtle difference that clojurebot just exhibited |
| 22:03 | TheMoonMaster | lol |
| 22:04 | amalloy | i use ` in functions when the functions are helper functions used by macros |
| 22:04 | gfrlog | amalloy: I'm trying to write some code to convert clojure functions to point-free versions. Does that sound stupid or awesome or like something that already exists? |
| 22:04 | TheMoonMaster | amalloy: I can see how that makes sense. |
| 22:04 | amalloy | because you don't (usually) break macros up into N smaller macros, you break them up into N functions and one master macro |
| 22:05 | amalloy | $google amalloy macro writing macros |
| 22:05 | sexpbot | First out of 38 results is: Clojure: macro-writing macros |
| 22:05 | sexpbot | http://hubpages.com/hub/Clojure-macro-writing-macros |
| 22:05 | amalloy | TheMoonMaster: ^ is my blog entry on it |
| 22:05 | gfrlog | $google amalloy babies having babies |
| 22:05 | sexpbot | First out of 86 results is: Dr. Stephen A. Malloy |
| 22:05 | sexpbot | http://www.rootsweb.ancestry.com/~ncccha/biographies/stephenamalloy/stephenamalloy.html |
| 22:05 | gfrlog | well that's enlightening |
| 22:05 | TheMoonMaster | Definitely bookmarking your site |
| 22:05 | amalloy | wth |
| 22:06 | gfrlog | sorry, I'm apparently in a strange mood tonight |
| 22:07 | gfrlog | hmm. that is a rather strange search result. |
| 22:08 | TheMoonMaster | lol |
| 22:08 | TheMoonMaster | So are clojure agents similar to Scala actors? |
| 22:09 | gfrlog | are scala actors similar to those erlang things? |
| 22:09 | TheMoonMaster | Yeah |
| 22:09 | gfrlog | okay. then I think the answer is no |
| 22:09 | gfrlog | but it might be yes |
| 22:09 | TheMoonMaster | Alright, I'll do some research, just curious if anyone had a fast answer. |
| 22:10 | brehaut | TheMoonMaster: typically actors define their operations internally (based on some sort of data message) whereas agents hold data and have the operations defined externally (as some sort of behavioural message) |
| 22:10 | TheMoonMaster | brehaut: Thanks for the clarification |
| 22:11 | brehaut | TheMoonMaster: clojure's agents also use a thread pool for executing on by default where as (at least conceptually in erlang) the agents have their own thread or process (typically lightweight) |
| 22:13 | TheMoonMaster | Makes sense, might be a jvm limitation |
| 22:13 | brehaut | its a design decision; agents and actors fullfil quite different design roles |
| 22:15 | TheMoonMaster | I suppose that is due to the functional nature of clojure |
| 22:15 | brehaut | not really |
| 22:15 | TheMoonMaster | Oh, I'm super new to functional programming beyond map reduce and filter |
| 22:15 | amalloy | TheMoonMaster: you are making a lot of statements of the form "i assume X" but have stated you don't know a lot about the domain. probably best to keep those crazy ideas to yourself for a while |
| 22:15 | amalloy | or at least ask about them rather than state them |
| 22:16 | TheMoonMaster | amalloy: Sorry about that, I'll keep that in mind |
| 22:46 | KineticShampoo | Do you guys use the counterclockwise plugin for eclipse? |
| 22:46 | tomoj | TheMoonMaster: I was a rubyist at your age ;) |
| 22:46 | tomoj | took me some years after to find clojure though, you've got a head start on me |
| 22:47 | TheMoonMaster | tomoj: Oh yeah? I find a lot of similarities in the philosophies between ruby and clojure. I am really loving it so far. |
| 22:47 | amalloy | KineticShampoo: some do |
| 22:47 | amalloy | most use emacs |
| 22:47 | TheMoonMaster | KineticShampoo: I use vim, it's nice with vimclojure |
| 22:48 | TheMoonMaster | tomoj: Do you use Ruby anymore? Or have you switched to using mostly clojure or some other language? |
| 22:49 | tomoj | if I have a choice I use clojure, ruby only for chef, python and php because people pay me |
| 22:50 | TheMoonMaster | Haha, I use PHP because people pay me. |
| 22:50 | tomoj | sucks eh? |
| 22:50 | TheMoonMaster | Yeah, I am used to it though, it was my first language. |
| 22:51 | tomoj | mine too I suppose, but that only reinforces my disgust. plus I had a good 4 years or so without ever having to look at it |
| 22:52 | TheMoonMaster | After I understood programming concepts and whatnot I kinda ditched PHP to learn other languages, then a about 3/4 years later I had to reunite with PHP. |
| 22:55 | amalloy | php is my most-recent language. it's not a happy language |
| 22:55 | TheMoonMaster | Haha, most certainly not. |
| 22:55 | TheMoonMaster | Whenever I can I try to use CodeIgniter to ease the pain |
| 22:56 | TheMoonMaster | And other times I am tortured by the horrible creation called wordpress plugins |
| 22:56 | TheMoonMaster | Writing those is the most annoying thing I have ever done programming wise. |
| 23:01 | carllerche | amalloy: eh, why did you learn PHP? |
| 23:02 | amalloy | carllerche: job |
| 23:02 | carllerche | amalloy: are you in SF? |
| 23:02 | amalloy | for now |
| 23:02 | carllerche | you should let me buy you a beer sometime for all the help :) |
| 23:22 | tomoj | TheMoonMaster: have you written any drupal modules? |
| 23:22 | TheMoonMaster | tomoj: Have not, never been a fan of drupal |
| 23:24 | tomoj | try never to :) |
| 23:25 | TheMoonMaster | tomoj: I think the rule of thumb is try to avoid PHP altogether. lol |
| 23:36 | zrilak | I've just been reminded of the difference between "evaluate" and "yield" by this block of code: (if-let [foo (...)] (handle normally) (throw (RuntimeException. (...)) What is the Clojure way to fire an exception in this case? |
| 23:37 | zrilak | Do I just split it into (let [...] (if ...)) ? |
| 23:38 | amalloy | zrilak: huh? that code looks fine; perhaps you can clarify what you want? |
| 23:38 | zrilak | amalloy: if-let does not evaluate the "else" form; I want the exception to be thrown at the time when "if-let" is evaluated, not lazily |
| 23:39 | zrilak | or am I horribly misunderstanding something? |
| 23:39 | amalloy | haha that apparently confused me so much i /parted |
| 23:40 | zrilak | I assumed you hit C-k in the wrong frame |
| 23:40 | amalloy | &(if-let [x nil] (prn x) (throw (Exception. "OMG x is false"))) |
| 23:40 | sexpbot | java.lang.Exception: OMG x is false |
| 23:40 | amalloy | zrilak: it already does what you want, is what i am getting at |
| 23:40 | zrilak | hrm, gotcha |
| 23:40 | zrilak | then it's obviously the "me not digging things right" case :) |
| 23:40 | amalloy | or, at any rate, what you are saying you want. it's never safe to assuming those are the same thing :) |
| 23:40 | zrilak | thanks |
| 23:40 | zrilak | true, true |
| 23:41 | zrilak | but again, your patience is limitless. Thanks :) |
| 23:45 | TheMoonMaster | Anyone see/use clojure atlas? |
| 23:46 | zrilak | I tried it, it's nifty, if a bit buggy |
| 23:46 | TheMoonMaster | Yeah, it does seem a bit buggy |
| 23:47 | TheMoonMaster | I don't think that was the best way to implement an API browser. |
| 23:47 | TheMoonMaster | But it was awesome |
| 23:47 | zrilak | Probably not, but it's good that people are experimenting with paradigms |
| 23:47 | TheMoonMaster | Yeah, it was an interesting concept |
| 23:52 | zrilak | I haven't had so much fun learning a new language since Oberon |
| 23:53 | TheMoonMaster | Haha, it feels almost like another ruby to me. |
| 23:53 | TheMoonMaster | Which is a good thing |
| 23:54 | zrilak | it's driving me crazy, though, I *know* there are macros and functions that can cut down my code and increase readability, but I just can't bring myself to stop typing and start reading, until I hit a hitch. |
| 23:55 | zrilak | I like to evaluate docs lazily |
| 23:56 | TheMoonMaster | lol, I'm just trying to take it slow and understand clojure. |
| 23:56 | tomoj | cemerick made it? |
| 23:56 | tomoj | atlas, I mean |
| 23:56 | tomoj | or coincidentally someone else named chas? |
| 23:57 | amalloy | tomoj: cemerick |
| 23:57 | tomoj | now I feel bad for clicking "I don't want to buy" |
| 23:58 | zrilak | buy the book instead :) |
| 23:58 | tomoj | which one? |
| 23:58 | zrilak | http://www.amazon.com/Clojure-Programming-Chas-Emerick/dp/1449394701 |
| 23:59 | TheMoonMaster | I am definitely getting that when it's released. |
| 23:59 | zrilak | though I've ordered "The Joy of Closure", seems denser |