Clojure + Java compilation and IntelliJ IDEA plugin

397 views
Skip to first unread message

Ilya Sergey

unread,
Mar 25, 2009, 11:42:38 AM3/25/09
to clo...@googlegroups.com
Hello, all.

I've just uploaded new version of La Clojure plugin for IntelliJ IDEA. Among several bugfixes and minor changes I have to note several essential moments.

1. Now Clojure support is added as so-called `facet', which may be attached to every module. Creating new module, just choose Clojure among desired technologies. In this case necessary clojure jar will be downloaded automatically and adjusted as a project library unless you point to it manually.

2. If you open existing project, clojure facet will be detected automatically. For now facet serves as a label for clojure-aware modules. In that modules you may invoke "create new clojure file" action and their clojure files will be compiled.

3. From now IntelliJ IDEA provides support for batch compilation of Clojure files, whose namespace is marked by :gen-calss tag. Compiled classes will be places to the appropriate output directory of a module. One may choose, which sources should be compiled first - Java or Clojure to resolve one-way dependencies. By default Clojure is compiled first. Moreoverm you may to choose whether to copy *.clj files to output path or not (this might be useful if you're going to invoke some functions from *.clj files dynamically). And, of course, automatic detection and compilation of class-labeled clojure files may be switched off. For more details see File -> Settings -> Compiler -> Clojure.

For someone these settings might seem not sufficiently flexible. So, all comments and proposals are appreciated. :)

With best regards,
Ilya Sergey


Christian Vest Hansen

unread,
Mar 25, 2009, 12:04:04 PM3/25/09
to clo...@googlegroups.com
Sounds great :)

On Wed, Mar 25, 2009 at 4:42 PM, Ilya Sergey <ilya...@gmail.com> wrote:
> Hello, all.
>
> I've just uploaded new version of La Clojure plugin for IntelliJ IDEA. Among
> several bugfixes and minor changes I have to note several essential moments.
>
> 1. Now Clojure support is added as so-called `facet', which may be attached
> to every module. Creating new module, just choose Clojure among desired
> technologies. In this case necessary clojure jar will be downloaded
> automatically and adjusted as a project library unless you point to it
> manually.
>
> 2. If you open existing project, clojure facet will be detected
> automatically. For now facet serves as a label for clojure-aware modules. In
> that modules you may invoke "create new clojure file" action and their
> clojure files will be compiled.
>
> 3. From now IntelliJ IDEA provides support for batch compilation of Clojure
> files, whose namespace is marked by :gen-calss tag. Compiled classes will be
> places to the appropriate output directory of a module. One may choose,
> which sources should be compiled first - Java or Clojure to resolve one-way
> dependencies. By default Clojure is compiled first.

Could you explain the reasoning behind compiling the Clojure code
before the Java code?

While trying out Daniel Spiewaks Clojure enabled Buildr, which also
compiles the Clojure code first, I noticed that I could not access
static methods of the classes that were defined in Java code. I have
not tested this, but I would assume that type hinting using these
classes don't work either. On the other hand, Java works with Clojure
through the classes and interfaces defined in clojure.jar, and
resolves their Vars at run time. The 'gen-class case stands as an
example where you might have to compile Clojure first, but I wonder if
this is the typical case?

> Moreoverm you may to
> choose whether to copy *.clj files to output path or not (this might be
> useful if you're going to invoke some functions from *.clj files
> dynamically). And, of course, automatic detection and compilation of
> class-labeled clojure files may be switched off. For more details see File
> -> Settings -> Compiler -> Clojure.
>
> For someone these settings might seem not sufficiently flexible. So, all
> comments and proposals are appreciated. :)
>
> With best regards,
> Ilya Sergey
>
>
>
> >
>



--
Venlig hilsen / Kind regards,
Christian Vest Hansen.

Stuart Halloway

unread,
Mar 25, 2009, 4:14:43 PM3/25/09
to clo...@googlegroups.com
Hi Ilya,

I would like to be able to demo the sample code from the book in IDEA.
Here are a few things I am seeing so far:

(1) When I set a breakpoint, I get a warning icon that says "no
executable code found at..." but the breakpoint does in fact seem to
work.

(2) The variable window correctly displays collections, but not large/
infinite sequences. If you try to open a variable view on an infinite
sequence, it will use all of memory. Can the plugin be modified to
respect the *print-length* and *print-depth* variables?

(3) I am unable to set a watch on the special variable *print-length*.
The entry UI goes wonky when I reach the hyphen character in the name.

It's exciting to see the plugin moving forward, thanks for your efforts!

Best,
Stu

Mark Engelberg

unread,
Mar 25, 2009, 7:30:28 PM3/25/09
to clo...@googlegroups.com
If we've already downloaded the first plugin, what's the best way to
upgrade? Do you have to delete the first one, or just install the
second on top? Is there a way to update the plugin from within the
IDE?

Thanks.

Ilya Sergey

unread,
Mar 25, 2009, 9:12:29 PM3/25/09
to clo...@googlegroups.com
Hello, Mark.

The easiest way to updae plugin from within the idea is to use plugin manager (see File -> Settings -> Plugins), find Clojure plugin in the list, right-click on it and hit "update". AFAIK, you also must see kind of blinking gear in the bottom right corener of IDEA main screen, which assumes, that you have some plugins to update.

With best regards,
Ilya

2009/3/26 Mark Engelberg <mark.en...@gmail.com>

Ilya Sergey

unread,
Mar 25, 2009, 9:22:59 PM3/25/09
to clo...@googlegroups.com
Hello, Christian


Could you explain the reasoning behind compiling the Clojure code
before the Java code?

