I am trying to write some software in Java and, amongst other problems, I'm
finding it very difficult to express simple concepts in Java.
For example, when writing RPC bindings I would like to write conversion
functions that translate a Java Set<T> into a format for the wire and back
again, where T is some type.
Ordinarily I would just pass the conversion function for the type T to the
conversion function for a polymorphic set but Java doesn't seem to support
higher-order functions. What hoops do I have to jump through to get this
done? I've considered wrapping every conversion function in a class in
order to mimic the passing of functions (as the passing of 1-method objects
instead). I've also considered using immediate objects to wrap functions at
each call site. Neither of these approaches seem reasonable, e.g. they are
both hugely verbose.
I also have some irritations regarding the stdlib. I had heard that it was
comprehensive but it appears to be largely superfluous. For example, I
believe the following is minimal Java code to load and save some XML:
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.*;
public class dom {
public static void main(String[] argv)
throws javax.xml.transform.TransformerConfigurationException,
javax.xml.parsers.ParserConfigurationException,
javax.xml.transform.TransformerException,
java.io.FileNotFoundException,
java.io.IOException
{
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DOMImplementation i = (f.newDocumentBuilder()).getDOMImplementation();
Document doc = i.createDocument(null, null, null);
InputStream in = new FileInputStream("test.xml");
t.transform(new StreamSource(in), new DOMResult(doc));
in.close();
Transformer t = (TransformerFactory.newInstance()).newTransformer();
t.transform(new DOMSource(doc), new StreamResult(System.out));
}
}
Are these patterns not factored out into a library function somewhere? If
not, why not? Finally, why does that Java not work?
Here's the OCaml for comparison:
Xml.to_string (Xml.parse_file "test.xml")
Cheers,
Jon.
Oliver Wong - 04 Aug 2006 22:47 GMT
> I am trying to write some software in Java and, amongst other problems,
> I'm
[quoted text clipped - 14 lines]
> each call site. Neither of these approaches seem reasonable, e.g. they are
> both hugely verbose.
"One method objects" is usually how "passing a function" works in Java,
aye.
> I also have some irritations regarding the stdlib. I had heard that it was
> comprehensive but it appears to be largely superfluous. For example, I
[quoted text clipped - 37 lines]
>
> Xml.to_string (Xml.parse_file "test.xml")
Yeah, Java's verbose.
- Oliver
Jon Harrop - 04 Aug 2006 23:17 GMT
> "One method objects" is usually how "passing a function" works in
> Java, aye.
Is there any stdlib support for these, or even a convention (e.g. is the
method always called "apply")? Presumably I have to start by declaring a
generic interface that is equivalent to the type 'a -> 'b?

Signature
Dr Jon D Harrop, Flying Frog Consultancy
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
Oliver Wong - 07 Aug 2006 17:44 GMT
>> "One method objects" is usually how "passing a function" works in
>> Java, aye.
>
> Is there any stdlib support for these, or even a convention (e.g. is the
> method always called "apply")?
No library to my knowledge. Closest to a convention is to name your
method "run", as that's what I usually see and I suspect it comes from
java.lang.Runnable.
> Presumably I have to start by declaring a
> generic interface that is equivalent to the type 'a -> 'b?
I've never done this, but after thinking about it for a bit, I came to
the same conclusion:
public interface Runnable2<A,B> {
public B run(A param);
}
- Oliver
Jean-Francois Briere - 06 Aug 2006 20:51 GMT
Consider creating your own utility/helper classes.
Then outputing an xml file to the console could *simply* be:
// DomTest.java
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class DomTest
{
public static void main(String[] args)
throws Exception
{
DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream is = new FileInputStream("test.xml");
Document doc = db.parse(is);
is.close();
System.out.println(DomUtil.toString(doc));
}
}
This is the utility class:
// DomUtil.java
import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import org.w3c.dom.*;
public class DomUtil
{
public static String toString(Document doc)
throws Exception
{
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
t.setOutputProperty(OutputKeys.METHOD, "xml");
if (doc.getXmlEncoding() != null)
t.setOutputProperty(OutputKeys.ENCODING,
doc.getXmlEncoding());
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(doc), new StreamResult(sw));
return sw.toString();
}
}
Regards