20-CS-4003-001 Organization of Programming Languages Fall 2017
Streams

Lambda calculus, Type theory, Formal semantics, Program analysis

    Previous     Next     All lectures        Code    

Stream Definition and Successor

import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.math.*;

// Stream declaration 
class Stream {
   public Stream () { isNull = true; }
   public boolean isNull;
   public BigInteger first;
   public Stream rest () { return null; }
}

// successor declaration 
class Successor extends Stream {

   public Successor (BigInteger num) { 
      first = num;
      isNull = false; 
   }

   public Successor rest () {
      BigInteger one = new BigInteger("1");
      return new Successor (first.add(one));
   }
}

class Stream_1Frame 
   extends JFrame implements ActionListener {
   JTextArea text;
   JButton go;
   Stream s;

   public Stream_1Frame () {
      setLayout(new BorderLayout());
      setBackground(new Color(255,255,223));
      add("Center", 
          new JScrollPane(text = new JTextArea()));
      JPanel p = new JPanel();
      p.setLayout(new FlowLayout());
      p.setBackground(new Color(255,255,223));
      p.add(go = new JButton("Next"));
      add("South", p);
      add("North", 
          new JLabel("Successor: 1,2,3...",JLabel.LEFT));
      go.addActionListener(this);
      s = new Successor(new BigInteger("1"));
   }

   public void actionPerformed (ActionEvent evt) {
      text.append(s.first.toString()+"\n");
      int p = text.getDocument().getLength();
      text.setCaretPosition(p);
      s = s.rest();
   }
}

public class stream_1 
   extends Applet implements ActionListener {
   JButton go;

   public void init () {
      setLayout(new BorderLayout());
      setBackground(new Color(255,255,223));
      add("Center", go = new JButton("Applet"));
      go.addActionListener(this);
   }

   public void actionPerformed (ActionEvent evt) {
      Stream_1Frame sf = new Stream_1Frame();
      sf.setSize(400,400);
      sf.setVisible(true);
   }
}
 -  A Stream class contains a first object, which in many of these examples is a BigInteger for easy comparisons, and a procedure rest() which returns the rest of the stream. There is also a field called isNull which returns true if the stream has no elements and false otherwise. A subclass of Stream needs to be designed with a constructor that installs the object representing the beginning of the stream into first. Information for doing this usually comes from the constructor's arguments. The procedure rest() needs to be designed to return a new object of the subclass with constructor arguments that will cause the first field of the new object to contain the next stream object. In this way, the delay-force paradigm of Scheme may be implemented: the delay is due to the creation of the new stream object being placed inside a procedure (rest) and the force happens when that procedure is invoked.

An example of a subclass of Stream that provides an infinite stream of BigIntegers is the Successor class, shown in green on the left. The rest procedure returns a new Successor object with a first value that is one greater than its own first value. Hence, successive stream elements are the integers beginning from the value given to the first creation of a Successor object. In this example the first red line shows a Successor stream being created (with first element 1) and assigned to the variable s. The second red line shows where the first element of s is printed. The third red line shows how the next stream element is obtained.