Re: API in Clojure for Java folklore

2010-06-07 Thread Jason Smith
I think the right place for this is Maven, Ant, Leiningen, and command
line.  It's a generic thing for any build system.  :-)  Generating
correct stubs is the common part, and then there is an integration
into each system.  I'm most interested in having this for Maven, but
there's really not much to the Maven part of this (aside from some
rather arcane knowledge).

See also 
http://groups.google.com/group/clojure-maven-plugin/browse_thread/thread/1d710e7d75a564b7
(related)

On Jun 5, 5:41 am, ka  wrote:
> On Jun 5, 1:33 am, Jason Smith  wrote:
>
>
>
>
>
> > The Java stubs are, ideally, a temporary thing.  They don't need to be
> > around forever.  However, I know of no way at present to generate them
> > automatically.
>
> > Also, you are solving half the problem.  Generating the stubs and
> > class files at the same time does not solve the compile-time
> > dependency problem.  Consider:
>
> > Clojure A references Java class B references Clojure class C
> > references Java class D.  A, B, C, D are in a single project.
>
> > You *must* run either gen-class or Javac first.  Without some kind of
> > stubbing, the compile-time references are unknown, either way.  Either
> > Java does not know about the Clojure gen-class classes that are to
> > come, or Clojure does not yet know about the Java classes in the
> > project.
>
> > So, treating Java as the least-common-denominator, you run:
> > * gen-stubs
> > * Javac
> > * gen-class
>
> > Since the stubs are around, you can also run JavaDoc.
>
> > The stubs don't need to be saved. In the Maven world, they are part of
> > the build, not source files.
>
> > On Jun 4, 8:03 am, ka  wrote:
>
> > > @Jason
>
> > > I'm supplying a Java API (implemented in Clojure) so needed a solution
> > > quickly which just worked w/o me having to do special things.
>
> > > Hence the gen-class+javadoc macro (http://gist.github.com/415269).
> > > But I feel there should be something like this available in contrib
> > > which handles the whole jing-bang of gen-class !
>
> > > Currently I'm using the strategy of generating .class files from gen-
> > > class, then generating java-stubs as required, running javadoc and
> > > just deleting the java-stubs (as they provide no value in their own).
>
> > > Why do you think keeping the java-stubs is necessary?
>
> > > - Thanks
>
> Oh, now I understand fully your last post!  I hadn't considered the
> cyclic dependencies situation, thanks for pointing that out.  Though I
> can't see why right now; in future I might write some code (of mine)
> in Java to be used from Clojure (maybe performance).  In that
> situation you are right we should -
>
> 1) Generate Java-stubs for Clojure gen-class, gen-interface.
>      My macro is a half-assed attempt to generate stubs automatically
> using the gen-class args.  One complexity is to choose return values
> if return type is primitive.
>
> 2) Run javac to compile all java sources properly.
>
> 3) Run gen-class to replace stubbed .class files by Clojure
> generated .class files.
>
> 4) Run javadoc to get the seamless documentation.
>
> I'm sure I'm not qualified enough to try to code this up, given that I
> haven't used maven or ant ever myself.  But I'd like to give it a shot
> given some guidance.
>
> Do you think the right place for this is leiningen?
>
> - Thanks- Hide quoted text -
>
> - Show quoted text -

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-06-05 Thread ka
On Jun 5, 1:33 am, Jason Smith  wrote:
> The Java stubs are, ideally, a temporary thing.  They don't need to be
> around forever.  However, I know of no way at present to generate them
> automatically.
>
> Also, you are solving half the problem.  Generating the stubs and
> class files at the same time does not solve the compile-time
> dependency problem.  Consider:
>
> Clojure A references Java class B references Clojure class C
> references Java class D.  A, B, C, D are in a single project.
>
> You *must* run either gen-class or Javac first.  Without some kind of
> stubbing, the compile-time references are unknown, either way.  Either
> Java does not know about the Clojure gen-class classes that are to
> come, or Clojure does not yet know about the Java classes in the
> project.
>
> So, treating Java as the least-common-denominator, you run:
> * gen-stubs
> * Javac
> * gen-class
>
> Since the stubs are around, you can also run JavaDoc.
>
> The stubs don't need to be saved. In the Maven world, they are part of
> the build, not source files.
>
> On Jun 4, 8:03 am, ka  wrote:
>
> > @Jason
>
> > I'm supplying a Java API (implemented in Clojure) so needed a solution
> > quickly which just worked w/o me having to do special things.
>
> > Hence the gen-class+javadoc macro (http://gist.github.com/415269).
> > But I feel there should be something like this available in contrib
> > which handles the whole jing-bang of gen-class !
>
> > Currently I'm using the strategy of generating .class files from gen-
> > class, then generating java-stubs as required, running javadoc and
> > just deleting the java-stubs (as they provide no value in their own).
>
> > Why do you think keeping the java-stubs is necessary?
>
> > - Thanks

Oh, now I understand fully your last post!  I hadn't considered the
cyclic dependencies situation, thanks for pointing that out.  Though I
can't see why right now; in future I might write some code (of mine)
in Java to be used from Clojure (maybe performance).  In that
situation you are right we should -

1) Generate Java-stubs for Clojure gen-class, gen-interface.
 My macro is a half-assed attempt to generate stubs automatically
