Skip to main content

Nice

17 replies [Last post]
markf
Offline
Joined: 2005-01-20

I've been looking through this extension of Java called "Nice". http://nice.sourceforge.net/

Has anyone else here looked through it? It seems like a quite interesting language, and impressively it outputs perfectly normal Java bytecode, executable on any modern JVM. Some aspects of it harken a bit too much to the old C++ days. But in any case, what do other people here think of it as a potential future direction for the Java language to take?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
dbr
Offline
Joined: 2005-03-03

Thanks for the pointer. I wanted to do some experiments and benchmarks on PEC, but its compiler crashes:

$ java -classpath compile.jar:. pec.compile.javacompiler.JavaCompiler javac -classpath compile.jar:. Bench.java

1. pec.compile.javacompiler.JavaCompilerException
class Bench$A
*** PEC(TM) BUG ***: field checkMethodName is null
Caused by: java.lang.NullPointerException
at pec.compile.Utilities.getRootDirectory(Utilities.java:1216)
at pec.compile.javacompiler.JavaCompiler.callCheckMethodLevel5CtClass(JavaCompiler.java:1200)

Does PEC not support inner classes at all?

Nice does allow you to separately compile packages into jars. You are right in that dynamically loading "plugins" extending multi-methods is not supported yet. The upside is that Nice can guarantee at compile-time that all methods are properly implemented, while PEC would fail at class-loading time if one method is not.

hlovatt
Offline
Joined: 2003-11-18

> Thanks for the pointer. I wanted to do some
> experiments and benchmarks on PEC, but its compiler
> crashes:
>
> ... stuff deleted
>
> Does PEC not support inner classes at all?

The bug you encountered has been fixed in a later version than was on the web site. I have put my latest version on the site and this bug is fixed in this version. There is still a bug when compiling multiple classes that refer to each other on the same command line. If you wish to compile multiple self-referential classes you might need to compile each one separately. Sorry for the inconvenience :(

> Nice does allow you to separately compile packages
> into jars. You are right in that dynamically loading
> "plugins" extending multi-methods is not supported
> yet. The upside is that Nice can guarantee at
> compile-time that all methods are properly
> implemented, while PEC would fail at class-loading
> time if one method is not.

I agree with your assessment.

As an aside to your comments:

1. Would you be good enough to send me your benchmark so that I can get a feel for what you are trying to do (hlovatt@dev.java.net)

2. You can see my timing experiments vs. single dispatch here:

https://pec.dev.java.net/nonav/compile/javadoc/pec/compile/multipledispa...

and vs. Nice, MultiJava, and Sprintabout here:

https://pec.dev.java.net/nonav/compile/javadoc/pec/compile/multipledispa...

dbr
Offline
Joined: 2005-03-03

> The bug you encountered has been fixed in a later
> version than was on the web site. I have put my
> latest version on the site and this bug is fixed in
> this version.

I have tried the newer version. It fails with a different RuntimeException. I'll send the file by email.

> > Nice does allow you to separately compile packages
> > into jars. You are right in that dynamically
> loading
> > "plugins" extending multi-methods is not supported
> > yet. The upside is that Nice can guarantee at
> > compile-time that all methods are properly
> > implemented, while PEC would fail at class-loading
> > time if one method is not.
>
> I agree with your assessment.

OK. I think you should clarify this in your web pages. Now people could wrongly understand that Nice requires the whole source code.

I looked at your benchmark with interest. However, it is biased in favor of the single dispatch implementation: TimeNumericSD is an interface, and therefore there is a single implementation of setAdd, in TimeIntegerSD. Therefore, there is no dispatch at all. To be fair, the Nice implementation should be similar: make TimeNumericNice an interface (or abstract class) with only the declaration of setAdd, no implementation:

interface TimeNumericNice {
void setAdd( TimeNumericNice notUsed );
}

This is better in any case, since Nice is able to check that all cases are covered. Writing a default, failing implementation is therefore not required and loses the associated safety.

This Nice version is as fast as the Java single dispatch version (0.2 s in server mode) ;-)

