LATENT METHODS. Richard CS

Similar documents
Smalltalk. Topics. History of Smalltalk. OOP and GUI. Steve Jobs, PARC, Dec Smalltalk 1. The best way to predict the future is to invent it.

Chapter 9 :: Data Abstraction and Object Orientation

Class 22: Inheritance

Chapter 10 :: Data Abstraction and Object Orientation

Lecturer: William W.Y. Hsu. Programming Languages

Data Structures (list, dictionary, tuples, sets, strings)

An Introduction to Smalltalk for Objective-C Programmers

Dynamic Object-Oriented Programming with Smalltalk 1. Introduction

Overview of OOP. Dr. Zhang COSC 1436 Summer, /18/2017

Squeak Object Model. Technion - Israel Institute of Technology. Updated: Spring Object-Oriented Programming 1

Simula 67. Simula and Smalltalk. Comparison to Algol 60. Brief history. Example: Circles and lines. Objects in Simula

Introduction. A. Bellaachia Page: 1

Dynamic Languages. CSE 501 Spring 15. With materials adopted from John Mitchell

Introduction to Computers and Programming Languages. CS 180 Sunil Prabhakar Department of Computer Science Purdue University

Object Oriented Programming

Lecture 09. Ada to Software Engineering. Mr. Mubashir Ali Lecturer (Dept. of Computer Science)

Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages. Corky Cartwright Mathias Ricken October 20, 2010

Basic Objects, Conditionals and Loops

Object Oriented Paradigm

ST Introduction. Birds-eye view

CS558 Programming Languages Winter 2013 Lecture 8

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

The Smalltalk class hierarchy

Core Java Syllabus. Pre-requisite / Target Audience: C language skills (Good to Have)

Object. Accessing. Changing. Chapter

Data Abstraction. Hwansoo Han

Subtyping (Dynamic Polymorphism)

Spring 2003 Instructor: Dr. Shahadat Hossain. Administrative Matters Course Information Introduction to Programming Techniques

OO design. Classes, Responsibilities, Collaborations (CRC) 13/9/1999 COSC

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

CS508-Modern Programming Solved MCQ(S) From Midterm Papers (1 TO 22 Lectures) BY Arslan

Short Notes of CS201

So on the survey, someone mentioned they wanted to work on heaps, and someone else mentioned they wanted to work on balanced binary search trees.

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

CS201 - Introduction to Programming Glossary By

CSE P 501 Compilers. Dynamic Languages Hal Perkins Winter UW CSE P 501 Winter 2016 X2-1

Guru 101 Grokking the Smalltalk system. Smalltalk Solutions Europe 1998 Joseph Pelrine Daedalos Consulting Group

Character Stream : It provides a convenient means for handling input and output of characters.

XXXXXXXXXXXXXXXXXXXXXXX. Evolution of Software Languages

CS153: Compilers Lecture 11: Compiling Objects

Advanced Database Applications. Object Oriented Database Management Chapter 13 10/29/2016. Object DBMSs

First Programming Language in CS Education The Arguments for Scala

Slide 1 CS 170 Java Programming 1 Testing Karel

PROFESSOR: Well, now that we've given you some power to make independent local state and to model objects,

Java Programming Constructs Java Programming 2 Lesson 1

What are the characteristics of Object Oriented programming language?

Design Pattern: Composite

Operating Systems CMPSCI 377, Lec 2 Intro to C/C++ Prashant Shenoy University of Massachusetts Amherst

CSE 70 Final Exam Fall 2009

MITOCW watch?v=flgjisf3l78

15CS45 : OBJECT ORIENTED CONCEPTS

Object-oriented programming in...

1 Shyam sir JAVA Notes

Chapter 10 Object-Oriented Programming

Building Robust Embedded Software

Slide 1 CS 170 Java Programming 1 The Switch Duration: 00:00:46 Advance mode: Auto

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

Client Code - the code that uses the classes under discussion. Coupling - code in one module depends on code in another module

CS Internet programming Unit- I Part - A 1 Define Java. 2. What is a Class? 3. What is an Object? 4. What is an Instance?

The Design Process. General Development Issues. C/C++ and OO Rules of Thumb. Home

Java Fundamentals p. 1 The Origins of Java p. 2 How Java Relates to C and C++ p. 3 How Java Relates to C# p. 4 Java's Contribution to the Internet p.

Object typing and subtypes

