Comp215: Thinking Generically

Similar documents
Lambdas and Generics (Intro)

Comp215: Covariance and Contravariance

Thinking Functionally

Comp215: More lists. Dan S. Wallach (Rice University) Copyright 2015, Dan S. Wallach. All rights reserved.

Matching & more list functions

CSE 331 Software Design and Implementation. Lecture 14 Generics 2

Chapter 1 Getting Started

Comp215: Trees. Dan S. Wallach (Rice University) Copyright 2015, Dan S. Wallach. All rights reserved.

The list abstract data type defined a number of operations that all list-like objects ought to implement:

CSE 331 Software Design and Implementation. Lecture 14 Generics 2

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

CS 3 Introduction to Software Engineering. 3: Exceptions

Exception Handling. Sometimes when the computer tries to execute a statement something goes wrong:

Exception Handling. Run-time Errors. Methods Failure. Sometimes when the computer tries to execute a statement something goes wrong:

Java Primer. CITS2200 Data Structures and Algorithms. Topic 2

BASIC COMPUTATION. public static void main(string [] args) Fundamentals of Computer Science I

Programming II (CS300)

QUIZ. What is wrong with this code that uses default arguments?

Error Handling. public int divide(double a, double b) { if (b==0) return -1; // error double result = a/b; return 0; // success }

20 Subclassing and Mutation

Comp215: Trees. Mack Joyner and Dan S. Wallach (Rice University) Copyright 2016, Dan S. Wallach. All rights reserved.

Introduction to Programming Using Java (98-388)

Intro. Scheme Basics. scm> 5 5. scm>

Designing Robust Classes

CSE Lecture 7: Polymorphism and generics 16 September Nate Nystrom UTA

A Third Look At Java. Chapter Seventeen Modern Programming Languages, 2nd ed. 1

Introduction to Object-Oriented Programming

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

CS 251 Intermediate Programming Methods and Classes

CS 251 Intermediate Programming Methods and More

Announcements. CS18000: Problem Solving And Object-Oriented Programming

Welcome to Comp215: Introduction to Program Design

CS/ENGRD 2110 FALL Lecture 7: Interfaces and Abstract Classes

17 Multiple Inheritance and ADT Extensions

Announcements. Lecture 14 Generics 1. Announcements. CSE 331 Software Design and Implementation. Leah Perlmutter / Summer 2018

CSE 331 Software Design and Implementation. Lecture 14 Generics 1

Brief Summary of Java

An Introduction to Subtyping

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

CS159. Nathan Sprague

Day 8. COMP1006/1406 Summer M. Jason Hinek Carleton University

Lecture 14: Exceptions 10:00 AM, Feb 26, 2018

F1 A Java program. Ch 1 in PPIJ. Introduction to the course. The computer and its workings The algorithm concept

Topics. Java arrays. Definition. Data Structures and Information Systems Part 1: Data Structures. Lecture 3: Arrays (1)

CS 61B Discussion 5: Inheritance II Fall 2014

Announcements. Working on requirements this week Work on design, implementation. Types. Lecture 17 CS 169. Outline. Java Types

Exceptions. References. Exceptions. Exceptional Conditions. CSE 413, Autumn 2005 Programming Languages

CS11 Introduction to C++ Fall Lecture 6

CS108, Stanford Handout #8. Java Generics

Programming II (CS300)

16 Multiple Inheritance and Extending ADTs

Computer Science & Engineering 505 Final December 10, 1999 Open book & notes 110 minutes 10 points per question 90 points total

CS61B Lecture #24. Today: Java support for generic programming. Readings for today: A Java Reference, Chapter 10.

Construction: High quality code for programming in the large

What did we talk about last time? Course overview Policies Schedule

COMP1008 Exceptions. Runtime Error

Classes, interfaces, & documentation. Review of basic building blocks

Assertions and Exceptions Lecture 11 Fall 2005

CSE 331 Software Design and Implementation. Lecture 13 Generics 1

CS/ENGRD 2110 SPRING 2018

Exceptions. What exceptional things might our programs run in to?

Program Fundamentals

16-Dec-10. Consider the following method:

Argument Passing All primitive data types (int etc.) are passed by value and all reference types (arrays, strings, objects) are used through refs.

Midterm Exam CS 251, Intermediate Programming March 6, 2015

Programming Languages and Techniques (CIS120)

Lecture 5: Implementing Lists, Version 1

CS558 Programming Languages

EXCEPTIONS. Prof. Chris Jermaine

Comp215: Enums / Testing

2SKILL. Variables Lesson 6. Remembering numbers (and other stuff)...

Object typing and subtypes

Exceptions. Errors and Exceptions. Dealing with exceptions. What to do about errors and exceptions

C# Programming for Developers Course Labs Contents

CS112 Lecture: Exceptions. Objectives: 1. Introduce the concepts of program robustness and reliability 2. Introduce exceptions

CSCI-142 Exam 1 Review September 25, 2016 Presented by the RIT Computer Science Community

Object Oriented Programming: In this course we began an introduction to programming from an object-oriented approach.

Errors and Exceptions

VARIABLES AND TYPES CITS1001

Exceptions. CSE 142, Summer 2002 Computer Programming 1.

Exceptions. Readings and References. Exceptions. Exceptional Conditions. Reading. CSE 142, Summer 2002 Computer Programming 1.

CS211 Computers and Programming Matthew Harris and Alexa Sharp July 9, Boggle

What can go wrong in a Java program while running?

Java Loose Ends. 11 December 2017 OSU CSE 1

15CS45 : OBJECT ORIENTED CONCEPTS

Array. Prepared By - Rifat Shahriyar

Object Oriented Programming

1 Epic Test Review 2 Epic Test Review 3 Epic Test Review 4. Epic Test Review 5 Epic Test Review 6 Epic Test Review 7 Epic Test Review 8

Expressions and Data Types CSC 121 Spring 2015 Howard Rosenthal

Research on the Novel and Efficient Mechanism of Exception Handling Techniques for Java. Xiaoqing Lv 1 1 huihua College Of Hebei Normal University,

CSE 331 Software Design & Implementation

COMP 250 Winter 2011 Reading: Java background January 5, 2011

CS18000: Programming I

Lesson 10A OOP Fundamentals. By John B. Owen All rights reserved 2011, revised 2014

20 Most Important Java Programming Interview Questions. Powered by

Generics. Computer Science and Engineering College of Engineering The Ohio State University. Lecture 10

Announcements. Written Assignment 2 Due Monday at 5:00PM. Midterm next Wednesday in class, 11:00 1:00. Midterm review session next Monday in class.

Expressions and Data Types CSC 121 Fall 2015 Howard Rosenthal

CSE 431S Type Checking. Washington University Spring 2013

Separate Compilation Model

Transcription:

Comp215: Thinking Generically Dan S. Wallach (Rice University) Copyright 2015, Dan S. Wallach. All rights reserved.

Functional APIs On Wednesday, we built a list of Objects. This works. But it sucks. class FList { public FList add(object o) {... public boolean contains(object o) {... public Object head() {... public FList tail() {... public boolean empty() {... FList fl = new FList().add("Hello").add("Rice").add("Owls"); System.out.println(fl.head()); // Owls System.out.println(fl.tail().head()); // Rice System.out.println(fl.tail().tail().head()); // Hello

The Problem with Objects When all the world s an Object, what if you want to treat it differently? Old school answer: explicit typecast to the proper type. The problem: what if you re wrong? Good style would require more error checking, makes code ugly. FList fl = new FList().add("Hello").add("Rice").add("Owls"); System.out.println(fl.head()); // Owls System.out.println(fl.tail().head()); // Rice System.out.println(fl.tail().tail().head()); // Hello String foo = (String) fl.head(); // cast to String Yuck! But I know they re all Strings!

Generic APIs Pronounced List of T or T List T is a type parameter. We can now have lists of String, lists of Foo, whatever. No need for typecasting. class FList<T> { final T value; final FList taillist; public FList add(t value) {... public boolean contains(t value) {... public T head() {... public FList tail() {... public boolean empty() {... FList<String> fl = new FList<>().add("Hello").add("Rice").add("Owls"); String foo = fl.head(); // no cast necessary!

Generic APIs Pronounced List of T or T List T is a type parameter. We can now have lists of String, lists of Foo, whatever. No need for typecasting. class FList<T> { final T value; final FList taillist; public FList add(t value) {... public boolean contains(t value) {... public T head() {... public FList tail() {... public boolean empty() {... FList<String> fl = new FList<>().add("Hello").add("Rice").add("Owls"); type parameter <T> String foo = fl.head(); // no cast necessary!

Generic APIs Pronounced List of T or T List T is a type parameter. We can now have lists of String, lists of Foo, whatever. No need for typecasting. FList of String class FList<T> { final T value; final FList taillist; Type inference: Java figures public FList it out add(t from value) context. {... public boolean contains(t value) {... public T head() {... public FList tail() {... public boolean empty() {... FList<String> fl = new FList<>().add("Hello").add("Rice").add("Owls"); String foo = fl.head(); // no cast necessary!

Shirt<T>

Vocabulary Alert Generics = Parametric Polymorphism (Type) Parameter = Type arguments in the brackets (<T>, etc.) Polymorphism = Same code can operate over different types Remember Zen Coding Rule #1: Don t Repeat Yourself. Generics help.

What about those singletons? Beforehand... class FList { final Object value; final FList taillist;... public static class Empty extends FList { private final static Empty singleton = new Empty(); // we don t want others using this protected Empty() { super(null, null); // call this to create an empty list, even // though it just returns one we already have public static FList create() { return singleton;

What about those singletons? Afterward... public static class FList<T> { final T value; final FList taillist; <?>? <T> s spread around in various places. The singleton is a bit weird. There s only one? What s it s instance type?... public static class Empty<T> extends FList<T> { final static FList<?> singleton = new Empty<>(); // we don t want others using this protected Empty() { super(null, null); // call this to create an empty list, even // though it just returns one we already have public static <T> FList<T> create() { @SuppressWarnings("unchecked") FList<T> result = (FList<T>) singleton; return result;

What about those singletons? Afterward... <T> s spread around in various places. The singleton is a bit weird. There s only one? What s it s instance type? Compiler directive. public static class FList<T> { final T value; final FList taillist;... public static class Empty<T> extends FList<T> { final static FList<?> singleton = new Empty<>(); // we don t want others using this protected Empty() { super(null, null); // call this to create an empty list, even // though it just returns one we already have public static <T> FList<T> create() { @SuppressWarnings("unchecked") FList<T> result = (FList<T>) singleton; return result;

What about those singletons? Afterward... <T> s spread around in various places. The singleton is a bit weird. There s only one? What s it s instance type? public static class FList<T> { final T value; final FList taillist;... Type parameter for public static class Empty<T> extends FList<T> { final static FList<?> singleton = static method. new Empty<>(); // we don t want others using this protected Empty() { super(null, null); // call this to create an empty list, even // though it just returns one we already have public static <T> FList<T> create() { @SuppressWarnings("unchecked") FList<T> result = (FList<T>) singleton; return result;

Understanding Java generics Rule #1: there s only one real class (FList, etc.) Java does type erasure, so FList<String> and FList<Foo> etc. become just FList. At runtime, there s no such thing as FList<String> Implications There s only ever one static member variable of a given name. Generic: final static FList<?> singleton = new Empty<>(); Erased: final static FList singleton = new Empty (); We can get away with mixing and matching FList.Empty<A> for FList.Empty<B> @SuppressWarnings("unchecked") At runtime, nobody knows what T is. Not allowed to say new T(...) -- a giant headache, sometimes really ugly workarounds

Java can t always read your mind What you wish you could write: FList<String> list = FList.Empty.create().add("Hello").add("Rice"); Java can t (always) figure out the generic return-type of create(). (Sigh.) Solution: break it into two lines. FList<String> emptylist = FList.Empty.create(); FList<String> list = emptylist.add("hello").add("rice");

Type restrictions Sometimes we don t care, e.g., FList<T> Sometimes we want to constrain T Example: for things you put in a tree, they need to be comparable interface Comparable<T> { int compareto(t o); If we had a tree class, we might say: class FTree<T extends Comparable<T>> {...

Multiple type parameters? No problem. public class Pair<A,B> { final public A a; final public B b; public Pair(A a, B b) { this.a = a; this.b = b; We ll use this when we want to return more than one thing at a time. return new Pair<>(thing1, thing2);

Generics + Class Inheritance = Headache For now, we ll keep it simple but here s the issue. Simplified. class B extends A {... FList<B> flb =...; fla = flb; // error! flb = fla; // error! Anybody who can deal with A can also deal with B, because B extends A. But, List of B doesn t drop in where List of A normally goes. Why? fla = fla.add(new A(...)); // fine fla = fla.add(new B(...)); // also fine, because B extends A fla = flb; // error, but let s pretend it s okay fla = fla.add(new A(...)); // you just added an A onto a list of B!

Generics + Class Inheritance = Headache For now, we ll keep it simple but here s the issue. Simplified. FList<B> class B extends expects A { B,... not B s supertype A If FList<B> you could flb = assign...; fla = flb, then you could violate the rule at fla = flb; // error! runtime. Java forbids this. flb = fla; // error! Anybody who can deal with A can also deal with B, because B extends A. But, List of B doesn t drop in where List of A normally goes. Why? fla = fla.add(new A(...)); // fine fla = fla.add(new B(...)); // also fine, because B extends A fla = flb; // error, but let s pretend it s okay fla = fla.add(new A(...)); // you just added an A onto a list of B!

Generics + Class Inheritance For now, just deal with List<A> and List<B> not being interchangeable. Later on, we ll learn about type wildcards that work around this. And, while we re at it, why functional lists give us more flexibility than mutating. If you re bored, go read up on covariance and contravariance. There s a lot of deep theory here that we re totally ignoring today. (Coming in week 6!)

Cool Java Features

Useful Java feature #1: auto-boxing Java has two kinds of values: primitive types and objects. int, float, double, long, char, byte, boolean You can only use object types for generic type parameters Sorry, FList<int> isn t allowed The solution? Java object classes specifically made to wrap the primitives Integer, Float, Double, Long, Char, Byte, Boolean FList<Integer> emptyintlist = FList.Empty.create(); FList<Integer> list = emptyintlist.add(5).add(3).add(7); You pass an int and it s automatically wrapped in an Integer

Useful Java feature #2: exceptions What do you do when you don t have something useful to return? Example: there really is no head() of an empty list. Typical ugly solution: return null But, like we said earlier, null sucks. Better: throw an exception public T head() { throw new RuntimeException("can't take head() of an empty list");

Catching exceptions @Test public void testhead() throws Exception { FList<String> emptylist = List.Empty.create(); FList<String> list = emptylist.add("alice").add("bob").add("charlie"); assertequals("charlie", list.head()); asserttrue(emptylist.empty()); // now, verify that we can't take head of an empty list try { String foo = emptylist.head(); fail("exception should have been thrown"); catch (RuntimeException e) { // good! another JUnit feature: an assertion that always fails

Zen coding rule #2: proper exceptions Exceptions have an inheritance hierarchy Create and throw specific exception types for your problem class EmptyListException extends RuntimeException {... Rules of thumb: Don t catch an exception you re not prepared to deal with Catch the most specific exception(s) that you expect you might see Throw specific exceptions (not just RuntimeException ) Declared vs. undeclared exceptions RuntimeException extends Exception extends Throwable Anybody can throw a RuntimeException or subclass Other exceptions thrown must be declared public T head() throws EmptyListException {... Forces the caller to do a try/catch block and catch the exception

Zen coding rule #2: proper exceptions Exceptions have an inheritance hierarchy Create and throw specific exception types for your problem class EmptyListException extends RuntimeException {... Rules of thumb: Don t catch an exception you re not prepared to deal with Catch the most specific exception(s) that you expect you might see Throw specific exceptions (not just RuntimeException ) Declared vs. undeclared exceptions RuntimeException extends Exception extends Throwable Anybody can throw a RuntimeException or subclass Other exceptions thrown must be declared public T head() throws EmptyListException {... Forces the caller to do a try/catch block and catch the exception Java8 Optional is even better. Stay tuned.

Live coding demo Convert FList from Objects to generics Make sure null is properly forbidden Write unit tests