#clojure log - Jul 21 2008

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

7:42 abrooks: Colin, of Project Euler just emailed me to say that he added Clojure to the list of available languages. If you've been solving your PE problems with Clojure you can now show that to the public. :)

11:01 Chouser: abrooks: that probably warrants a post to the list

11:19 * drewr wishes clojure-log had a feed of some sort

11:32 Chouser: drewr: daily atom?

11:33 hourly rss?

11:33 I guess every IRC post could be its own feed entry...

11:44 drewr: I couldn't come up with a good solution.

11:44 Every post shouldn't be an entry. That could get out of control.

11:45 Maybe hourly would work.

11:45 No entry if there wasn't activity.

11:46 Chouser: hourly would fit in with the current design pretty well.

15:06 rhickey_: note, latest svn has new namespaces for set et al -> clojure.set etc. aliases coming...

15:40 Chouser: can static functions not be called using (classname/methodname arg) syntax?

15:41 static methods I mean.

15:42 cemerick: Chouser: should work -- I've been using that for a while

15:43 er, no, just for fields

15:43 sorry -- there's a contrib lib for that -- import-static, I think

15:43 rhickey_: user=> (Boolean/valueOf "true")

15:43 true

15:44 Chouser: yep, sorry -- it's non-static method. I'm trying to run some old code and wasn't paying close enough attention.

16:20 mebaran151: is there a linter for clojure that I can call from emacs?

16:21 Chouser: mebaran151: to check for syntax error or something?

16:21 mebaran151: just to prettify the code

16:21 and fix nasty indentation

16:21 I still haven't gotten down a good LISP indentation style yet

16:22 Chouser: ah. I think there's a clojure-mode, but I have no idea if it helps with indentation or not. I don't use emacs.

16:23 toyvo: mebaran151: tell me if you find one :) I have been sitting in scheme-mode, which indents OK except some parts that are idiomatic to Clojure

16:23 rhickey_: http://clojure.codestuffs.com/

16:23 mebaran151: Chouser, what editor do you use?

16:24 I have the clojure mode, but I don't think it contains a linter

16:24 Chouser: vim

16:24 toyvo: rhcickey_: thanks Rich, looks good.

16:25 Chouser: the plugin I use for indentation is imperfect -- perhaps similar to what toyvo described.

20:25 toyvo: I also have Clojure in inferior-lisp, for what it's worth for now. But must check out that Clojure mode.. Anyone tried running a long-standing Clojure with detachtty? Any issues with that? That would be fun - a dynamic JVM in production.

20:25 rhickey_: mebaran151: still not quite sure what you mean by linter, but if you select a region and do C-M-\ clojure mode will re-indent the region

20:26 mebaran151: you sure it's C-m-\? That just seems to add a new line to the top of my buffer.

20:27 rhickey_: mebaran151: did you have a region selected?

20:28 mebaran151: yeah

20:28 that's ctrl-m backslash right?

20:29 rhickey_: mebaran151: ctrl-meta-\

20:29 all together

20:30 mebaran151: that doesn't seem to change anything

20:30 rhickey_: may be ctrl-alt-\ depending on os

20:30 mebaran151: just put it on a nasty bit of clojure I'm working on it and it slightly forgot to do anything

20:31 rhickey_: if you go down the code and type Tab on each line does it indent?

20:34 toyvo: mebaran151: maybe you are in text mode and not in scheme/lisp/clojure mode? I go to scheme mode by pressing escape, then x, then typing scheme-mode (enter). Should be similar for other modes.

20:34 mebaran151: it's seems to be syntax highlighting properly

20:36 how do I reindent in scheme mode

20:36 just switched to it

20:37 toyvo: M-x mark-whole-buffer and then M-x escape-region. M-x - emacs jargon for Esc then x, or Alt+x, or Meta+x

20:38 sorry, indent-region, not escape-region

20:38 these commands should be the same in any mode

20:43 rhickey_: namespace aliases are up, via Graham Fawcett (alias 'set 'clojure.set)

20:44 Chouser: nice

20:46 now give scgilardi a few minutes to integrate that into lib...

20:46 toyvo: Do you guys plan to go for Clojure code repo like CPAN or Scala Bazaars? Are those 12 or so files in SVN I've seen (under User Contributions) the repository as of today? Or is the preferred way of distributing Clojure code is in jars?

20:50 Chouser: toyvo: I'm sure someone else can answer better than I, but my understanding is that the relationship between directory structure namespaces is currently in flux.

20:50 once that has settled down and lib (or something like it?) has been rolled into stock clojure releases, we'll have sufficient framework to think about the next stage.

20:51 for now there's clojure-contrib and various bits of .cljs and .jars here and there on the web.

20:53 The fact that Java has nothing like CPAN (that I know of?) and "hasn't needed it" may mean Clojure never gets something like it either. Dunno.