using the gen-class args.  One complexity is to choose return values
if return type is primitive.

2) Run javac to compile all java sources properly.

3) Run gen-class to replace stubbed .class files by Clojure
generated .class files.

4) Run javadoc to get the seamless documentation.

I'm sure I'm not qualified enough to try to code this up, given that I
haven't used maven or ant ever myself.  But I'd like to give it a shot
given some guidance.

Do you think the right place for this is leiningen?

- Thanks

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-06-04 Thread Jason Smith
The Java stubs are, ideally, a temporary thing.  They don't need to be
around forever.  However, I know of no way at present to generate them
automatically.

Also, you are solving half the problem.  Generating the stubs and
class files at the same time does not solve the compile-time
dependency problem.  Consider:

Clojure A references Java class B references Clojure class C
references Java class D.  A, B, C, D are in a single project.

You *must* run either gen-class or Javac first.  Without some kind of
stubbing, the compile-time references are unknown, either way.  Either
Java does not know about the Clojure gen-class classes that are to
come, or Clojure does not yet know about the Java classes in the
project.

So, treating Java as the least-common-denominator, you run:
* gen-stubs
* Javac
* gen-class

Since the stubs are around, you can also run JavaDoc.

The stubs don't need to be saved. In the Maven world, they are part of
the build, not source files.

On Jun 4, 8:03 am, ka  wrote:
> @Jason
>
> I'm supplying a Java API (implemented in Clojure) so needed a solution
> quickly which just worked w/o me having to do special things.
>
> Hence the gen-class+javadoc macro (http://gist.github.com/415269).
> But I feel there should be something like this available in contrib
> which handles the whole jing-bang of gen-class !
>
> Currently I'm using the strategy of generating .class files from gen-
> class, then generating java-stubs as required, running javadoc and
> just deleting the java-stubs (as they provide no value in their own).
>
> Why do you think keeping the java-stubs is necessary?
>
> - Thanks

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-06-04 Thread ka
@Jason

I'm supplying a Java API (implemented in Clojure) so needed a solution
quickly which just worked w/o me having to do special things.

Hence the gen-class+javadoc macro (http://gist.github.com/415269).
But I feel there should be something like this available in contrib
which handles the whole jing-bang of gen-class !

Currently I'm using the strategy of generating .class files from gen-
class, then generating java-stubs as required, running javadoc and
just deleting the java-stubs (as they provide no value in their own).

Why do you think keeping the java-stubs is necessary?

- Thanks


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-06-01 Thread Jason Smith
[Note, you can implement this solution by writing stub classes by
hand.  This means you write stubbed out Java classes, run Javac first,
and allow Clojure to overwrite the stubbed class files when it
compiles.  This is easy to do in Maven, and not difficult in ANT.  And
I have not actually tried this yet, so it's possible that there are
wrinkles that still need to be ironed out.]

For a general solution to this problem, which covers not only Javadoc
but also the compile-time dependency "chicken-and-egg" problem, I
believe we need two stages of compilation to be compatible with
Javac.

1) Generate Java stubs from Clojure.
2) Generate class files from Clojure.

These need to be separate steps, since (1) must be run before Javac
and (2) must be run afterwards.

Here is how it would work in the bigger scheme of things.

a) gen-stubs generates stubbed Java files.  These files are actual
Java source, but the methods just throw NotImplementedException.
  (1) includes Javadoc from Clojure metadata
  (2) includes annotations
  (3) includes Types, including generic definitions
b) Run Javac against Java classes and Clojure (Java) stubs.
Everything compiles, and the annotation processor (Java 5 and 6) is
happy as well.
c) Run Clojure compile, which overwrites all the stubbed classes from
step (b).

d) (OPTIONAL) Run Javadoc against Java + Clojure stubs.  This will
produce complete, seamless Javadoc for consumption by Java users.

By using two steps and stubs, the chicken-and-egg problem is solved.
You don't get odd compile-time dependency problems.  Even though there
are two separate compilations happening, it works as if there is only
one.

I am hoping that someone else will implement this solution before I
get around to needing it!  :-)

Note also that this would allow you to combine Java, Groovy (which
already implements stubbed compilation), and Clojure all in the same
build with circular dependencies between all three languages.

On May 28, 3:36 pm, ka  wrote:
> I've also added a :class-doc key to the macro -
>
> (gen-class+javadoc
>   :class-doc "Class Docs
>                        One   Two  
>                      "
>   :name "a.b.c.MyCoolClass"
>   :methods [
>                   #^{:static true} [method1
> [clojure.lang.PersistentArrayMap] int]
>                   #^{:static true} [method2 [int int float]
> clojure.lang.LazySeq]
>                   #^{:static true} [method3 [] Object]
>                   ])
>
> Thanks

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-05-28 Thread ka
I've also added a :class-doc key to the macro -

