#clojure log - Jul 29 2008

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

0:54 Chouser: I just added gen-interface to clojure-contrib.

0:54 It's undocumented, weakly tested, and the API will probably change. But I believe it is functionally complete.

0:55 The filename and namespace may not even be correct -- I haven't quite figured out the new contrib layout.

0:57 perhaps make-array could take either an integer or a seq. integer would be current behavior, seq would use the given member type, but populate it with the contents of the seq like into-array does.

1:11 jykrd: I don't see why this should be so hard. I'm trying to add clojure support to scite, right? But I'm using the plain lisp lexer that comes with scite.. I just want scite to associate all my *.clj files with the clj shell script (which runs clojure). But I can't get it to work.

1:12 file.patterns.clj=*.clj

1:12 filter.clj=clj (clj)|*.clj|

1:12 lexer.$(file.patterns.clj)=lisp

1:12 command.go.$(file.pattern.clj)=/home/john/bin/clj $(FilePath)

1:13 those four lines, in the lisp.properties file, should do the trick, as far as I can tell

1:14 that, and I added clj to a few places in the SciTEGlobal.properties file

1:24 oh, wait, I think I did it

1:26 um, yes.. frick ya

1:30 no to build a keyword list.

1:32 Which basically means any reserved word?

1:32 ie, don't use the Clojure sense: Keywords are like symbols, except: They can and must begin with a colon, e.g. :fred. They cannot contain '.' or name classes.

1:54 omg the keyword list is long.. I'm just putting in the entire api

2:12 dude, that was a lot of typing

2:16 mebaran151: well jykrd those aren't really keywords per se

2:16 much closer to a stdlib

2:21 jykrd: right, and I guess "Special forms" would be closer to keywords?

2:21 but where do I draw the line?

2:21 well, I suppose some can be over-riden and others not, right?

2:26 but what's better, "def" and "first" show up as different colors or both as blue?

2:27 or def and map

2:30 hoeck: jykrd: are you talking about editor highliting?

2:30 jykrd: yea, scite, the editor

2:31 hoeck: jykrd: ahh, i see

2:31 jykrd: It's working pretty well actually

2:31 it's using the lisp lexer

2:32 I've added all the clojure words in there

2:32 I go to tools -> go, and it executes into a second window pane

2:33 got the pretty highlights going and everything.

2:33 now, here's the really interesting part:

2:33 hoeck: emacs lisp modes are highlighting every symbol matching ^\(def.*

2:34 jykrd: does that not cover everything in the api?

2:35 oh well, the keyword list can be tweaked... here's the interesting thing:

2:36 hoeck: actually not, only standard "if", "let", ":keywords" and strings

2:36 jykrd: I'm looking at a tutorial right now to integrate java ide features into scite: java classes highlighting, calltips, and auto completion

2:37 so, what I'm going to do is work through this tutorial, but use it on my clj extensions to scite, rather than java

2:37 and see what kind of java integration I can mingle in with the clojure

2:38 http://www.burgaud.com/scite-java-api/

2:39 start typing StringB.. and it lists options for StringBuffer, StringBufferInputString, StringBuilder, etc

2:39 does emacs do that?

2:39 ;)

2:39 well, you could probably make it do that

2:41 hoeck: yeah, there is some kind of keyword-completion

2:41 jykrd: yea, but can you hook in the entire java api?

2:41 plus, java help docs?

2:42 hoeck: iirc you have to generate tags from the source files

2:44 but i prefer the dynamic abbreviation mode, where the editor tries to complete a given string by searching the open files for matches

2:51 i actually would like to have a kind of a hybrid environment, where you use the editor for code input and some self-hosting clojure-routines for browsing, inspection, profiling ..