20:53 mebaran151: what do other lisps do for pkg management?

20:53 toyvo: Chouser: Thanks - that's how the situation looks to me. Hmm...

20:54 I know PLT Scheme has a pretty innovative PlaneT repository. It allows you to do something equivalent to Java's code loading over HTTP.

20:54 THat is, you just write (require (planet ...)) and the system downloads and installs the correct version of the package and its dependencies for you.

20:54 leadnose: common lisp has asdf and cl-build

20:54 Chouser: mebaran151: gentoo seems to actively package and distribute common lisp libs via their standard OS distro system.

20:54 mebaran151: without something like CPAN, the biggest problem is that most libraries won't reuse the utils in the others

20:55 because dependency management would be too much of a pain

20:56 btw, I'm maintaining a clojure pkg for archlinux

20:57 toyvo: mebaran151: great!

20:57 mebaran151: I wish you guys would just include the jline jar inside clojure

20:58 Chouser: I don't use JLine.

20:58 I like rlwrap. :-)

20:58 mebaran151: I was thinking of making everyone just use rlwrap, but I wondered if there were any downsides

20:58 toyvo: Ah that's what it is! I'm on rlwrap too :)

20:59 I've not written much java before this week - but supposedly something like JLine is NOT included, can you load it over HTTP? Is that something URLClassLoader is about?

21:00 mebaran151: I don't like the idea of loading remote code: seems like a huge security risk

21:00 Chouser: toyvo: I think so, but I don't think it caches it anywhere.

21:01 toyvo: Then we could mash-up a clojure library that loads it and caches in /tmp.. Yes, it's a huge security risk. But on the other hand, loading Linux packages - isn't that a risk? I wonder.

21:01 Chouser: since clojure source can have Java dependencies, it seems like a CPAN-for-clojure would actually have to be a pretty complete Java/jar/clj fetching, dependency resolving, caching thing.

21:02 mebaran151: toyvo, it's a very explicit risk though

21:02 when I install package, I have to explicit run it before evil stuff happens

21:02 in a remote URL loading scheme, someone could just mangle the byte code to point to their evil botnet maker

21:03 toyvo: Ah yes... Perhaps certificates can help?

21:03 Chouser: I've heard Maven does something like that? Or no? Sorry, my Java is rudimentary.

21:04 mebaran151: yes, maven does automatically pull dependency

21:04 there actually really isn't any reason its infrastructure couldn't be exploited: scala does something

21:04 the only problem is that maven is very much wedded to a compile cycle, which may or may not be appropriate for a lsip

21:05 toyvo: Looks like... So that may be a good start... If it has classes we can take out and reuse.

21:05 Chouser: if we think of "compiling" clojure as being more of "fetch and compile java dependencies, fetch .clj and run any gen-class stuff" it maps ok, right?

21:06 mebaran151: maybe, though compiling is a very external process in Java Scala land

21:06 toyvo: There's another related question I spent some time thinking about: can you load new versions of classes into a JVM without restarting it? Erlang VM guarantees such hot uploads, for JVM I was a bit confused..

21:07 mebaran151: JVM has a security model that interferes with this, but it's currently a JSR

21:07 you could try something like java rebel, but it's proprietary and I don't see how it maintains bytecode security

21:08 Chouser: Clojure works hard to allow dynamic code changes without actually having to replace Java classes.

21:08 mebaran151: you can also try class loader hacks, but those are always very memory leaky

21:09 toyvo: Ah... Right! Hm.. But in Clojure, if I load new proxies, these are different classes, right? So the old ones can get recycled.

21:11 But then, it looks like distributing Clojure as compiled bytecodes is out, because new versions cannot be hot-updated in the JVM as easily, having static class names.

21:11 mebaran151: for a servlet, is there any real downside to using a proxy: I know their slower to instantiate, but aren't servlets only loaded once at server boot?

21:11 toyvo, I think the ASM library might support some name mangling

21:12 cemerick: toyvo: I understand that Rich is contemplating a FASL-esque distributable path, rather than compiling to bytecode

21:13 rhickey_: right now the story is, dynamic code means load new source

21:13 toyvo: I'm googling for "FASL"... :)

21:14 cemerick: toyvo: you won't find much -- there's no spec or anything -- it appears to be implemented differently in every lisp

21:14 toyvo: oh, but what IS it? I'm los

21:15 Ah, got it

21:16 mebaran151: can Java call clojure?

21:17 toyvo: mebaran151: that was a good question. I'm interested too if proxy servlets are in any way inferior. They seem superior in being easily reloaded - modified from a REPL.

21:17 mebaran151: well I've read that proxy's instantiate much slower

21:17 but for a server, I think that a servlet only needs to be loaded once

21:18 rhickey_: The best recipe for servlets is to use gen-and-save-class, this gives you a static class stub, with all of the real logic in Clojure, and thus re-loadable

