#clojure logs

2008-05-12

12:05abrooksrhickey: I keep waiting for Yegge to realize that Clojure's the language he's looking for. I know he thinks the paren issue is too much for the genral population. I'm not quite sure. BTW, did you really post 15 minutes after Yegge posted his article?
12:24rhickeyabrooks: Yegge seems most interested in JavaScript, having resigned himself to the language limits at Google. I've realized as people trot out the Lisp-has-had-its-day argument that I need to highlight how Clojure is, IMO, much cleaner looking and approachable than CL/Scheme, a combination of fewer parens in let et al and the vector and map literals.
12:25rhickeyabrooks: I think I was much later than 15 minutes...
13:06ChouserI wonder if it'd be worth coding up a couple of relatively attrocious CL examples and show them with Clojure equivalents.
13:09rhickeyChouser: I think it's more important to go head-to-head with JRuby/Groovy/Jython, as those developers might not realize Lisp might not be the parens-infested nightmare they imagine. CL devs have already come to grips with parens, knowing the power of macros enabled by them...
13:11Chouserhm. ok. tougher sell, but ok. :-)
13:12ChouserI've got a friend who, after seeing some of your videos, has decided Clojure is the right way to go, if only he can create a C-like syntax on top of it.
13:12rhickeyOh no!!
13:13rhickeyI attended many of the dynamic language sessions (Groovy/JRuby/Jython) at JavaOne. Clojure looks pretty decent by comparison, considering all the syntactic sugar they have, and is actually less complex due to the lack of it.
13:14ChouserI won't tell him you said that. I'm encouraging him to try, since the more closely you look at the problem (and spend time reading/writing s-expressions), the more better s-exprs look.
13:15rhickeyYeah, it's an inevitable part of learning Lisp...
13:17ChouserAnd for my part, I wouldn't mind if he succeeded. He's hardly the first to try, so I'm not too hopeful, but I'm sure there is a set of programmers who could be hooked if they had a more familiar syntax to start with.
13:24rhickeyClojure is no more different from Python than Python is from C/Java, syntactically, except no infix ops, say. Given the climate of people learning new language that exists today, I'm hopeful Clojure is directly approachable. Personally, Ruby/Scala etc syntax gives me a headache. The longer people avoid code-as-data the longer until they 'get' Clojure/Lisp.
13:26mfredricksoni think the statement vs. expression distinction is a larger impediment to Lisps than code vs data (though certainly an important concept)
13:27rhickeymfredrickson: interesting... Ruby is all expressions, Python too?
13:28mfredricksonrhickey: ruby (of which I am more familiar) skates a line between statemtents and expression
13:28mfredricksonfor example, I can write a function like def foo; 3; end
13:28mfredricksonit evaluates to 3 and returns that value
13:29mfredricksoni can also write def foo; if something; return 12; end 3 end
13:29rhickeythe return is needed?
13:29mfredricksonin the second foo, that first "if" is a statement (as in, no return value), but the 3 (if reached) is an expression
13:29mfredricksonnot strictly
13:30mfredricksonthus the duality of the language
13:30ozzileeHey all, is there a way to load in a .java file from the REPL? It's not in my classpath.
13:30rhickeyyuck
13:30rhickeyozzilee: .java is source, do you mean .class?
13:30mfredricksonrhickey: yeah. it's weird. i'm writing some Rails code write now, and I keep switching back and forth between expression and statement style. I'm schizo
13:31ozzileerhickey: No, actually .java. I'd be interested to hear of a way to do .class files as well though.
13:32rhickeyGeneral question for those that know Ruby/Python/Groovy - do you find Clojure to be simpler/smaller or more complex/larger?
13:33rhickeyozzilee: no, you must compile with javac and get the class file on the classpath, or use something like Janino from Clojure.
13:34ozzileerhickey: So, in general, if I download a java library (be it a .java, .class, or .jar file), I'm going to need to restart my REPL before I can play with it?
13:35rhickeyozzilee: a Java library will most likely be in a .jar. I'm looking at adding support for dynamic loading of jars.
13:35ozzileeOk, that would be cool.
13:36ozzileemfredrickson: I might be wrong, but I'm pretty sure that "if" statement returns a value regardless. I haven't used ruby in a few months, though.
13:36mfredricksonozzilee: it returns nil
13:37mfredricksonozzilee: according to the IRB session i have open anyway
13:37ozzileemfredrickson: Hrm you're right.
13:38ozzileeNo, the repl just gets confused.
13:39ozzileea = if 1; "foo"; end;
13:39ozzileea is "foo"
13:39ozzileeIt still returns a value.
13:41mfredricksonozzilee: if the REPL is confused, how am I supposed to know what's going on? ;-)
13:42ozzileeHeh. Lines with colons in them just don't show their return values in the REPL, apparently.
13:42ozzilee1; 2; 3; // No return values.
13:42Chouserrhickey: I posted a pure-clojure hack for dynamic loading of .jars the other day.
13:42mfredricksoni would still argue that because of it favors the OO/mutal state model Ruby is more of a statement style language
13:43mfredricksonthough I do appreciate using expressions in it
13:43Chouserpython has distinction between statements and expressions (unlike ruby). ...and it hurts.
13:43ozzileeChouser: Yeah, I think I found that.
13:44ozzileehttp://paste.lisp.org/display/60512 ?
13:44rhickeyChouser: yes, thanks, just trying to avoid the setAccessible call
13:44Chouserrhickey: heh. yes. good idea.
13:45Chouserfor example, python has "lambda", but only allows it to include a single expression. But "if" is a statement, so you can't use it in a lambda body.
13:45rhickeyChouser: looking at making DynamicClassLoader derive from URLClassLoader
13:46mfredricksonChouser: my brain hurts already. and here I was thinking I should learn python to give significant whitespace a try
13:46ozzileeChouser: Yeah, Python deliberately discourages anonymous funcitons. I believe I heard it said that he wanted to take lambda out all together.
13:46ozzilee(can't think of his name right now)
13:47Chousermfredrickson: every language has warts, and Python certainly has merits.
13:47rhickeyI'm trying to find the web page where the guy wrote Lisp code, then used progressively lighter fonts for the parens until it looked like Python, to demonstrate what happens after a while - the parens disappear for a Lisp programmer, but can't find it right now :(
13:47mfredricksonChouser: I'm being dramatic. I'm sure I'd learn a thing or two from picking up python
13:48Chouserozzilee: yeah, but Guido van Rossum's swimming up-stream. Python's picking up a lot of functional contructs -- to its benefit, I think.
13:48ozzileeGuido, that's his name :-)
13:49ozzileeI don't think he's anti-functional. Just anti-lambda.
13:49rhickeyChouser: I thought GVR was pro-iteration and against more functional style?
13:49ozzileeAre list comprehensions considered functional?
13:50rhickeynot really, fancy iteration
13:50rhickeymap/reduce/apply etc
13:50ozzileeHmm. Well they're pretty slick, anyway.
13:50ozzileeYeah, Python has those.
13:50Chouserwell, but comprehensions generally accept a value and return a value without side-effects. ...more functional than many alternatives for the same functionality.
13:50mfredricksonrhickey: it's not the disappearing parens, but I've keeping my eye on "readable s-expression"
13:50mfredricksonhttp://www.dwheeler.com/readable/
13:51mfredricksoni keep meaning to write a little Lisp to try them out
13:51Chouserrhickey: That's my impression of GVR as well, but he has a community that he doesn't entirely ignore. :-)
13:52rhickeykeeping lambda limited reduces the utility of map/reduce etc
13:52ozzileeYeah, it sure does. Python's just got different goals, readability high on the list.
13:53ozzileeI'm certainly not saying it's better than lisp. It is pleasant, though.
13:53rhickeyAnything Pythons list comprehensions do that Clojure's don't?
13:53ozzileeHeh I doubt it. No idea, though, haven't look at Clojure's.
13:56ChouserI don't think so. But the syntax is all backwards -- you start with the returning expression and then the bindings, and finally the test
13:57rhickeyThat's the Haskell way
13:58rhickeywhich makes somewhat more sense when your lists are built up using infix cons (::)
13:58ozzileeSpeaking of list comprehensions, what's a good way to get a lazy infinite list of random values?
13:59ozzileeOr even a finite list.
13:59ozzileeI think I ended up on (for [x (range 10)] (rand)), but I don't really like that.
14:00ozzileeI'd like something like (take 10 (repeat (rand))); which obviously doesn't work.
14:01rhickey(defn randoms [] (lazy-cons (rand) (randoms)))
14:01rhickey(take 10 (randoms))
14:03ozzileeBlech :-)
14:03rhickeyyou don't like it?
14:03ozzileeHow does fnseq work? (take 10 (fnseq (rand) rand)) doesn't do what I'd expect.
14:04ozzileeIt's fine, I was just looking for something more general, like (take 10 (repeat-fn rand)) or something.
14:04ozzilee(which I'm I could write, but if it's built-in...)
14:05rhickeyozzilee: fnseq's second arg must be a fn that returns a seq
14:06rhickeyozzilee: yeah, I also occasionally want a repeatedly macro, (repeatedly (rand))
14:07ozzileeYeah, that would work.
14:09ozzileeSorry to sidetrack the conversation, just feeling my way around the language.
14:11rhickey(defmacro repeatedly [e]
14:11rhickey `((fn rec# []
14:11rhickey (lazy-cons ~e (rec#)))))
14:12ozzileeAnd there it is :-)
14:15ChouserI've got a new format for the #clojure logs up at: http://clojure-log.n01se.net/
14:15ChouserLet me know if it looks broken in your favorite browser.
14:16rhickeyChouser: looks fine here Camino OS/X 10.4.11
14:17ozzileeChouser: Long usernames get screwed up on FF/Linux.
14:18ozzileemfredrickson, for example.
14:18ozzileeBy "screwed up" I mean cut off.
14:19Chouserhm. indeed -- text piling up.
14:20ozzileeHeh changing the margin-left on b elements fixes it, but that's not really a solution.
14:20Chouseryeah, because then you run into the timestamps.
14:21Chouserb { overflow: hidden } also solves it sorta-but-not-really.
14:24mfredricksoni win. I broke chouser's design.
14:24Chouser:-)
14:24ozzileeHeh.
14:26ozzileeTables?
14:26ChouserYeah, the old design used tables. http://n01se.net/chouser/clojure-log/2008-05-12.html
14:27ozzileeYeah, I don't see any way around tables as long as you stick with that general layout.
14:28ozzileeSomething like username<br>message could be done in css, but bleh.
14:28ChouserI don't mind clipping ridiculously long nicks (sorry, mfredrickson!) client-side if it looks good, but I'm not sure if it's worth the trouble.
14:28ozzileeOf course, that would stop really long usernames from shoving everything to the right...
14:29ChouserThe benefit of no tables is it's easier for the browser to show the top of the page soon while still loading the bottom of the page.
14:29Chouseroh well. I can't work on it now anyway. I'll poke at it again some other time.
14:38hoeckchouser: long usernames look bad too on opera 9.02/linux
14:44ozzileeIs there anything set up to collect Clojure libraries? For example, if I were to write a JSON library...
14:46Chouserozzilee: http://sourceforge.net/projects/clojure-contrib/
14:57ozzileeChouser: Thanks.
15:21abrooksrhickey: Going back to this mornings context of Yegge's post -- Yes. My experience with Clojure is that it's really crossed a cleanliness / expressiveness barrier that other Lisps handn't been able to do (for me). I've sat down and gotten myself workably proficient with various CL implementationts four times in the past but never got to the point where I felt like the language was a natural way to express things. Clojure ...
15:21abrooks... crossed that barrier in the first hour of me using it. I've found myself very comfortable in Clojure and belive the small ammounts of additional map, set and vector literals and general expressiveness really bridge that gap for me.
15:21abrooksChouser, rhickey: The friend who likes Clojure but doesn't like parens isn't looking for C syntax. It's more of a Pythonic indent based syntax that he's looing for.
15:22abrooksHe gets annoyed at the duplicated expression of nesting (both in s-expressions and in indentation).
15:23abrooksDisappearing parens? I should read all of the backlog. I was in meetings and am just catching up now.
15:23ozzileeDoes anything besides emacs do decent s-expr indentation? Eclipse?
15:23ozzileeabrooks: Have you tried Scheme, out of curiousity?
15:24abrooksrhickey: Are you talking about sweet-expressions?
15:24abrookshttp://www.dwheeler.com/readable/retort-lisp-can-be-readable.html
15:24abrooksThe parens bugged me too... up until Clojure. Then I just didn't care any more.
15:24rhickeyno, not really disappearing, just an example of how they effectively disappear
15:25rhickeynot in favor of sweet-expressions
15:26abrooksI'm not either. There was a time I thought that idea was nifty. Like I said, it doesn't bother me any more.
15:26abrooksI should really try to identify why it bugged me and why that
15:26abrooksI should really try to identify why it bugged me and why that's not an issue to me.
15:27rhickeyright, the trick is to convey that effect to newcomers, since invariably anyone who sticks with it soon no longer cares
15:27abrooksrhickey: I do think one important thing that eventually happened over my previous Lisp forrays is learing to format Lisply instead of Cishly.
15:27abrooksFormatting properly is a big part of not having to read the parens.
15:27rhickeyyes, indentation is as important as, well everywhere else
15:28abrooksPerhaps all intro to Lisp tutorials should start with a reformat your thinking about formatting.
15:29abrooksi.e. This is how you format and read code in Lisp (or in our case, Clojure).
15:31ozzileeWhat do you guys use for an editor?
15:31abrooksI'm using Vim for now. I want more out of it but its working well enough.
15:32leadnoseI'm quite a newbie to lisp, but the parentheses never really bugged me because a proper editor should handle it just as easily as any else
15:32leadnoseI've been using emacs with slime
15:33ozzileeHeh. Why is it that anytime the phrase "proper editor" comes up, it's emacs?
15:33ozzilee</rhetorical>
15:33leadnoseI didn't say it is the only one :)
15:34leadnosebut I think that the editor should handle most of the formatting in any language
15:34leadnosemostly indenting though
15:34ozzileeYeah, it should, but a lot of editors don't deal with s-exprs very well. Textmate, for one. IDK about Eclipse, haven't tried it.
15:35ozzileeIt's too bad about Clojure removing parens from cond. It doesn't indent properly without a special rule now...
15:35ChouserI'm working on getting jVi to work with enclojure in NetBeans. ...still don't have it right yet.
15:36ChouserI'm headed home. ...later...
15:36ozzileelater
15:37abrooksozzilee: Didn't see your question until now -- no, I've never written Scheme though I've read chunks of SICP.
15:38abrooksActually, I guess I did a really small amount of Guile.
15:38abrooks...And librep but that's neither here nor there.
15:39ozzileeabrooks: It's a lot cleaner than CL. I don't much like CL either.
15:40ozzileeMight be worth checking out. I think Clojure's going to end up being more practical for a lot of things.
15:40ozzileeI'd recommend Chicken Scheme myself.
15:41ozzileeer, "more practical for a lot of things, though."
15:50rhickeyI've added repeatedly and add-classpath:
15:50rhickey(add-classpath "file:/Users/rich/dev/colt/lib/colt.jar")
15:51rhickey(take 10 (repeatedly rand))
15:52ozzileerhickey: Wow, you're intense :-)
15:53ozzilee(repeatedly rand) or (repeatedly (rand)) ?
15:53rhickeynote repeatedly is a function, not a macro like I showed before
15:53ozzileeOk, that was my question :-)
15:53rhickeyso (repeatedly rand)
15:55ozzileeVery cool, I'm going to have to switch to trunk for add-classpath, that will be nice.
15:56ozzileeMaybe just on my Mac at home though, I always feel like I'm working with boxing gloves on in Linux...
15:57ozzileerhickey: Do you work on Clojure full-time?
16:00rhickeyozzilee: no
16:01abrooksIt just might appear that way but Clojure has allowed rhickey to open a spacetime portal and have TWO full time jobs.
16:02ozzileeabrooks: I see. Is that macro in SVN trunk? I might have to upgrade for that...
16:03abrooksozzilee: I've been trying to use it but I find it flaky. It must be something in rhickey's environment that I don't have. I wind up having half the time I had before I found Clojure. ;-)
16:04ozzileeheh
16:04abrooksMaybe I'm using the wrong JDK. Like one without quantum entanglement.
16:04rhickeyabrooks: as long as you get twice as much done with the Clojure half...
16:06abrooksIt's not quite there. I still have a lot of Java learning before I can just go in a straight line without zagging to check various Java resources. The clojure part is pretty smooth aside from the moments of confusion followed by epiphany. :)
16:06ozzileeabrooks: What languages are you coming from, if you don't mind me asking?
16:08abrooksC, C++, Python, Ruby, Haskell, et al.. I did some Java stuff ages ago but don't really count it.
16:09abrooksI mostly do C, Python and Bash at my current Job.
16:09abrooksThe C is mostly Linux kernel. Most userspace is a mix of Bash and Python with some small parts in C.
16:11ozzileeNice. So a decent mess of stuff :-)
16:11abrooksOh, and GNU Make. =-O
16:11abrooksozzilee: Yes, all the horrors of the programming language universe. :-)
16:12abrooksWe actually use Lisp inhouse for our DMA engine compiler and some internal network analysis tools but that's not my domain.
16:12abrooksSBCL is the Lisp we use.
16:12ozzileeInteresting that Clojure seems to be pulling in a lot of people with no other interest in the JVM.
16:13ozzileeI don't think Scala or Groovy could say the same thing.
16:14abrooksYes. I only had ill feelings for the Java universe. (I didn't mind the JVM so much as certain language misfeatures and the warped Sun mindset that Java is a self sufficient universe that doesn't need to acknowledge anything outside.)
16:15abrooksI think the things happening with GNU Classpath and IceTea are exciting. Hopefully opensource will truly come to JavaLand.
16:16rhickeyOne nice take-away from Java One was that the JVM is truly detached from Java - lots of support for non-Java langs etc.
16:16abrooksozzilee: I do think it's interesting that the number of JVM languages appears to be growing. Java 7 has dynamic language support -- something that Sun would have never done 5 years ago as it does nothing for Java.
16:16abrooksrhickey: Exactly. --^
16:18ozzileeIt will certainly be interesting to follow for the next few years.
16:19rhickeyI think the JVM is going to see very much increased use
16:19rhickeySo much free infrastructure
16:20rhickeygreat tech (HotSpot)
16:20rhickeyopen source
16:20ozzileeI'm curious to see if Apple changes their attitude on it. They seem pretty lukewarm towards it lately.
16:20abrooksYep. And one thing I have been impressed with are the tools that Sun has provided for debuging and profiling.
16:21rhickeythat was a stunning disconnect at the show. In the sessions I attended, Macs were used by 90% of the presenters...
16:21rhickeyBut some of the JavaFX stuff is still not supported on Mac, so they were running in VMs
16:21rhickeySun and Apple have to get this together
16:24ozzileeThey really do. Heh I just googled "iphone jvm" and found a bunch of articles talking about how the lack of Java was going to bury the iPhone. Not so much...
16:25drewrI'm not sure I understand how Java and the JVM can be disconnected. Could you write a language for hosting on the JVM in something other than Java?
16:26abrooksdrewr: If you bootstrapped you could.
16:26abrooksI'm not sure you'd want to, I guess.
16:26drewrWhat's Java written in?
16:26rhickeyYou could write one today in Clojure
16:27abrooksAlso, you'd lose all of the libraries if you were to entirely purge Java. I'm not sure you'd want that either.
16:27abrooksdrewr: C++ IIRC.
16:28rhickeyJava is really a good infrastructure language. I hope they stop changing it. But you need something like it, just not for all applications
16:28drewrSo could you write a Scheme hosted on the JVM that's properly tail-recursive?
16:29rhickeythe disconnection is that you don't need to program in Java in order to leverage it and the JVM
16:29abrooksdrewr: Java sources, now that you distracted me. ;-) http://hg.openjdk.java.net/
16:29ozzileedrewr: Kawa is tail-recursive, I believe.
16:29rhickeyonly in a special slow mode
16:29drewrI guess I don't understand how VM architecture works (Gemstone, Hot Spot, et al).
16:30abrooksThe bytecode instructions are stack based.
16:30rhickeyan interpreter could be tail recursive, see SISC
16:30drewrKawa and SISC are written in Java though, aren't they?
16:30rhickeyand Sun could make the JVM native calling do TCO, in which case Clojure would immediately do the same
16:31abrooksIt goes all the way down to the instructions but with the changes happening for dynamic languages in Java 7 I wonder if you could get an efficient tail recursion instruction set added.
16:31rhickeydrewr: there is a spec for the bytecode, and many ways to generate that
16:31drewrAh, OK.
16:31rhickeyabrooks: TCO is not on the short list for JDK 7 AFAIK
16:32abrooksrhickey: No.
16:32abrooksrhickey: I meant theoretically the project might be ammenable to accepting it in a future release if you could demonstrate the demand.
16:32rhickeyThe JDK7 dynamic languages stuff benefits languages like JRuby and Jython more than Clojure
16:33abrooksRight. I've looked at the changes.
16:33abrooksThey excite me but do nothing that I can tell for Clojure.
16:33abrooksHm. Is there any benefit that Clojure could extract from the dynamic language changes?
16:33abrooksrhickey: --^
16:34rhickeyabrooks: That emphasis (JRuby/Jython) is not a good one IMO. Trying to make ported interpreted languages without great semantics run well, vs languages written for the JVM (Clojure/Scala/Groovy)
16:34rhickeyFor Clojure I would like TCO and tagged references
16:35abrooksWhat would tagged references buy you?
16:35rhickeyno boxed numbers
16:35abrooksboxed numbers?
16:36rhickeyhttp://blogs.sun.com/jrose/entry/fixnums_in_the_vm
16:36abrooksAh!
16:36rhickeywould greatly speed up math and use of numbers
16:36abrooksOkay.
16:36abrooksEfficient "cut-through" objects without the objects, right?
16:37rhickeyOther than that Clojure is pretty well satisfied by what currently exists, since type hints get rid of the need for all the reflection optimizations, and Clojure's native calling is very fast right now.
16:37abrooksI just didn't recognize the term.
16:38rhickeyabrooks: no boxing means no allocations, no blowing cache to follow references to numbers in random memory locations etc
16:38abrooksYep.
16:38rhickeyIt's my #1 feature request, but the importance of it is not recognized by some of the other dynamic lang devs
16:39rhickeyhttp://groups.google.com/group/jvm-languages/browse_frm/thread/ac9308ae74da9b7e
16:40rhickeyBy building for the existing JVM, with a pragmatic approach, Clojure is doing quite well, vs langs that inherited a design they have to make work on the JVM, especially one that started out as an interpreter.
16:41rhickeyoff to my second full-time job :)
16:41bpattisonhas anyone had any problems using enclojure in netbeans 6.1 under windows? namely <alt-enter> doesn't seem to be committing my expression to REPL -- plus shift-ctl-L doesn't seem to work
17:09ozzileeWhat? Clojure doesn't have fold??
17:10ozzileeOh, I guess I can just cons the starting value onto the front of the sequence and use reduce...
17:25lisppaste8ozzilee pasted "I love lisp." at http://paste.lisp.org/display/60648
18:58esquesque_what does a metadata map for a map look like?
18:59esquesque_is it just the type of the value?
19:00esquesque_#^String {:key "value"}
19:01rhickeyno, metadata is an optional map that can be attached to some objects - collections and symbols. If you hadn't added metadata to a map there would be none:
19:01rhickeyuser=> (def m {:a 1 :b 2})
19:01rhickey#'user/m
19:01rhickeyuser=> (meta m)
19:01rhickeynil
19:02esquesque_you can't attach metadata to a map?
19:02rhickeyyes you can
19:02rhickeythere is no metadata unless you put some on it
19:04esquesque_erm... metadata for a function looks like #^Type (defn ...) because a function evaluates to only one value
19:04esquesque_but a map has two - key and value
19:04esquesque_i was wondering if the metadata for a map had a constraint for the key and value or just the value
19:05rhickeymetadata is always a map, no matter what it is attached to
19:05esquesque_i'm talking about conveying types to the compiler
19:06rhickeythere is read/print shorthand for metadata when the only entry in the map is :tag, in which case it prints like #^Tag
19:07rhickeywhen you convey types to the compiler you do so by attaching metadata to symbols usually. Metadata is also available for arbitrary program use
19:08rhickeyuser=> (def m #^{:x 1 :y 2} {:a 1 :b 2})
19:08rhickey#'user/m
19:08rhickeyuser=> m
19:08rhickey{:a 1, :b 2}
19:08rhickeyuser=> (meta m)
19:08rhickey{:x 1, :y 2}
19:11esquesque_okay, thanks
19:11esquesque_i was thinking you could apply :tag to maps