Computer Components. Software{ User Programs. Operating System. Hardware

Traits at Work: the design of a new trait-based stream library

Object-Oriented Technology. Rick Mercer

PROFESSOR: Last time, we took a look at an explicit control evaluator for Lisp, and that bridged the gap between

Simula and Smalltalk. Comparison to Algol 60. Brief history. Example: Circles and lines. Objects in Simula. John Mitchell

Object Model. Object Oriented Programming Spring 2015

Lecture 16: Object Programming Languages

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

MITOCW watch?v=w_-sx4vr53m

References: Chapters 10 and 11 Chapters 8, and 12( 2 and 3)

Chapter 2. Pseudocodes: Speedcoding. 2.2 Minimal Hardware Programming: Pseudocodes. Evolution of the Major Programming Languages

Forth Meets Smalltalk. A Presentation to SVFIG October 23, 2010 by Douglas B. Hoffman

CS107 Handout 37 Spring 2007 May 25, 2007 Introduction to Inheritance

Why are there so many programming languages? Why do we have programming languages? What is a language for? What makes a language successful?

2. The object-oriented paradigm!

Introduction to Java and OOP. Hendrik Speleers

Chapter 21a Other Library Issues

Design issues for objectoriented. languages. Objects-only "pure" language vs mixed. Are subclasses subtypes of the superclass?

Chapter 5 Names, Binding, Type Checking and Scopes

Chapter 6 Introduction to Defining Classes

Applying Traits to the Smalltalk Collection Classes

Object-Oriented Software Engineering Practical Software Development using UML and Java. Chapter 2: Review of Object Orientation

Smalltalk: developed at Xerox Palo Alto Research Center by the Learning Research Group in the 1970 s (Smalltalk-72, Smalltalk-76, Smalltalk-80)

CIS 110: Introduction to computer programming

Object Model Comparisons

2. Classes & Inheritance. Classes. Classes. Éric Tanter Objects and Design in Smalltalk. How do you create objects?

AP Computer Science Chapter 10 Implementing and Using Classes Study Guide

Files and Streams

A PROGRAM IS A SEQUENCE of instructions that a computer can execute to


CS 403/503 Exam 4 Spring 2015 Solution

Lecture 15: Object-Oriented Programming

CSCI 2041: Object Systems

Principles of Programming Languages, 2

Compaq Interview Questions And Answers

Goals of the Lecture OO Programming Principles

Late Binding; OOP as a Racket Pattern

CS 360 Programming Languages Day 14 Closure Idioms

Transcription:

LATENT METHODS Richard O'Keefe @ CS

Outline Background The problem Some non-solutions My solution Does it apply elsewhere

Background Alan Kay invented tablet computers (the Dynabook) His research group at Xerox produced Smalltalk-80, the second famous OO language after Simula-67. Simula-67 strongly influenced early C++. Smalltalk-80 influenced Java, but not its syntax.

Background 2 Smalltalk was originally implemented by compilation to byte codes, executed by microcode. Later systems used a Just-In-Time compiler. I told you Java was influenced by Smalltalk! Smalltalk Virtual machines are portable between different architectures. I told you (oh, I told you)

Background 3 Squeak is an open source descendant of Smalltalk-80. It used not to have a JIT. Bryce Kampjes wanted to do a research degree here with me developing a new JIT for Squeak. He later built Exupery, but not here. While I thought this would happen, I thought, we need a baseline. How hard can it be to write a Smalltalk compiler?

Smalltalk Everything is an object, including 137. Every object has a class, including classes. The language is single-inheritance. There is no type system (except in Animorphic Smalltalk, which Sun bought and killed). It's dynamic: everything can be changed at run time. x become: y swaps x's and y's identities

Salvation! There is an ANSI standard for Smalltalk. None of the dynamic stuff is there. There is no #become:. The GUI isn't there either (because different Smalltalk vendors had pushed it in incompatible ways). If only they had proof-read it, it would have been so easy...

PROJECT Implement ANSI Smalltalk as a batch compiler generating ISO C. Make the translation straightforward, but not totally dumb. Do not do type reconstruction. Use the Boehm garbage collector. AIM: to provide a reasonable baseline for evaluating other compilers. Once Bryce had left, AIM': hey, this thing looks useful,

POLICY Smalltalk has good support for reflection. Including anobject respondsto: aselector. In both free (GNU ST, Squeak, Pharo) and commercial (ST/X, Dolphin, VisualWorks, VisualAge) Smalltalks, #respondsto: is unreliable. Example on next slide. Policy: an object should never claim to implement a method unless it will work sometimes.

Example String>>at: index put: acharacter treats a string as a mutable array. Symbol is a subclass of String for unique strings (Lisp atoms). Symbol>>at: index put: acharacter self shouldnotimplement. So #at:put: never makes sense for symbols, but it's in their interface. I refuse to do that.

Java does it too The default implementation of java.lang.iterator.remove() throws UnsupportedOperationException. That's a precise equivalent of Smalltalk's #shouldnotimplement. So in Java as in Smalltalk, reflection is unreliable. A method can be in an object's interface even if it can never be used on that object. I don't want to do this.

The problem: duplicate code Part of the Collection hierarchy: Collection AbstractKeyedCollection AbstractSequence ReadOnlyArray Array ReadOnlyString String ReadOnlyByteArray ByteArray

Mutation Methods #at:put: has to be different for each kind of mutable array because the generated C code has to be different. atall: indices put: anelement indices do: [:each self at: each put: anelement] doesn't have to be different. But it cannot be inherited; the common ancestor of Array, String, ByteArray, BooleanArray, BitArray, ShortArray, Float{E,D,Q}Array is not mutable So I need 9 copies of this method... and others!

Stream Classes Stream InputStream ReadStream "based on sequences" OutputStream WriteStream "based on sequences" ReadWriteStream You can tell what's coming, can't you?

Stream Methods upto: endobject result item result := OrderedCollection new. [self atend or: [(item := self next) = endobject]] whilefalse: [result addlast: item]. ^result has 9 versions. Some are genuinely different. ReadStream can return a slice of its container without an OrderedCollection. Some are not.

The Problem (1) Reduce code duplication (2) keeping reflection honest (3) with no difficulty about what is inherited

A B C X (*) Y (*) Z

Non-Solution: historic Smalltalk The traditional Smalltalk approach is that if a method should appear in class X and class Y you put it in A, their nearest common ancestor. For example, Smalltalk has mutable arrays (X) and immutable strings (Y). Their common ancestor is ArrayedCollection. The #at:put: method goes there. But Interval (lb to: ub by: step) then inherits it and has to block it. Code duplication is avoided (1). Reflection is not reliable (2).

Non-solution: Java interfaces Classic Java interfaces do not solve the code duplication problem but create it. Declaring that a class implements an interface creates an obligation to implement its methods. It does not provide code you can inherit. Java 8 default methods I count as multiple inheritance. They answer the question how to add new features to an interface with existing implementors that lack them. Two parent interfaces with default definitions for the same method = multiple inheritance. Oops.

Non-solutions: macros ArrayedCollection subclass: #Array $include 'array-mutation-methods.ist' ArrayedCollection subclass: #String $include 'array-mutation-methods.ist' Means I only have to write a definition once, and reflection works. But the compiler has to compile multiple copies of such definitions. Object code bloat. We also get obscure source code.

Non-solution: multiple inheritance If P has parents Q and R, and both define m, which m does p inherit? Common Lisp: each class has a class precedence list. Two classes with the same set of ancestors may inherit different things. Dylan: like Common Lisp, but computes class precedence list differently. Eiffel: elaborate language for connection

Multiple Inheritance 2 C++: dislike of its complexity is why Java and C# became popular. Multiple inheritance solves (1) code duplication and (2) honest reflection (if you have it) but (3) it's hard to tell where things will come from. Multiple inheritance is too powerful.

Key insight Smalltalk is nearly right. We do want to define a "common" method once, and the common ancestor A is a good place to do it. The problem is that placing a definition in A makes it available in B C and Z as well as X and Y. But definition and availability don't have to be the same thing!

Latent Methods A latent method is defined in a class together with a condition. It becomes available in a (sub)class when the condition is satisfied in that class. But what kind of condition?

Latent method = template method In Design Patterns, a template method is an algorithm, typically in an abstract class, that calls methods that are overridden in subclasses so that the subclasses can customise its behaviour. atall: indices put: anelement indices do: [:each self at: each put: anelement]

Available when? It makes sense for a latent method to become available in precisely those (sub)classes where it is first true that all the self methods exist. Actually, template methods are always available. They should be latent ones. People make mistakes. So we should say which self methods we intend to be filled in by subclasses

Example Stream latent #(atend next) methods: do: ablock [self atend] whilefalse: [ ablock value: self next].... latent #(nextput:) methods: nextputall: acollection acollection do: [:each self nextput: each].

Implementation In a typed single-inheritance language, latent methods go in the virtual function table just like any other methods. Availability is mainly enforced at compile time. There is no run-time overhead for ordinary dynamic dispatch. Reflection is trickier, but can use the same technique that my Smalltalk uses. Calls through reflection pay a small price.

Implementation 2 SmartEiffel introduced the idea of not using a virtual function table. Instead an object begins with a class number, and dynamic dispatch uses a sort of optimised switch(). My Smalltalk copied this. Baseline, remember? This obviously wasn't going to be fast enough. Except it was.

Dynamic dispatch object.selector(args...) => selector'(object, args) where Word selector'(word self, Word...) { Tag const c = CLASSNO(self); /* tree of if () statements */ return does_not_understand( "selector", self,...); } branches of the tree can share (thanks, goto!)

Duplication? No. If multiple class number ranges correspond to a single definition, they can all be-or-jump-to a single translation. This is needed anyway to handle overriding. Subproblem (1) is solved.

Reflection? object respondsto: #selector ==> responds(classno(object), selector") where selector" is an array of half-open intervals of class numbers where some definition of the selector is available and responds() does a binary search. The test is logarithmic in the number of intervals, which is usually much less than the number of classes.

Reflection? 2 The where-available tables can be shared between selectors. Currently, 874 classes (*2 for metaclasses), 7697 selectors, 1724 unique range lists, longest has 47 ranges, average 2.75, memory to hold range lists = 56612 bytes. 860258 lines of generated C for everything else. The scheme is practical.

Really dynamic languages The dynamic dispatch technique I'm using relies on whole-program compilation to number the classes. Smalltalk is really dynamic. Implementations use inline caches, possibly polymorphic inline caches, which still work. Fallback searches the object's class and ancestors checking each's method dictionary. This is easy to adapt.