teaching machines

CS 330 Lecture 37 – Promises and Futures

May 6, 2015 by . Filed under cs330, lectures, spring 2015.

Agenda

TODO

Intentions

Evaluate This

How should we evaluate the following entities? Eagerly? Eagerly but asynchronously? Lazily?

  1. A nearby region in an interactive 3D world
  2. Full resolution images hosted by a photo storage service and accessed on a mobile app
  3. The hash code of a string
  4. An index of your hard drive
  5. The bodies of email messages
  6. The balance of your checking account

Code

Future.scala

import java.awt.image.BufferedImage
import javax.swing.JLabel
import javax.swing.ImageIcon
import java.awt.Color
import java.io.File
import java.awt.Robot
import javax.swing.JFrame
import javax.imageio.ImageIO
import scala.math._

class Future[T](thunk : => T) {
  private var cache : T = _

  private val thread = new Thread {
    override def run {
      cache = thunk
    }
  }

  println("about to start thread")
  // thread.run 
  thread.start
  println("started thread")

  def apply(): T = {
    while (cache == null) {
      try {
        println("force")
        thread.join
      } catch {
        case e : InterruptedException => {}
      }
    }

    cache
  }
}

object Main {
  def main(args: Array[String]) {
    val future = new Future[BufferedImage]({
      val in = ImageIO.read(new File("/Users/johnch/Desktop/front_page.jpg"))
      Thread.sleep(5000)
      val out = new BufferedImage(in.getWidth, in.getHeight, in.getType)

      for (c <- 0 until out.getWidth; r <- 0 until out.getHeight) {
        val color = new Color(in.getRGB(c, r));
        val swappedColor = new Color(color.getBlue, color.getGreen, color.getRed);
        out.setRGB(c, r, swappedColor.getRGB);
      }

      out
    })

    println("other important stuff")

    // Do other very important work.
    val radius = 120
    val r = new Robot
    
    for (t <- 0 to 720 by 2) {
      val x = 4.0 * sin(toRadians(t))
      val y = sin(2 * toRadians(t))
      r.mouseMove((radius * x + 600).toInt, (radius * 1.5 * y + 300).toInt)
      r.delay(10)
    }

    new ImagePopup(future())
    new ImagePopup(future())
    new ImagePopup(future())
    new ImagePopup(future())
    new ImagePopup(future())
  }
}

class ImagePopup(val image : BufferedImage) extends JFrame {
  add(new JLabel(new ImageIcon(image)))
  pack
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
  setVisible(true) 
}

promise.html

<!DOCTYPE html>
<html>
<head>
  <title>...</title>
</head>
<body>

<img src="" id="red"/>
<img src="" id="yellow"/><br/>
<img src="" id="green"/>
<img src="" id="blue"/>

<script>
function load(color, delay) {
  var img = document.querySelector('#' + color);
  img.onload = function() {
    console.log(color);
    // resolve();
  }
  img.src = 'slow_image.php?color=' + color + '&delay=' + delay;
}

load('red', 1);
load('yellow', 2);
load('green', 3);
load('blue', 4);
</script>

</body>
</html>

Haiku

on callback hell
Old Phoenix burned up
But he forgot to hit Next
No more phoenixes