(gen-class+javadoc
  :class-doc "Class Docs
   One   Two  
 "
  :name "a.b.c.MyCoolClass"
  :methods [
  #^{:static true} [method1
[clojure.lang.PersistentArrayMap] int]
  #^{:static true} [method2 [int int float]
clojure.lang.LazySeq]
  #^{:static true} [method3 [] Object]
  ])

Thanks

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-05-26 Thread ka
Hi all,

Inspired by Erik above, I've written a macro: gen-class+javadoc
(http://gist.github.com/415269).

It works quite well for me on Windows XP.  For *nix, I think people
will have to make at least one change - the shell command (at line
57).

What it does -
1. Generates a javadoc for your API made using gen-class.

How to use -
1. Just use gen-class+javadoc macro instead of the gen-class macro.
_No other changes are required by the coder_.

Functioning -
1. It calls gen-class first as usual with the args.
2. Generates a .java file containing the javadoc.
3. Runs the javadoc command and generates docs in the doc/ directory.
4. Deletes the .java file created above.

Few points to note -
1. It is by no means complete.  For eg. it doesn't handle interface
related stuff yet.
2. It uses macroexpand inside a macro, but some people on Clojure#
pointed out that this is not recommended.  I'm very new to macro-foo,
so please let me know of the alternatives.
3. The macro itself contains a lot of side effects, dunno if this is a
very big issue.

Try it out if you expose an API through gen-class.

Any comments / suggestions / critiques are welcome.

- Thanks


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-05-24 Thread Jason Smith
It sure seems like we need a good stub generator for Clojure.  Java-
interop just doesn't seem complete without it.

On May 22, 10:12 pm, ka  wrote:
> Hi, any responses?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 
> athttp://groups.google.com/group/clojure?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-05-24 Thread Erik Söhnel
hi,

you could use a simple class signature generator and then run javadoc
on it:

(def javadoc-strings (atom {}))

(defn javadoc [class name & body]
  (swap! javadoc-strings update-in [class] #(conj (or % []) %2) [name
(apply str body)])
  nil)

(defn -myMethod
  "My cool documentation"
  [x y]
  '...)

(javadoc 'MyClass '-myMethod
 "
/* .
 * " (:doc (meta #'-myMethod)) "
 */
 public Object MyMethod(int x, int y) { };
")

(javadoc 'Bar 'one "
/*
 *
 */
 public Object one(int t) {};
")

(javadoc 'Bar 'two "
/*
 *
 */
 public Object one(int t) {};
")

(deftype Bar [x]
  Foo
  (one [t] (+ x 2))
  (two [t] (+ x 2)))

(defn make-docclass [p c]
  (let [cname (str c)
methods (into {} (get @javadoc-strings c))]
(str "package " p \; \newline
 "public class " c "{" \newline
 (apply str (interpose \newline (map second methods)))
 "}")))

(clojure.contrib.io/make-parents (java.io.File. "/src/bar/foo/
Bar.java"))
(clojure.contrib.io/spit
 "/src/bar/foo/Bar.java"
 (make-docclass "bar.foo" 'Bar))

;; in the  directory, call:
;; javadoc -sourcepath src bar.foo


Depending on your time and macro-foo skills, you can extend this to
automtically generate documentation from a genclass definition or a
whole namespace. But for  a one-shot documentation of a simple API,
this might be enough.

Erik

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: API in Clojure for Java folklore

2010-05-22 Thread ka
Hi, any responses?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


API in Clojure for Java folklore

2010-05-21 Thread ka
Hi all,

I've written an API in Clojure to be consumed by people working in the
Java world.  Now most of these people haven't even heard of Clojure;
but all they care about is 1) a working API and 2) with nice
documentation.

1) Something about the API - I tried out various things, types,
records, protocols (from the master).  But finally I've decided to
stick with 2-3 defrecords + gen-class.  The API is just a bunch of
static methods with zero state (earlier I was thinking fancy stuff
like OO, and keeping state for each object ... but didn't like any of
it).  Anyway, so now I've a working API.

2) The problem I have now is how to put Javadocs in all my static
methods?  I don't want to create documentation that is detached from
the code.

For example, if I declare a method in gen-class as -
#^{:static true} [myCoolFn [int int] clojure.lang.LazySeq]

and definition of the function-
(defn -myCoolFn
  "My cool documentation"
  [a b]
  ...
)

The .class file generated and hence the API -
2.1) Doesn't have the parameters named int a, int b :(.  They are
named as int arg0, int arg1.
2.2) "My cool documentation" doesn't come up in the Javadocs.

I'm not much familiar with Java so please advise.
Thanks!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en