2:52 jykrd: part if this tutorial provides 'tooltips' which give pop up tips showing you what types of parameters a give method accepts. Like, type buffer.append( and a tooltip pops up saying "append(String)". You configure that functionality in a scite config file with this:

2:52 calltip.java.word.characters=._$(word.chars.cxx) calltip.java.parameters.start=( calltip.java.parameters.start=) calltip.java.parameters.separators=.

2:52 How could I translate that into clojure?

2:53 calltip.java.parameters.start=.*

2:53 (with a space at the end)

2:55 hoeck: the problem is, in clojure you (normally) type the method before the class

2:55 as in (.method class)

2:55 jykrd: I thought it was (.method param)

2:55 hoeck: i mean object

2:56 jykrd: right, param could be object, right?

2:56 but it's the parameter

2:56 hoeck: (.method object params...)

2:56 jykrd: oh

2:57 yea

2:57 hoeck: yes, so the 'intellisense' doesn't know the methods to complete

2:57 jykrd: looking at that now...

2:58 hoeck: completing ctors would work

2:58 jykrd: so maybe (02:52:35 AM) jykrd: calltip.java.parameters.start=.word word

2:59 hoeck: at least for java interop

3:00 jykrd: if scite is using some kind of regex resolution there, and it has some way to express "dot word word $"

5:46 Lau_of_DK: Chouser : You here?

6:01 Anybody here comfortable working with XML in Clojure ?

6:06 user=> (class (first (xml-> x :problem)))

6:07 class clojure.lang.LazilyPersistentVector

6:07 user=> (class (xml-> x :problem [:title "Broken room"]))

6:07 class clojure.lang.PersistentList

6:07 Why arent these the same class-type, anybody know?

6:16 hoeck: Lau_of_DK: you are using "first" in the first example

6:17 where can i find the "xml->" function?

6:27 Lau_of_DK: in xml.clj in clojure.jar

6:28 sorry Im mistaken, its in Chousers' zip-filter in user-contrib

6:28 http://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/trunk/zip-filter.clj?revision=90&view=markup

6:31 But hoeck, you actually clued me in already, I just wrapped the second statement in (first ..) and then it was cast to a LPV - Thanks a lot! :)

6:47 hoeck: Lau_of_DK: np :)

6:48 Lau_of_DK: But hoeck, do you know why (first) casts as it does? It seems weird that the output type is unpredictable (to me anyway) when it can cause meltdowns later in the program

6:51 rhickey: Lau_of_DK: what do you mean?

6:54 Lau_of_DK: user=> (class (first (xml-> x :problem)))

6:54 class clojure.lang.LazilyPersistentVector

6:54 user=> (class (xml-> x :problem [:title "Broken room"]))

6:54 class clojure.lang.PersistentList

6:55 rhickey : this to me was a bit unpredictable behavior. It wasnt clear to me (it isnt) why it picked list for 1, and vector for another, and why zip/root and all those related functions crashed it it was not all done as a vector

6:55 rhickey: what does xml-> return?

6:58 In any case, a collection and the items in a collection need not be the same type. In one case you call first, getting the first item, in the other you don't:

6:58 user=> (def x [1 2 3])

6:58 #'user/x

6:58 user=> (class x)

6:58 class clojure.lang.PersistentVector

6:58 user=> (class (first x))

6:58 class java.lang.Integer

6:59 Lau_of_DK: In this case, it was (def x (zip/xml-zip (xml/parse "xmlfile.xml"))))

7:16 Meaning, (xml-> x :problem [:title "First problem"]) should be the same as (first (xml-> :problem)) right ?

7:16 I mean the content is completely identical, only one is wrapped in () and the other in []

7:17 rhickey: x and (first x) are 2 different things, for any x

7:17 except nil

7:26 Lau_of_DK: Ok, then thats the thing thats confusing me, I imaged that (first '(1 2)) was the same as {:first 1 :second 2} and then taking the first value.

9:05 Chouser: Lau_of_DK: xml-> generally returns a seq of zip nodes (unless your final expression is "node" or "text")

9:06 so the class of that will be a PersistentList or perhaps some kind of lazy list.

9:07 calling first on it will get you a single zip node. Zip nodes are currently implemented as a PersistentVector of 2 items, but you really don't want to deal with them at that level, you just want to use the zip.clj API to manipulate them.

9:38 Lau_of_DK: Chouser, thanks alot - that made perfect sense :)

