CS Programming Languages: Scala

Similar documents
Programming in Scala Mixin inheritance Summer 2008

G Programming Languages - Fall 2012

Imperative Programming 2: Traits

CS Programming Languages: Scala

CS159. Nathan Sprague

The SCAlable LAnguage

Software Engineering: Design & Construction

Overview. Elements of Programming Languages. Advanced constructs. Motivating inner class example

Software Engineering Design & Construction

Lecture 21: The Many Hats of Scala: OOP 10:00 AM, Mar 14, 2018

Java Object Oriented Design. CSC207 Fall 2014

Bibliography. Analyse et Conception Formelle. Lesson 5. Crash Course on Scala. Scala in a nutshell. Outline

Programming II (CS300)

More on Objects in JAVA TM

CS159. Nathan Sprague

Encoding Scala Programs for the Boogie Verifier. Valentin Wüstholz

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

Programming in Scala Second Edition

CS Programming Languages: Scala

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

Object-oriented programming

Inheritance. Inheritance Reserved word protected Reserved word super Overriding methods Class Hierarchies Reading for this lecture: L&L

Lecture 4. Types, Memory, Exceptions

Exercise 8 Parametric polymorphism November 18, 2016

Overview. Elements of Programming Languages. Objects. Self-Reference

Object Oriented Features. Inheritance. Inheritance. CS257 Computer Science I Kevin Sahr, PhD. Lecture 10: Inheritance

Advanced Object-Oriented Languages Scala

CS558 Programming Languages

Overview. Elements of Programming Languages. Objects. Self-Reference

What can go wrong in a Java program while running?

Software Engineering Design & Construction Dr. Michael Eichberg Fachgebiet Softwaretechnik Technische Universität Darmstadt

Programming Languages and Techniques (CIS120)

CS 251 Intermediate Programming Inheritance

15 Multiple Inheritance and Traits

Control Structures. Christopher Simpkins CS 3693, Fall Chris Simpkins (Georgia Tech) CS 3693 Scala / 1

Scalable Component Abstractions

Object Oriented Issues in VDM++

Software Engineering Design & Construction Dr. Michael Eichberg Fachgebiet Softwaretechnik Technische Universität Darmstadt

CS 11 java track: lecture 3

Programming II (CS300)

Week 7 Inheritance. Written by Alexandros Evangelidis. Adapted from Joseph Gardiner. 10 November 2015

Copyright 2018 Tendril, Inc. All rights reserved.

CS-202 Introduction to Object Oriented Programming

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

To Think About. MyClass.mogrify(new int[] { 1, 2, 4, 6 }));

Subtyping and Objects

Functional Objects. Christopher Simpkins CS 3693, Fall Chris Simpkins (Georgia Tech) CS 3693 Scala / 1

CSCI-GA Final Exam

Learning Scala Seminar 2

Prelim 1 SOLUTION. CS 2110, September 29, 2016, 7:30 PM Total Question Name Loop invariants. Recursion OO Short answer

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

Scala. Fernando Medeiros Tomás Paim

Official Survey. Cunning Plan: Focus On Objects. The Need for a Calculus. Object Calculi Summary. Why Not Use λ-calculus for OO?

Lecture 2. 1 Immutability. 2 Case Classes

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

CS-XXX: Graduate Programming Languages. Lecture 23 Types for OOP; Static Overloading and Multimethods. Dan Grossman 2012

Cloning Enums. Cloning and Enums BIU OOP

CS 2340 Objects and Design - Scala

More Relationships Between Classes

INHERITANCE & POLYMORPHISM. INTRODUCTION IB DP Computer science Standard Level ICS3U. INTRODUCTION IB DP Computer science Standard Level ICS3U

6.005 Elements of Software Construction

Sri Vidya College of Engineering & Technology Question Bank

Programming Paradigms, Fall 06

Principles of Software Construction: Objects, Design, and Concurrency. Objects (continued) toad. Spring J Aldrich and W Scherlis

CS152: Programming Languages. Lecture 24 Bounded Polymorphism; Classless OOP. Dan Grossman Spring 2011

