The Artima Developer Community
Sponsored Link

Java Buzz Forum
OO Programming Support in Pnuts

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Toyokazu Tomatsu

Posts: 66
Nickname: tomatsu
Registered: Jul, 2003

Toyokazu Tomatsu is a developer of Pnuts.
OO Programming Support in Pnuts Posted: Jul 26, 2007 10:41 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Toyokazu Tomatsu.
Original Post: OO Programming Support in Pnuts
Feed Title: Pnuts Addict
Feed URL: http://www.jroller.com/tomatsu/feed/entries/rss
Feed Description: Toyokazu Tomatsu's Weblog
Latest Java Buzz Posts
Latest Java Buzz Posts by Toyokazu Tomatsu
Latest Posts From Pnuts Addict

Advertisement

Over years, I was trying to understand how OO feature should be integrated into a procedural language with lexical scoping. In the recent updates of Pnuts, its class infrastructure was re-designed, based on more sophisticated internal architecture than several attempts I made in previous versions. In this article, I will explain how OO functionality has been integrated into Pnuts.

Classes in Pnuts

For example, a simple counter can be defined in Pnuts as follows.
class Counter {
   i = 0
   inc(){ i++ }
}
The class is compiled into an ordinary Java class. There is no difference from Java classes once it is compiled and loaded.

Attributes may or may not be typed. In the example above, the variable i represents an un-typted attribute. Getter and setter methods, which are getI() and setI() in this example, are implicitly defined for each attribute.

It is assumed that class definition follows Java Beans naming convention. Getter and setter methods are called when reading (or writing) the attribute from scripts.

c = Counter()
c.i      ---> 0
c.i = 1
c.i      ---> 1

Return type and parameter types of methods are optional. If no type is specifed, Object.class is implicitly used, except when the method overrides an existing method defined in a superclass; in this case it inherits the method signature.

No access control can be specified for methods and constructors. Methods and constructors are always public.

The keywords this and super can be used in Pnuts as in Java. For examples, the following code illustrates how to customize a setter method.

class MyCounter extends Counter {
   setI(i){
      if (this.i != i) println("changed")
      super.setI(i)
    }
   inc(){ setI(this.i+1) }
}
The following code is another example, which is a subclass of HashMap that automatically creates a Set for unmapped key.
class MyMap extends java.util.HashMap {
   get(key){
      if ((v = super.get(key)) == null){
        super.put(key, v = new java.util.HashSet())
      }
      v
   }
}

Class Loading

Classes defined in Pnuts can be loaded in either of two different ways. First, script files with suffix .pnc can be automatically compiled and then loaded by PnutsClassLoader, as if it were .class files which can be loaded by system class loader. Since dependency between classes is automatically resolved by the class loader, it is less likely that linkage errors (or duplicated definition errors) occur, than the other options.

Alternatively, class definition can be embedded in a script file and executed as an ordinary script file. In this case, the classes are temporarily defined in the script, that is, the scope of class name is inside the script file that contains the class definition. When script 'A' executes script 'B', those scripts uses different class loaders to load embedded classes.

Implementation

When Counter class is compiled, the compiler generates a skelton class of the specified signature. At the same time, the compiler creates a function that creates a closure. The function returns an array of functions, each one is associated with a method of the class.

Attributes are mapped to local variables of the function. Getter and setter methods (and the associated functions) to access the attribute are automatically generated.

For example, the following function is created for the Counter class that was previously defined.

function (this, super){
   i = 0
   [
    function inc(){ i++ },
    function getI(){ i },
    function setI(_i){ i = _i }
   ]
}
Next, the class below illustrates what the skelton class looks like. It has a method and a set of fields to bind Pnuts functions. The constructor calls the function above and initializes private fields with each element of the array returned by the function. It does not contain actual code for the method body. Instead, each method just calls a Pnuts function bound to the associated private field.
public class Counter {
  static PnutsFunction function_factory;
  static Context context;
  private PnutsFunction inc_function;
  private PnutsFunction get_function;
  private PnutsFunction set_function;

  public static void attach(PnutsFunction function_factory, Context context){
      Counter.function_factory = function_factory;
      Counter.context = context;
  }

  public Counter(){
    PnutsFunction[] function_array = function_factory.call(new Object[]{this, superProxy}, context);
    this.inc_function = function_array[0];
    this.get_function = function_array[1];
    this.set_function = function_array[2];
  }

  public Object inc(){
   this.inc_function.call(new Object[]{}, context);
  }
  ...
}
Since Pnuts function has lexical scoping rule, classes defined in Pnuts also have the same scoping rulle. If a class is defined in a local scope, symbols in the local scope are visible from the class definition. For example, the following function create an instance of counter, which the variable used in the inc() method comes from the parameter of the function.
function counter (i){
  new Object() {
     inc(){ i++ }
  }
}
Similarly, a class attribute can be referenced from functions defined in a method.
class Counnter {
   i = 0
   inc_func(){
     {-> i++}
   }
}

Summary

The new OO programming support is a natural extension to Pnuts. The language is still small and simple, which is one of the goal of the language design.

Pnuts generates real Java classes on the fly. Classes defined in Pnuts can be replaced by Java class if necessary.

Classes in Pnuts has lexical scoping rule. The lexical scoping rule is preserved even when functions and classes are intermixed.

Read: OO Programming Support in Pnuts

Topic: How To Split Java String By Newlines Previous Topic   Next Topic Topic: Black Swallowtail

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use