9:38 Chouser: heh, great.

10:19 bstephenson: #enclojure

12:40 scgilardi: rhickey: hi Rich. The new clj directory in svn 972 is empty.

12:48 Chouser: he speaks the truth

12:48 rhickey: try now

12:54 Chouser: looks good

12:54 rhickey: sorry about that, IntelliJ made it look like the dirs were version controlled

12:57 Chouser: svn has particular problems with moving and deleting directories

12:58 storing metadata inside each subdirectoy turns out to be a Poor Choice.

14:25 ericthorsen: just pulled the latest down from svn and I'm getting an exception running the Repl: Exception in thread "main" java.lang.ExceptionInInitializerError

14:25 at clojure.lang.Repl.<clinit>(Repl.java:22)

14:25 Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: Var refer is unbound.

14:25 at clojure.lang.RT.<clinit>(RT.java:312)

14:30 Chouser: I'm not. Did you try a clean and rebuild?

14:30 That's just the REPL, no .clj file?

14:31 ericthorsen: Chouser: yes...clean build

14:33 chouser: You are running the latest clojure.lang.Repl no problems?

14:33 Chouser: yes I am. SVN 973

14:34 ericthorsen: chouser: ok, let me try again. thx

14:34 Chouser: I've not done much with it, but a repl prompt comes up ok.

14:41 shoover: ericthorsen: Do you have anything in user.clj that calls in-ns and tries to refer?

14:42 ericthorsen: shoover: no, I just pulled the latest source using IntelliJ to build, ran the Repl and I'm getting an error....let me try a fresh pull again. Thx

15:58 meredydd: Grr.

15:59 * meredydd adds his name to the long, long list of people who wish there were a way to compile Clojure to .class ahead of time, and run without code generation.

15:59 meredydd: (and I want a pony. One that flies.)

15:59 Chouser: really? why?

15:59 meredydd: Embedded platforms suck.

16:00 Chouser: I mean, I know why you want a pony. But why class files?

16:00 meredydd: Chouser: Oh, I'm starting out with Android.

16:00 It translates to a different VM, so you can't compile stuff dynamically

16:00 albino: ahh dalvik IIRC

16:00 meredydd: yep

16:01 Chouser: yeah, clojure would be fundamentally incompatible, wouldn't it?

16:01 albino: I was going to use the jython compiler with that, the jython project has deprecated their compiler though

16:01 Chouser: oh, does it traslate java bytecode to android bytecode or something?

16:01 meredydd: Well, not so much "fundamentally" - there's a mechanised JVM bytecode --> Dalvik conversion

16:02 albino: They have a compiler?!

16:02 Chouser: ah, ok. I assumed android used Java source and had its own compiler.

16:02 * meredydd goes on a frantic search.

16:02 albino: meredydd: they did for version 2.1, but like I said it's deprecated

16:02 meredydd: (hmm...wonder what the overheads are)

16:02 albino: Bugger.

16:02 so I'm back to sodding Java.

16:02 albino: meredydd: if you're willing to write 7 year old python code :)

16:02 meredydd: albino: Well, if it's that or Java...

16:03 albino: Nutter was saying jruby would get one, wonder if they have made much progress on that front

16:03 Chouser: heh, you could try emulating the asm API and generate Dalvik instead.

16:03 meredydd: I guess I'm just feeling ranty. I just looked at the easy, gentle introduction to JUnit

16:03 cemerick: I'd love to have a compile-to-classfile path; fasl-esque output will do well enough, though.

16:03 albino: meredydd: well yeah, between java and python I choose python, but interestingly enough the last two weeks I've met a few who would choose the opposite

16:03 meredydd: and it's TWENTY-SIX BLOODY LINES LONG.

16:04 This to test a single method call. Heaven help you if you need a mock object.

16:04 cemerick: meredydd: clojure-contrib/test-is is the answer to your prayers :-)