Pieter van den Hombergh Thijs Dorssers Stefan Sobek. January 11, 2018

Implementing a Universe Type System for Scala. Manfred Stock

HAS-A Relationship. If A uses B, then it is an aggregation, stating that B exists independently from A.

Object Oriented Programming

JAVA MOCK TEST JAVA MOCK TEST II

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

Chapter 10 Classes Continued. Fundamentals of Java

Java Inheritance. Written by John Bell for CS 342, Spring Based on chapter 6 of Learning Java by Niemeyer & Leuck, and other sources.

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

University of Tartu Faculty of Mathematics and Computer Science Institute of Computer Science

G Programming Languages - Fall 2012

Object Oriented Programming. Java-Lecture 11 Polymorphism

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

Lecture 13: Object orientation. Object oriented programming. Introduction. Object oriented programming. OO and ADT:s. Introduction

Adding support for CLR Generics

Inheritance and Encapsulation. Amit Gupta

Inheritance. Benefits of Java s Inheritance. 1. Reusability of code 2. Code Sharing 3. Consistency in using an interface. Classes

More About Objects. Zheng-Liang Lu Java Programming 255 / 282

n n Official Scala website n Scala API n

CSSE 220 Day 15. Inheritance. Check out DiscountSubclasses from SVN

CS 61B Data Structures and Programming Methodology. July 7, 2008 David Sun

Object-oriented programming. and data-structures CS/ENGRD 2110 SUMMER 2018

First Programming Language in CS Education The Arguments for Scala

Atelier Java - J2. Marwan Burelle. EPITA Première Année Cycle Ingénieur.

Last name:... First name:... Department (if not D-INFK):...

Java Wildcards Meet Definition-Site Variance

PROGRAMMING LANGUAGE 2

CSE 130: Spring 2012

Programming Languages and Techniques (CIS120)

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division. P. N. Hilfinger

CS Programming I: Inheritance

Exercise 6 Multiple Inheritance, Multiple Dispatch and Linearization November 4, 2016

Pieter van den Hombergh Thijs Dorssers Stefan Sobek. February 10, 2017

Everything is an object. Almost, but all objects are of type Object!

Transcription:

CS 3101-2 - Programming Languages: Scala Lecture 5: Exceptions, Generic Classes Daniel Bauer (bauer@cs.columbia.edu) November 19, 2014 Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 1/28

1 Exceptions 2 Traits 3 Type Variance, Upper bounds Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 2/28

