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

Lambda calculus, Type theory, Formal semantics, Program analysis

    Previous     Next     All lectures        Code    

A Stream Filter

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; }
}

// Remove the stated int item from an int stream
class Remove extends Stream {
   Stream stream;
   BigInteger to_remove;

   public Remove (BigInteger item, Stream s) {
      isNull = s.isNull;
      to_remove = item;
      if (!isNull) {
         while (s.first.equals(item)) s = s.rest();
         first = s.first;
      }
      stream = s;
   }

   public Remove rest() {
      return new Remove (to_remove, stream.rest());
   }
}

// 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));
   }
}

// Inputs: an integer n and a Stream s of numbers
// Output: the Stream of all tokens of s multiplied by n
class Times extends Stream {
   Stream s1;
   BigInteger multiplier;

   public Times (BigInteger n, Stream s) {
      isNull = s.isNull;
      s1 = s;
      multiplier = n;
      if (!isNull) first = n.multiply(s.first);
   }

   public Times rest() {
      return new Times (multiplier, s1.rest());
   }
}

// Inputs: two streams of integers in increasing order
// Output: a stream in increasing order consisting of
// exactly those numbers in the input streams (assume
// only infinite streams).
class Merge extends Stream {
   Stream s1, s2;

   public Merge (Stream a, Stream b) {
      isNull = false;
      if (!a.isNull &&
          (b.isNull ||
           a.first.compareTo(b.first) < 0)) {
         s1 = a;
         s2 = b;
      } else if (!b.isNull &&
                 (a.isNull ||
                  a.first.compareTo(b.first) >= 0)) {
         s1 = b;
         s2 = a;
      } else {
         isNull = true;
      }
      if (!isNull) first = s1.first;
   }

   public Stream rest () {
      return new Merge(s1.rest(), s2);
   }
}

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

   public Stream_5Frame () {
      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("Filter 15", JLabel.LEFT));
      go.addActionListener(this);
      s = new Remove(
             new BigInteger("15"),
             new Merge(
                new Times(
                   new BigInteger("3"),
                   new Successor(new BigInteger("1"))),
                new Times(
                   new BigInteger("5"),
                   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_5
   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_5Frame sf = new Stream_5Frame();
      sf.setSize(400,400);
      sf.setVisible(true);
   }
}
 -  The class Remove to the left filters objects from a stream. In this case only the number 15 is filtered. The red lines on the left show where the output stream is referenced by s. Walking through s is done as in the previous slide.