16:04 Chouser: meredydd: heh. The gen-interface I checked in last night is itself not even 26 lines.

16:05 meredydd: cemerick: I know. Well, actually, I use my own, cause I started before that was released.

16:05 cemerick: Hey, it was only 100 lines :)

16:05 cemerick: Chouser: I'm so behind the ball. gen-interface, checked in, like, where? :-P

16:05 meredydd: Chouser: Suddenly, it's so much more painful to go back :D

16:06 Chouser: cemerick: clojure-contrib. I didn't make a big announcement 'cuz it's probably not ready for prime-time. But it pretty much just works.

16:06 albino: meredydd: doesn't scala compile down to .class files

16:06 acutally I'm sure of it

16:07 meredydd: albino: It does - it's on my shortlist. Dunno how terse it gets, though.

16:07 cemerick: Chouser: Fantastic.

16:07 albino: meredydd: I wasn't happy with a lot of the syntax

16:07 meredydd: (that, and their type system scares me.)

16:07 Chouser: cemerick: do you have a use for it? If so, please let me know if it looks like it's headed in the rigth direction.

16:07 cemerick: I'm actually thinking about writing a gen-interface that dumps java source, simply so that I have something to run javadoc over.

16:07 meredydd: (Oh, yeah, the half-a-ton of syntax, too. But that's gettable-used-to.)

16:08 albino: heh, gettable-used-to

16:08 cemerick: Chouser: Yes, I do. I'll have to figure out how easy (or not) it would be to hook up javadoc so that :doc metadata on interface definitions can be integrated into its output, though.

16:08 Chouser: cemerick: I'm thinking the -and-save function should actually to a load as well, so that later gen calls can have param types etc. from earlier gens.

16:09 ah, interesting.

16:09 cemerick: Chouser: yeah, we do that as a matter of course now

16:11 Chouser: oh, you do that with gen-and-save-class?

16:13 cemerick: Yes, we have a save-gen-class macro that loads a stub of the same name and then saves the full definition. That way the gen-class spec can be colocated with code that references the generated type (as opposed to siting the specs in a -gen.clj file or something).

16:13 I posted that macro as part of my genbean post on the google group.

16:14 Chouser: yeah, I saw it, but I didn't understand your use case well enough to make sense of it.

16:14 cemerick: In our case, we use type hints that refer to the generated class.

16:14 ...in the same file, which is the point. Makes the build process a lot simpler.

16:17 Chouser: so during build you load all your .clj files?

16:17 cemerick: Yup, with *warn-on-reflection* on.

16:18 Chouser: and some other flag so your app doesn't try to start up?

16:19 cemerick: we put all of our app entry points within (if *command-line-args* ...) forms, and bind *command-line-args* to nil while we load all of the .clj files.

16:19 Chouser: that's really interesting. So you catch whatever syntax errors you can at build time, as well as generating .class files where needed.

16:20 abrooks: Hm. That is interesting.

16:20 cemerick: Yup.

16:21 I might bundle it up into an ant plugin eventually, once clojure's core settles down some.

16:21 Chouser: all without sacrificing the ability to have a repl and hot-swap code as needed later.

16:21 cemerick: There's really no other way to do it, AFAIC. There's a compiler there, one should use it. :-)

16:29 Chouser: It makes a lot of sense if you already have a build step that you run through regularly anyway. But I expect a lot of apps will need either no build step at all, or something pretty minimal to generate a .class file once in a blue moon.

16:30 cemerick: yeah, maybe. I'm pretty far away from a development environment like that, though.

17:38 Chouser: a quick run through the javadoc sources makes me think that coercing it to emit javadoc based on anything other than .java files is folly

17:40 a java-source-emitting gen-interface-src may be the only option, at least in my situation; your gen-interface would still be necessary during the build process though (yeesh, all this to avoid specifying method names more than once!)

17:52 Chouser: cemerick: you don't have a similar javadoc requirement for gen-class?

17:53 cemerick: Chouser: In general, no. I've not yet had occasion to introduce new :methods in a gen-class form.

