Calling apply on java methods

91 views
Skip to first unread message

Alexandre Patry

unread,
May 11, 2010, 1:39:52 PM5/11/10
to Clojure
I am trying to call a java method using apply, like :

(apply .println [System/out "hello" "world"])

But I get an error: "Unable to resolve symbol: .println in this context"

Am I missing something?

Thanks,

Alex

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Heinz N. Gies

unread,
May 11, 2010, 1:45:10 PM5/11/10
to clo...@googlegroups.com

On May 11, 2010, at 19:39 , Alexandre Patry wrote:

> I am trying to call a java method using apply, like :
>
> (apply .println [System/out "hello" "world"])
>
> But I get an error: "Unable to resolve symbol: .println in this context"
>
> Am I missing something?

Apply only works on clojure methods not on java methods sorry. the only Idea I have would be to wrap your functionality in a clojure fn and then do your thing. Also you might need the reflection API for that.

Regards,
Heinz

Alexandre Patry

unread,
May 11, 2010, 1:49:58 PM5/11/10
to clo...@googlegroups.com
Le 2010-05-11 13:45, Heinz N. Gies a écrit :
> On May 11, 2010, at 19:39 , Alexandre Patry wrote:
>
>
>> I am trying to call a java method using apply, like :
>>
>> (apply .println [System/out "hello" "world"])
>>
>> But I get an error: "Unable to resolve symbol: .println in this context"
>>
>> Am I missing something?
>>
> Apply only works on clojure methods not on java methods sorry. the only Idea I have would be to wrap your functionality in a clojure fn and then do your thing. Also you might need the reflection API for that.
>
Ok, thanks.

Stuart Halloway

unread,
May 11, 2010, 1:52:02 PM5/11/10
to clo...@googlegroups.com
For now, the idiomatic way to do this is to use the shorthand
anonymous form:

(apply #(.println %) ... )

Of course the example of printing to System.out is fairly well covered
with Clojure API fns anyway...

Stu

Michael Gardner

unread,
May 11, 2010, 1:56:35 PM5/11/10
to clo...@googlegroups.com
On May 11, 2010, at 12:39 PM, Alexandre Patry wrote:

> I am trying to call a java method using apply, like :
>
> (apply .println [System/out "hello" "world"])
>
> But I get an error: "Unable to resolve symbol: .println in this context"
>
> Am I missing something?

Unfortunately, Java methods are not currently first-class functions in Clojure. But you can use memfn to create one (see "Java Interop" section at clojure.org):

(apply (memfn println s) [System/out "hello world"])

(Note that your original version won't work because println only takes one String argument.) You can also do (apply #(.println %1 %2) [System/out "hello world"]), of course.

Aravindh Johendran

unread,
May 11, 2010, 3:07:21 PM5/11/10
to Clojure

On May 11, 1:39 pm, Alexandre Patry <patry...@iro.umontreal.ca> wrote:
> I am trying to call a java method using apply, like :
>
> (apply .println [System/out "hello" "world"])
>
> But I get an error: "Unable to resolve symbol: .println in this context"
>
> Am I missing something?

The semantics (meaning of the syntax/code) when using Java interop is
a little murky. Java interop is neither Java syntax nor Lisp code. It
is Java code written in Lisp syntax. In general, semantics of Java has
nothing to do with semantics of pure Clojure. They are worlds apart.

Apply method won't work in your example because it is a Clojure/Lisp
construct. It has meaning only in the Lisp world. It doesn't have an
equivalent in the Java world. Java interop is merely a way to write
Java code. When you invoke Java code in Clojure, it may help to
remember that you have stepped outside of pure Lisp/Clojure. You are
invoking Java code whenever you use a dot to prefix or suffix a word.

Except, of course, when you use memfn or anonymous function wrapping
over the java member function. When you do this, you enter a gray
zone, a haze really, in terms of simple semantics. This mechanism is a
bridge between the high-level language and the low-level language on
which the high-level language is built. The bridge is provided so that
the vast amount of libraries available for the JVM can be utilized
inside Clojure. This frees Clojure's implementor(s) to focus on higher
level constructs such as concurrency mechanisms, modern data
structures and so on.

Think of it this way - you know how sometimes, if people want to speed
things up in Java, they write native functions in C/C++? What if the
creators of Java had provided a means to call C/C++ with special
syntax from inside Java, instead of having to write and compile C++
separately in a different file? Not a completely correct analogy, but
I hope it is useful to some extent.


(.println System/out "1 2 3") is just another way of writing

(. System/out (println "1 2 3"))

which is just a convenient way of writing in Clojure, the following
line in Java.

System.out.println("1 2 3");


Just because you can invoke Java from Clojure does not mean you can
mix and match both languages freely inside the same form/expression

Are you familiar with Java and Lisp/Scheme? If not, when you find the
time, you could spend just enough time in each of the languages to
write a moderately sized application that invokes date/time functions,
vectors, arrays and file I/O. And then write the same application in
Clojure.



- Aravindh

Aravindh Johendran

unread,
May 12, 2010, 10:16:38 AM5/12/10
to Clojure


On May 11, 1:39 pm, Alexandre Patry <patry...@iro.umontreal.ca> wrote:
> I am trying to call a java method using apply, like :
>
> (apply .println [System/out "hello" "world"])
>
> But I get an error: "Unable to resolve symbol: .println in this context"
>
> Am I missing something?

The apply method takes a Clojure function as the first argument.
".println" is not a function as understood by clojure but rather an
instance method belonging to PrintStream class.


The semantics when using Java interop is a little murky. Java interop
is neither Java syntax nor Lisp code. It is Java code written in Lisp
syntax. In general, semantics of Java has nothing to do with semantics
of pure Clojure. They are worlds apart.

Apply method won't work in your example because it is a Clojure/Lisp
construct. It has meaning only in the Lisp world. It doesn't have an
equivalent in the Java world. Java interop is merely a way to write
Java code. When you invoke Java code in Clojure, it may help to
remember that you have stepped outside of "pure" Lisp/Clojure. You are
invoking Java code whenever you use a dot to prefix or suffix a word.

Except, of course, when you use memfn or anonymous function wrapping
over the java member function. When you do this, you enter a gray
zone, a haze really, in terms of simple semantics.

The interop mechanism is a bridge between the high-level language and
the low-level language on which the high-level language is built. The
bridge is provided so that the vast amount of libraries available for
the JVM can be utilized inside Clojure. This frees Clojure's
implementer(s) to focus on higher level constructs such as concurrency
mechanisms, modern data structures and so on.

Think of it this way - you know how sometimes, if people want to speed
things up in Java, they write native functions in C/C++? What if the
creators of Java had provided a means to call C/C++ with special
syntax from inside Java, instead of having to write and compile C++
separately in a different file? Not a completely correct analogy, but
I hope it is useful to some extent.


(.println System/out "1 2 3") is just another way of writing

(. System/out (println "1 2 3"))

which is just a convenient way of writing in Clojure, the following
line in Java.

System.out.println("1 2 3");


Just because you can invoke Java from Clojure does not mean you can
mix and match both languages _freely_ inside the same form/expression.

Are you familiar with Java and Lisp/Scheme? If not, when you find the
time, you could spend just enough time in each of the languages to
write a moderately sized application that invokes date/time functions,
vectors, arrays and file I/O. And then write the same application in
Clojure.



- Aravindh

Reply all
Reply to author
Forward
0 new messages