hot programming in java cos 441 princeton university fall 2004

36
HOT Programming in Java COS 441 Princeton University Fall 2004

Post on 21-Dec-2015

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: HOT Programming in Java COS 441 Princeton University Fall 2004

HOT Programming in Java

COS 441

Princeton University

Fall 2004

Page 2: HOT Programming in Java COS 441 Princeton University Fall 2004

What’s HOT

Term coined by Bob Harper

Higher-Order and Typed

Some HOT languages

SML, Haskell, Java, C#

Page 3: HOT Programming in Java COS 441 Princeton University Fall 2004

Features of HOT Languages

• Type-Safe

• Lexical Closures

• Garbage Collected

Page 4: HOT Programming in Java COS 441 Princeton University Fall 2004

A HOT Programming Style

SML is arguably “HOTer” than most language– Immutable by default– Supports inductive datatypes and pattern

matching– Advanced module system– Second-Class Polymorphism with Type

Inference

How does Java stack up?

Page 5: HOT Programming in Java COS 441 Princeton University Fall 2004

Object Orientated vs HOT Programming

Mitchell asked the question (10.2.5)“Can you program in an Object Oriented way in ML?”

Today’s question is“Can you program in a HOT way in and Object Oriented language?”

AlternativelyHow can I use what I learned about programming in SML and use it in a “real language”

Page 6: HOT Programming in Java COS 441 Princeton University Fall 2004

A Simple Example

datatype nat = Zero | Succ of nat

fun add(m,Zero) = m | add(m,Succ(n)) = Succ(add(m,n))

