#clojure log - Apr 05 2009

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

14:25 AWizzArd: wb Chouser

14:25 hiredman: Chouser: welcome back

14:25 Chouser: AWizzArd: thanks!

14:26 clojurebot: Chouser might make night

14:26 hiredman: ~botsnack

14:26 clojurebot: thanks; that was delicious. (nom nom nom)

14:26 Chouser: looks like my poor machine has been failing to log for a few days. :-(

14:26 AWizzArd: jsankey and hiredman: thanks for these introductions into jetty, tomcat, jboss, j2ee and java beans.

14:26 jsankey: np

14:27 fwiw, i'm a happy Jetty user - I would recommend it if you need a servlet container

14:36 duck1123: can jetty be run as a service?

14:36 that's why I use tomcat

14:36 jsankey: sure

14:36 but any java program can using something like java service wrapper

14:37 we embed jetty in our app so we use our own startup script which uses the service wrapper

14:38 duck1123: are you using jetty with clojure, or just plain java?

14:38 I just updated my compojure app to the post-ring version, I think I'm liking it

14:38 jsankey: this is a java app i'm referring to, so java

14:39 dreish: ,(- Integer/MIN_VALUE)

14:39 clojurebot: java.lang.ArithmeticException: integer overflow

14:39 dreish: ,(#(- %) Integer/MIN_VALUE)

14:39 clojurebot: 2147483648

14:39 Chouser: nice!

14:39 dreish: First one compiles to a call to static public int Numbers.minus(int x). Second one doesn't.

15:46 Sebboh: hey. Fix your damned bot.

15:46 Channel notices beep!

16:10 duck1123: does anyone know if it's possible to get compojure to output well-formed xhtml?

16:33 or does anyone recommend a different library for easily creating xml

16:34 Chouser: there are many xml-emitting libs

16:35 duck1123: I need to do xforms, so good namespace support is important

16:35 Chouser: ah. well, that should help you narrow the field a bit

16:35 duck1123: clojure.xml is a little too verbose for my tastes

16:35 Chouser: possibly to zero. :-(

16:37 hiredman: yay!

16:42 danlarkin: How do I create a pattern with re-pattern that has the same escaping done on it that a #"" regex literal does?

16:43 replaca: danlarkin: ?, you mean on the source string? I don't think you do...

16:43 Chouser: ,(re-pattern (str #"\woo" "bar"))

16:43 hiredman: I don't think you can

16:43 clojurebot: #"\woobar"

16:43 hiredman: heh

16:44 replaca: Chouser, FTW!

16:44 Chouser: danlarkin: is that what you meant?

16:44 it's not terribly efficient, of course. One of the benefits of #"" is the Pattern is compiled at readtime, and the above example loses that benefit.

16:45 replaca: but if you're constructing patterns at run-time, what can you do?

16:45 regex's don't have sql-like prepared statements, do they?

16:45 danlarkin: well I have a series of complicated regexes that I kinda want to re-use in subsequent regexes

16:46 Chouser: danlarkin: I think the Right Solution for that kind of thing will be a clojure-sexp-based DSL for string processing.

16:47 but until that exists, using #"" to build escaped Patterns, and then str to print them in a form that can be combinded, re-parsed, and re-compiled at runtime will have to do.

16:47 replaca: Chouser: I've heard you say that before (and I have also thought about it). Do you know if anyone has ever tried such a thing in Lisp?

16:48 Chouser: replaca: I haven't looked. Is there something that does for reading what cl-format does for writing?

16:48 hiredman: Chouser: I think it's called fnparse

16:48 Chouser: heh

16:48 could be

16:48 hiredman: :P

16:48 man

16:48 replaca: well, cl-format is kind of the inverse of regex

16:49 Chouser: right

16:49 hiredman: I completely forgot to get better at using fnparse

16:49 replaca: cryptic, but compact and powerful

16:49 Chouser: oh, I see what you mean. yeah, that's not what I'm talking about then, is it.

16:49 but maybe it points to regex being a better alternative than I'm giving it credit for.

16:50 replaca: Chouser: yeah, of thought of the same thing for output - a real dsl for describing output

16:50 pstickne: is there a really simple way to tell if a list contains a given item?

16:50 Chouser: do people ever want to programmatically create cl-format directive strings like they want to with regexes?

16:50 pstickne: e.g. (list-contains :a [:a :b :c]) ?

16:50 replaca: the problem is that typically, you want to keep those things small to get them out of the way of your algorithm

16:51 hiredman: ,(.contains [1 2 3] 2)

16:51 clojurebot: true

16:51 hiredman: ,(.contains [1 2 3] 4)

16:51 clojurebot: false

16:51 Chouser: pstickne: maybe you want a set instead of a list?

16:51 replaca: Chouser: not so much, but they do complain about the write-only nature

16:51 pstickne: Chouser: a set is fine too, still with the .contains method?

16:51 hiredman: ,(#{1 2 3} 2)

16:51 clojurebot: 2

16:51 Chouser: pstickne: you can just "call" a set, like you would a function.

16:51 hiredman: ,(#{1 2 3} 4)

16:51 clojurebot: nil

16:52 pstickne: ohh

16:52 sweet

16:52 like a map :p

16:52 hiredman: but sets also have .contains

16:52 pstickne: ,([1 2 3] 0)

16:52 clojurebot: 1

16:52 hiredman: .contains is part of the java collections api

16:52 pstickne: neat, thanks :)

16:53 Chouser: replaca: conversely, regexes sometimes *are* your algorithm.

16:55 hiredman: ~literal [5] clojure

16:55 clojurebot: like life: you make trade-offs

16:55 hiredman: that uses regexs

17:15 slashus2: Is there an equivalent to prog1 in clojure?

17:16 cmvkk: what's the difference between prog1 and progn again?

17:16 slashus2: prog1 returns the first

17:17 cmvkk: there's nothing built in for that, to my knowledge. seems like it wouldn't be hard to make a macro for that though

17:24 * hiredman fires off an email pushing fn->al

18:17 replaca: Chouser: (sorry, I was eating & putting my kid to bed): Yes, you are right. My only point would be that once people learn to do regex, they seem uninterested in less compact ways of expressing the same thing

18:18 but I'd emphasize "seem" since I don't have any counter experience

18:21 gnuvince_: replaca: I know that some people I talk with think that regexes are better than other alternatives (such as having a real parser)

18:22 replaca: gnuvince_: one nice thing is that a regex is "in the form of" the data on which it's operating (i.e. a string)

18:23 danlarkin: parsers and regexes each have a legitimate domain

18:23 IMO

18:23 replaca: but there's obviously some crossover point where you've got the wrong hmmer for the nail

18:23 danlarkin: agree 100%, though there can be overlap

18:23 durka42: replaca: i don't know about that. simple regexes can look like their text, but they get unreadable really fast

18:23 replaca: esp, if the parser is really accessible, which usually isn't true

18:26 durka42: yeah, that's where you get into the grey area

18:26 but usually, bringing in a parser is really heavy artillery (think yacc/lex) so peopel will ride the regex train as far as they can

18:27 (mixed metaphors, our specialty)

18:29 Raynes-: The Twitter team has switched to Scala. They are now using Scala along with existing RoR code.

18:30 Would be moar awesome if it was Clojure, but it's a start.

18:36 replaca: THey were desparate for something that scaled and "Scala" sounds like it would, just from the name :-)

18:59 dakrone_hb: hi all, I'm attempting to get use a jar from Clojure and having some trouble importing it, the java line works as "import estraier.*;" and then a Database() object is available, however clojure won't let me do (import '(estraier Database)), even though estraier.jar is in the classpath

18:59 I apologize for the long question

18:59 I apologize for the long question

19:00 is this the right way to be importing from a 3rd-party jar?

19:00 hiredman: what happens when you try the import?

19:00 dakrone_hb: java.lang.ClassNotFoundException: estraier.Database (NO_SOURCE_FILE:0)

19:01 hiredman: are you sure it is on the classpath?

19:01 dakrone_hb: (import '(estraier)) returns nil, but I'm not sure that's the right way to import it

19:01 hiredman: (System/getProperty "java.class.path")

19:01 dakrone_hb: yea, command-line is java -cp /home/hinmanm/src/clojure/trunk/estraier.jar:/home/hinmanm/src/clojure/trunk/jline-0.9.94.jar:/home/hinmanm/src/clojure/trunk/clojure.jar jline.ConsoleRunner clojure.lang.Repl

19:01 hiredman: dakrone_hb: that is not

19:02 dakrone_hb: the getProperty command has the estraier.jar in it

19:02 hiredman: what is Database?

19:03 cmvkk: so does import estraier.Database; work from java?

19:03 dakrone_hb: http://hyperestraier.sourceforge.net/javanativeapi/

19:03 yep, an example of a short java file is here: http://hyperestraier.sourceforge.net/javanativeapi/

19:04 cmvkk, It's used as import estraier.*; in Java

19:04 cmvkk: right, but does it work to do estraier.Database; ?

19:04 because it ought to, right?

19:05 dakrone_hb: it should, I haven't tried it explicitly, should I?

19:05 cmvkk: I don't know...it can't hurt I guess

19:05 dakrone_hb: I'll give it a shot

19:05 cmvkk: your syntax is right, for clojure, there's no reason why your clojure code shouldn't work when the java code does. that's the only difference between them.

19:12 dakrone_hb: hmm...I think there might be a library installation problem.

19:13 but it's good that I know the clojure syntax is right, thanks cmvkk

19:13 cmvkk: i wonder what's wrong that .* would work but not .Database though

19:13 I am not very familiar with how packages and importing work in java

19:23 cp2: ,'1/0

19:23 clojurebot: Divide by zero

19:23 cp2: lame

19:24 cmvkk: what do you want it to return?

19:24 hiredman: ,'1/3

19:24 clojurebot: 1/3

19:24 hiredman: ,(class '1/3)

19:24 clojurebot: clojure.lang.Ratio

19:25 hiredman: go figure

19:25 cmvkk: what...what's surprising about that?

19:25 hiredman: ,(symbol "1/3")

19:25 clojurebot: 1/3

19:25 hiredman: ,(class (symbol "1/3"))

19:25 clojurebot: clojure.lang.Symbol

19:27 cmvkk: because getting a ratio out of 1/3 is a reader trick.

19:27 ,(namespace (symbol "1/3"))

19:27 clojurebot: "1"

19:50 slashus2: Hypothetically could clojure's STM be implemented in clojure?

19:51 hiredman: yes

19:51 rhickey has talked about self hosting clojure somewhere post 1.0

19:51 (which would imply the stm written in clojure)

19:52 slashus2: One would use the class generator?

19:53 hiredman: the stm is bascially a system of locks

19:54 slashus2: right

19:54 hiredman: and clojue has acess to locks

19:54 slashus2: (locking ?

19:54 hiredman: yeah

19:56 slashus2: To implement Ref Atom Agent etc. the class generator would have to be used?

19:56 hiredman: yeah, gen-interface at least

19:56 I assume the asm library would not be rewritten in clojure

19:58 slashus2: hmm... I don't think it could if clojure was to self boot-strap.

19:58 Unless you had a clojure implementation there to begin with.

19:58 I guess that is how gcc works.

19:58 hiredman: the asm lib is some third party thing anyway

19:59 slashus2: It was first written in asm, compiled, then the compiler was written in C. The process is probably slightly different.

20:04 cmvkk: the thing about self-hosting clojure is that you wouldn't be able to just supply the source and expect people to build it

20:04 since you would need a compiled version of clojure to compile clojure

20:07 slashus2: cmvkk: Right.

20:08 That was probably the problem with gcc to begin with too?

20:09 cmvkk: yeah. well all you need is one compiled C compiler, then after that, you just use the immediately previous version to compile the next version.

20:09 slashus2: yup

22:05 In a transaction, if you both both an alter and a commute, what sort of retry behavior should be expected?

22:10 I guess if the alter value changes, the whole transaction will retry, but it keeps it from retrying if the commute value changes.

22:12 cmvkk: the commute never goes through unless the transaction actually commits.

22:12 and then it goes through on commit, regardless of what else happened.

22:13 slashus2: So the alter value is the only thing holding it back.

22:13 alter I should say

22:13 cmvkk: yeah, if you alter the ref inside a transaction, it will retry.

22:13 if something else alters it first, anyway

22:14 what i want to know is, if you commute a ref inside a transaction and then alter it, the actual behavior of the ref is reversed in the real world, from how it looks inside the ref

22:14 is that right?

22:16 slashus2: Well since the commute won't succeed unless the alter succeeds, I think it will fail if the ref is altered elsewhere. I don't think the world is touched until the transaction succeeds?

22:16 cmvkk: right, i mean if the transaction goes through.

22:16 inside the transaction, the ref is commuted then altered. but in the real world, the ref is altered first then commuted.

22:16 or so the commute docs seem to suggest.

22:17 slashus2: (dosync (commute r + 1) (ref-set r 20))

22:17 If that succeeds I wouldn't the ref be commuted first?

22:18 cmvkk: interesting.

22:18 orero: hi. quick question: why do I need the quote before the map form in this (-> [1 2 3] '(map inc) first - dec (+ 3) (min 5)) ?

22:18 cmvkk: ,(let [foo (ref 0)] (dosync (commute foo inc) (ref-set foo 20)))

22:18 clojurebot: java.lang.IllegalStateException: Can't set after commute

22:18 slashus2: ooo

22:18 ..

22:19 orero: anyone knows?

22:19 cmvkk: hold on

22:20 that's odd behavior, orero, but

22:21 orero: is that a bug or is it me?

22:21 cmvkk: based on the expected behavior of ->, that map form would be wrong...since it inserts the object as the first argument

22:21 i.e. #(map % inc), when what you want is #(map inc %)

22:21 orero: right.

22:21 cmvkk: using the quote somehow fixes that

22:21 apparently

22:21 orero: so how did it manage to work anyway?

22:22 cmvkk: oh wait.

22:22 ,(-> [1 2 3] '(map inc))

22:22 slashus2: ,(macroexpand '(-> [1 2 3] '(map inc) first - dec (+ 3) (min 5)))

22:22 clojurebot: [1 2 3]

22:22 (min (clojure.core/-> (clojure.core/-> (clojure.core/-> (clojure.core/-> (clojure.core/-> [1 2 3] (quote (map inc))) first) -) dec) (+ 3)) 5)

22:22 cmvkk: it doesn't do anything.

22:22 it puts the vector in as an argument to quote.

22:23 which returns it like normal.

22:23 so it doesn't give an error, but the answer isn't correct either.

22:23 orero: oh.

22:23 got it. thanks, man.

22:24 slashus2: cmvkk: I am guessing that the alters and commutes are commited in order?

22:24 cmvkk: well, they are, but only because that order is enforced in-transaction.

22:25 slashus2: right

22:25 cmvkk: the commute docs say that the in-transaction value of the ref will be commuted when you call commute,

22:25 but the actual commute won't happen in the real world until the point of commit

22:25 which would be after the alter, if you did it that way.

22:25 slashus2: yeah

22:25 cmvkk: rather than having weird behavior, it seems it's just not allowed at all.

22:31 ,(-> [1 2 3] (#(map inc %)))

22:31 clojurebot: (2 3 4)

22:31 cmvkk: is there a better way to do that i wonder

22:36 slashus2: ,(let [a-fn (fn [x] (map inc x))] (-> [1 2 3] a-fn))

22:36 clojurebot: (2 3 4)

Logging service provided by n01se.net