I think this illustrates the fact one shouldn't be concerned with the performance of multiple dispatch. It can be made as fast as single dispatch when both are possible, and allows for situations where single dispatch does not work at all and where workarounds like the visitor pattern have a similar or lower performance.

hlovatt
Offline
Joined: 2003-11-18

dbr was good enough to send me his benchmark that didn't work, the main problem was that it added a class to package pec which is one of the packages in my PEC Compile API jar file. If this is changed to another package then the problem goes away. Working code with further explanation below:

[code]
/*
* Original file from Daniel Bonniet (dbr), author of Nice
* Modified by Howard Lovatt, author of PEC:
* 1. Packaged changed from pec to examples; pec is in a jar file, so can't be used
* 2. Methods in class B made final; PEC requires all the Multiple Dispatch methods to be final
* 3. main expanded to demonstrate all cases
* 4. Comments added
* 5. Reformatted
*/
package examples;

import pec.compile.multipledispatch.*;

public class Bench {
public static void main( String[] args ) {
System.out.println( new A().test( new A() ) );
System.out.println( new B().test( new A() ) );
System.out.println( new A().test( new B() ) );
System.out.println( new B().test( new B() ) );
}

public interface I extends MultipleDispatch {
int test( I that );
}

public static class A implements I {
public final int test( I that ) { // dummy instance method that is modified by the PEC to do the multiple dispatching
throw new AssertionError(); // body replaced by PEC; body can be anything that will compile, it gets replaced!
}

public static final int test( final A x, final A y ) { // Multiple Dispatch method

return 1;
}
}

public static class B extends A { // Multiple Dispatch methods in a second class
public static final int test( B x, A y ) { // Multiple Dispatch method

return 2;
}

public static final int test( A x, B y ) { // Multiple Dispatch method

return 3;
}

public static final int test( B x, B y ) { // Multiple Dispatch method

return 4;
}
}
}
[/code]

As you would expect the output is:

1
2
3
4

hlovatt
Offline
Joined: 2003-11-18

The following Pattern Enforcing Compiler (PEC) adds multimethods, called multiple dispatch, to standard Java:

https://pec.dev.java.net/nonav/compile/index.html

Particularly:

https://pec.dev.java.net/nonav/compile/javadoc/pec/compile/multipledispa...

Also the method of adding multiple dispatch used by PEC does not have the limitations that Nice's method has. In Nice you pretty much have to compile your whole application on one machine for multiple dispatch to work, i.e. not from jars and not over the net. Nice uses a global database of methods. The implementation in PEC builds up the database on the fly as new classes are loaded.

mayhem
Offline
Joined: 2003-06-11

Interesting. Multiple dispatch would indeed be a very valuable addition to the Java language. What kind of performance penalties are we talking about for multiple dispatch compared to single dispatch? Is it similar to those of the visitor pattern?

dbr
Offline
Joined: 2005-03-03

With simple methods that only dispatch on the first argument, performance can be identical (I mesured a 3% slowdown with Nice). I haven't made benchmarks with real multiple dispatch, but it should be at least as fast as the visitor pattern. It could even be faster, since the (Nice) compiler can produce optimized dispatch code that would be tedious and ugly to write by hand.

monika_krug
Offline
Joined: 2004-10-14

> I've been looking through this extension of Java
> called "Nice". http://nice.sourceforge.net/
>
> Has anyone else here looked through it? It seems
> like a quite interesting language, and impressively
> it outputs perfectly normal Java bytecode, executable
> on any modern JVM. Some aspects of it harken a bit
> too much to the old C++ days. But in any case, what
> do other people here think of it as a potential
> future direction for the Java language to take?

Yes, I have previously looked through it. No more NullPointerExceptions - that would be so *nice*.

One feature of Nice, generics, has already been added to JDK 5.0 :-) . I think there was another one, but I cannot find which one it was right now.

I think I would like multimethods. I have wanted to add some methods to String sometimes ^^.

I am not such a big fan of closures / anonymous functions, but many people have asked for that in this forum.

Monika.

d3levava
Offline
Joined: 2005-03-02

