Understanding Object-Oriented Programming through Object Calculi - Prof. Westley Weimer, Study notes of Programming Languages

An introduction to object calculi, a formal system for modeling and understanding object-oriented programming (oop). The authors discuss the need for a calculus for oop, the limitations of using λ-calculus for oop, and the basics of an untyped object calculus. The document also covers the syntax and operational semantics of the calculus, as well as examples and encodings of fields and functions.

Typology: Study notes

Pre 2010

Uploaded on 03/19/2009

koofers-user-63b-1
koofers-user-63b-1 🇺🇸

10 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
#
1
Modeling and Understanding
Modeling and Understanding
Object
Object-
-Oriented Programming
Oriented Programming
#
2
Official Survey
Please fill out the Toolkit course survey
40142 CS 655-1
Apr-21-2006 Midnight May-04-2006 9am
Why not do it this evening?
#
3
Cunning Plan: Focus On Objects
A Calculus For OO
Operational Semantics
Type System
Expressive Power
Encoding OO Features
#
4
The Need for a Calculus
There are many OO languages with many
combinations of features
We would like to study these features
formally in the context of some primitive
language
Small, essential, flexible
We want a “λ-calculus” or “IMP” for objects
#
5
Why Not Use λ-Calculus for OO?
We could define some aspects of OO languages
using λ-calculus
e.g., the operational semantics by means of a translation
to λ-calculus
But then the notion of object be secondary
Functions would still be first-class citizens
Some typing considerations of OO languages are
hard to express in λ-calculus
i.e., object-orientation is not simply “syntactic sugar”
#
6
Object Calculi Summary
As in λ-calculi we have
operational semantics
denotational semantics
type systems
type inference algorithms
guidance for language design
We will actually present a family of calculi
typed and untyped
first-order and higher-order type systems
We start with an untyped calculus
pf3
pf4
pf5

Partial preview of the text

Download Understanding Object-Oriented Programming through Object Calculi - Prof. Westley Weimer and more Study notes Programming Languages in PDF only on Docsity!

1

Modeling and UnderstandingModeling and Understanding

Object Object--Oriented ProgrammingOriented Programming

2

Official Survey

• Please fill out the Toolkit course survey

• 40142 CS 655-

• Apr-21-2006 Midnight → May-04-2006 9am

  • Why not do it this evening?

3

Cunning Plan: Focus On Objects

• A Calculus For OO

• Operational Semantics

• Type System

• Expressive Power

• Encoding OO Features

4

The Need for a Calculus

• There are many OO languages with many

combinations of features

• We would like to study these features

formally in the context of some primitive

language

  • Small, essential, flexible

• We want a “λ-calculus” or “IMP” for objects

5

Why Not Use λ-Calculus for OO?

  • We could define some aspects of OO languages

using λ-calculus

  • e.g., the operational semantics by means of a translation to λ-calculus
  • But then the notion of object be secondary
  • Functions would still be first-class citizens
  • Some typing considerations of OO languages are

hard to express in λ-calculus

  • i.e., object-orientation is not simply “syntactic sugar”

    6

Object Calculi Summary

  • As in λ-calculi we have
    • operational semantics
    • denotational semantics
    • type systems
    • type inference algorithms
    • guidance for language design
  • We will actually present a family of calculi
    • typed and untyped
    • first-order and higher-order type systems
  • We start with an untyped calculus

7

An Untyped Object Calculus

  • An object is a collection of methods
    • Their order does not matter
  • Each method has
    • A bound variable for “self” (denoting the host object)
    • A body that produces a result
  • The only operations on objects are:
    • Method invocations
    • Method update

8

Untyped Object Calculus Syntax

  • Syntax: a, b ::= x - variables | [mi = ς(x) bi ] - object constructor - ς is a variant of Greek letter σ - x is the local name for “self” | a.m - method invocation - no arguments (just the self) | a.m ← ς(x) b - method update - this is an expression! - the result is a copy of the object with one method changed
  • This is called the untyped ς-calculus (Abadi & Cardelli)

9

First Examples

  • An object o with two methods m 1 and m 2
    • m 1 returns an empty object
    • m 2 invokes m 1 through self o = [m 1 = ς(x) [], m 2 = ς(x) x.m 1 ]
  • A bit cell with three methods: value, set and reset
    • value returns the value of the bit (0 initially)
    • set sets the value to 1, reset sets the value to 0
    • models state without λ/IMP (objects are primary) b = [ value = ς(x). 0, set = ς(x). x.value ← ς(y). 1, reset = ς(x). x.value ← ς(y). 0 ] # 10

Operational Semantics

  • a → b means that a reduces in one step to b
  • The rules are: (let o be the object [mi = ς(x). bi ] )

o.mi → [o/x] bi

o.mk ← ς(y). b → [mk = ς(y). b, mi = ς(x). bi]

(i ∈ {1,…, n} - { k})

  • We are dealing with a calculus of objects
  • This is a deterministic semantics (has the Church-

Rosser or “diamond” property)