Throwing Exceptions Exceptions work similar to Java throw{... catch{... finally{... throw is an expression (but the value of the expression can never be used) val half = if (n % 2 == 0) n / 2 else throw new RuntimeException (" n must be even ") Exceptions are used less often than in Java or Python. Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 3/28

Catching Exceptions Exceptions are passed up the call hierarchy, until they reach a catch clause. import scala. io. Source import java. io.{ FileNotFoundException, IOException val filename = " input. txt " try { val input = Source. fromfile ( filename ) for ( line <- input. getlines ()) { println ( line ) catch { case ex: FileNotFoundException => println (" File not found.") case ex: IOException => println (" Cannot read from file.") Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 4/28

finally clause A finally clause will be executed whether an exception occurs or not. import scala. io. Source import java. io.{ FileNotFoundException, IOException val filename = " input. txt " val input = Source. fromfile ( filename ) try { for ( line <- input. getlines ()) { println ( line ) catch { case ex: FileNotFoundException => println (" File not found.") case ex: IOException => println (" Cannot read from file.") finally { input. close () Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 5/28

The Loan pattern Write a higher-order function that borrows a resource and makes sure it is returned. def withfilesource ( filename : String )( op: Source => Unit ) { val filesource = Source. fromfile ( filename ) try { op( filesource ) finally { filesource. close () withfilesource (" input. txt ") { input => { for ( line <- input. getlines ()) println ( line ) Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 6/28

1 Exceptions 2 Traits 3 Type Variance, Upper bounds Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 7/28

Traits vs. Inheritance Inheritance means adding to the implementation of a single parent class (or overriding). Scala does not support multiple inheritance (unlike e.g. Python), but offers traits. Traits are a fundamental unit of code reuse. Defines methods and attributes that can be re-used by various classes. Classes can mix in any number of traits. Similar to Java interfaces. No parameters. trait Philosophical { def philosophize () { println (" I consume memory, therefore I am!") Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 8/28

Defining and Using Traits trait Philosophical { def philosophize () { println (" I consume memory, therefore I am!") trait HasLegs { val legs : Int = 4 class Animal class Frog extends Animal with Philosophical with HasLegs { override def tostring = " green " scala > val frog = new Frog frog : Frog = green scala > frog. philosophize I consume memory, therefore I am! scala > frog. legs res0 : Int = 4 Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 9/28

Using Traits II A single Trait can be mixed in using extends. trait Philosophical { def philosophize () { println (" I consume memory, therefore I am!") // mix in Philosophical class Philosopher extends Philosophical scala > class Philosopher extends Philosophical defined class Philosopher scala > val p = new Philosopher p: Philosopher = Philosopher@ 2dc4de05 scala > p. philosophize I consume memory, therefore I am! Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 10/28

Traits are Types trait Philosophical { def philosophize () { println (" I consume memory, therefore I am!") class Animal class Frog extends Animal with Philosophical { val color = " green " scala > val phil : Philosophical = new Frog () // trait as type f: Philosophical = Frog@ 16a15a6e scala > phil. philosophize I consume memory, therefore I am! Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 11/28

Traits are Types trait Philosophical { def philosophize () { println (" I consume memory, therefore I am!") class Animal class Frog extends Animal with Philosophical { val color = " green " scala > val phil : Philosophical = new Frog () // trait as type f: Philosophical = Frog@ 16a15a6e scala > phil. philosophize I consume memory, therefore I am! scala > phil. color // not accessible because defined on Frog < console >:12: error : value color is not a member of Philosophical Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 11/28

Polymorphism with Traits trait Philosophical { def philosophize () { println (" I consume memory, therefore I am!") class Animal class Frog extends Animal with Philosophical { override def tostring = " green " override def philosophize () { println (" It ain t easy being " + tostring + "!") scala > val phrog : Philosophical = new Frog () phrog : Philosophical = green scala > phrog. philosophize It ain t easy being green! Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 12/28

Thin vs. Rich Interfaces to Classes Thin Interfaces: Minimal functionality, few methods. Easy for the developer of the interface. Larger burden on client using the class (needs to fill in the gaps or adapt general methods). Rich Interfaces: Many specialized methods. Larger burden when implementing the class. Convenient for the client. Traits can be used to enrich thin interfaces, re-using existing methods. Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 13/28

Thin vs. Rich Interfaces - Example: Rectangular Objects class Point ( val x: Int, val y: Int ) class Rectangle ( val topleft : Point, val bottomright : Point ) { def left = topleft.x def right = bottomright.x def width = right - left // and many more geometric methods... Another class outside of the same type hierarchy with similar functionality: abstract class Widget { def topleft : Point def bottomright : Point def left = topleft.x def right = bottomright.x def width = right - left // and many more geometric methods... Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 14/28

Thin vs. Rich Interfaces - Example: Rectangular Objects def Rectangular { def topleft : Point def bottomright : Point def left = topleft. x def right = bottomright. x def width = right - left // and many more geometric methods... abstract class Widget extends Rectangular { // other methods... class Rectangle ( val topleft : Point, val bottomright : Point ) extends Rectangular { // other methods... Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 15/28

Modifying Methods with Traits import scala. collection. mutable. ArrayBuffer abstract class IntQueue { def get (): Int def put (x: Int ) class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer [ Int ] def get () = buf. remove (0) def put (x: Int ) { buf += x Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 16/28

Modifying Methods with Traits import scala. collection. mutable. ArrayBuffer abstract class IntQueue { def get (): Int def put (x: Int ) class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer [ Int ] def get () = buf. remove (0) def put (x: Int ) { buf += x scala > val queue = new BasicIntQueue queue : BasicIntQueue = BasicIntQueue@24655f scala > queue. put (10) scala > queue. put (20) Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 16/28

Modifying Methods with Traits import scala. collection. mutable. ArrayBuffer abstract class IntQueue { def get (): Int def put (x: Int ) class BasicIntQueue extends IntQueue { private val buf = new ArrayBuffer [ Int ] def get () = buf. remove (0) def put (x: Int ) { buf += x scala > val queue = new BasicIntQueue queue : BasicIntQueue = BasicIntQueue@24655f scala > queue. put (10) scala > queue. put (20) scala > queue. get () res0 : Int = 10 scala > queue. get () res1 : Int = 20 Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 16/28

Modifying Methods with Traits Traits can modify (override) methods of a base class. Add some functionality but then call method of the super class. trait Incrementing extends IntQueue { abstract override def put ( x: Int ) { super. put ( x + 1) scala > class MyQueue extends BasicIntQueue with Incrementing defined class MyQueue Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 17/28

Modifying Methods with Traits Traits can modify (override) methods of a base class. Add some functionality but then call method of the super class. trait Incrementing extends IntQueue { abstract override def put ( x: Int ) { super. put ( x + 1) scala > class MyQueue extends BasicIntQueue with Incrementing defined class MyQueue scala > val queue = new MyQueue scala > val queue = new BasicIntQueue with Incrementing queue : BasicIntQueue with Incrementing = $anon$1@ 5fa12d Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 17/28

Modifying Methods with Traits Traits can modify (override) methods of a base class. Add some functionality but then call method of the super class. trait Incrementing extends IntQueue { abstract override def put ( x: Int ) { super. put ( x + 1) scala > class MyQueue extends BasicIntQueue with Incrementing defined class MyQueue scala > val queue = new MyQueue scala > val queue = new BasicIntQueue with Incrementing queue : BasicIntQueue with Incrementing = $anon$1@ 5fa12d scala > queue. put (10) scala > queue. get () res : Int = 21 Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 17/28

Modifying Methods with Traits Multiple traits can be mixed in to stack functionality. Methods on super are called according to linear order of with clauses (right to left). trait Incrementing extends IntQueue { abstract override def put (x: Int ) { super. put (x + 1) trait Filtering extends IntQueue { abstract override def put (x: Int ) { if (x >= 0) super. put (x) Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 18/28

Modifying Methods with Traits Multiple traits can be mixed in to stack functionality. Methods on super are called according to linear order of with clauses (right to left). trait Incrementing extends IntQueue { abstract override def put (x: Int ) { super. put (x + 1) trait Filtering extends IntQueue { abstract override def put (x: Int ) { if (x >= 0) super. put (x) scala > val queue = new ( BasicIntQueue with Incrementing with Filtering ) queue : BasicIntQueue with Incrementing with Filtering... Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 18/28

Modifying Methods with Traits Multiple traits can be mixed in to stack functionality. Methods on super are called according to linear order of with clauses (right to left). trait Incrementing extends IntQueue { abstract override def put (x: Int ) { super. put (x + 1) trait Filtering extends IntQueue { abstract override def put (x: Int ) { if (x >= 0) super. put (x) scala > val queue = new ( BasicIntQueue with Incrementing with Filtering ) queue : BasicIntQueue with Incrementing with Filtering... scala > queue. put ( -1); queue. put (0); scala > queue. get () res : Int = 1 Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 18/28

Traits or Abstract Classes Both traits and abstracts classes can have abstract and concrete members. Traits: No constructor paramters or type parameters. Multiple traits can be mixed into class definitions. Semantics of super depends on order of mixins. Can call abstract methods. Abstract Classes: Have constructor parameters and type parameters. Work better when mixing Scala with Java. super refers to unique parent. Can only call concrete methods. Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 19/28

1 Exceptions 2 Traits 3 Type Variance, Upper bounds Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 20/28

Parametric Types Typically want to specify type of elements of a collection. Using generic classes. scala > val x : List [ Int ] = 1 :: 2 :: 3 :: Nil x: List [ Int ] = List (1, 2, 3) scala > val y : List [ Int ] = 1 :: 2 :: " Hello " :: Nil < console >:7: error : type mismatch ; found : List [ Any ] required : List [ Int ] val y : List [ Int ] = 1 :: 2 :: " Hello " :: Nil Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 21/28

Parametric Types Typically want to specify type of elements of a collection. Using generic classes. scala > val x : List [ Int ] = 1 :: 2 :: 3 :: Nil x: List [ Int ] = List (1, 2, 3) scala > val y : List [ Int ] = 1 :: 2 :: " Hello " :: Nil < console >:7: error : type mismatch ; found : List [ Any ] required : List [ Int ] val y : List [ Int ] = 1 :: 2 :: " Hello " :: Nil scala > val x = 1 :: 2 :: " Hello " :: Nil x: List [ Any ] = List (1, 2, Hello ) scala > x (2) // Don t know specific type of this element res0 : Any = Hello Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 21/28

Scala s Type Hierarchy scala.any scala.anyval scala.anyref (java.lang.object) scala.double scala.float scala.unit scala.boolean scala.scalaobject java.string scala.short scala.char scala classes other java classes scala.int scala.long scala.byte Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 22/28

Type Parameters for Methods Methods can also have type parameters (for return value and parameters). def dup [T](x: T, n: Int ): List [T] = if (n == 0) Nil else x :: dup (x, n - 1) println ( dup [ Int ](3, 4)) println ( dup (" three ", 3)) Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 23/28

By Defaul, Classes are Invariant Type parameters generate a family of types. Is GenericClass[A] a subtype of GenericClass[B] if A is a subtype of b? scala > class Container [ A]( val content : A) defined class Container scala > val x = new Container (" test ") x: Container [ String ] = Container@ 256f8274 scala > val y : Container [ AnyRef ] = x < console >:9: error : type mismatch ; found : Container [ String ] required : Container [ AnyRef ] Note : String <: AnyRef, but class Container is invariant in type A. You may wish to define A as +A instead. ( SLS 4.5) val y : Container [ AnyRef ] = x Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 24/28

Covariance Annotations Prefixing a type parameter with + makes the class covariant in this parameter. scala > class Container [+ A]( val content : A) defined class Container scala > val x = new Container (" text ") x: Container [ String ] = Container@ 14f5da2c scala > val y : Container [ AnyRef ] = x y: Container [ AnyRef ] = Container@ 14f5da2c Container[String] is now a subclass of any Container[A] if String is subtype of A. Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 25/28

Covariance can be tricky Prefixing a type parameter with + makes the class covariant in this parameter. scala > class Container [+ A]( var content : A) // make it a var Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 26/28

Covariance can be tricky Prefixing a type parameter with + makes the class covariant in this parameter. scala > class Container [+ A]( var content : A) // make it a var < console >:9: error : covariant type A occurs in contravariant po class Container [+ A]( var content : A) What s wrong with this class definition? Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 26/28

Covariance can be tricky II Prefixing a type parameter with + makes the class covariant in this parameter. scala > class Container [+ A]( val content : A) { def printexternal ( x : A) { println (x) Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 27/28

Covariance can be tricky II Prefixing a type parameter with + makes the class covariant in this parameter. scala > class Container [+ A]( val content : A) { def printexternal ( x : A) { println (x) < console >:10: error : covariant type A occurs in contravariant p def printexternal ( x : A) { What s wrong with this class definition? Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 27/28

Covariance can be tricky II Prefixing a type parameter with + makes the class covariant in this parameter. scala > class Container [+ A]( val content : A) { def printexternal ( x : A) { println (x) < console >:10: error : covariant type A occurs in contravariant p def printexternal ( x : A) { What s wrong with this class definition? General rules: Cannot use covariance if type parameter is used for a mutable field. Cannot use covariance if type paramater is used for a method paramter. Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 27/28

Lower Bounds Lower bounds can be used when defining methods of covariant classes. Reveal at least some information about the parameters. scala > class Container [+ A]( val content : A) { def printexternal [ B >: A]( x : B) { println (x) def maketuple [B >: A]( other : B): (B, B) = ( content, other ) scala > val x = new Container ("hi") x: Container [ String ] = Container@ 6d2a209c scala > x. maketuple (3) res1 : (Any, Any ) = (hi,3) Daniel Bauer CS3101-2 Scala - 05 - Exceptions, Generic Classes 28/28