>Yes, I have previously looked through it. No more NullPointerExceptions - that would be so *nice*.

I agree, in big project there are a nightmare.

see sun bug database 5030232 (Add Nice Option types to Java to prevent NullPointerExceptions)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5030232

see also discussion about preventing NullPointerException
http://www.theserverside.com/news/thread.tss?thread_id=32390#161075

excerpt :

Question :
"What percentage of null pointers can they prevent - that would be a great gain for productivity."

Excerpt from the reply of Daniel Bonniot:

"100%! That is, the compiler will check that your code can never throw NullPointerException. This is possible because you can formally declare in types whether null is allowed or not (unlike Java were this is left for the javadoc at best, or unspecified at worst). And the compiler runs a powerful static analysis to detect what values might be null."

alexmoffat
Offline
Joined: 2004-01-24

What I'd really like to see is some form of type inference so that we can have static typing with some of the benefits of dynamic typing. The compiler should be able to infer, in many situations, what the appropraite type of a variable must be. Languages like Haskell and ML do this, Java should be able to. I'd also like to see continuations.

vpatryshev
Offline
Joined: 2004-06-30

Wow! That's the language I've been looking for! I wanted something that would use the ubiqutous JVM, but be more than old-fashioned single-dispatch object model.

Anybody ever asked anybody, how come java.lang.Object was never upgraded, 10 years after Java became popular? I'll look closer. Thank you!

dbr
Offline
Joined: 2005-03-03

Could you also describe what features you don't like in Nice?

markf
Offline
Joined: 2005-01-20

I would suggest that the ability to define class methods outside of a class is a maintenance disaster. I remember trying to debug C++ code, and the absolute pain it was trying to locate the code sometimes. Nice opens up that particular Pandora's box again. The same goes for default parameter values.

I also dislike how Nice defines constructors, but that may just be because it's novel to me.

dbr
Offline
Joined: 2005-03-03

External methods: is this a problem that a good IDE cannot solve? Also consider that unlike C++, the reason to allow external methods in Nice is that it allows greater expressivity and modularity, since you can define new methods on existing, imported classes.

What problems do default parameter values create?

Indeed, Nice constructors are a bit surprising at first, since they enforce the separation of object creation and object initialization. There is a strong motivation for this choice: allowing method calls before the object is completely created is unsafe (that is, you risk running into uninitialized fields that shouldn't be, and you cannot easily prevent it because of method overrides). Still, more convenient syntax that allows setting fields with assignments instead of calling this(...) would probably be more familiar, and should be added in a later version.

markf
Offline
Joined: 2005-01-20

Some IDEs can indeed solve the multimethod issue, but unfortunately not every developer uses such an IDE. Many are using vim, emacs, kate, gedit, or some other "lightweight" development environment. Just because you and I use Netbeans/Eclipse/Whatever doesn't mean everyone else does.

Aside from that, Nice's multimethods and alternative constructor layout are too different from Java. Adding them to Java would go beyond a simple extension; it would be transforming Java into a different language. This thread isn't really about debating Nice's merits, but whether some subset of its features could be used to extend Java in a positive way.

jwenting
Offline
Joined: 2003-12-02

Why change Java to be just like some other language?
If you like that other language so much just use that instead and good riddance to you.

markf
Offline
Joined: 2005-01-20

I'm not all suggesting that Java should _become_ Nice -- far from it. Nice has many undesirable features, and is radically different from Java in many ways. But it does demonstrate some features that could be used to cleanly extend Java.

Specifically, I would suggest that the following features could be added relatively cleanly to Java:

Tuples (these have been independently proposed many times)

The "ensures" and "requires" constructs, which complement the assert keyword, and which facilitate certain kinds of debugging.

The "alike" keyword, which would go some of the way towards cleaning up the nightmare that is "clone()". This too has been independently proposed several times.

Closures and functionals. Functional programming is extremely powerful, and you can see facets of it in languages like Python and Ruby. It would improve the development of GUIs, and eliminate some of the management problems with Listeners and Comparators.

The fact that none of these things require changes to the JVM should stand as recommendation of their reasability.