fun fib(Zero) = Succ(Zero) | fib(Succ(Zero)) = Succ(Zero) | fib(Succ(Succ(n))) = add(fib(Succ(n),

fib(n))

Page 7: HOT Programming in Java COS 441 Princeton University Fall 2004

Encoding a Datatype

datatype nat = Zero | Succ of nat

abstract class Nat { }class Zero extends Nat {

Zero(){ /* nop */ } }class Succ extends Nat { final Nat n; Nat(Nat n) { this.n = n; }}

Page 8: HOT Programming in Java COS 441 Princeton University Fall 2004

Creating a Value

val one = Succ(Zero)

final Nat one = new Succ (new Zero ());

Page 9: HOT Programming in Java COS 441 Princeton University Fall 2004

Creating a Value

val one = Succ(Zero)

import static Nat.*;final Nat one = Succ (Zero);

abstract class Nat { static Nat Zero = new Zero(); static Nat Succ(Nat n) {

return new Succ(n); } }

Page 10: HOT Programming in Java COS 441 Princeton University Fall 2004

The General Pattern

When encoding a type of the form

t = A + B + C + D

Create an abstract class of type “t” and have each case inherit from the abstract base class

Page 11: HOT Programming in Java COS 441 Princeton University Fall 2004

Encoding a Function

Several ways to do this

Will try obvious pure OO way first

Later approach using type casts

Finally Visitor Pattern

fun add(m,Zero) = m | add(m,Succ(n)) = Succ(add(m,n))

Page 12: HOT Programming in Java COS 441 Princeton University Fall 2004

Encoding a Function

Swap order of arguments so that add is inductively defined on its first argument

Now think of add(n,m) as n.add(m) where n is either a Zero or Succ object

Define methods appropriately

fun add(Zero,m) = m | add(Succ(n),m) = Succ(add(n,m))

Page 13: HOT Programming in Java COS 441 Princeton University Fall 2004

Encoding a Function

fun add(Zero,m) = m | add(Succ(n),m) = Succ(add(n,m))

abstract class Nat { abstract Nat add(Nat n); }

class Zero extends Nat { … Nat add(Nat m) { return m; } }class Succ extends Nat { … Nat add(Nat m) {

return new Succ(this.n.add(m)); }}

Page 14: HOT Programming in Java COS 441 Princeton University Fall 2004

A General Pattern?

Technique we described was not a general solution relies on having simple inductive definition of first argument

How do we handle binary methods like “eq”

fun eq(Zero,Zero) = true | eq(Succ(n),Succ(m)) = eq(n,m) | eq(_,_) = false

Page 15: HOT Programming in Java COS 441 Princeton University Fall 2004

Double Dispatchfun eq(Zero,Zero) = true | eq(Succ(n),Succ(m)) = eq(n,m) | eq(_,_) = false

abstract class Nat { … abstract boolean eq(Nat m); abstract boolean zeroEq(); abstract boolean succEq(Nat n);}

Page 16: HOT Programming in Java COS 441 Princeton University Fall 2004

Double Dispatchfun eq(Zero,Zero) = true | eq(Zero,_) = false

class Zero extends Nat { … boolean eq(Nat m){return m.zeroEq();} boolean zeroEq() {return true; } boolean succEq(Nat n) {return false;}}

Page 17: HOT Programming in Java COS 441 Princeton University Fall 2004

Double Dispatchfun eq(Succ(n),Succ(m)) = eq(n,m) | eq(_,_) = false

class Succ extends Nat { … boolean eq(Nat m){

return m.succEq(this.n); } boolean zeroEq() {return false; } boolean succEq(Nat n){

return n.eq(this.n); }}

Page 18: HOT Programming in Java COS 441 Princeton University Fall 2004

What about Fib?

Encoding Fib not easy to encode for other reasons besides double dispatch!

fun fib(Zero) = Succ(Zero) | fib(Succ(Zero)) = Succ(Zero) | fib(Succ(Succ(n))) = add(fib(Succ(n),

fib(n))

Page 19: HOT Programming in Java COS 441 Princeton University Fall 2004

What about Fib?

fun fib(Zero) = Succ(Zero) | fib(Succ(Zero)) = Succ(Zero) | fib(Succ(Succ(n))) = add(fib(Succ(n),

fib(n))

Nat fib(Nat n) {if(n instanceof Zero) {

return new Succ(new Zero());}Succ m = (Succ) n;…

}

Page 20: HOT Programming in Java COS 441 Princeton University Fall 2004

InstanceOf

Java provides instanceof operator to test for class at runtime and dynamic type casts to cast appropiately

Requires runtime type info (not available in C++)

Error Prone and Hard to read

Page 21: HOT Programming in Java COS 441 Princeton University Fall 2004

Reducing to Primitive Matching

fun fib(Zero) = Succ(Zero) | fib(Succ(Zero)) = Succ(Zero) | fib(Succ(Succ(n))) = add(fib(Succ(n),

fib(n))fun fib(Zero) = Succ(Zero) | fib(Succ(m)) = fibSucc(m)and fibSucc(Zero) = Succ(Zero) | fibSucc(Succ(n)) = add(fib(Succ(n),

fib(n))

Page 22: HOT Programming in Java COS 441 Princeton University Fall 2004

Visitor Design Patternabstract class Nat { abstract Nat accept(NatVisitor v); }

interface NatVisitor { Nat vZero(); Nat vSucc(Nat n);}

Page 23: HOT Programming in Java COS 441 Princeton University Fall 2004

Visitor Design Patternclass Zero extends Nat { … Nat accept(NatVisitor v) { return v.vZero(); }} class Succ extends Nat { … final Nat n; Nat accept(NatVisitor v) { return v.vSucc(this.n); }}

Page 24: HOT Programming in Java COS 441 Princeton University Fall 2004

Visitor for Computing Fibclass Fib implements NatVisitor { static Nat fib(Nat n) {

return n.accept(new Fib()); } public vZero() { return new Succ(new Zero()); } public vSucc(Nat n) { return FibSucc.fibSucc(n); }}

Page 25: HOT Programming in Java COS 441 Princeton University Fall 2004

class FibSucc implements NatVisitor { static Nat fibSucc(Nat n) {

return n.accept(new FibSucc()); } public vZero() { return new Succ(new Zero()); } public vSucc(Nat n) { return Fib.fib(new Succ(n)). add(Fib.fib(n)); }}

Page 26: HOT Programming in Java COS 441 Princeton University Fall 2004

Reducing to Primitive Matching

fun fib(Zero) = Succ(Zero) | fib(Succ(Zero)) = Succ(Zero) | fib(Succ(Succ(n))) = add(fib(Succ(n),

fib(n))fun fib(Zero) = Succ(Zero) | fib(Succ(n)) = (case n of Zero => Succ(Zero) | Succ(m) => fib(n,m))

Alternate way that avoids extra function

Page 27: HOT Programming in Java COS 441 Princeton University Fall 2004

Using An Anonymous Inner Class

class Fib implements NatVisitor { … public vSucc(final Nat n) { return n.accept(new NatVisitor() { public vZero { return …;} public vSucc(Nat m) { return fib(n,m); }

} ); }}

Page 28: HOT Programming in Java COS 441 Princeton University Fall 2004

A Generic Visitorabstract class Nat { abstract <T> accept(Visitor<T> v); }

interface Visitor<T> { T vZero(); T vSucc(Nat n);}

Page 29: HOT Programming in Java COS 441 Princeton University Fall 2004

How Painful Is This?Lines of

SMLLines of

JavaJava/

SML

Name Library 33 26 0.79

MinML Syntax 30 188 6.27

Static Semantics 48 86 1.79

Dynamic Semantics 36 84 2.33

Shape Library 62 109 1.76

Ratio is ~2.5 Lines of Java for Every Line of SML

Page 30: HOT Programming in Java COS 441 Princeton University Fall 2004

How Fast Is This?

20 Loops of fib(25)

SML Java

Native 0.25 sec 0.12 sec

MinML Interp 33 sec 60 sec

Java is about 2x slower but our scheme is 4x more expensive when compare to SML/NJ

Page 31: HOT Programming in Java COS 441 Princeton University Fall 2004

Dimensions of Feature Extensions

Add Mul Fact Fib …

Zero … … … … …

Succ … … … … …

Extensible number of functions or attributes

Fix

ed s

et o

f O

bjec

ts

Page 32: HOT Programming in Java COS 441 Princeton University Fall 2004

Dimensions of Feature Extensions

Weight Desnsity Cost

Bricks … … …

Stone … … …

Wood … … …

Glass … … …

Fixed set of attributes or functions

Ext

ensi

ble

num

ber

kind

s of

obj

ects

Page 33: HOT Programming in Java COS 441 Princeton University Fall 2004

I Want Both

We have been extending MinML interpreter in both dimensions!

Different operational semantics

M-Machine, C-Machine, E-Machine, …

Different expressions and types

Pairs, Sums, Recursive, Polymorphic, …

Page 34: HOT Programming in Java COS 441 Princeton University Fall 2004

Language Design Challenge

• A good language should support extensions in both dimensions

• ML clunky in the object extension direction

• Java is clunky in the functionality extension dimension

• New languages being designed as we speak to support both well– Nice, Scala, MultiJava, …

Page 35: HOT Programming in Java COS 441 Princeton University Fall 2004

An Old Saying

A FORTRAN programmer can program FORTRAN in any language!

i.e. Program in any language as if it were FORTRAN!

Page 36: HOT Programming in Java COS 441 Princeton University Fall 2004

Summary

A HOT programmer can program HOTly in any language!

i.e. Never let your programming language stop you from being too clever!