TWiki . Doc . FunctionsAndMethods

Methods are one of the main area where Nice differs from traditional object oriented languages. This difference makes Nice much more powerful, but it also requires some adaptation when learning the language. Let's take a simple example in Java, and see how it can be done in Nice.

Java version

In our exemple, we declare some classes to describe geometrical figures.

package geometry;

public abstract class Shape
{
  abstract double area();
}

public class Rectangle extends Shape
{
  private double length;
  private double width;

  double area()
  {
    return length * width;
  }
}

In class Shape, we declared a method area, and we implemented it in Rectangle.

Nice version

In Nice, you would write the following:

package geometry;

public abstract class Shape
{
  double area();
}

public class Rectangle extends Shape
{
  private double top;
  private double left;
  private double height;
  private double width;

  area()
  {
    return length * width;
  }
}

There are only two differences:

Using this syntax, you already know how to write methods in Nice. For every method written in Java, you can write an equivalent one in Java, applying the two differences. In the next section, we see more advanced features for writing methods in Nice that have no equivalent in traditional OO languages.

External methods and multiple dispatch

Suppose that a geometry library is already written. It might be in the standard library of the language, or distributed as a jar file by a company or a freeware website. In any case, you can only use it, but not modify this library. Now, what happens if you need some functionality that is not in the library? For instance, you would like a method that takes two shapes, and returns a boolean, depending on whether they overlap or not.

If you are using Java, your only possibility is to create a utility class, with a static method overlap that has two Shape arguments.

package my.package;

import geometry.*;

class Tools
{
  static boolean overlap(Shape s1, Shape s2)
  {
    if (s1 instanceof Rectangle && s2 instanceof Rectangle)
      {
         ...
         // return the result in this case
      }
    throw new Error("Case not supported: " + s1.getClass() + " and " + s2,getClass());
  }
}

Not very pretty. And this solution has three fundamental problems:

What you would really like to do is to add a new method to class Shape. This is something very simple and natural to do in Nice:

package my.package;

import geometry;

// We declare a new method, that has two arguments.
boolean overlap(Shape s1, Shape s2);

// Here is the code for overlap, when both arguments are rectangles
overlap(s1@Rectangle, s2@Rectangle)
{
  // Here s1 and s2 are both rectangles. We don't need to use instanceof or cast.
  ...
  // return the result
}

This solution solves all three problems:

Note that this solution uses two concepts in Nice:

If you go back to the first example now, you will see that we could also have defined area as an external method, instead of declaring it inside the class. Both forms are stricly equivalent. It is a matter of style to decide which one to use in that case.

-- DanielBonniot - 30 May 2003

----- Revision r1.2 - 30 May 2003 - 11:02 GMT - DanielBonniot
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.