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

Lambda calculus, Type theory, Formal semantics, Program analysis

    Previous     Next     All lectures        Code    

Times is a Consumer and Producer, Merge Defined

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

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

// successor declaration 
class Successor extends Stream {

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

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

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

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

   public Stream_3Frame () {
      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("Merge streams",JLabel.LEFT));
      go.addActionListener(this);
      s = 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_3 
   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_3Frame sf = new Stream_3Frame();
      sf.setSize(400,400);
      sf.setVisible(true);
   }
}
 -  A third stream, called Merge, is introduced and connects with a two multiplied Successor streams. Its purpose is to merge all numbers of two increasing sequences, as streams, into a single increasing sequence, as a stream. In this example, a Merge object connects to a stream produced by a Times object that multiplies numbers from a Successor stream by 3 and a Times object that multiplies numbers from another Successor stream by 5. This is shown in the red lines on the left where the output stream is referenced by s. Walking through s is done as in the previous slide.