#clojure log - Oct 24 2008

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

1:40 burkelibbey: I get java.lang.UnsupportedClassVersionError when I do script/run in Compojure (I tried multiple source revisions).

1:40 Here's the stack trace: http://gist.github.com/19348 . I'm on OS X, and I'm largely clueless about Java. Am I missing something obvious?

1:43 arbscht: burkelibbey: are you running an older jvm than the version you compiled for?

1:45 burkelibbey: oh, quite possible. I'll look into that

1:45 well... I have java version "1.5.0_16"

1:46 arbscht: what compiler version did you use (or what did it target)?

1:47 burkelibbey: Compojure comes bundled with clojure. I'm not sure

1:47 I'll try the .jar that I know works on my system

1:48 oh well there we go. That worked. Thanks :)

1:55 arbscht: was that just the clojure.jar? do the other included jars work?

1:57 burkelibbey: I'm not sure actually. I thought it worked -- no more class version error. Now It's just spinning my processor.

2:04 hmm, works right away on my linux machine with 1.6.0_07. I probably just have to figure out some way to upgrade java in OS X >_>

2:11 Ok. Upgrading java fixed my problems. For the logs: http://www.apple.com/support/downloads/javaformacosx105update1.html in OS X.

2:13 arbscht: burkelibbey: out of curiosity, where did you get compojure?

2:14 burkelibbey: arbscht: http://github.com/weavejester/compojure/tree/master

2:16 arbscht: ah, yes, it looks like the clojure.jar classes target java 6

2:16 burkelibbey: Can't hurt to upgrade anyhow

4:57 Pupeno: Hello.

4:57 Anybody knows how to build Enclojure from SVN?

5:03 Hello Lau_of_DK.

5:12 Lau_of_DK: Hello Mr. Pupeno :)

5:24 Pupeno: Lau_of_DK: Everything all-right up north?

5:52 Lau_of_DK: Pupeno, yes sir, it seems that everything is going just fine

5:53 How about the Neutral-land ?

6:32 achim_p, Hi! :)

6:53 achim_p: hi lau!

6:54 arbscht: heh cute, metadata makes it trivial to implement multisets atop sets

6:57 http://paste.lisp.org/display/69100

7:01 equality semantics are lost though :(

7:03 Lau_of_DK: Looks.... Like Patchworj :)

7:03 k

7:03 achim_p: arbscht: why not just use a map? it would have correct equality

7:04 arbscht: achim_p: yes, I suppose any coll will do

7:05 achim_p: yeah, maps have fast key lookup times, though, should be as fast as a set

7:06 arbscht: achim_p: you mean a map in place of a set?

7:07 achim_p: yes, i'd just use the map you put inside the metadata instead of the set

7:08 arbscht: right

7:09 I'm trying to see if the formal definition can be neatly expressed

7:10 achim_p: it would allow for a simple multiset-union: (merge-with + ...)

7:12 arbscht: looks like the way to go

7:13 the 'underlying set' is then (set (keys multiset))

7:14 Lau_of_DK: does anyone here have a login to search the logs on this # ?

7:16 achim_p: Lau_of_DK: a login?

7:17 Lau_of_DK: I know that n01se.net monitors the channel, but it requires a login to search

7:18 achim_p: arbscht: yes, but that's probably rarely needed. maps behave much like sets, contains? etc. will work right away for (element->multiplicity)-maps: (contains? {:a 1} :a) => true

7:23 arbscht: achim_p: right

7:23 Lau_of_DK: Should this run? (filter #(every? alphanumeric? %) stream of chars

7:23 When alphanumeric returns true if the charcode is in a certain range

7:23 Shouldnt that filter out alpanumericals?

7:27 achim_p arbscht ? :)

7:28 achim_p: Lau_of_DK: why the "every?"?

7:29 Lau_of_DK: Thats a good question

7:30 I honestly dont know why my logic works that way

7:30 It might be a defect in the brain :)

7:33 achim_p: is stream of chars a sequence of chars? filter decides on a per-item-basis: (filter even? [1 2 3 4])

