Differences with Java

PIL is based on a subset of Java. There are a number of differences, however, some for simplification reasons, others for stylistic reasons.

Simplification changes

  • No visibility modifiers. PIL has no visibility modifiers such as public, private and protected.
  • No abstract classes and interfaces. PIL has no abstract classes or interfaces. These can typically be emulated by concrete classes with stub methods throwing Exceptions.
  • Inner/anonymous classes.
  • import statements. On a PIL-level, types do not have to be resolved to fully-qualified names. Note, that an abstraction on top of PIL adds this feature for convenience, however PIL back-ends only have to deal with fully qualified names.
  • Checked exceptions. PIL does not have checked exceptions, i.e. Java-like exceptions that you have to catch or report to throw on a method level (throws IOException).
  • Primitive types. PIL does not have primitive types, only object types. The Java back-end does use primitive types when possible, however.
  • File system hierarchy and one-public-class-per-file requirements. PIL has no rules about where to store PIL source files.
  • Static class members. PIL does not have static members, similar features can be implemented by global variables and global functions, if necessary.
  • No method overloading. You cannot define multiple methods with a different number or type of arguments.

Stylistic changes

In addition to stylistic changes, we also made some stylistic changes in PIL as compared to Java. These changes were applied mostly because, well, we could.

  • :: for namespaces/package names rather than . So it's pil::String rather than pil.String
  • Type conversion and casting merges the ideas of casting and type conversion in one. For instance, converting a Long to an Int in PIL is written as l.as<Int>, similarly converting a Long to a String is similarly written as l.as<String>.
  • Constructors in PIL are called new and declared as follows: class Something { new(...) { ... } }