2010-12-30
| 00:15 | Gigaroby | guys someone knows a good jetty hosting (possibly free ) |
| 00:31 | AWizzArd | Bing / Google brought nothing up? |
| 00:33 | Gigaroby | no nothing on google that's why I asked |
| 00:34 | technomancy | cheap shared hosts don't usually support Java |
| 00:34 | technomancy | too much memory |
| 00:38 | Derander | prgmr.com has a fairly cheap ($20/mth) 1gb vps |
| 00:38 | Derander | and several cheaper & smaller plans |
| 01:02 | joshua__ | I have a question about cond. |
| 01:03 | joshua__ | How do I make it look less ugly? Every time I use it I'm horrified by the way the code looks. I know that is sort of off. It like.. smells bad or something. |
| 01:03 | joshua__ | example: http://pastebin.com/GZGZAfp8 |
| 01:05 | technomancy | meh; I'm not too fond of cond either |
| 01:06 | technomancy | what you probably want is more than one function |
| 01:07 | amalloy | joshua__: i agree that the formatting for cond doesn't feel right; i wonder if emacs behaves that way because the CL cond looks like (cond ((< a 1) (inc a)) ((something?) (something))) |
| 01:09 | joshua__ | In that case.. How hard would it be to change the indent to give an indent after cond conditionals? |
| 01:10 | amalloy | joshua__: i tried to change indentation once and i went blind for a month |
| 01:11 | amalloy | seriously though, i didn't try for more than an hour or so. if you figure it out, i've got another change i'd like you to make |
| 01:11 | joshua__ | I might look into it haha. |
| 01:12 | joshua__ | Seriously it would be a really nice to have an indent for cond conditionals. Or to phrase that another way.. I just edited my code to put in that indent and it doesn't look as ugly or smell as funny. |
| 01:13 | joshua__ | What change would you want amalloy? |
| 01:13 | joshua__ | Not saying I'm going to try this but I am curious. |
| 01:14 | amalloy | joshua__: try ((comp - +) a<NEWLINE>b) |
| 01:14 | amalloy | b should line up with a, but it lines up with (comp |
| 01:14 | joshua__ | that is ugly... |
| 01:15 | joshua__ | I can look into if I decide to risk my eyes. |
| 01:15 | joshua__ | If I do it won't be tonight. |
| 01:15 | amalloy | sure, no hurry |
| 01:16 | joshua__ | I'm going to try and finish up a script to write bot plugins tonight for that C++ bot I made. Planning on trying to sell them ;) |
| 01:18 | joshua__ | Ooo.. and so that I don't forget to mention. I bought Paradigms of AI Programming by Peter Norvig with some Christmas Barnes N Noble giftcards today =) |
| 02:18 | seancorfield_ | technomancy: AWizzArd: Derander: on the subject of cheap hosting... you could point folks at stax.net / cloudbees... pretty sure their web templates include a jetty option |
| 02:18 | seancorfield_ | (sorry i'm two hours late on that - wasn't paying attention earlier) |
| 02:19 | Derander | I forgive you |
| 02:19 | seancorfield_ | lol |
| 02:22 | hoeck | q |
| 02:30 | Berengal | What are agents best for? |
| 02:32 | amalloy | Berengal: not many things |
| 02:33 | LauJensen | Berengal: logging |
| 02:33 | Berengal | How about single-threaded use of a single shared resource? |
| 02:33 | amalloy | Berengal: no |
| 02:34 | LauJensen | Berengal: Not many concurrency challenges in single-threaded mode |
| 02:34 | amalloy | i mean, the right answer is tautological: agents are best for managing an identity that changes values over time, and which you want to manipulate asynchronously from multiple threads |
| 02:34 | Berengal | I meant a resource that can only be used by one thread at a time |
| 02:35 | LauJensen | hehe, ok. It depends on whether you want in sync or async, atoms/agents |
| 02:35 | Berengal | amalloy: That answer doesn't have any information in it though. Those who know will understand it, but those who don't won't understand any better after hearing it ;) |
| 02:35 | amalloy | Berengal: like i said, tautological. agents are best for what agents are best for |
| 02:35 | LauJensen | Berengal: Ive been telling him that for months, but he refuses to read my blog :) |
| 02:36 | amalloy | i've never found a good use for agents personally |
| 02:36 | amalloy | JoC shows a good use of them for, as LauJensen says, logging |
| 02:37 | Berengal | Logging is a bit too simplistic. I refuse to believe that's all they're good for ;) |
| 02:37 | LauJensen | Berengal: They are also the preferred method when you need a side-effect inside of a transaction, but now we're fishing :) |
| 02:37 | amalloy | Berengal: what kind of "shared resource" did you have in mind? |
| 02:39 | Berengal | Okay, here's a scenario I'm thinking about where I thought maybe agents would be useful: There's a program managing workflows. These workflows have many tasks, both concurrent and sequential, essentially forming a graph. The task-performing is done out-of-process... |
| 02:39 | Berengal | Basically, the program receives a workflow, sends out tasks to be performed async, then stores the state |
| 02:40 | Berengal | At any point any of the tasks sent could be returned. Handling these return messages (updating state, sending out new tasks) needs to be done single-threaded per workflow |
| 02:41 | Berengal | The problem with the system we have now is that it's both dog-slow and uses locks all over the place |
| 02:41 | Berengal | dog-slow because it has to hit the database on each message, and some workflows have lots of small messages that return "instantly" |
| 02:43 | amalloy | Berengal: so you imagine the agent being, say...a map of (pending-task => status) pairs, or something? |
| 02:45 | Berengal | amalloy: No, I imagine the agent containing the workflow, so on each message you send it off to the agent containing that workflow. Every message would be processed sequentially, but you'd get away from the locking while fetching the workflow |
| 02:45 | Berengal | Basically the receiver thread would just dispatch the handling to the agents |
| 02:46 | Berengal | (The entire core system runs in several processes so I can't use clojure agents directly, but I'm trying to model/prototype a new version, and agents are easy to lift to the process level) |
| 02:47 | seancorfield_ | i just went and read the agents page on clojure.org and the example makes no sense to me :( |
| 02:47 | amalloy | Berengal: what data would each agent contain? would it change over time? |
| 02:47 | Berengal | amalloy: yes. workflow-state -> new-workflow-state |
| 02:48 | seancorfield_ | so i'm fascinated by this discussion because i don't understand what agents are good for :) |
| 02:48 | amalloy | seancorfield_: neither do we! |
| 02:49 | Berengal | Eh, crap, I need to leave for work. I should join the mailinglist or something... |
| 02:49 | amalloy | Berengal: hm. well, sounds good so far, but i'm not exactly an agent expert |
| 02:49 | amalloy | i think it needs fleshing out but doesn't sound crazy |
| 02:50 | Berengal | Maybe plain message passing instead of clojure-agents are a better way of modeling the concurrency... |
| 04:22 | ejackson | Morn'n |
| 05:04 | ordnungswidrig | hi all |
| 05:24 | auser | hola ordnungswidrig |
| 05:37 | ordnungswidrig | anybody using hiccup? I'm annoyed by the vector+keyword syntax. Any reason why hiccup does not use s-expressions? |
| 05:41 | auser | is there a way to get a handle on the function that is currently running in? For instance... (fn [] (println (str "Running in the function handle: " (this-func)))) |
| 05:43 | raek | auser: you can get a reference to the function object: (fn f [] (println (str "Running in the function handle: " f))) |
| 05:44 | auser | yep! Just found that in the clojure docs. Thanks for the heads up raek :) |
| 05:44 | raek | ,((fn f [] (str f))) |
| 05:44 | auser | :) |
| 05:44 | clojurebot | "sandbox$eval1061$f__1062@4f1ada" |
| 05:45 | raek | np |
| 07:30 | mids | why is the #' reader macro used for (run-jetty #'adder.core/app ...) and (def app (-> #'handler ...)) in http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html ? |
| 07:32 | nickik | because you want tu pass the var itself |
| 07:33 | nickik | and not the thing that is in the var |
| 07:33 | nickik | why they programm it that way i dont know |
| 07:35 | mids | nickik: it also works when I just use the symbol. which is also what mark uses in some of his other ring documentation |
| 07:35 | nickik | mids: then i cant help you sry. |
| 07:35 | mids | TIMTOWTDI? :) |
| 07:37 | fbru02 | hey guys, i was looking at this http://clojuredocs.org/clojure_core/clojure.core/take-while , in the example , i don't get the cond (partial > 1000) why '>' ? |
| 07:37 | fbru02 | shouldn't it be lesser? |
| 07:39 | mids | ,((partial > 1000) 999) |
| 07:39 | clojurebot | true |
| 07:39 | arbscht | fbru02: x<1000 is equivalent to 1000>x |
| 07:40 | fbru02 | arbscht: mids : thanks (stupid me ! ) :) |
| 08:37 | sexpbot | Thanks to the excellent and hard work of amalloy, the weird "clojail.core/tester is unbound" bug with lazy sequences has been fixed. This has been a public service announcement by your friendly neighborhood IRC bot. |
| 08:41 | pazu | hey guys, what would you recommend for someone who's been trying to learn clojure for a couple of weeks? |
| 08:42 | pazu | toy projects, exercises... I'm really liking clojure, but I can't find a way to use it on my day job, making it harder to progress. |
| 08:44 | mids | pazu: I enjoyed doing http://codingkata.org/ |
| 08:44 | pazu | hm, I like the title. |
| 08:44 | ejackson | pazu: Project Euler helped me along |
| 08:47 | mids | pazu: also given your extensive java experience you could create a clojure wrapper for your favorite java library |
| 08:48 | mids | that might also be a good way to start sneaking some clojure into your day job |
| 08:48 | pazu | hm, that might work |
| 08:49 | mids | make it opensource, document your effort in your blog and you might even get some valuable feedback |
| 08:49 | ejackson | mids: nice idea |
| 08:50 | pazu | a Spring MVC bridge to clojure or something like that |
| 08:50 | pazu | certainly a lot of work, but that might be exactly what I need. |
| 08:51 | cemerick | pazu: I've been toying with doing the same for spring-security |
| 08:52 | cemerick | Lots of goodness in there, but its usage of XML as the (essentially) exclusive path to configuration is infuriating. |
| 08:55 | pazu | god, yes |
| 08:55 | pazu | I hope one day people will understand that XML is not a programming language. |
| 08:58 | cemerick | I have no problem with the XML app context route in general. I just want to be able to throw together a security context programmatically without having to read spring sources to figure out the correspondence between the reference material (which uses XML exclusively) and the actual components. |
| 10:10 | ejackson | is this really what it should look like ? |
| 10:10 | ejackson | (-> @requests keys ((partial apply min)) inc) |
| 10:10 | ejackson | I keep falling over the pattern for partialing on apply |
| 10:11 | ejackson | ((...)) seems like a disturbance in the force |
| 10:11 | ejackson | (and looks like a tie fighter, which is never good) |
| 10:12 | tonyl | I don't know what you are trying to do, but shouldn't it just be (partial apply min) |
| 10:12 | ejackson | tony... no that won't actually execute... |
| 10:13 | ejackson | ,(-> [1 20 12 -2] (partial apply max) inc) |
| 10:13 | clojurebot | java.lang.ClassCastException: clojure.core$partial$fn__3680 cannot be cast to java.lang.Number |
| 10:13 | ejackson | ,(-> [1 20 12 -2] ((partial apply max)) inc) |
| 10:13 | clojurebot | 21 |
| 10:13 | tonyl | yeah i see the error now |
| 10:14 | ejackson | all I want is a function that looks like (partial apply max) |
| 10:15 | cemerick | ,(-> (range 10) (apply max) inc) |
| 10:15 | clojurebot | java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn |
| 10:16 | cemerick | ,(->> (range 10) (apply max) inc) |
| 10:16 | clojurebot | 10 |
| 10:16 | tonyl | so @request returns a vector or a map |
| 10:16 | cemerick | ejackson: is that what you want? ^^ |
| 10:16 | ejackson | tonyl: yup |
| 10:16 | ejackson | cemerick: I believe so :) |
| 10:16 | tonyl | cemerick is right |
| 10:16 | ejackson | cemerick: i get it, thanks :) |
| 10:17 | btw0 | what is "#^" as seen in ,(if-let [#^String type (:content-type req)] ...) ? |
| 10:17 | ejackson | cemerick: i knew it looked sideways |
| 10:17 | cemerick | ejackson: if you want the TIE-fighter... |
| 10:17 | cemerick | ,(->> (range 10) ((apply partial max)) inc) |
| 10:17 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$max |
| 10:17 | cemerick | hrm |
| 10:18 | tonyl | btw0, that is how you assign a meta tag info before 1.2 version |
| 10:18 | btw0 | tonyl: ah i see, in 1.2 it's just "^String", right? |
| 11:32 | jkn2 | can someone show the the syntax for destructuring a vector in a function parameter? seems like all the examples i find are maps and i can't get it right |
| 11:33 | @rhickey | ,((fn [[a b]] [b a]) [1 2]) |
| 11:33 | clojurebot | [2 1] |
| 11:33 | jkn2 | rhickey: from the man himself :) thanks! |
| 12:22 | ejackson | wow - extending objects to protocols even works :) Just extended DateTime to WriteJSON. Beautiful :) |
| 12:25 | kaiser | hi, guys |
| 12:25 | Guest33465 | i'm trying to replace an element in a vector like that |
| 12:25 | Guest33465 | (replace [:a 2] [:a 2 3 4]) |
| 12:26 | Guest33465 | but it seems not working with keywords |
| 12:26 | Guest33465 | sorry |
| 12:26 | Guest33465 | i found my mistake |
| 12:26 | Guest33465 | i have to pass a map |
| 12:26 | Guest33465 | as first argument to replace |
| 12:29 | dnolen | ejackson: even better it's not monkey-patching. your extensions are local. |
| 12:29 | ejackson | I'm smiling :) |
| 12:31 | cemerick | dnolen: we'll have to return to the question of a preference mechanism soon. :-) |
| 12:31 | cemerick | if the class ejackson was looking to extend WriteJSON to implemented j.u.Collection, he'd be far less happy. |
| 12:32 | ejackson | cemerick: how would that have poked me in the eye ? |
| 12:33 | cemerick | ejackson: WriteJSON is extended by default to j.u.Collection to emit a JSON array containing the JSON serializations of the collection's elements. Your local extension wouldn't be picked up. |
| 12:34 | ejackson | gotcha - in both senses. |
| 12:34 | cemerick | Or, actually, since the iteration order is undefined, your local extension would be picked up *sometimes*. |
| 12:35 | cemerick | ejackson: there's a lively thread on this topic here: http://groups.google.com/group/clojure-dev/browse_frm/thread/fb3a0b03bf3ef8ca |
| 12:35 | ejackson | thanks, I'll give it a read. |
| 12:36 | cemerick | I've been thinking about it and working around the problem in various unpleasant ways in the meantime. I've been secretly hoping rhickey would jump in in the interim, before I open my mouth again anyway. :-) |
| 12:36 | dnolen | cemerick: yeah, I may change my position on that :) but my concern still stands, it's slippery slope allowing people to build crazy hierarchies. |
| 12:38 | cemerick | dnolen: Yeah, I see your point, which is why I went quiet for a while. In the end though, I want that rope! ;-) |
| 12:40 | cemerick | I remember Rich saying something about the potential for default protocol implementations (part of his answer to "mixins" (variously defined)) that might include some answer to the desire for a preference mechanism. |
| 13:10 | Berengal | How's clojure's interop with Java EE containers? |
| 13:39 | cemerick | Berengal: what sort of interop are you looking for? |
| 13:40 | Berengal | cemerick: Mainly running ejbs in containers |
| 13:40 | cemerick | There are definitely people doing EJB dev using clojure. |
| 13:41 | Berengal | Do you know how that's working out? |
| 13:41 | cemerick | Berengal: Seems pretty straightforward: http://www.deepbluelambda.org/programming/clojure/building-ejbs-with-clojure |
| 13:41 | Berengal | Thanks :) |
| 14:07 | leafw_ | hi all |
| 14:08 | leafw_ | are there any guidelines for the proper way to type-hint methods in a reify or defrecord, or any documentation on type hints at all? |
| 14:12 | cemerick | leafw_: http://clojure.org/java_interop#Java%20Interop-Type%20Hints |
| 14:13 | leafw_ | cemerick: yes, that's the official one, and very brief. It does not cover deftype, defrecord, reify |
| 14:13 | cemerick | leafw_: what's your question, specifically? |
| 14:13 | leafw_ | for example: does one add type hints to the actual method implementation, or to the protocol, or to the interface defintion, or where. |
| 14:14 | pdk | i dunno if there's anything in the online docs |
| 14:14 | cemerick | hints are no-ops on protocols at the moment |
| 14:14 | pdk | though i've read practical clojure which does talk about type hints on their own and within protocols |
| 14:14 | pdk | or records whichever |
| 14:15 | leafw_ | in 1.3, hints are no-ops on protocols? |
| 14:17 | leafw_ | if so, good to know. Thanks. |
| 14:18 | cemerick | leafw_: yes |
| 14:18 | cemerick | leafw: if you absolutely need a typed interface, there's definterface, which can be hinted as you like. |
| 14:21 | leafw | cemerick: ok, and then if an interface is typed, do I need to type the record methods that implements the interface? |
| 14:22 | leafw | and is the interface then type-agnostic if not typed? |
| 14:26 | amalloy | leafw: without typehints, the interface methods will be Foo.bar(Object, Object), Foo.baz(Object), ... |
| 14:27 | cemerick | leafw: if the interface being implemented is typed, then types, records, and reified instances will have their implementing methods typed as well. |
| 14:27 | leafw | amalloy: thanks. |
| 14:28 | leafw | cemerick: ok, so typing needs to be done only once then. |
| 14:28 | cemerick | Right. |
| 14:28 | cemerick | leafw: this is for interop purposes, I presume? |
| 14:28 | leafw | cemerick: yes |
| 14:29 | cemerick | Just making sure ;-) |
| 14:29 | leafw | cemerick: I assume that for protocols, types are passed along on their own |
| 14:29 | cemerick | "passed along"? |
| 14:29 | leafw | hum |
| 14:29 | leafw | too much assuming |
| 14:29 | leafw | can a protocol be typed? |
| 14:29 | leafw | you said it's a no-op |
| 14:30 | cemerick | right, that means the corresponding generated interface is untyped (Objects all around) |
| 14:30 | leafw | I hope someday they will be typed |
| 14:30 | cemerick | Protocol implementations do get their first arg hinted automatically, FWIW. |
| 14:30 | leafw | otherwise one must write plenty of (let ..) to add type hints |
| 14:31 | leafw | their first arg being the "this" or "self". |
| 14:31 | leafw | well at leas tthat. |
| 14:31 | cemerick | I'm guessing they will be typed eventually (outside of the first arg) |
| 14:31 | cemerick | leafw: just add type hints in the argument vector. No need for a separate let form. |
| 14:31 | leafw | 1.3 is still alpha4, perhaps for 1.3 beta. |
| 14:32 | leafw | in the argument vector of the implementing method. Will then the interface match? |
| 14:32 | cemerick | No -- why would a type hint in an implementing method change a previously-generated interface? |
| 14:33 | amalloy | cemerick: i think leafw means, won't type-hinting the implementing method cause a mismatch with the un-hinted interface |
| 14:33 | amalloy | answer: no, it won't |
| 14:33 | cemerick | ah! |
| 14:33 | cemerick | leafw: what amalloy said ^^ :-) |
| 14:34 | cemerick | sorry, I had a brutal conversation earlier today that now has me thinking that no one knows what they're talking about :-( |
| 14:34 | amalloy | cemerick: a fair assumption most of the time, anyway |
| 14:34 | leafw | o problem :) |
| 14:35 | leafw | amalloy: thanks, so no mismatch. |
| 14:35 | cemerick | amalloy: I try mightily to not be so cynical. |
| 14:35 | amalloy | cemerick: a sisyphian task sometimes, but worth the effort :) |
| 14:36 | cemerick | Especially in this job! ;-) |
| 14:36 | cemerick | sisyphusian, more like :-) |
| 14:37 | amalloy | cemerick: http://mw2.m-w.com/dictionary/sisyphian |
| 14:37 | leafw | also .. definterface typing requires fully qualified class names. It tries to do "java.lang.Collection", for example, when given "^Collection". Looks like an error. |
| 14:38 | amalloy | leafw: even if you import java.util.Collection first? |
| 14:38 | leafw | yes |
| 14:39 | cemerick | amalloy: wow -- I never knew his name lost a phoneme in that form |
| 14:41 | leafw | http://clojure.pastebin.com/CXU466B8 |
| 14:41 | leafw | that is surprising |
| 14:41 | leafw | oops |
| 14:41 | leafw | wait, I saw *my* error |
| 14:43 | leafw | ok great, it does find the improper object passed. |
| 14:44 | kumarshantanu | hi all |
| 14:44 | kumarshantanu | when in a macro how do you pass fn body to another macro? |
| 14:47 | amalloy | kumarshantanu: that's a vague question. could you maybe make a gist/pastie of what you wish would work? |
| 14:51 | kumarshantanu | amalloy: here -- http://pastebin.com/wMGGD7Zy |
| 15:01 | cemerick | kumarshantanu: splice in bar, too, since you're gathering body as a rest arg |
| 15:03 | kumarshantanu | cemerick: splicing inside bar works...i am trying to do this inside a bigger macro where it's gining me -- java.lang.IllegalStateException: Var clojure.core/unquote is unbound. |
| 15:03 | kumarshantanu | s/gining/giving/ |
| 15:03 | sexpbot | <kumarshantanu> cemerick: splicing inside bar works...i am trying to do this inside a bigger macro where it's giving me -- java.lang.IllegalStateException: Var clojure.core/unquote is unbound. |
| 15:04 | kumarshantanu | I will try and post another example |
| 15:04 | cemerick | kumarshantanu: then the splice isn't in a quasiquoted form |
| 15:05 | kumarshantanu | cemerick: I don't understand that, can you give an example? |
| 15:06 | cemerick | &(let [a 5] [~a]) |
| 15:06 | sexpbot | java.lang.IllegalStateException: Var clojure.core/unquote is unbound. |
| 15:06 | cemerick | vs… |
| 15:06 | cemerick | &(let [a 5] `[~a]) |
| 15:06 | sexpbot | ⟹ [5] |
| 15:09 | kumarshantanu | cemerick: I see...will fiddle a bit more -- let me post the entire code |
| 15:11 | kumarshantanu | cemerick: it's here http://pastebin.com/scrHkADr |
| 15:11 | cemerick | kumarshantanu: there's no quasiquote in with-connection |
| 15:13 | kumarshantanu | cemerick: oops...sorry, not sure how I overlooked that! |
| 15:13 | cemerick | :-) |
| 15:25 | cemerick | amalloy: funny, that's usually my job ;-) |
| 15:26 | amalloy | cemerick: btw, quasiquote? i thought we called it syntax-quote |
| 15:27 | cemerick | amalloy: old habits die hard, I guess |
| 15:30 | cemerick | amalloy: I wonder where the syntax-quote term came from, actually. I only see it mentioned in conjunction with clojure in a cursory googling. |
| 15:32 | amalloy | cemerick: i don't know about where it came from, and i wasn't familiar with quasiquote before, but it made sense to me because it namespace-qualifies things |
| 15:33 | amalloy | ie, it's not just a quote, it's a quote that tidies up your syntax somehow |
| 15:36 | cemerick | amalloy: "quasiquote" is a scheme-ism AFAIK; "backquote" is the CL term |
| 15:36 | amalloy | yeah, backquote is what i'd heard of |
| 15:37 | cemerick | "syntax-quote" is perhaps more sensible to those not familiar with the concept at all…? |
| 15:37 | cemerick | i.e. at least tenuously indicates the semantics |
| 15:37 | amalloy | *shrug* |
| 15:40 | @rhickey | yes, I thought syntax-quote was more descriptive, and needed to be different from backquote since it behaves differently |
| 15:40 | cemerick | rhickey: thanks :-) |
| 15:43 | cemerick | rhickey: it must be a little surreal (/thrilling/annoying) to have hordes of people pouring over one's work so thoroughly and constantly |
| 15:43 | @rhickey | cemerick: yes |
| 15:44 | amalloy | cemerick: augh, if you like words, plz poring, not pouring |
| 15:44 | cemerick | heh |
| 15:44 | cemerick | amalloy: noted, thank you :-) |
| 15:50 | mduerksen_ | since i see all the overminds gathered here :) , i'd like to ask a question which is keeping me thinking for a while: what tool should i use to build abstractions: macros or protocols? |
| 15:51 | cemerick | mduerksen_: those are entirely orthogonal tools |
| 15:51 | cemerick | In general, avoid macros. |
| 15:51 | cemerick | Or, if you can do something with functions, there's no need to touch macros. |
| 15:53 | LauJensen | mduerksen_: Again, I refer you to Christophes slides from the Conj Conf |
| 15:53 | mduerksen_ | to explain: i'm new to lisp, and while i do have made some macros and love them, i'm not sure how to use them appropiately when it comes to abstractions. are the meant to be used for that? pgraham and other lisp advocates seem to have used them, but seeing the slides of "macros not= dsl" made me think |
| 15:54 | ordnungswidrig | mduerksen_: i see macros as a whay to abstract control flow. if-then-else or try-finally can be abstracted away by macros. |
| 15:54 | ordnungswidrig | s/whay/way/ |
| 15:54 | sexpbot | <ordnungswidrig> mduerksen_: i see macros as a way to abstract control flow. if-then-else or try-finally can be abstracted away by macros. |
| 15:55 | qbg | macros = syntax sugar |
| 15:56 | cemerick | mduerksen_: macros are roughly useful when you want to (a) control execution (b) front-load computation to compile-time, and (c) define syntax. |
| 15:56 | cemerick | s/and/or |
| 15:56 | sexpbot | <cemerick> mduerksen_: macros are roughly useful when you want to (a) control execution (b) front-load computation to compile-time, or (c) define syntax. |
| 15:58 | mduerksen | sorry, my connection broke :( did anyone respond to my question? |
| 15:59 | cemerick | heh |
| 15:59 | cemerick | mduerksen: http://clojure-log.n01se.net/#15:50 |
| 16:00 | amalloy | mduerksen: http://www.raynes.me/logs/irc.freenode.net/clojure/today.txt |
| 16:00 | amalloy | is updated in real-time; n01se lags behind a little bit |
| 16:01 | cemerick | amalloy: that *might* be called efficient write-behind ;-) |
| 16:02 | cemerick | Raynes: your logger doesn't like UTF... |
| 16:02 | amalloy | cemerick: i didn't say there isn't a good reason for it; but when i opened your link it was missing at least one of the answers to his question. it's not so hot for up-to-the-second logs |
| 16:02 | cemerick | amalloy: I know, I was just being cheeky ;-) |
| 16:02 | amalloy | cemerick: wow, you're right about utf |
| 16:03 | cemerick | I should say, non-ASCII |
| 16:04 | cemerick | testing: é 旗 فص |
| 16:04 | cemerick | hrm, even the low ISO-level stuff |
| 16:05 | mduerksen | thanks everyone :) my connection tends to break exactly when i depend on it... |
| 16:05 | amalloy | cemerick: i suspect the issue is that it just doesn't put the UTF marker at the beginning of the file |
| 16:05 | cemerick | amalloy: the page is being served up with ISO-8859 of all things |
| 16:05 | cemerick | right |
| 16:05 | cemerick | well, it's actually straight text, not HTML |
| 16:06 | amalloy | sure |
| 16:19 | LauJensen | Guys, over the past couple of days Ive written some code which has become a surprisingly awesome CMS system. I plan to release a pre-beta soon - Any ideas for a name? |
| 16:20 | ossareh | LauJensen: "precious" > |
| 16:20 | ossareh | ? |
| 16:20 | LauJensen | Not manly enough :) |
| 16:20 | ossareh | CMS's are male? huh... |
| 16:20 | cemerick | manly? o_O |
| 16:21 | amalloy | LauJensen: gollum? he keeps preciouses |
| 16:21 | ossareh | Genghis |
| 16:23 | mduerksen | LauJensen: what's it's main focus? storage or collaboration? |
| 16:24 | ossareh | lol.. the internet has everything: http://www.cracked.com/article_14982_the-9-manliest-names-in-world.html - "Dick Pound" is the manliest real name on the list. |
| 16:24 | LauJensen | mduerksen: You supply design templates, which contain a "<div id="content"/>" and then you get a markdown editor which generates live previews. Once you're happy hit "generate site" and it spits out a static site generated from your markdown and your templates. I hope to launch clojureql.org soon using this tool |
| 16:24 | LauJensen | (for which purpose I wrote it) |
| 16:25 | LauJensen | ossareh: I quite like "Staff Sgt. Max Fightmaster" :) |
| 16:26 | lancepantz | *cough* notice who's name is on that list *cough* *cough* |
| 16:27 | lancepantz | "It's impossible to hear this name without picturing many men getting impaled on a battlefield" |
| 16:27 | LauJensen | lancepantz: But we knew you were a real mans man, even before the list though :) |
| 16:27 | lancepantz | :P |
| 16:28 | technomancy | vlad the impaler. |
| 16:28 | Raynes | cemerick, amalloy: I'm aware. I don't particularly care. People whine about sexpbot's arrow like it's my fault that they use bad fonts all the time. |
| 16:28 | lancepantz | heh, best name for a deployment tool ever |
| 16:28 | amalloy | Raynes: no, that's not the issue |
| 16:29 | amalloy | raynes.me is serving the UTF-8 file with the wrong text-encoding |
| 16:29 | lancepantz | LauJensen: you should call it 'duke' that's a manly name |
| 16:29 | LauJensen | lancepantz: true, its hard to beat duke.. How about 'Serious CMS' ? :) |
| 16:29 | lancepantz | i like that too |
| 16:30 | Raynes | amalloy: Once again, I'm aware. |
| 16:30 | ossareh | 'Serious CMS' is a bit too ... serious ? |
| 16:30 | Raynes | amalloy: I was just pointing out that people don't like my pretty arrow anyway. |
| 16:30 | LauJensen | ossareh: But you know what they say 'Double your gun, double your fun'. That would be the slogan |
| 16:30 | ossareh | LauJensen: *chuckle* |
| 16:30 | mduerksen | LauJensen: brew-it-yourself, cooke, tausendsassa (german for allrounder, one can do everything) |
| 16:30 | Raynes | I thought it was handsome. |
| 16:31 | ossareh | unfortunately it seems technomancy has the monopoly on cool names for things - I can't get over "radagast" - awesome. |
| 16:31 | lancepantz | heh, you should replace the arrow with ⟹ in the channel as well |
| 16:31 | lancepantz | just really grind on people |
| 16:32 | LauJensen | ossareh: Well, Phil is plagarizing anything he finds in litterature :) |
| 16:32 | ossareh | I think I'm going to call my next set of projects prime numbers. |
| 16:32 | ossareh | "seventy three", etc. |
| 16:32 | ossareh | LauJensen: which is fair game, as long as you're not reading "Barbie: the life story" and naming your software "Ken" :) |
| 16:33 | LauJensen | hehe, true |
| 16:33 | lancepantz | ossareh: think that's how microsoft product managers name their phones? |
| 16:34 | technomancy | oh, I have a free name that I almost used a while back that's up for grabs |
| 16:34 | technomancy | Lupus Yonderboy |
| 16:34 | technomancy | from Neuromancer |
| 16:34 | technomancy | head of the Panther Moderns |
| 16:34 | cemerick | Raynes: What does the arrow have to do with the encoding sent for the log file? |
| 16:34 | technomancy | dunno if it's good for a CMS, but there it is |
| 16:34 | Raynes | cemerick: Zoom. That's the sound of everything I've said going over your head. ;) |
| 16:34 | ossareh | so many good names in those gibson novels |
| 16:35 | lancepantz | i like 'Panther Moderns' better |
| 16:35 | technomancy | lancepantz: yeah, that's pretty good |
| 16:35 | LauJensen | I shall call it simply 'Glen Beck' |
| 16:35 | technomancy | they are a quasi-terrorist organization though, so you may not want those associations |
| 16:35 | ossareh | "Etiquette" is a cool name. |
| 16:35 | LauJensen | technomancy: Well, I dont live in the US so I guess I shouldnt be afraid of being incarserated in definitely without trial |
| 16:35 | cemerick | Raynes: this was a bikeshedding issue? |
| 16:35 | lancepantz | hehe, clj-panther-moderns, coming soon |
| 16:36 | technomancy | LauJensen: heh, lucky you =) |
| 16:36 | LauJensen | Yea we have a few desirable things in Europe after all, you know like civil liberties and stuff :) |
| 16:37 | mduerksen | LauJensen: eckstein (german for cornerstone), boxit, you-name-it, sushi, yello, sandwish, imp... |
| 16:37 | ossareh | mduerksen: I definitely liked "tausendsassa" |
| 16:38 | mduerksen | ossareh: thank you, i hoped one would hit ;) |
| 16:39 | ossareh | LauJensen: how about a recursive acronym? or is that too late 90's ? |
| 16:39 | LauJensen | ossareh: Naah that never gets old :) |
| 16:43 | ossareh | wow... those are hard to think up though huh... best I've done: FMS - FMS Markup Scripter |
| 16:43 | qbg | Apply the Y combinator to a recursive acronym |
| 16:47 | mduerksen | LauJensen: Gepetto (pinocchio's woodcarver) |
| 16:48 | mduerksen | wait, he's written Geppetto |
| 16:49 | LauJensen | Ok, considering :) |
| 16:51 | ossareh | "primordial soup" |
| 16:52 | ossareh | whence content originates |
| 16:57 | mduerksen | LauJensen, cemerick: sorry i still can't let go of the macro topic :) if i understand it correctly, the reason why macros should be used with care is roughly this: once they are written, they're not flexible to change, and don't work together nicely with other language features (since it's an own mini-language) |
| 16:58 | mduerksen | do i have the right picture? |
| 16:59 | lancepantz | mduerksen: as i understand it, the downside to macros is that they are not composable |
| 16:59 | cemerick | mduerksen: roughly, yes. The inflexible point is a little murky in your telling, but it's definitely true that depending upon macros means you can't use them like you use functions. |
| 16:59 | LauJensen | Right. Macros are solely for when you MUST control evaluation of items in the argumentlist. It should be a rare requirement |
| 17:01 | cemerick | cemerick: from an author's perspective, they're almost always *way* more rope than you need at any time. |
| 17:01 | LauJensen | wow, cemerick talking to himself in public... unexpected |
| 17:01 | cemerick | hrm, so I am |
| 17:02 | cemerick | the psychiatric disorders have made their appearance! :-P |
| 17:03 | LauJensen | The XML was the first symptom! |
| 17:04 | lancepantz | lol |
| 17:04 | lancepantz | we knew something was wrong when he wouldn't shut up about maven |
| 17:04 | mduerksen | cemerick: with unflexible i mean: clojure is well designed, and unless you design your mini-language just as well, you will run into problems when using it outside it's own definition. and even if you would try to do so (i.e. design the mini-language well), the entire purpose of a mini-language is to be limited to a small subset of problems, so it will never be so flexible as clojure itself |
| 17:05 | cemerick | funny, I thought I'd shut up about maven months ago… |
| 17:05 | lancepantz | :P |
| 17:05 | mduerksen | i hope that wasn't to philosophical, it's a new topic to me, so it indeed is a little blurry :) |
| 17:07 | LauJensen | I have to duck out, thanks everybody for giving me some name inspiration, I appreciated all the manly suggestions :) |
| 17:07 | mids | LeatherCMS |
| 17:07 | lancepantz | hahah |
| 17:08 | dnolen | mduerksen: macros don't just support mini-languages. Racket has many fairly fleshed out variants (typed, lazy, Prolog) built entirely upon macros. |
| 17:10 | cemerick | mduerksen: what dnolen said. |
| 17:10 | cemerick | You can do amazing things with macros, as long as you have really thought through your usage. |
| 17:11 | cemerick | Part of that is making sure that macros are getting you enough bang for your buck to make it worth losing functional composition, etc. |
| 17:13 | mduerksen | cemerick: yes, and that is hard to find out if you start from scratch. dnolen: i haven't heard of racket yet, is there some code if can dive into? |
| 17:13 | qbg | http://racket-lang.org/ |
| 17:14 | qbg | It was PLT-Scheme |
| 17:14 | qbg | It has a lot of amazing stuff in it. |
| 17:16 | mduerksen | qbg, cemerick, dnolen: thanks. seeing some code which has maxed out the possibilities of macros will be very helpful to grasp the scope of that topic. i don't wan't to miss out something ;) |
| 17:17 | qbg | If you want to be scared, take a look at the source of for in Clojure |
| 17:17 | cemerick | mduerksen: I think someone was working on a reimplementation of CL's LOOP in Clojure. That's sure to be pretty epic. |
| 17:18 | qbg | ITERATE would be nicer |
| 17:18 | dnolen | mduerksen: Clojure itself is the result of many macros. |
| 17:20 | KirinDave | cemerick: If you've got clojure-type aware combinator parsers, it's not so hard. |
| 17:20 | KirinDave | cemerick: Unlike most ad-hoc macros which break horribly, Loop actually has error semantics. |
| 17:20 | KirinDave | cemerick: So some sort of more-formal-than-most parsing is mandated. |
| 17:20 | mduerksen | dnolen: yes, i've already seen some of them, but they don't seem to be a prototype for abstraction rather than flow-control (the preferred usage of macros which i get know) |
| 17:21 | qbg | The syntax-parse stuff in my syntax-rules implementation should make parsing loop easy also |
| 17:21 | cemerick | KirinDave: yeah, there's various parsec impls floating around |
| 17:21 | KirinDave | I wish everyone would do it that way, tbh |
| 17:22 | KirinDave | The way that clojure makes macro errors somewhat opaque means that some formalism wouldn't hurt there. |
| 17:23 | dnolen | mduerksen: ? macros are a form of abstraction. |
| 17:23 | KirinDave | Like, I remember working with Enlive and not lein wasn't including the resource dir as a valid source to the jvm. |
| 17:23 | amalloy | ,(binding [doc dec] #'doc) |
| 17:23 | clojurebot | #'clojure.core/doc |
| 17:23 | KirinDave | So it wasn't finding the template file |
| 17:23 | amalloy | why doesn't that print dec? |
| 17:23 | KirinDave | And how clojure reported this was by just barfing and not passing up the file-not-found exception. :( |
| 17:24 | amalloy | ,(binding [doc dec] (#'doc 1)) ; but this prints 0? |
| 17:24 | clojurebot | 0 |
| 17:24 | qbg | My almost complete defn implementation gives better error messages that Clojure's does in some cases: https://gist.github.com/757885 |
| 17:28 | mduerksen | dnolen: ok the word abstraction is too unspecific, i meant it more in the sense of data and capability characteristics (or something like that) |
| 17:32 | mids | why is the #' reader macro used for (run-jetty #'adder.core/app ...) and (def app (-> #'handler ...)) in http://mmcgrana.github.com/2010/07/develop-deploy-clojure-web-applications.html ? |
| 17:32 | mids | it also works when I just use the symbol, this is also what mark uses in some of his other ring documentation. can you explain me the difference? |
| 17:33 | amalloy | mids: if someone rebinds app later, #'app will pick up the new meaning, while app will still refer to the old value |
| 17:34 | mids | so #' is typically used during development? |
| 17:34 | mids | (in this context) |
| 17:35 | qbg | ,(binding [doc dec] (println #'doc (= @#'doc dec))) |
| 17:35 | clojurebot | #'clojure.core/doc true |
| 17:36 | amalloy | qbg: ah, i think i see |
| 17:36 | qbg | binding changes the value, not the name! |
| 17:36 | amalloy | ,(binding [doc dec] (println @#'doc doc)) |
| 17:36 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/doc |
| 17:37 | amalloy | ,(binding [doc dec] (println @#'doc)) |
| 17:37 | clojurebot | #<core$dec clojure.core$dec@1962534> |
| 17:41 | mids | I dont quite understand the clojurebot samples in relation to this |
| 17:42 | Raynes | mids: His testing is entirely unrelated to your questions. |
| 17:42 | Raynes | I think it was just bad timing. |
| 17:42 | mids | ah :) |
| 18:07 | qbg | Hopefully just one remaining issue to solve with my syntax-rules library |
| 18:07 | qbg | The extra features generate *so* many edge cases |
| 18:08 | qbg | But they are so useful |
| 18:09 | qbg | I also need to HDD a better templating system some day, but not for the first release |
| 18:15 | qbg | I wonder if the Racket people are working on something like that... |
| 18:15 | lancepantz | is there a way to break out of an infinite loop in a slime repl without killing swank-clojure? |
| 18:15 | qbg | (or already have something) |
| 18:15 | qbg | C-c C-c |
| 18:16 | qbg | Should also be in the menu |
| 18:17 | lancepantz | thanks qbg |
| 19:08 | ossareh | qbg: what is your syntax rules lib? |
| 19:20 | amalloy | ossareh: he's implementing scheme's syntax-rules macro system in clojure. i don't know a lot about scheme, but i gather the idea is to make the simple "template with some blanks to fill in" macro case easier/clearer |
| 19:52 | cemerick | LauJensen: That's a very unfortunate blog post of yours. :-( |
| 20:05 | qbg | ossareh: It makes tearing apart expressions with complex grammars easy and allows you to fill in templates |
| 20:05 | qbg | Useful for many macros that are just a layer of sugar above functions |
| 20:06 | qbg | and more complicated things |
| 20:43 | scottj | dnolen: what's the "design for async code" project you mentioned on HN? |
| 20:44 | dnolen | scottj: http://dev.clojure.org/display/design/Channels, and stuartsierra's work on cljque |
| 20:44 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.Exception: 503> |
| 21:58 | amalloy | clojurebot: did hiredman break you, or are you just enjoying exceptions? |
| 21:58 | clojurebot | http://paste.lisp.org/display/74305 |
| 21:59 | amalloy | thanks. that's really helpful |