Download
structure and abstraction in hot languages n.
Skip this Video
Loading SlideShow in 5 Seconds..
Structure and Abstraction in HOT Languages PowerPoint Presentation
Download Presentation
Structure and Abstraction in HOT Languages

Structure and Abstraction in HOT Languages

124 Vues Download Presentation
Télécharger la présentation

Structure and Abstraction in HOT Languages

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Structure and Abstraction inHOT Languages A Comparison of Polymorphism, Modules, and Objects David MacQueen Bell Labs Marktoberdorf

  2. How OO and FP Support Adaptable Programming Parameterization, Subtyping, Iinheritance David MacQueen Bell Labs Marktoberdorf

  3. Hot Languages • higher-order • binding code and data • typed • static type checking (for error detection) • specifying structure of data and program interfaces • formalism for analyzing language constructs • functional and object-oriented (OO) paradigms Marktoberdorf

  4. Functional Paradigm • value-oriented programming -- computing by constructing • functions as data (closures) • parameterization at value, type, and module level • "algebraic" data types for unions, records for products • pure vs impure functional languages • Haskell pure, lazy • ML impure (imperative), strict Marktoberdorf

  5. OO Paradigm • state-oriented, imperative programming • objects as data (instance state + method code) • subtyping (based on subclassing) • subclasses for unions, objects for products • pure vs impure object oriented languages • Smalltalk and Java pure (everything an object) • Eiffel, Modula3, C++, Object Pascal, etc. impure Marktoberdorf

  6. Theme: Static typing good Static typing, based on a sound type system (“well-typed programs do not go wrong”) is a basic requirement for robust system programming. Marktoberdorf

  7. Why Types? • safety: well typed programs do not go wrong • a language and disciple for design of data structures and program interfaces • support for separate development via precise interfaces • properties and invariants verified by the compiler (“a priori guarantee of correctness”) • support for orderly evolution of software • consequences of changes can be traced Marktoberdorf

  8. Types and FP • In FP, types determine behavior to a much greater extent than in conventional procedural or OO languages. • OO languages use “modeling languages” like UML. For FP, the type system serves as the modeling language. • In FP, the extent of program behavior covered by type checking (in Greg Nelson’s terminology) is greater than for imperative programming. Marktoberdorf

  9. Theme: Program adaptation To support code reuse, we must be able to build general purpose program units and then adapt them to particular uses. How do we build generic units, and how do we specialize them, or derive specialized versions? Marktoberdorf

  10. Overview • Introduction: parameterization, subtyping, inheritance • Review of Type Systems • Functional Programming (ML) • functions, polymorphism, modules • Object-Oriented programming • reconstruction from first principles • Comparison of OO and FP • Synthesis of OO and FP Marktoberdorf

  11. Adaptation Mechanisms • parameterization • values: procedures and functions • types: parametric polymorphism • subtype polymorphism • dynamic dispatch • implementation inheritance: extension and update of functionality • information hiding, abstraction, modularity Marktoberdorf

  12. Procedural abstraction • Most basic form of reuse • Name a block of code, call it repeatedly • Preserves env. of definition (closure) procedure P() = begin x := x+1; y := y*x; end var x: int; ... P(); ... P(); ... Marktoberdorf

  13. data parameters: 1st order functions • abstract over names of values • specialize by application to different arguments Marktoberdorf

  14. data parameters: sorting lists this can sort different lists of ints, but only with respect to fixed, hardwired ordering < fun sort(l: int list) = (if null l ... x < y ...) -- code to sort l sort : int list -> int list sort [2, 17, -3, 5] => [-3, 2, 5, 17] Marktoberdorf

  15. function parameters: higher-order fns • abstract over names of functions • specialize by passing functions fun sort (< : int*int->bool)(l: int list) = (if null l  x < y ) sort : (int*int->bool) -> int list -> int list sort (>) [2, 17, -3, 5] => [-3, 2, 5, 17] Marktoberdorf

  16. Type parameters: polymorphic functions • abstract over names of types • specialize by passing a type argument Marktoberdorf

  17. Polymorphic sort fun sort [t](<: t*t->bool)(l: t list) = (if null l ... x < y ...) sort : t.(t*t->bool) -> t list -> t list sort[int](>int)[2, 17, -3, 5] => [-3, 2, 5, 17] sort[string](<string)[“bob”, “alice”, “tom”] => [“alice”, “bob”, “tom”] Marktoberdorf

  18. Type parameters: polymorphic sort Note that if the element type is a parameter, the comparison function <must also be a parameter. fun sort [t](<: t*t->bool)(l: t list) = (if null l ... x < y ...) sort : t.(t*t->bool) -> t list -> t list Marktoberdorf

  19. Interface parameters • Interface specifies a set of components (types and values), defining the type of a module. • Abstract a module over an interface. signature Order = sig type t val < : t * t -> bool end functor Sort(X: Order) = struct fun sort(l: X.t list) = ... end Marktoberdorf

  20. Subtype polymorphism • The subtype relation • Subsumption Rule A <: B “every A is a B” Nat <: Int, Ascii <: Unicode A <: B x: A x: B Marktoberdorf

  21. Picturing subtyping: A <: B subset B A embedding B 1 - 1 A Marktoberdorf

  22. Sources of subtyping Mathematics: Nat <: Int Machines: UnsignedInt32 <: Int32 ? Mathematics: Int <: Real Machines: Int32 <: Float64 (representation shift) Marktoberdorf

  23. Sources of subtyping: records point = {x: int, y: int} colorpoint = {x: int, y: int, c: color} colorpoint <: point point colorpoint colorpoint’ x x c y y x c y Marktoberdorf

  24. Using Subtyping move : Point -> Point ColorPoint <: Point cp : ColorPoint cp : Point move cp : Point Marktoberdorf

  25. Implementation Inheritance • A principle adaptation mechanism of OO languages • class-based: subclasses • object-based: cloning + extension + method update • Based on “open recursion” replacing members of a family of mutually recursive functions Marktoberdorf

  26. Inheritance A class and a derived subclass class Counter(n: Int) var x: Int = n method get() = x method add(y: Int) = x := x + y class BCounter(max: int) inherits Counter method add(y: Int) = (* override *) if get()+y < max then x := get() + y method inc() = (* extend *) if get() < max-1 then x := get() + 1 Marktoberdorf

  27. f g h Open recursion • conventional closed recursion Marktoberdorf

  28. Open recursion open recursion: replacing members of a recursive family of functions f g f g’ h h Marktoberdorf

  29. Open recursion with function refs fr = ref(dummy); gr = ref(dummy) fun f(x) = ... !gr(-) ... !gr(-) ... fun g(x) = ... !gr(-) ... !fr(-) ... fun g’(x) = ... !gr(-) ... Old family fr := g; gr := g; ... !fr(-) ... New family gr := g’; ... !fr(-) ... Marktoberdorf

  30. II. Type systems • What is a type? • a set of values int = {... -2, -1, 0, 1, 2, ...} • a specification of the form or structure of values • a device for controlling how we can act on values of the type Marktoberdorf

  31. Language of types • Types are expressed by terms in a type abstract syntax: A ::= int | A * B | A -> B | ... E.g. int, int * int, int -> int, int -> (int -> int) • add constructs to increase power and expressiveness Marktoberdorf

  32. Types and Terms • Types are related to an underlying language for expressing and manipulating values e ::= x | fun(x)e | e e’ (implicit) e ::= x | fun(x:A)e | e e’ (explicit) through typing judgements: e : A “e has type A” Marktoberdorf

  33. Typing environments • How do we know the type of a free variable? x: ? • Answer: typing environments C ::=  | C; x: A (finite mapping from variables to types) • Contexts are added to typing judgements to deal with free vars C |- e : A E.g. x: int; y: bool |- x: int Marktoberdorf

  34. Typing Rules • deduction rules for typing judgements C |- e: A -> B C |- e’ : A (->Elim) C |- e e’ : B C; x: A |- e : B (->Intro) C |- fun(x:A)e : A -> B Marktoberdorf

  35. Typing rules: atomic expressions Integer constants (n an integer) C |- n : Int Variables (Var) C; x: A |- x: A Marktoberdorf

  36. Typing derivations • proof of a valid typing judgement • laid out as a tree of rule instances Derivation of :C |- +(x,3): int, where C = + : int * int -> int; x: int C |- x:intC |- 1:int C |- +: int*int -> int C |- (x,3) : int*int C |- +(x,3) : int Marktoberdorf

  37. Well-typing e is well-typedwrt context C if there is a type A such that C |- e : A is a valid judgement. 1+3 - well typed wrt context C 1+true - ill typed (true: bool) there is no type A with valid judgement C |- 1+true : A Marktoberdorf

  38. Type Inference • Type inference (for a term e) is the process of discovering a type A and a derivation of C |- e : A Marktoberdorf

  39. Multiple typings • There may be more than one type A such that C |- e : A • E.g. typing (untyped) identity function x: Int |- x : Int |- fun(x)x : Int -> Int x: Bool |- x : Bool |- fun(x)x : Bool -> Bool x: A |- x : A |- fun(x)x : A -> A Marktoberdorf

  40. References for Type Systems • Cardelli: “Type Systems” tutorial in library, Cardelli’s web page • B. Pierce: “Type Systems” forthcoming comprehensive book with software toolkit Marktoberdorf

  41. Typing and program behavior • Denotational semantics • • : expressions values • • : types  sets of values • Soundness:  |- e: A  e  A • Type errors e = wrong if e contains a type error e.g. 1+true = wrong wrongA for any type A Marktoberdorf

  42. Typing and program behavior • Operational semantics e e’ single step reduction ee’ multiple step reduction • Subject reduction ee’ and  |- e: A   |- e’: A • Corollary: well-typed expressions don’t get stuck. 1 + true is a stuck expression Marktoberdorf

  43. Some basic type constructs • products: A * B • records: {m1:A1,...,mn:An} • sums: A + B • functions: A -> B • recursion: t.A • refs: RefA • subtypes: A <: B Marktoberdorf

  44. C |- e1 : A C |- e2 : B (*Intro) C |- (e1, e2): A * B Products A * B = {(a,b)| a  A, b  B} C |- e: A * B (*Elim left) C |- fst e : A C |- e: A * B (*Elim right) C |- snd e : B Marktoberdorf

  45. Products p = (1,true) : Int * Bool fst p : Int ==> 1 snd p : Bool ==> true  |- 1 : Int  |- true : Bool  |- (1, true): Int * Bool Marktoberdorf

  46. Products Projections as primitive operations for each pair of types A and B: fst(A,B) : A * B -> A snd(A,B) : A * B -> B pairing as a primitive? (.,.)(A,B) : A -> B -> A * B (?) Marktoberdorf

  47. Records record = labeled product = finite map from labels to values r ={age = 13, name = “Bob”} record type = finite map from labels to types r : {age : Int, name : String} field = labeled component of a record r.age : Int ==> 13 (field selection) Marktoberdorf

  48. Typing records Obvious generalization of product rules: C |- ei: Ai (i=1,...,n) C |- {m1=e1,...,mn=en} : {m1:A1,...,mn:An} (RecordIntro) C |- e : {m1:A1,...,mn:An} (RecordElim) C |- e.mi: Ai Marktoberdorf

  49. Sums A + B - tagged union of A and B inl: A -> A + B inr: B -> A + B outl: A + B -> A outr: A + B -> B isl: A + B -> Bool isr: A + B -> Bool Actually, should be: inl(A,B) , etc. Marktoberdorf

  50. Sums i = inl 3 : Int * Bool (inl(Int,Bool)) b = inr true : Int * Bool isl b : Bool ==> false outl a : Int ==> 1 Marktoberdorf