7:34 rhickey: filter keeps, remove removes

7:34 achim_p: Lau_of_DK: if your stream was a sequence of sequences of chars, you'd need "every?"

7:34 Lau_of_DK: Yes I got that - Thanks :)

7:38 (defn alpha-numeric?

7:39 I dont quite get, why this throws the "Dont know how to create ISeq from Character"

7:39 When you map/filter a stream, % is characters right? and (int \character) is an int ? which I numerically compare to another int

7:39 Its the same with either map or filter

7:40 (filter #(and ((> (int %) (int \a)) (< (int %) (int \Z)))) str))

7:41 (should be <= >= I know)

7:41 rhickey: java.lang.Character.isLetterOrDigit

7:42 or whatever

7:42 lots of predicates there

7:49 achim_p: Lau_of_DK: how about (.replaceAll "ishjegoiwejf23iu2352j3b5342" "\\d" "") ?

7:50 rhickey: user=> (filter #(Character/isLetterOrDigit %) "abs23-54//:qwer")

7:50 (\a \b \s \2 \3 \5 \4 \q \w \e \r)

8:07 Lau_of_DK: Thanks alot Rich :)

9:48 Chouser: I guess I can't (set! *print-length* 100) in my user.clj?

9:49 rhickey: Chouser: I knew someone would ask that

9:50 Chouser: user.clj seems to be used for various purposes. So far I've only used it to set up my repl with doc/introspection helpers.

9:51 rhickey: It really seems to be a repl setting, not a global one. Perhaps the repl could get defaults from somewhere

9:53 Chouser: ~/.clojurereplrc

10:18 ok, I moved my personal repl settings to ~/.iclj.clj and created iclj shell script that uses rlwrap, my normal classpath, and include ~/.iclj.clj on the command line to clojure.lang.Repl

10:18 duck1123: I would like to see a setting that wraps the printing of seqs in an implicit (take *max-print-sequence* ...) so if I accidentally try to eval (constantly 1) I would only see a hundred or so. (with some sort of marker indicating the sequence was trunicated)

10:18 Chouser: this gives me exactly the behavior I want

10:18 duck1123: heh.

10:19 that's what we're talking about. *print-length* just went in this morning.

10:19 duck1123: ahh, that was before I logged in this morning

10:20 excelent

10:20 Chouser: wasn't mentioned here, just on the google group.

10:20 duck1123: I'm behind on my mail

10:24 j-dot: Chouser: I did essentially the same thing with a REPL-specific script that gets loaded by an iclj shell script. I wouldn't mind seeing something like this supported like user.clj is.

10:25 Chouser: I'm not sure. A distro- or OS-specific script might be just the right place to handle this kind of thing.

10:27 duck1123: http://github.com/dudleyf/clojure-bin loads a ~/.clojure script if it exists

10:27 Chouser: ah, I love. I didn't have to make any changes to clojurescript to support *print-length*. Re-generate boot.js and it just works.

10:29 I'm still trying to figure out the best way to handle passing command-line arguments through to the clojure app.

10:31 j-dot: you mean passing them through a shell script on to clojure?

10:43 Chouser: yeah, with the -- on the java command line

10:44 j-dot: using /bin/sh, appending "$*" to the end of the clojure command works for me

10:46 jdz: j-dot: putting that in double quotes would be wrong i think

10:46 what i think it means is that all the parameters will be passed as one

10:46 but i avoid shell scripting like a plague

10:46 j-dot: so, my command is: rlwrap java -cp /path/to/clojure.jar:/path/to/clojure-contrib/src clojure.lang.Repl /path/to/my/repl-specific/initializer/script $*

10:46 Chouser: well, I guess I'm thinking for shebang support. So foo.clj would have #!/bin/clj as its first line, and then running foo.clj --opt1 --opt2 would be like running java clojure.lang.Script foo.clj -- --opt1 --opt2

10:47 j-dot: Yeah, I don't have the quotes

10:49 duck1123: what's the best way to exit from the repl? So far, I've just been hitting C-c, or otherwise killing the connection.

10:50 jdz: C-d?

10:50 Chouser: EOF -- ^D on unix, ^Z on windows

10:50 duck1123: ok

10:57 j-dot: Chouser: in your example, how do you plan on passing the clojure code off to clojure? since "#" isn't a comment char in clojure, foo.clj can't be a straight clojure script.

10:59 jdz: j-dot: #! can be a nice reader macro

11:02 how does one make a string out of a bunch of characters?

11:03 j-dot: jdz: (apply str '(\a \b \c))

11:07 duck1123: #! should be a reader macro for ;

11:08 for those times when you want to start a comment with twice as many characters :)

11:12 fogus: Am I completely braindead, or only mostly-so? http://clojure.pastebin.com/d4f598985

11:18 wwmorgan: is this what you're trying to do? http://clojure.pastebin.com/m75ecfc99

11:20 Chousuke: /usr/bin/clj could just be a wrapper that execs java and clojure. http://clojure.pastebin.com/m75ecfc99

11:20 eh

11:20 I didn't intend to say that.

11:20 fogus: That is it. So 'class' means: dispatch on class?

11:20 wwmorgan: fogus: class is just a function. (class obj) evaluates to the class of obj

11:21 fogus: I see. That makes more sense

11:22 Thanks for the clarification

11:26 Chouser: j-dot: yeah, I dunno. there is the trick on the wiki.

11:26 j-dot: yeah, I like that trick, but I haven't used it myself

11:27 What about clojure.lang.Script treating the first line differently if it starts with a shebang?

11:27 i.e., ignoring it

11:28 Chouser: I think that'd make a lot of sense, but I don't have any idea what rhickey would think of it.

11:28 cemerick: rhickey: Shouldn't Float/TYPE => #=java.lang.Float/TYPE, not #=float?

11:29 I'm still unsure of my footing with #=, etc

11:31 alvin-x: what's the best way to get a java.util.Map from a clojure.lang.PersistentArrayMap?

11:32 rhickey: cemerick: yeah, looks like they'll need special handling

11:32 patch welcome

11:32 cemerick: rhickey: of course, (.getName Float/TYPE) => "float", so perhaps RT.classForName should be the target of the patch?

11:36 rhickey: cemerick: no, Java defines the name of those types, I don't want to mask that

11:36 trying to find a #= expression to do this, #=java.lang.Float/TYPE won't work

11:38 Chousuke: alvin-x: just cast it?

11:39 rhickey: user=> (instance? java.util.Map {:a 1})

11:39 true

11:40 alvin-x: Exception in thread "main" java.lang.ClassCastException: clojure.lang.PersistentArrayMap incompatible with java.util.Map

11:41 rhickey: alvin-x: what version of Clojure?

11:41 alvin-x: rhickey: clojure_20080916, Java 5, IBM J9

11:42 cemerick: rhickey: array classes are also in a tight spot (#=[Ljava.lang.Object;)

11:43 alvin-x: user=> (instance? java.util.Map {:a 1})

11:43 false

11:43 !

11:43 Chouser: alvin-x: too old. :-(

11:44 alvin-x: Chouser: Clojure, or Java?

11:44 Chouser: alvin-x: clojure maps have implemented java.util.Map since Oct 6

11:44 Clojure.

11:44 alvin-x: ok, i'll try from svn.

11:45 Chouser: yep, svn + ant should do it for you.

11:46 cemerick: I think I'm not yet clear on the semantics of #=, but it seems like #=(identity Float/TYPE) would work as a readable Float/TYPE, etc.

12:04 alvin-x: Chouser: thanks for the tip

12:05 Chouser: alvin-x: got it working?

12:05 alvin-x: Chouser: yep; hit other problems regarding RMI, but the problem with Maps is gone.

12:06 Chouser: great.

12:12 cemerick: lisppaste8: url?

12:13 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

12:14 rhickey: cemerick: are you using print/read for serialization now?

12:17 cemerick: rhickey: no, I just ran into this issue while experimenting/learning about #=, etc.

12:17 lisppaste8: cemerick pasted "rhickey: potential print-method patch for primitive classes?" at http://paste.lisp.org/display/69118

12:18 cemerick: rhickey: hope that's what you were aiming for; it seems to work, although I know I don't know the edge cases at work here.

12:19 I know you've said that throwing exceptions is a no-no in the core, but I'm not sure what else to do in that case.

12:19 it's too bad there's no .getBoxedClass or somesuch on java.lang.Class

12:52 lisppaste8: fogus pasted "fogus" at http://paste.lisp.org/display/69119

12:57 rhickey: cemerick: can just use a map instead of cond, no need for :else

12:59 cemerick: rhickey: for some reason, I had thought you wouldn't like that. That's good though, as there should be a canonical mapping to support emitting primitive class-symbols in macros.

12:59 wwmorgan: fogus: I got a significant speed-up between the first and consequtive runs of (time (mri odd? (range 10000))). Also, remove is now part of the API

13:00 43ms to 13ms

13:01 fogus: wwmorgan: strange, my second call was 2x slower

13:03 sohail: so if someone wanted to make and distribute some clojure code, do they currently have to ship the source code or can they compile it to class files or some other object files?

13:04 wwmorgan: fogus: also, since your function (and remove) is lazy, you should probably do (time (doall (mri ...)))

13:06 fogus: wwmorgan: Wrapping it with doall was very different. ~40ms vs. 4ms

13:27 dmiles_afk: does clojure work ok in IKVM?

13:32 drewr: dmiles_afk: Check out http://is.gd/4INp

13:33 dmiles_afk: thanks drewr

13:47 Chouser: sohail: currently you ship the clojure source for your app (though it can be bundled in a .jar)

13:49 sohail: Chouser, I guess that it is written in clojure is enough to stop people from trying to tweak it :-)

14:18 lisppaste8: cemerick annotated #69118 with "rhickey: potential print-method patch for primitive and array classes, pt. 2" at http://paste.lisp.org/display/69118#1

14:19 cemerick: that seems to handle primitive and array classes properly

14:27 sohail: can someone verify this for me... clojure has a fixed set of types and you cannot extend the type system by defining compound or aggregate types (you have to use struct maps which are of class StructMap)

14:28 Chouser: a map of vectors or a vector of maps is not a compound nor aggregate type?

14:28 sohail: it is, but one isn't distinguished from another except by comparing each element

14:28 they aren't tagged automatically, I guess

14:29 Chouser: or by comparing metadata.

14:29 sohail: ah

14:29 Chouser: which as you suggest isn't added automatically

14:29 sohail: doh

14:30 * sohail is still attempting to unlearn what he has learnt

14:30 Chouser: I've got half a blog post written on structmaps and multimethods, but I need a better concrete example than what I've got currently.

14:30 sohail: can I see it?

14:30 where is your blog, btw

14:31 Chouser: It's pretty sparse. Must of my clojure-related writing goes right here, or on the google group.

14:31 http://blog.n01se.net/

14:32 there's actually a few authors there, but it's the only blog I post to.

14:32 Lau_of_DK: Evening gents

14:33 Chouser: Lau_of_DK, you little devil, you've got me mired in projecteuler again.

14:33 Lau_of_DK: I really wish you'd find another nickname for me, but I'm glad you decided to have some fun with us :)

14:36 Chouser: "fiend" rather than "devil"?

14:36 Lau_of_DK: almost there, add 1x 'r' and Im good :)

15:05 cemerick: using a build from clojure head, I'm seeing stack traces with line numbers that are within ns forms -- is this to be expected?

15:25 Lau_of_DK: Filter is lazy right ?

15:25 wwmorgan: Lau_of_DK: yes

15:25 Lau_of_DK: k

15:26 kotarak: Lau_of_DK: (doc filter) says so, ;)