11

Expressiveness

  • A calculus based only on methods with “self”
    • How expressive is this language? Let’s see.
    • Can we encode languages with fields? Yes.
    • Can we encode classes and subclassing? Hmm.
    • Can we encode λ-calculus? Hmm.
  • Encoding fields
    • Fields are methods that do not use self
    • Field access “o.f” is translated directly
      • to method invocation “o.f”
    • Field update “o.f ← e” is translated to “o.f ← ς(x) e”
    • We will drop the ς(x) from field definitions and updates

12

As Expressive As λ

• Encoding functions

  • A function is an object with two methods
    • arg - the actual value of the argument
    • val - the body of the function
  • A function call updates “arg” and invokes “val”

• A conversion from λ-calculus expressions

x = x.arg (read the actual argument)

e 1 e 2 = (e 1 .arg ← ς(y) e 2 ).val

λx. e = [arg = ς(y) y.arg, val = ς(x). e ]

  • The initial value of the argument is undefined
  • From now on we use λ notation in addition to ς

19

Typing Rules

making an object

updating a method

invoking a method

20

Type System Results

• Theorem (Minimum types)

  • If Γ ⊢ a : A then there exists B such that for any

A’ such that Γ ⊢ a : A’ we have B < A’

  • If an expression has a type A then it has a

minimum (most precise) type B

• Theorem (Subject reduction)

  • If ∅ ⊢ a : A and a → v then ∅ ⊢ v : A
  • Type preservation. Evaluating a well-typed

expression yields a value of the same type.

21

Type Examples

  • Consider that old BitCell object

o = [ value = ς(x). 0,

set = ς(x). x.value ← ς(y). 1,

reset = ς(x). x.value ← ς(y). 0 ]

  • An appropriate type for it would be

BitType = [ value : int, set : BitType, reset : BitType]

  • Note that this is a recursive type
  • Consider part of the derivation that o : BitType (for set)

22

Unsoundness of Covariance

  • Object types are invariant (not co/contravariant)
  • Example of covariance being unsafe:
    • Let U = [] and L = [m : U]
    • By our rules L < U
    • Let P = [x : U, f : U] and Q = [x : L, f : U]
    • Assume we (mistakenly) say that Q < P (hoping for covariance in the type of x)
    • Consider the expression: q : Q = [x = [m = []], f = ς(s:Q) s.x.m ]
    • Then q : P (by subsumption with Q < P)
    • Hence q.x ← [] : P
    • This yields the object [ x = [], f = ς(s:Q) s.x.m ]
    • Hence (q.x ← []).f : U yet (q.x ← []).f fails!

23

Covariance Would Be Nice Though

  • Recall the type of bit cells

BitType = [ value : int, set : BitType, reset : BitType]

  • Consider the type of flipable bit cells

FlipBitType = [ value : int, set : FlipBitType, reset : FlipBitType, flip : FlipBitType]

  • We would expect that FlipBitType < BitType
  • Does not work because object types are invariant
  • We need covariance + subtyping of recursive types
    • Several ways to fix this

24

Variance Annotations

  • Covariance fails if the method can be updated
    • If we never update set, reset or flip we could allow covariance
  • We annotate each method in an object type with a

variance:

  • means read-only. Method invocation but not update
  • means write-only. Method update but not invocation 0 means read-write. Allows both update and invocation
  • We must change the typing rules to check

annotations

  • And we can relax the subtyping rules

25

Subtyping with

Variance Annotations

  • Invariant subtyping (Read-Write)

[… mi^0 : B …] < [… mi^0 : B’ …] if B = B’

  • Covariant subtyping (Read-only)

[… mi+^ : B …] < [… mi+^ : B’ …] if B < B’

  • Contravariant subtyping (Write-only)

[… mi-^ : B …] < [… mi-^ : B’ …] if B’ < B

  • In some languages these annotations are implicit
    • e.g., only fields can be updated

26

Classes, Types and Variance

• Recall the type of bit cells

BitType = [ value^0 : int,

set+^ : BitType, reset+^ : BitType]

• Consider the type of flipable bit cells

FlipBitType = [ value^0 : int, set+^ : FlipBitType,

reset+^ : FlipBitType, flip+^ : FlipBitType]

• Now we have FlipBitType < BitType

  • Recall the subtyping rule for recursive types

27

Classes and Types

  • Let A = [mi : Bi] be an object type
  • Let Class(A) be the type of classes for objects of

type A

Class(A) = [new : A, mi : A → Bi]

  • A class has a generator and the body for the methods
  • Types are distinct from classes
  • A class is a “stamp” for creating objects
  • Many classes can create objects of the same type
  • Some languages take the view that two objects have the same type only if they are created from the same class
  • With this restriction, types are classes
  • In Java both classes and interfaces act as types

28

Higher-Order Object Types

  • We can define bounded polymorphism
  • Exmaple: we want to add a method to BitType that

can copy the bit value of self to another object

lendVal = ς(z) λx:t