#clojure logs

2008-07-04

00:16arbschtI have to chime in as well, I think you're on to a winner, rhickey_ :)
00:16arbschtI've had a really fun week hacking in clojure
00:17rhickey_great!
01:08abrooksWhen I have the form: (apply and '(true false true))
01:09abrooksIt evaluates to the expanded macro form: (clojure/let [and__160 false] (if and__160 (clojure/and true false) and__160))
01:09abrooksNot the expected value: false
01:09abrooksOf course I can get this by evaling the resultant form: (eval (apply and '(true false true)))
01:09abrooksBut that's not what I was expecting. Are my expectations wrong? Is something broken?
01:09slavawell, apply is generally not supported for macros
01:10slavaclojure should raise an error there
01:11abrooksIt seems reasonable to want to apply to (and ) as an operator. Should apply really be a macro so it can take macros?
01:11slavathe problem with passing macros to apply is that you'd have to invoke the evaluator at runtime
01:11slavaif you have a list, and you want to test if all elements are true, you should use another function
01:12slavainstead of applying and
01:13abrooksHm. True.
01:14arohner (every? identity '(true true true))
01:16abrooksOr, perhaps more clear expression: (every? true? '(true true true))
01:16abrooksslava, arohner: Thanks for your help. I really wasn't thinking there.
01:17arohnerI do like true? better. I didn't know it was there
01:17abrooksIt's more computation I think but I am given to favor the human over the CPU. :)
01:18slavai would think the compiler would produce equivalent code for both
01:18arohnerhah. There aren't too many premature optimizers in a lisp forum :-)
01:18abrooks:-D
01:18slavabut i develop compilers, so that i don't have to prematurely optimize the application itself ;)
01:19slava0.5% improvements to the code generator add up over time
01:19arohnerdefinitely
01:19abrooksYep. And you're not making your code harder to maintain to do so.
01:20slavawell, you want to keep the compiler maintainable too :)
01:20slava(see: gcc)
01:20abrooksTrue enough.
01:20slavai'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:21abrooksIan Lance Taylor presented a plan for gcc to be written in C++.
01:21slavai'm hoping something based on llvm replaces gcc eventually
01:21slavai've found so many bugs in gcc :(
01:22abrooksslava: Shark is based on LLVM IIRC.
01:22slavathe profiler?
01:22slavathere's something called clang, but its not ready yet
01:22abrooksShark the icedtea JIT.
01:22slavaah
01:23abrooksYeah, here it is: http://gbenson.net/?p=83
01:23arohnerso shark is based on LLVM, but it outputs JVM bytecode?
01:23slavait consumes JVM bytecode
01:23slavaand outputs x86/ppc/whatever
01:23arohneroh, interesting
01:23slavallvm is not really a vm in any sense of the word
01:23abrooksIt's JITing ... yeah, bytecode to native.
01:24slavaits a compiler where the input is an AST for a low level language that you construct directly using the llvm api
01:24slavaso 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:24arohnercool
01:25arohnerit's always irritated me that Java is not self hosting
01:25arohnerand now my new favorite lisp (clojure) basically never will be self hosting
01:25slavajavac is self hosting
01:26arohnersun's JVM is not
01:27arohnerIIRC, there's a lot more code in the JVM than javac
01:28arohnereven excluding libraries
01:28slavai understand that
08:24cgrandHi rhickey. I noticed that (drop 0 x) returns x and not (seq x)
08:24rhickeyI'll look at that
08:26cgrandthanks, drop-while behaves similarly (when the predicate is false on the first element)
08:30rhickeycgrand: fixed - thanks for the report
08:31cgrandthanks, yw
11:18iceycgrand: sorry for giving you crap on reddit :D
11:24cgrandicey: I promise I'll never check reddit just before going to bed again
11:25iceycgrand: 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:27cgrandand my answer to the original question is IBM RPG :-)
11:31iceyso, for an actual Clojure question; have any of you guys deployed a Clojure app out into the wild yet?
11:31iceyas in, a production release
11:35ChouserI haven't really, although the clojure-log.n01se.net is produced by a clojure app.
11:37iceyit'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:38Chouserare you using Java currently?
11:58Chousericey: if you're already using Java, you could introduce a little clojure at the edges and see how it does for you.
11:58iceyunfortunately, i'm not a java guy at all
11:59Chouseryeah, me either.
11:59iceybut 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:01iceywe'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:01Chouserinteresting.
12:02Chouserwe're so deeply into C++ at work, that I don't see how to bring in any significant Clojure there.
12:05iceyAhh 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:06iceyI 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:06iceyinstead, we'll probably end up using seaside or something in python for now
13:25rhickeyAnyone 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:30Chouserhm, I might be able to join a team. anyone else?
16:25kotarakHmm.. Will metadata be extended to arbitrary types?
16:25rhickeynot likely
16:27rhickeyI 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:27kotarakI'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:29kotarakMaybe that's a sign, that I should do it differently in clojure.
16:56ChouserWould it be a bad idea to take strings produced by prn-str and save them into a relational database?
16:56rhickeywhat's in the strings?
16:56Chousermaps. hashes of strings and vectors
16:57rhickeyopaque to the db?
16:57Chouserstuff that, if I were to normalize my database, would require a half-dozen tables.
16:57Chouseryeah, 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:57kotarakWhen there are fn's somewhere in the structures there is a problem, I presume.
16:58Chouseryeah, I don't need fn's in there.
16:58rhickeyI 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:59rhickeyI really like Clojure read/print format as an interop/wire format
16:59jcritesChouser: practically speaking that kind of stuff is useful to do.... you might want to skip the DB though
16:59jcritesjust go for something like a BDB
16:59ChouserI'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:59jcritesyou'd get a lot better performance from a key-value pair oriented DB
17:00jcritesChouser: check out BerkeleyDB
17:00Chouserjcrites: yeah, good point.
17:01Chouserwhen reading these kinds of data structures, is it more efficient to do just (read) than something that also evals, like load-file?
17:01rhickeyyou should only need read
17:01jcritesyou could also explore an online solution.... like Google Bigtable or Amazon SDB
17:01rhickeyan advantage of read/print vs json eval
17:02Chouserso just read would be faster?
17:03rhickeydefinitely - read is the first phase of load, but then there's a whole analysis phase, then eval
17:03ChouserI've dabbled with using a triple-db (RDF) as another way to avoid both object/relational and pure relational tables.
17:03Chouserrhickey: ok, thanks. I think when I've done this before I did (load-file).
17:04Chouserhm.. (read) would be safe too, from a tainted-data point of view. No Java calls or re-defining root vars.
17:05rhickeythat's what I meant re: json eval
17:05Chouserjcrites: would feel a little silly to have transactions in memory but not in my database. ;-)
17:06rhickeyread yields data and you're done
17:06jcriteshmmm, how will you need them?
17:06jcritesBDBs do support transactions luckily :)
17:06jcriteswell
17:06jcritesnot exactly transactions. I forget exactly what
17:07Chousermaybe having STM means I wouldn't need transactions in the db.
17:11Chouserrhickey: 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:12ChouserBut I'm guessing other threads would block or have more restarts if you did it that way?
17:13jcriteshard to say ... have to know what your usage pattern is like
17:14rhickeyChouser: 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:14Chousercould it starve complete? no, because you have "barging" or something, right?
17:15rhickeyIt's a reader, so it doesn't lock, so it doesn't barge...
17:16rhickeythe 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:16rhickeyeventually history windows will adapt to become long enough for he read patterns...
17:17rhickeythat's the idea anyway - that's the multiversion part of MVCC
17:17rhickeyeach ref can keep multiple old values to satisfy readers
17:18Chouserman. ok.
17:18rhickeyit's pretty neat
17:19rhickeybut no reason to stress it when you know what's going on - get in, get out
17:20Chousersure, just trying to understand.
17:20rhickey:)
17:38ChouserA ref has a linked list of values it's had, each timestamped?
17:38rhickeysort of
17:39rhickeyjust as many values as dynamically called for, normally only one
17:40Chouserok. gotta run. thanks!
17:41rhickeysure