2008-07-04
| 00:16 | arbscht | I have to chime in as well, I think you're on to a winner, rhickey_ :) |
| 00:16 | arbscht | I've had a really fun week hacking in clojure |
| 00:17 | rhickey_ | great! |
| 01:08 | abrooks | When I have the form: (apply and '(true false true)) |
| 01:09 | abrooks | It evaluates to the expanded macro form: (clojure/let [and__160 false] (if and__160 (clojure/and true false) and__160)) |
| 01:09 | abrooks | Not the expected value: false |
| 01:09 | abrooks | Of course I can get this by evaling the resultant form: (eval (apply and '(true false true))) |
| 01:09 | abrooks | But that's not what I was expecting. Are my expectations wrong? Is something broken? |
| 01:09 | slava | well, apply is generally not supported for macros |
| 01:10 | slava | clojure should raise an error there |
| 01:11 | abrooks | It seems reasonable to want to apply to (and ) as an operator. Should apply really be a macro so it can take macros? |
| 01:11 | slava | the problem with passing macros to apply is that you'd have to invoke the evaluator at runtime |
| 01:11 | slava | if you have a list, and you want to test if all elements are true, you should use another function |
| 01:12 | slava | instead of applying and |
| 01:13 | abrooks | Hm. True. |
| 01:14 | arohner | (every? identity '(true true true)) |
| 01:16 | abrooks | Or, perhaps more clear expression: (every? true? '(true true true)) |
| 01:16 | abrooks | slava, arohner: Thanks for your help. I really wasn't thinking there. |
| 01:17 | arohner | I do like true? better. I didn't know it was there |
| 01:17 | abrooks | It's more computation I think but I am given to favor the human over the CPU. :) |
| 01:18 | slava | i would think the compiler would produce equivalent code for both |
| 01:18 | arohner | hah. There aren't too many premature optimizers in a lisp forum :-) |
| 01:18 | abrooks | :-D |
| 01:18 | slava | but i develop compilers, so that i don't have to prematurely optimize the application itself ;) |
| 01:19 | slava | 0.5% improvements to the code generator add up over time |
| 01:19 | arohner | definitely |
| 01:19 | abrooks | Yep. And you're not making your code harder to maintain to do so. |
| 01:20 | slava | well, you want to keep the compiler maintainable too :) |
| 01:20 | slava | (see: gcc) |
| 01:20 | abrooks | True enough. |
| 01:20 | slava | i've found the best way to do that is to structure it into as many passes as possible, keeping each pass simple and independently testable |
| 01:21 | abrooks | Ian Lance Taylor presented a plan for gcc to be written in C++. |
| 01:21 | slava | i'm hoping something based on llvm replaces gcc eventually |
| 01:21 | slava | i've found so many bugs in gcc :( |
| 01:22 | abrooks | slava: Shark is based on LLVM IIRC. |
| 01:22 | slava | the profiler? |
| 01:22 | slava | there's something called clang, but its not ready yet |
| 01:22 | abrooks | Shark the icedtea JIT. |
| 01:22 | slava | ah |
| 01:23 | abrooks | Yeah, here it is: http://gbenson.net/?p=83 |
| 01:23 | arohner | so shark is based on LLVM, but it outputs JVM bytecode? |
| 01:23 | slava | it consumes JVM bytecode |
| 01:23 | slava | and outputs x86/ppc/whatever |
| 01:23 | arohner | oh, interesting |
| 01:23 | slava | llvm is not really a vm in any sense of the word |
| 01:23 | abrooks | It's JITing ... yeah, bytecode to native. |
| 01:24 | slava | its a compiler where the input is an AST for a low level language that you construct directly using the llvm api |
| 01:24 | slava | so its sort of like generating C then compiling with gcc, except its simpler/saner than C, and there's no text printing/parsing involved |
| 01:24 | arohner | cool |
| 01:25 | arohner | it's always irritated me that Java is not self hosting |
| 01:25 | arohner | and now my new favorite lisp (clojure) basically never will be self hosting |
| 01:25 | slava | javac is self hosting |
| 01:26 | arohner | sun's JVM is not |
| 01:27 | arohner | IIRC, there's a lot more code in the JVM than javac |
| 01:28 | arohner | even excluding libraries |
| 01:28 | slava | i understand that |
| 08:24 | cgrand | Hi rhickey. I noticed that (drop 0 x) returns x and not (seq x) |
| 08:24 | rhickey | I'll look at that |
| 08:26 | cgrand | thanks, drop-while behaves similarly (when the predicate is false on the first element) |
| 08:30 | rhickey | cgrand: fixed - thanks for the report |
| 08:31 | cgrand | thanks, yw |
| 11:18 | icey | cgrand: sorry for giving you crap on reddit :D |
| 11:24 | cgrand | icey: I promise I'll never check reddit just before going to bed again |
| 11:25 | icey | cgrand: if it's worth anything at all, it gave me a good laugh - i recognized your name from either here... or news.yc or google groups or something ;) |
| 11:27 | cgrand | and my answer to the original question is IBM RPG :-) |
| 11:31 | icey | so, for an actual Clojure question; have any of you guys deployed a Clojure app out into the wild yet? |
| 11:31 | icey | as in, a production release |
| 11:35 | Chouser | I haven't really, although the clojure-log.n01se.net is produced by a clojure app. |
| 11:37 | icey | it's a terribly cool language; i'd love to use it for some stuff, but most of the code i write anymore ends up in a production system and i'd rather wait until a few people have experienced some loads with it ;) |
| 11:38 | Chouser | are you using Java currently? |
| 11:58 | Chouser | icey: if you're already using Java, you could introduce a little clojure at the edges and see how it does for you. |
| 11:58 | icey | unfortunately, i'm not a java guy at all |
| 11:59 | Chouser | yeah, me either. |
| 11:59 | icey | but you're right, and that's what i'll end up doing - I'll find some tiny throwaway project that needs to get written and use Clojure for it |
| 12:01 | icey | we're in the process of moving away from the microsoft stack at my office right now; once we get settled into apache land, it will be easier |
| 12:01 | Chouser | interesting. |
| 12:02 | Chouser | we're so deeply into C++ at work, that I don't see how to bring in any significant Clojure there. |
| 12:05 | icey | Ahh that's too bad... I'm very fortunate - our main application is written in vb.net 1.1, which I took over last year. It's half a million lines of code, 90% of which is boilerplate. So we're getting ready to move it one chunk at a time to a newer framework that has better abstractions. |
| 12:06 | icey | I would have loved to use a Lisp, but I would far prefer Clojure to SBCL for example... The ability to use the Java stack for serving and the java toolchain is too attractive to pass up |
| 12:06 | icey | instead, we'll probably end up using seaside or something in python for now |
| 13:25 | rhickey | Anyone going to try ICFP in Clojure? Unfortunately, it's not yet a supported language, but they say they are open to others. I'll be traveling so can't participate: http://www.icfpcontest.org/rules.html |
| 13:30 | Chouser | hm, I might be able to join a team. anyone else? |
| 16:25 | kotarak | Hmm.. Will metadata be extended to arbitrary types? |
| 16:25 | rhickey | not likely |
| 16:27 | rhickey | I don't 'own' the other types, so I can't add it; don't want to wrap everything; and associating metadata with identity maps has different semantics |
| 16:27 | kotarak | I'm looking for a way to attach some tag (for multimethod invokation) to an arbitrary value. But I don't see a way to do it. Metadata would work perfectly. |
| 16:29 | kotarak | Maybe that's a sign, that I should do it differently in clojure. |
| 16:56 | Chouser | Would it be a bad idea to take strings produced by prn-str and save them into a relational database? |
| 16:56 | rhickey | what's in the strings? |
| 16:56 | Chouser | maps. hashes of strings and vectors |
| 16:57 | rhickey | opaque to the db? |
| 16:57 | Chouser | stuff that, if I were to normalize my database, would require a half-dozen tables. |
| 16:57 | Chouser | yeah, it'd have to be opaque -- no useful way to query for things I didn't pull out into their own columns ahead of time. |
| 16:57 | kotarak | When there are fn's somewhere in the structures there is a problem, I presume. |
| 16:58 | Chouser | yeah, I don't need fn's in there. |
| 16:58 | rhickey | I think it's the normal db story - it's technically wrong schema-wise, but you can pull anything out into a column or related table if you needed |
| 16:59 | rhickey | I really like Clojure read/print format as an interop/wire format |
| 16:59 | jcrites | Chouser: practically speaking that kind of stuff is useful to do.... you might want to skip the DB though |
| 16:59 | jcrites | just go for something like a BDB |
| 16:59 | Chouser | I'm still just flailing with disk-storage. I don't like having to unpack all my nice data structures into piles of loosly-connected tables, but I also don't like realtional/object models. |
| 16:59 | jcrites | you'd get a lot better performance from a key-value pair oriented DB |
| 17:00 | jcrites | Chouser: check out BerkeleyDB |
| 17:00 | Chouser | jcrites: yeah, good point. |
| 17:01 | Chouser | when reading these kinds of data structures, is it more efficient to do just (read) than something that also evals, like load-file? |
| 17:01 | rhickey | you should only need read |
| 17:01 | jcrites | you could also explore an online solution.... like Google Bigtable or Amazon SDB |
| 17:01 | rhickey | an advantage of read/print vs json eval |
| 17:02 | Chouser | so just read would be faster? |
| 17:03 | rhickey | definitely - read is the first phase of load, but then there's a whole analysis phase, then eval |
| 17:03 | Chouser | I've dabbled with using a triple-db (RDF) as another way to avoid both object/relational and pure relational tables. |
| 17:03 | Chouser | rhickey: ok, thanks. I think when I've done this before I did (load-file). |
| 17:04 | Chouser | hm.. (read) would be safe too, from a tainted-data point of view. No Java calls or re-defining root vars. |
| 17:05 | rhickey | that's what I meant re: json eval |
| 17:05 | Chouser | jcrites: would feel a little silly to have transactions in memory but not in my database. ;-) |
| 17:06 | rhickey | read yields data and you're done |
| 17:06 | jcrites | hmmm, how will you need them? |
| 17:06 | jcrites | BDBs do support transactions luckily :) |
| 17:06 | jcrites | well |
| 17:06 | jcrites | not exactly transactions. I forget exactly what |
| 17:07 | Chouser | maybe having STM means I wouldn't need transactions in the db. |
| 17:11 | Chouser | rhickey: in ants.clj at the top of render you "rip through" the board to copy the state into a vector. You'd still get correct results if your transaction encompassed the whole of render instead, right? |
| 17:12 | Chouser | But I'm guessing other threads would block or have more restarts if you did it that way? |
| 17:13 | jcrites | hard to say ... have to know what your usage pattern is like |
| 17:14 | rhickey | Chouser: it's reading, so it won't impede anyone else. But _it_ would have more retries itself, as it would have a longer isolation window |
| 17:14 | Chouser | could it starve complete? no, because you have "barging" or something, right? |
| 17:15 | rhickey | It's a reader, so it doesn't lock, so it doesn't barge... |
| 17:16 | rhickey | the way longer running readers get covered is, each time they have to retry, they increase the history window for the ref for which the transaction aborted... |
| 17:16 | rhickey | eventually history windows will adapt to become long enough for he read patterns... |
| 17:17 | rhickey | that's the idea anyway - that's the multiversion part of MVCC |
| 17:17 | rhickey | each ref can keep multiple old values to satisfy readers |
| 17:18 | Chouser | man. ok. |
| 17:18 | rhickey | it's pretty neat |
| 17:19 | rhickey | but no reason to stress it when you know what's going on - get in, get out |
| 17:20 | Chouser | sure, just trying to understand. |
| 17:20 | rhickey | :) |
| 17:38 | Chouser | A ref has a linked list of values it's had, each timestamped? |
| 17:38 | rhickey | sort of |
| 17:39 | rhickey | just as many values as dynamically called for, normally only one |
| 17:40 | Chouser | ok. gotta run. thanks! |
| 17:41 | rhickey | sure |