17:53 Chouser: ah, I see.

17:55 cemerick: what I'm aiming for is to use a genbean-like form to emit an interface (that is javadoc-able) along with a default impl in one fell swoop. I might give gen-interface-src a try shortly...

18:01 Chouser: wow. ok.

18:02 cemerick: Chouser: either you're amazed or horrified or both :-P

18:03 Chouser: you need it to be real javadoc so your API consumers won't know you're not using Java?

18:04 cemerick: Chouser: roughly, yes. Some of them would absolutely freak out.

18:04 That, and it's a mixed project anyway -- the other code's docs are in javadoc, and there's really no good reason to have things split up.

18:08 Chouser: dinner. bbl.

18:12 albino: heh

18:12 I would love to see the freak out when they find out

18:13 what the f*** are all these .clj files

18:13 oh no....LISP!

18:13 cemerick: albino: they won't see any .clj files anyway ;-)

18:14 albino: cemerick: well you should do that to them at some point just for fun, have an ambulance standing by

18:15 Sometimes when i go to language groups I hear people mention lisp and the reactions are kind of funny

18:15 some people can't believe it still exists

18:15 others feel pure horror for some reason

18:16 cemerick: well, that makes for a competitive advantage for us :-)

18:16 albino: cemerick: who are you competing with?

18:17 cemerick: I should buy some of your stock so I can profit from this competitive advantage

18:17 cemerick: various other companies

19:35 jykrd: it irks me that no one is in the #scite channel

20:17 Hooke: (hi :)

20:24 jykrd: hello

20:42 Hooke: hello jykrd, how are you

20:44 (instance? jykrd FeelingGoodPerson)

20:56 Chouser: goes the other way 'round. ;-)

21:01 Hooke: false

21:01 (instance FeelingGoodPerson jykrd)

21:01 true

21:02 (doto Chouser thank)

21:02 :)

21:21 Chouser: :-)

21:36 Hooke: reading http://clojure-log.n01se.net/date/2008-06-29.html

21:37 jykrd: (.person wake (/me))

21:37 I'm good

21:38 is there a freenode room to talk about stocks and markets? I'm looking for advice

21:41 oh, theres a command for that

21:41 Hooke: for what?

21:41 jykrd: for searching for rooms by keyword

21:42 /search

21:42 or something

21:42 Hooke: aha

21:42 dunno

21:43 sorry :D

21:43 jykrd: it's cool

21:47 Hooke: I was wondering whether there is/will be a functional reactive programming framework (like frtime) in clojure

21:47 are "reactive agents" something like that?

22:27 gtg, byee

23:25 pjb3: I'm wondering how to call a Clojure function from Java, is that possible?

23:28 Chouser: sure. Repl.java calls a couple

23:29 pjb3: Chouser: I'm trying to figure out how to do the most basic hello world type thing

23:29 some how in clojure (defn foo [] "foo)

23:30 and then from Java call the foo function

23:30 Compiler.eval ?

23:30 Chouser: static final Var foo = RT.var("user", "foo");

23:31 foo.invoke()

23:31 I think. Tell me how that goes. :-)

23:32 oh, yeah, you've got to load your .clj first.

23:33 Compiler.loadFile("foo.clj")

23:36 pjb3: there is no Compiler.loadFile, I tried RT.loadResourceScript("foo.clj");

23:36 and foo.clj is in the class path

23:36 but I get Var foo is unbound

23:45 Chouser: hm, not sure. I'm just going off of Repl.java -- I don't have my own example.

23:45 maybe make sure that foo.clj is getting loaded? print something?

23:46 and make sure that function foo is defined in the "user" namespace?

23:46 that's all I've got. I'm off to bed. Hope you figure it out!

23:54 shoover1: pjb3: I got it working; my foo.clj has (clojure/in-ns 'user) at the top to make sure (defn foo ...) happens in the user namespace, as Chouser mentioned.

23:55 Also a (clojure/refer 'clojure) to make sure defn is available.

Logging service provided by n01se.net