#clojure log - May 08 2011

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

1:03 TheMoonMaster: STM is amazing.

4:20 kzar: Can you perform dynamic method calls without creating a macro?

4:41 thorwil: kzar: do you mean somehow arriving at the name of a function as a string, then call it?

4: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?

4: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

4:47 guess an alternative to a macro might be eval

5:07 raek: kzar: (clojure.lang.Reflector/invokeInstanceMethod object "method name" (to-array [arg1 arg2 ...]))

5:13 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.

5:17 kzar: raek: Ah right, actually which approach is more idiomatic?

5: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

5:19 that will be compiled into a invokevirtual JVM bytecode instruction

5:20 a reflective call will be far mor slower, but sometimes you simply do not know class+method until at runtume

5: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

5:24 raek: kzar: so you want to be able to do someting like (foo :insert obj ...)?

5:25 kzar: raek: Yea pretty much I guess

5: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 :/

5:27 kzar: raek: I think I'm just going to use a case statement on the type keyword and make it easier on myself

5:27 raek: (case action :insert (.insert ...), :update (.update ...), :query (.query ...), :delete (.delete ...))

5:27 kzar: raek: Yep exactly! I'll try and be clever another day

5:28 raek: You see what I mean though, it feels like you should be able to go from :insert to (.insert object ..)

5: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

5:29 kzar: any reason you don't want four separate defns?

5:29 kzar: how do you mean?

5:30 raek: (defn insert-fn [...] (.insert ...)) (defn update-fn [...] (.update ...)) etc

5: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

5: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?

5:32 kzar: raek: Just with a map, I could check the type of action in the mapping function though for sure

5:34 raek: something like this maybe? (def fn-map {:insert #'insert-fn, :update #'update-fn}) (map #((fn-map %1) %2) actions args)

5:35 this is one way that closely fits the "to go from :insert to (.insert object ..)" description

5:36 the case way would be fine too, I guess

5:37 kzar: raek: How about this, I map over the list of actions with a macro that generates the method calling code

5:39 raek: kzar: sounds good

5:40 given that the method name is the only difference between the calls, of course

5: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!

5:44 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 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 "/css/"

11:28 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 (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 gfrlog: all the comments are there. i probably should expand on the issue a bit.

11:40 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 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 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 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 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 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 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 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 I found the term while searching for college assignments on Clojure to practice on.

16:30 http://www.cis.upenn.edu/~matuszek/cis554-2010/Assignments/clojure-01-exercises.html

16:31 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 &((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 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 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 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 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 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 Oh, i see, just what I just typed.

17:12 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 But my identity hack works around it, if you must support both.

17:14 maacl: fliebel: well, you never know

17:15 fliebel: yes, thanks

17:15 * fliebel goes to bed wiser than he was 5 minutes ago.

17:25 KineticShampoo: hm.

17:29 gfrlog: KineticShampoo: yep.

17:33 ekoontz: hey, question about mapcat..

17:33 https://gist.github.com/961694

17:34 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 makes sense..the googles they did nothing

17:39 *cool-kids not cook-kids lol

17:40 KineticShampoo: ##mapcat #(list %1 %2) [1 2 3] [4 5] [6] [7 8 9])

17:40 ##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 use to (mapcar #'(lambda(x) ...)

17:46 *used

17:47 tomoj: was your example just for playing around with mapcat?

17:48 ekoontz: yeah let me try pastebin

17:48 * ekoontz also having gist connection problems

17:49 ekoontz: sorry having pastebin problems too lol

17:49 brehaut: my internet is just extremely slow ATM

17:49 i cant get to anything ;)

17:49 ekoontz: http://pastebin.com/FGAaq1uc

17:49 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 ,(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 ok..that makse sense

17:54 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 needs a while to digest this stuff..thanks to you guys ;)

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 (most of the time)

17:59 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 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 but it seems very intuitive :)

18:02 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 $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 $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 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 `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 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 Finished this project tasks I had with my school software.

21:29 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 it probably had a catchy name too

21:30 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 Oh yeah, that's Raynes site.

21:30 gfrlog: right

21:31 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 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 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 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 I should've caught that

21:36 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 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 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 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 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 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 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 Haha, to be honest I really don't do much JAva

21:59 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 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 the obvious difference is that ` allows unquoting, which you just observed

22:01 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 but you can use it anywhere

22:02 ,`(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 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 $google amalloy macro writing macros

22:05 sexpbot: First out of 38 results is: Clojure: macro-writing macros

22:05 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 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 hmm. that is a rather strange search result.

22:08 TheMoonMaster: lol

22:08 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 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 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 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 most use emacs

22:47 TheMoonMaster: KineticShampoo: I use vim, it's nice with vimclojure

22:48 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 Whenever I can I try to use CodeIgniter to ease the pain

22:56 And other times I am tortured by the horrible creation called wordpress plugins

22:56 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 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 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 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 true, true

23:41 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 I don't think that was the best way to implement an API browser.

23:47 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 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 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 atlas, I mean

23:56 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

Logging service provided by n01se.net