It's very good question, and to be honest I don't know exact question for it. I may imagine both cases from Clojure to Java and vise versa. Making first variant default I was followed by one letter I had received. It was about some project written in IDEA, where Clojure is used for core funcationality whereas al UI is written in Java via UI designer.
Untill we have no stub-generation (as it was done in Groovy) or Java code analysis like in Scala only one consistent solution will be to define compilation order explicitly. Tricky project decomposion into modules may help to resolve cross-languge dependencies.

With best regards,
Ilya

2009/3/25 Christian Vest Hansen <karma...@gmail.com>

Ilya Sergey

unread,
Mar 25, 2009, 9:32:11 PM3/25/09
to clo...@googlegroups.com
Hi, Stuart.


I would like to be able to demo the sample code from the book in IDEA

That's great, I'm really happy to hear it.

As for all three issues you've mentioned, all of them have same origin and related to so-called evaluator API. What you can see now using debugger is nothing but vanilla  Java stack, some of whose variable may coincide with appropriate Clojure variables. Implmentation of watches, evaluate expression or some specific cases like dealing with lazy structures is _very_  non-trivial problem, cause all clojure constructs, written, say, in 'watches' section should be translated to correct Java code to capture appropriate stack and environment from JVM and being evaluated.
For now, we solved this problem partially for Groovy, because Groovy is not so hard to translate to Java and we're working on the same problem for Scala, which is much more dificult because of presence of string typeing. As for Clojure, I don't see an easy way for now to implement such feature.
For me such tasks as smart completion and resolve have greater priority.

BTW, I'm not sure, that thiss issue was already mentioned in errata for book, but I failed to compile tasklist.clj example from last book version (27 feb), because some function (sort of `lazy-eval') from clojure-contrib raised an error during compilation. Same result was obtained by compilation from command line, so I'm afraid some-thing wrong either with current clojure-contrib  version or this example.

Kind regards,
Ilya




2009/3/25 Stuart Halloway <stuart....@gmail.com>

AlamedaMike

unread,
Mar 26, 2009, 1:33:50 AM3/26/09
to Clojure
>> It's very good question, and to be honest I don't know exact question for
it. I may imagine both cases from Clojure to Java and vise versa.
Making
first variant default I was followed by one letter I had received. It
was
about some project written in IDEA, where Clojure is used for core
funcationality whereas al UI is written in Java via UI designer.

That may have been my email. Given that there is currently no solid
GUI forms designer for Clojure, IDEA will have a strong market niche
by developing one. The idea (no pun intended) is that each language
should do what it does best. At some point Clojure may have the tools
to be best at GUI forms, but not right now. In this scenario, Clojure
will presumably need to be compiled first, unless there is some way to
invoke the GUI from Clojure (my Java skills are very rusty).

Christian Vest Hansen

unread,
Mar 26, 2009, 5:50:17 AM3/26/09
to clo...@googlegroups.com

Reading this description I become unsure of whether you want to call
into Java from Clojure, or into Clojure from Java.

Here's where I stand:

I presume that in most Clojure programs, the majority of the business
logic will be implemented in Clojure. The Java code, if any, will be
used for implementing low-level stuff (ie. primitive math, mutating
algorithms) and library intergration work. In this case, the wirering
work will be done mostly in Clojure using the standard interop
features of the language. Considering this, the Java code will know
little or nothing about Clojure and is easily compiled first, whereas
the Clojure code might want to have the class files from the Java code
handy during compilation for things such as avoiding reflection, type
hinting and what have you. In short: the Java code *should* be
compiled first.

The inverse case is where Java uses Clojure as a scripting language of
sorts. Here, the Java code may or may not be dominant, but in either
case it knows about Clojure; it may work with the data structures and
it may call functions implemented in Clojure. However, because of the
dynamic nature of Clojure there is seldomly any new types defined in
it, with the intent of direct consumption from Java. Instead, the Java
code interacts with the Clojure code through the various interfaces
defined in clojure.jar. Here's an example of what I mean:

http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Invoking_Clojure_from_Java

As we see from that example, the reference to the "foo" function is,
in the Java sense, resolved at run-time. Therefor, the Java code *can*
be compiled first, and if the Clojure code, for some reason, knowingly
interacts with the types defined in the Java code, it *should* [have
the Java compiled first].

This leaves us, to the best of my knowledge, just one case where the
Clojure code *must* be compiled first: When Clojure define new types
through gen-class (or the embedded ASM library) that needs to be
directly and knowingly interacted with in the Java code.

So, my *assumption* (because I have no way of knowing for sure) is
that this last case is the less common one, and therefor it makes
sense to compile the Java code first.

This is my reasoning anyway.

Stuart Halloway

unread,
Mar 26, 2009, 10:29:20 AM3/26/09
to clo...@googlegroups.com
Ilya,

I have checked in a unit test for the tasklist example that
demonstrates it working correctly locally. Can you try it and see
what's different for you?

Git repos: http://github.com/stuarthalloway/programming-clojure/tree/master

Then "bin/runtests.sh" or "bin\runtests.bat" depending on your
platform. The individual test is examples/test/tasklist.clj.

Thanks,
Stu

Ilya Sergey

unread,
Mar 30, 2009, 6:55:10 AM3/30/09
to clo...@googlegroups.com, stuart....@gmail.com
Hello, Stuart.

I've checked examples from book by that address. All of them work fine for me. Moreover, suddenly it turned out, that compilation using IntelliJ IDEA works fine as well.So, sorry for disturbance and thanks for your help.

With best regards,
Ilya

2009/3/26 Stuart Halloway <stuart....@gmail.com>
Reply all
Reply to author
Forward
0 new messages