21:18 mebaran151: but right now, I'd prefer not create trash class files as develop the servlet

21:18 rhickey_: ?

21:19 mebaran151: well doesn't it write a class file

21:19 or is this class file static as I change it's internal logic

21:19 rhickey_: yes, and the same one will be useful for the entire lifecycle of development

21:19 it doesn't need to be regenerated

21:21 note: new in svn - all of the .cljs have moved out of the root! and now follow classpath rules

21:22 toyvo: gen-and-save-class - is it only in SVN? My system seems not to find it.

21:22 Let me upgrade

21:22 mebaran151: rhickey, what do you mean by moved out of root?

21:24 rhickey_: boot.clj et al were all in the root of the jar, now in classpath-compliant subdirectories corresponding to the packages of the classes of the generated functions

21:24 user=> map

21:24 clojure.map__571

21:24 user=> clojure.set/union

21:24 clojure.set.union__1962

21:26 in /clojure/boot.clj and /clojure/set/set.clj respectively

21:30 toyvo: Has anyone thought of writing a Clojure bot to sit in the IRC? Like Haskell's Lambda bot?

21:31 Chouser: it's been mentioned several times. Nobody's quite bothered to do it yet though.

21:32 toyvo: I'll give it an hour.. Seems to be a fun thing to do.

21:32 mebaran151: ah, so this is more of an internal thing, the classpath edits?

21:34 rhickey_: well, some of the libraries need to be manually loaded, so people might need to edit the paths. Otherwise, it is for tooling, lots of Java support for finding things in classpaths, so now Clojure is more compliant. It also provides a known schema for file layout that can be leveraged by the lib/require framework.

21:35 drewr: ,test

21:35 clojurebot: I don't yet know what "test" means.

21:35 drewr: clojurebot: Learn then!

21:35 Chouser: ,(println "hello everyone")

21:35 clojurebot: I don't yet know what "(println "hello everyone")" means.

21:35 Chouser: awww

21:35 drewr: :-)

21:36 Haven't decided yet what to hook into it. Probably the DOC function for starters.

21:36 toyvo: Ah

21:36 Neat

21:36 Chouser: Doing any Java sandbox stuff? Any logging?

21:37 drewr: Nope, basically an echo service currently.

21:37 * Chouser nods

21:38 toyvo: ,(doc gen-and-save-class)

21:38 clojurebot: I don't yet know what "(doc gen-and-save-class)" means.

21:38 drewr: I didn't do logging because I didn't have a dedicated box for it. I'm going to switch my VPS to a vendor whose network allows IRC and then I'll fire it up.

21:39 toyvo: ,(doc int)

21:39 Chouser: drewr: ok. When that's done, if you're interested we can look at rolling clojure-log into it.

21:39 clojurebot: I don't yet know what "(doc int)" means.

21:40 toyvo: ,(def id #(%))

21:40 clojurebot: I don't yet know what "(def id #(%))" means.

21:40 rhickey_: drewr: doc is easy, just echo (doc x) => http://clojure.org/api#x

21:40 Chouser: drewr: right now clojure-log is connected from my aging linux workstation over residential DSL. Anything would be more robust, I'm sure.

21:41 drewr: Chouser: Yup. I didn't want to bother unless it was going to improve on what you've done.

21:42 toyvo: drewr: so clojurebot is just an echo? man, i'm confused :) I kept thinking it's an interpreter with an unknown limited set of commands.

21:43 Or is there something it does right now?

21:43 ,(+ 1 2 3)

21:43 clojurebot: I don't yet know what "(+ 1 2 3)" means.

21:43 drewr: toyvo: It's unlikely I'll allow readable expressions.

21:43 I would think it's too hard to do it securely, so I haven't given it much thought.

21:43 toyvo: drewr: what does/will it allow then?

21:44 drewr: toyvo: Print docstrings and google results perhaps.

21:45 toyvo: drewr: Well... Are you sure security is such a big big issue?

21:45 rhickey_: drewr: http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html

21:45 toyvo: Rich: thanks for the link!

22:18 fyuryu: is it normal, that stuff gets printed twice? http://paste.lisp.org/display/64026

22:28 Chouser: what's swing-frame?

22:28 fyuryu: in other words: do methods contained in proxy are somehow executed twice?

22:29 Chouser: oh, just a function that creates a swing-frame and packs the applet into into it

22:31 Chouser: the body of your "setup" method shouldn't be called at all when it's defined

22:32 you're sure swing-frame isn't somehow causing your setup method to be called twice?

22:34 fyuryu: Chouser: no, applets require (according to javadoc) that a "init" call when inserted into a swing frame, but I don't call "setup" myself

22:36 Chouser: maybe it's a Processing thing

22:41 Chouser: ok, I got it. I created the frame in a try catch block

Logging service provided by n01se.net