15:27 wwmorgan: also (do (filter even? (repeat 2)) 1)

16:06 Lau_of_DK: (.. "Hi there" toUpperCase) - Why does this complain about "Hi there" not being recognized as a Symbol when "Hi there".toUpperCase() would fly in Java ( I assume, it would in C# ), and by does (.. (String. "Hi") toUpperCase not work either?

16:06 drewr: (.toUpperCase "Hi there")

16:08 wwmorgan: or (. "Hi there" toUpperCase)

16:09 drewr: That style will be deprecated, but you're right, that's probably what Lau_of_DK was trying to do.

16:09 wwmorgan: oh really? Was that on the group

16:09 the .method style makes more sense but I didn't know it was going away

16:10 Lau_of_DK: drewr, your example says tht "there" is not a known symbol

16:10 Chousuke: I think it was in the TODO that rhickey pasted a while ago.

16:10 Lau_of_DK: check your typing.

16:10 maybe you forgot a quote?

16:10 drewr: Chousuke: Yep. Doesn't mean it's set in stone, but I think it's likely.

16:11 Chousuke: I suppose it's not that useful

16:11 Lau_of_DK: Chousuke, checked it, its copy/pasted

16:13 drewr: Lau_of_DK: Make sure your IRC client isn't changing the double-quote character.

16:13 (.toUpperCase "Hi there!")

16:13 "HI THERE!"

16:13 kotarak: Lau_of_DK: is .. supposed to be a .?

16:14 Lau_of_DK: Is there a command in clojure that will show which rev. Im on ?

16:14 drewr: No, I think rhickey voted that down a while back.

16:14 Someone might have changed his mind later, but I'm not sure.

16:14 Lau_of_DK: ok

16:14 Its funny

16:14 (.toUpperCase "Hi there!")

16:14 ERROR

16:15 (.toUpperCase "Hi there!")

16:15 "HI THERE!"

16:15 I think my Chimp might be misbehaving

16:15 But thanks for the help everybody

16:27 Chouser: (take 3 (filter #(do (prn :test %) true) (range 10)))

16:27 Why does that test 3?

16:29 wwmorgan: because take tests (seq coll) eagerly

16:30 Chouser: take doesn't test anything, does it?

16:30 (take 3 (iterate #(do (prn :take %) (inc %)) 0)

16:32 wwmorgan: (seq coll) is always true if coll is an iteration

16:32 Chouser: filter tests, and you're right it seems to do one extra eagerly.

16:33 wwmorgan: yeah you could change the implementation of take

16:35 actually, I'm not sure about that

16:35 drewr: If I lazy-cat together lazy-cons, will the second lazy-cons ever get called?

16:36 Chouser: I suspect it's the (if (pred (first coll)) ...) in take, because that's outside of any lazy-cons

16:36 drewr: A lazy-cons doesn't be definition have to be infinite, does it?

16:36 s/be /by /

16:36 Chouser: drewr: right, it could eventually return nil instead of another lazy-cons, and then lazy-cat would go to the next one.

16:36 kotarak: (lazy-cons 5 nil)?

16:37 drewr: kotarak: Good point.

16:38 kotarak: drewr: it just means, the contents don't get evaluated until accessed.

16:38 Chouser: wwmorgan: you're right, it's take's fault.

16:38 oh, dangit, messed up my test. ok, still not sure. :-)

16:38 Lau_of_DK: Is there something similar to Contains? that would work on a vector of strings?

16:38 drewr: I'm trying to figure out why lazily pulling queries from a db hangs after the first one.

16:39 Chouser: Lau_of_DK: that's a linear search, which means it'll be slow.

16:39 Lau_of_DK: so rhickey has resisted having a builtin, but you can still say (some #{"word"} [...])

16:39 Lau_of_DK: Chouser, enlighten me, you want a hash map then?

16:40 Resistance is futile

16:40 Chouser: yeah, or a hash-set. both would be much faster for looking up a given word.

16:40 Lau_of_DK: ok, and then just use contains?

16:41 Chouser: or just call the set

16:41 Lau_of_DK: how do I automate the calling ?

16:42 Chouser: (def dict #{"one" "two" "three"})

16:42 (dict "one") -> true

16:42 (dict "five") -> nil

16:43 Lau_of_DK: Alright, while we're at it, I know that Strings have a split function, how do I split every word into a single item, like in C# you could do "Hi there Chouser".Split(" ") = ["Hi" "there" "Chouser"]

16:44 Chouser: (apply hash-set (.split "Hi there Lau"))

16:45 sorry: (apply hash-set (.split "Hi there Lau" " "))

16:47 Lau_of_DK: Thanks

16:47 Chouser: wwmorgan: ok, you're definitely correct. It's take.

16:48 (first (filter #(do (prn :test %) true) (range 10))) only tests one

16:48 but if you use (take 1 ...) it tests 0 and 1

16:48 wwmorgan: right. it checks for logical truth before it decides whether to return a lazy-cons or nil

16:49 Chouser: "take" does? (seq coll) doesn't realize either the "first" or the "rest" parts of a lazy-cons, does it?

16:50 oh, it does!

16:50 wwmorgan: it does on a filter, because it has to make sure that at least one remaining element passes the test

16:51 Chouser: man, this is subtle.

16:52 wwmorgan: that's why you didn't see the same behavior on your iterate: an iteration is always logically true

16:52 Lau_of_DK: logically :)

16:53 user=> (containsEnglishWords? "hej med dig, min amerikanske ven er usually meget good")

16:53 ("usually" "good")

16:53 sweet, good thinking Chouser :)

17:15 lisppaste8: Chouser pasted "take (fixed)" at http://paste.lisp.org/display/69146

17:16 Chouser: With that, this only tests 0, 1, and 2:

17:16 (take 3 (filter #(do (prn :test %) true) (range 10)))

17:19 cemerick: rhickey: did you see this earlier, or no? I've been in and out myself: http://paste.lisp.org/display/69118#1

17:20 rhickey: cemerick: I didn't - looks good, thanks! - could you please post to the group?

17:20 cemerick: rhickey: yeah, I will, thanks

17:21 I wasn't really around for any of the conversation about making a print multimethod, etc., but so far, I'm not enamored of the approach so far

17:22 (I hate to be one of those people that pops up with opinions long after decisions are made and code is written :-) )

17:23 rhickey: cemerick: what would you propose instead?

17:23 cemerick: It seems like there's a lot of niggly details that will need to be resolved (e.g. classnames of primities and arrays), a lot of reinventing the wheel given that there's a *lot* of serialization mechanisms for Java.

17:24 Chouser: cemerick: are you talking about multimethod vs. written in Java? Or the new #= format?

17:26 cemerick: I suppose the #= format. There's nothing to say that the existing javabean serialization (for example) couldn't just get dropped into a form that the reader would bring back in transparently. There's less lispy love there, but I worry about what dragons await yet another serialization mechanism.

17:27 I'm sure I've not thought about the issues nearly as much as others, so take all this with the requisite pound of salt. :-)

17:27 Chouser: I don't think there was any discussion of the #= format. :-)

17:28 rhickey: cemerick: I looked at JavaBean serialization - it's unconscionably verbose

17:29 cemerick: definitely so, but it works, and has a lot of support behind it so it will "automatically" grow along with new JDK versions, etc

17:30 is verbosity an issue, though? How often would we expect serialized objs to be viewed by humans?

17:30 rhickey: um, every time they work at the repl?

17:31 cemerick: there's clearly some benefits to having everything be printed readably all the time, but the repl vs. storage vs. transmission are very different use-cases

17:32 Chouser: the old print format didn't work for storage or transmission of unusual Java objects either, did it?

17:33 rhickey: cemerick: print/read is a strong and valuable Lisp tradition, nothing about it removes other serialization mechanisms

17:33 cemerick: Chouser: no, not at all

17:35 rhickey: Sure. I guess I'd just worry about having to keep print-method well-fed.

17:36 ...in addition to whatever odd corner-cases exist w.r.t. Java idiosyncrasies

17:36 This is all monday-morning quarterbacking on my part though, so I think I'll just sit back down. :-)

17:38 rhickey: I think Javabeans serialization might be a good fallback if no other method is defined, the current default has only been marginally useful

17:39 cemerick: rhickey: hrm, having a featureful fallback is a good idea. I suspect Javabean serialization is just a baseline though -- I'm sure there's better options. I brought it up only because I'm familiar with it.

17:43 duck1123: so is anyone here familiar with compojure?

17:43 I'm still having troubles getting the compojure repl connected via slime

17:44 cemerick: huh, looks like the google group email gateway has gotten snappier

17:44 lisppaste8: rhickey pasted "XMLEncoder format" at http://paste.lisp.org/display/69149

17:45 rhickey: cemerick: it is text, but another problem is its graph nature

17:45 cemerick: oh, yeah, it can get vile -- but for storage/transmission, it's great as long as it's zipped

17:46 I've not thought much about serialization issues -- I'm not aware of the problem(s) with object graphs.

17:49 have a good weekend, everyone!

17:51 drewr: In JSwat, I see a Timestamp object, but its value is "#2455."

17:51 Is that a memory address?

17:51 Can I only inspect strings?

18:00 islon: hi guys o/

20:31 sohail: is let like let* or like let from CL

20:32 rhickey: sohail: like let*

20:32 sohail: thanks rhickey, I am not very good at navigating the documentation

21:20 RadioApeShot: Question, is there a predicate which detects whether a thing is seq-able?

21:20 drewr: (doc seq?)

21:20 RadioApeShot: seq? detects if a thing _is_ a seq

21:21 drewr: True.

21:21 RadioApeShot: So (seq? [1 2 3]) -> false

21:21 Suppose one wanted to write a function which returns the first of a thing if the thing is seq-able, like a vector

21:22 drewr: Idiomatically, you just (when (seq [1 2 3]) ...)

21:22 RadioApeShot: But otherwise returns something else

21:22 when

21:22 Very clever.

21:22 Thanks

21:23 But wait

21:24 (defn first-or [x y] (when (seq x) (first x) y))

21:24 That still will not work

21:24 At least it will not if x is, for instance, a symbol

21:25 because (seq x) will throw an exception

21:25 drewr: Yes, you need to be fairly certain you're getting some kind of collection.

21:25 RadioApeShot: Is there a collection?

21:25 (collection? x)

21:26 I am just porting some Scheme code where I use the nth-or idiom a lot.

21:26 drewr: Can you wrap it in a try and deal with the exception?

21:26 RadioApeShot: But I am trying to make this collection independent.

21:26 I can do that

21:26 It just seems a bit weird to do so.

21:27 drewc: is there an IGNORE-ERRORS in clojure?

21:27 RadioApeShot: Not that I know of.

21:28 drewc: seems like a use-case.. though quite frankly i avoid it in CL and prefer the explicit error handlers.

21:28 (defn first-or [x y] (when (ignore-errors (seq x)) ...)

21:28 RadioApeShot: Ok

21:28 Place is closing

21:28 Gotta run

21:28 Thanks for the help

21:29 I appreciate it

21:30 drewr: (doc coll?)

21:36 drewc: How are you liking clojure so far?

21:37 drewc: drewr: having a lot of fun so far :)

21:38 drewr: Awesome.

21:38 drewc: drewr: i have not been working with it long enough for any of my grievances to have any real merit.

21:38 lisp-1 is driving me nuts, but i'm willing to look past it :)

21:39 drewr: Haha.

21:40 We incited some discussion about that at dinner before lisp50.

21:41 drewc: me, i'm just exited that there is a new lisp actually worth looking at. Rich has put an incredible amount of thought into it, and he has the cojones to go through with it.., i'm suitably impressed.

21:41 * drewc has been taling about clojure for at least 6 mos.

21:42 drewc: talking

21:42 drewr: :-)

21:46 drewc: I'm getting used to the syntax even .. who'd a thunk it.

21:49 drewr: I find it extremely expressive.

22:00 drewc: what i absolutely _love_ is STM

22:09 rhickey: Nice blog from OOPSLA: http://lispy.wordpress.com/2008/10/25/lisp50-notes-part-vi-the-future-of-lisp/

22:16 danlarkin: the default wordpress template annoys me so much

22:17 because when I increase the font to a readable size then only like 5 words fit on a line

Logging service provided by n01se.net