Why Functional Programming Matters --- In an Object-Oriented World! Matthias Felleisen Rice University.

Slides:



Advertisements
Similar presentations
Higher-Order Functions and Loops c. Kathi Fisler,
Advertisements

When is Orientated Programming NOT? Mike Fitzpatrick.
The C ++ Language BY Shery khan. The C++ Language Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program.
Programming Paradigms and languages
1 Programming Languages (CS 550) Lecture Summary Functional Programming and Operational Semantics for Scheme Jeremy R. Johnson.
CSE341: Programming Languages Lecture 16 Datatype-Style Programming With Lists or Structs Dan Grossman Winter 2013.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Functional Programming. Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends.
CSE 425: Semantics II Implementing Scopes A symbol table is in essence a dictionary –I.e., every name appears in it, with the info known about it –Usually.
Classes & Objects Computer Science I Last updated 9/30/10.
Safety as a Software Metric Matthias Felleisen and Robert Corky Cartwright Rice University.
Programming Language Paradigms: summary. Object-oriented programming Objects are the fundamental building blocks of a program. Interaction is structured.
Module: Definition ● A logical collection of related program entities ● Not necessarily a physical concept, e.g., file, function, class, package ● Often.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
Programming Language Semantics Mooly SagivEran Yahav Schrirber 317Open space html://
About the Presentations The presentations cover the objectives found in the opening of each chapter. All chapter objectives are listed in the beginning.
Guide To UNIX Using Linux Third Edition
C++ for Engineers and Scientists Third Edition
Building “Real World” Software in Academia Matthias Felleisen PLT, Rice University.
C++ fundamentals.
Abstraction: Polymorphism, pt. 1 Abstracting Objects.
1 CS101 Introduction to Computing Lecture 19 Programming Languages.
1 Programming James King 12 August Aims Give overview of concepts addressed in Web based programming module Teach you enough Java to write simple.
Chapter 9: Coupling & Cohesion Omar Meqdadi SE 273 Lecture 9 Department of Computer Science and Software Engineering University of Wisconsin-Platteville.
Sadegh Aliakbary Sharif University of Technology Fall 2011.
6 Dec 2001Kestrel1 Teaching with Patterns Matthias Felleisen Daniel Jackson.
Recap (önemli noktaları yinelemek) from last week Paradigm Kay’s Description Intro to Objects Messages / Interconnections Information Hiding Classes Inheritance.
4 Dec 2001Kestrel1 From Patterns to Programming Languages Matthias Felleisen Northeastern University.
Copyright 2003 Scott/Jones Publishing Standard Version of Starting Out with C++, 4th Edition Chapter 13 Introduction to Classes.
Objects & Dynamic Dispatch CSE 413 Autumn Plan We’ve learned a great deal about functional and object-oriented programming Now,  Look at semantics.
C++ Programming Basic Learning Prepared By The Smartpath Information systems
1 Tutorial 14 Validating Documents with Schemas Exploring the XML Schema Vocabulary.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
XP Tutorial 8 Adding Interactivity with ActionScript.
Computers, Variables and Types Engineering 1D04, Teaching Session 2.
Starting Out with C++ Early Objects ~~ 7 th Edition by Tony Gaddis, Judy Walters, Godfrey Muganda Modified for CMPS 1044 Midwestern State University 6-1.
Salman Marvasti Sharif University of Technology Winter 2015.
1 Programming 2 Aims Give overview of concepts addressed in Web based programming module Teach you enough Java to write simple web and network applications.
Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns.
1 Lecture 14: Assignment and the Environment Model (EM)
Principles of programming languages 10: Object oriented languages Isao Sasano Department of Information Science and Engineering.
General Computer Science for Engineers CISC 106 Lecture 12 James Atlas Computer and Information Sciences 08/03/2009.
TeachJava! 2003 Corky Cartwright Dung Nguyen Stephen Wong Charlie Reis, James Hsia, Peter Centgraf.
Chapter 1 Java Programming Review. Introduction Java is platform-independent, meaning that you can write a program once and run it anywhere. Java programs.
Object Oriented Programming. OOP  The fundamental idea behind object-oriented programming is:  The real world consists of objects. Computer programs.
OOP Basics Classes & Methods (c) IDMS/SQL News
CSE 341 Section 10 Subtyping, Review, and The Future.
Chapter 9: Coupling & Cohesion Omar Meqdadi SE 273 Lecture 9 Department of Computer Science and Software Engineering University of Wisconsin-Platteville.
Sadegh Aliakbary Sharif University of Technology Fall 2010.
Operational Semantics of Scheme
Functional Programming
Edited by Original material by Eric Grimson
Java Primer 1: Types, Classes and Operators
Representation, Syntax, Paradigms, Types
September 4, 1997 Programming Languages (CS 550) Lecture 6 Summary Operational Semantics of Scheme using Substitution Jeremy R. Johnson TexPoint fonts.
About the Presentations
Programming Language Concepts (CIS 635)
Names, Binding, and Scope
The Metacircular Evaluator
Representation, Syntax, Paradigms, Types
Representation, Syntax, Paradigms, Types
What would be our focus ? Geometry deals with Declarative or “What is” knowledge. Computer Science deals with Imperative or “How to” knowledge 2/23/2019.
6.001 SICP Variations on a Scheme
COP 3330 Object-oriented Programming in C++
Introduction to Data Structure
Chapter 3: Selection Structures: Making Decisions
How to organize and document your classes
Representation, Syntax, Paradigms, Types
6.001 SICP Interpretation Parts of an interpreter
Classes, Objects and Methods
Presentation transcript:

Why Functional Programming Matters --- In an Object-Oriented World! Matthias Felleisen Rice University

What to Compare: Models of Computation Models of Programming –Design –Abstraction (Single Point of Control) –Extensibility The Winner Lessons Learned

The Focus of OO and Functional Computation: Data TAG OO Computation: manipulate data by sending a message to an object and waiting for an answer FP Computation: apply a primitive operation to a piece of data How can these two views possibly be related?

Two Simple Languages: FUN and OOPS FUN is (like ML/Scheme) basic data: numbers... datatype function definitions expressions, including –variables –primitives: +, -,... –conditionals –function application –blocks –assignment OOPS is (like Java/Eiffel) basic data: numbers... class definitions, interfaces method definitions expressions, including –variables –primitives: +, -, … –conditionals –method application –blocks –assignment

Two Sample Programs (in lieu of Grammars): datatype List = empty | cons(first:int,rest:List) add1*(l:List) = case l of empty : void; cons : l.first := l.first + 1; add1*(l.rest) end interface List { add1* : -> void } class Empty implements List { void add1*() {} } class Cons(first:int, rest:List) implements List { void add1* () { first := first+1; rest.add1*(); } }

The Computational Models Given: a program Wanted: a sequence of “states” that shows its behavior A program is a sequence of definitions (datatype/functions or interface/classes) an expression ( “main” ) A state is a program.

Expression (Block) Definitions are Static, Expressions Capture the State: Definitions : let x = new cons(1,empty) in x.first := 2 end let x = new cons(2,empty) in void end the above definitions for list, cons, empty Assumption: Definitions are well-formed according to the rules of FUN and OOPS (scope, types, …)

Creating Data: let x = … y = … … in … new CC(x,BV) … end let x = … y = … z = new CC(x,BV) … in … z … end FUN Definitions: datatype T = … CC(a:Ta, b:Tb) |... OOPS Definitions: class CC(a:Ta, b:Tb) implements T { … }

Extracting Pieces: let x = … y = … z = new CC(x,BV) … in … x… end FUN Definitions: datatype T = … CC(a:Ta, b:Tb) |... OOPS Definitions: class CC(a:Ta, b:Tb) implements T { … } let x = … y = … z = new CC(x,BV) … in … z.a … end

Mutating Data: let x = … y = … z = new CC(y,BV) … in … void … end FUN Definitions: datatype T = … CC(a:Ta, b:Tb) |... OOPS Definitions: class CC(a:Ta, b:Tb) implements T { … } let x = … y = … z = new CC(x,BV) … in … z.a := y; … end

Calling Methods in OOPS: let x = … y = … z = new CC(x,BV) … in … exp [s=x,u=BV2,this=z]… end OOPS Definitions: class CC(a:Ta, b:Tb) implements T { … T m(S s, U u) { exp } … } let x = … y = … z = new CC(x,BV) … in … z. m(x,BV2)… end Example: class CC(a:CC, b:int) implements T { … T m(CC s, U u) { s.a := u; } … }

Calling Functions in FUN: let x = … y = … z = new CC(x,BV) … in … exp [t=z,s=x,u=BV2]… end FUN Definitions: m(T t, S s, U u) = exp let x = … y = … z = new CC(x,BV) … in … m(z,x,BV2)… end Example: m(CC t, CC s, int u) = s.a := u

How about First-Class Functions? let x = … y = … z = (lambda (x) exp) … in … z … end let x = … y = … … in … (lambda (x) exp)… end create let x = … y = … z = (lambda (x) exp) … in … (z U) … end let x = … y = … z = (lambda (x) exp) … in … exp[z = U] … end apply

How about Inheritance? class A(X x, Y y) { method1 method2 method3 } class B(Z z) extends A { method4 } class A(X x, Y y) { method1 method2 method3 } class B(X x, Y y, Z z) { method1 method2 method3 method4 } type elaboration

How about Inheritance with Overriding? class A(X x, Y y) { method1 method2 method3 } class B(Z z) extends A { method1 method4 } class A(X x, Y y) { method1 method2 method3 } class B(X x, Y y, Z z) { method1 method2 method3 method4 } type elaboration

Type Elaboration: The Global Picture Object, Any Class Derivation Path(s)

Models of Computation: Conclusion After type elaboration, the two pictures are nearly indistinguishable In both models, creation, access, and mutation of data proceeds in a coherent (“safe”) manner Tagged compound data are the essence of computation -- the rest is terminology

The Focus of OO and Functional Computation: Data method1method2method3 function1function2 In OOPS, methods are attached to data by a physical link. In FUN, functions are attached to data by a safety policy. The effect: a completely safe treatment of data in both models

Models of Programming What is a program How do people design programs in FUN, OOPS –Data-driven designs –Patterns –How things relate How do people edit (“abstract”) and comprehend?

What is a Program? a batch-processing accounting software an elevator controller (context: physical device) a GUI with buttons and text fields and... (context: monitor) a space probe (context: devices, broadcast, …) … Program

Designing Programs in a Data-Driven Fashion the shape of the program is determined by the description of the class of input data flat: inexact numbers, chars, truth values, … compound: 2D 3D points, personnel records, … mixed: an animal is either a spider, an elephant, … arbitrarily large: a stack is either empty or a value pushed onto a stack

Flat Data Collections: Numbers In FUN, define a function. In OOPS, define a static method. These things require domain knowledge and CS/SE isn’t going to help much.

Compound Data An elephant has a name, an age, and a certain demand for space. In FUN: datatype Elephant = e of (name:String, age:Number, space: Number) In OOPS: class Elephant ( name: String, age: Number, space: Number) {}

Compound Data and Programming In FUN: datatype Elephant = e of (name:String, age:Number, space: Number) fits_into(ele: Elephant, cage_space: Number) = ele.space < cage_space In OOPS: class Elephant ( name: String, age: Number, space: Number) { fits_into(cage_space: Number) { space < cage_space } In both cases, remember the available pieces!

Mixed Data (Union) An animal is either (1) an elephant (2) a spider or (3) a monkey In FUN: datatype Animal = e of (name: String, age: Number, space: Number) | s of (name: String, legs: Number) | m of (name: String) In OOPS: interface Animal {} class Elephant ( name: String, age: Number, space: Number) implements Animal {} class Spider (name: String; legs: Number) implements Animal {} class Monkey(name:String) implements Animal {}

Mixed Data and Programming In FUN: datatype Animal = e of (name: String, age: Number, space: Number) | s of (name: String, legs: Number) | m of (name: String) fits_into : Elephant Number -> Bool fits_into(a: Animal, cage_sp: Number) = case a of e : a.space < cage_sp s : true m : false In OOPS: interface Animal { fits_into : Number -> Bool } class Elephant ( name: String, age: Number, space: Number) implements Animal { fits_into(cage_sp: Number) { space < cage_sp } } class Spider (name: String; legs: Number) implements Animal { fits_into(cage_sp: Number) { true } } class Monkey(name:String) implements Animal { … fits_into … }

Arbitrarily Large Data A sequential file is either (1) end of file (2) a character followed by a sequential file. A family tree is either (1) empty (2) a node consisting of a name, a family tree for the mother, and a family tree for the father. A directory has a name, a size, and a directory listing. A directory listing is either (1) empty (2) a directory followed by directory listing (3) a file followed by a directory listing

Arbitrarily Large Data and Data Definitions In FUN: datatype FT = empty | node (name: String, father: FT, mother: FT) In OOPS: interface FT {} class Empty implements FT {} class Node( name : String; father : FT; mother: FT) implements FT {}

Arbitrarily Large Data and Programming In FUN: datatype FT = empty | node (name: String, father: FT, mother: FT) depth : FT -> number depth(a_ft: FT) = case a_ft of empty: 0 node: depth(a_ft.father) + depth(a_ft.mother) In OOPS: interface FT { depth: -> Number} class Empty implements FT { depth( ) { 0 } } class Node( name : String; father : FT; mother: FT) implements FT { depth() { father.depth() + mother.depth() } }

Arbitrarily Large Data: the Interpreter Pattern In FUN: layout data type definition one clause per variant deconstruct each variant use natural recursions dispatch via case In OOPS: layout data type definition one clause per variant deconstruct (implicit) use natural recursions

More Program Design: More Similarities mutually recursive data definitions parallel processing of arbitrarily large pieces of data (multi-methods, parallel recursion) mutable data –keeping track of “history” –exchanging “history” concurrency/parallelism launching programs –via batch –via graphical interaction (modal or reactive) –via devices

Launching Programs: Via Interaction drop-down menu button

Launching Programs: Via Interaction In FUN: type Callback = Event GUI -> void button1 : Callback button1(e: Event, go : GUI) = …. menu1 : Callback menu1(e : Event, go : GUI) = … *** Menu(… menu1 …) *** *** Button(… button1 …) *** In OOPS: interface Callback { execute : Event GUI -> void } class Button1 ( ) implements Callback { execute(e: Event, go : GUI) { …. } } class Menu1 ( ) implements Callback { execute(e : Event, go : GUI) { … } } *** Menu(… Menu1( ) …) *** *** Button(… Button1( ) …) ***

Launching Programs: the Command Pattern separate “view” from “model” store callback functions –in FUN: use closures –in OOPS: use instances of commands (new ~ lambda, execute ~ apply) process data from GUI elements using methods based on structural design, “history” design,... modal or reactive processing …

Abstraction (That’s not an UGLY word!) Abstracting is “editing” Abstracting means factoring out common pieces Abstracting helps maintaining code: –need to comprehend code/invariant once –fix errors once –improve code once (algorithmic, style) –add functionality once Abstracting affects the “bottom line” Software engineers: “single point of control”

Abstraction in FUN: Abstracting SUM : list-of-numbers -> number SUM(a_list) = case a_list of empty : 0 cons: a_list.first + SUM(a_list.rest) PI : list-of-numbers -> number PI(a_list) = case a_list of empty : 1 cons: a_list.first * PI(a_list.rest) F(a_list) = case a_list of empty : cons: a_list.first + F(a_list.rest)

Abstraction in FUN: Specializing MAKE : num (num num -> num) -> (list-of-numbers ->num) MAKE(base, combine) = let F(a_list) = case a_list of empty : base cons: combine( a_list.first, F(a_list.rest)) in F SUM : list-of-numbers -> number SUM = MAKE(0,+) PI : list-of-numbers -> number PI = MAKE(1,*)

Abstraction in OOPS: Abstracting class Cart (x: double, y: double) { double distance_to_O() { … something with square root and squares of x and y … } bool closer_to(pt : Point) { this.distance_to_O() <= pt.distance_to_O() } } class Manhattan(x: double, y: double) { double distance_to_O() { … something with x and y … } bool closer_to(pt : Point) { this.distance_to_O() <= pt.distance_to_O() } } abstract class Cart (x: double, y: double) { bool closer_to(pt : Point) { this.distance_to_O() <= pt.distance_to_O() } }

Abstraction in OOPS: Specializing abstract class PointA(x: double, y: double) { abstract double distance_to_O() bool closer_to(pt : Point) { this.distance_to_O() <= pt.distance_to_O() } } class Cart (x: double, y: double) extends PointA { double distance_to_O() { … something with square root and squares of x and y … } } class Manhattan(x: double, y: double) extends PointA { double distance_to_O() { … something with x and y … } }

Abstraction: Inheritance and the Template Pattern identify similar pieces of code, differences create abstraction –in FUN: use higher-order function, application –in OOPS: use inheritance, the Template pattern if most class extension use same hook, make it the default and use overriding

Comprehending Code: Many Variants An A-expression (A) is either - a variable - a numeric constant - an addition: A + A - a subtraction: A - A - a multiplication: A * A - a division: A / A - an exponentiation: A ** A -... A x5+-*/**…...

Comprehending Code: the Visitor Pattern A x5+-*/**…... for- for+ for_num for_var

Comprehending Code: the Visitor Pattern vs Case class A_Visitor(…) { void for_variables(x: variable) … void for_numbers(c: number) … void for_plus(l: A, r: A) … void for_minus(l: A, r: A) … void for_times(l: A, r: A) … void for_division(l: A, r: A) … void for_exp(l: A, r: A) … } fun_for_A (x : A …) { case x of variable … number … plus … minus … times … division … exp … }

Comprehension: Understanding “Functionality” collect those pieces of code that perform a function create body of code –in FUN: functions and case do it naturally –in OOPS: use call-forwarding and the Visitor pattern

Black Box Extensibility: Adding Variants An A-expression (A) is either - a variable - a numeric constant - an addition: A + A - a subtraction: A - A - a multiplication: A * A - a division: A / A - an exponentiation: A ** A A x5+-*/** And here are more A-expressions: -- a sin-expression: sin(A) sin

Black Box Extensibility: Adding or Modifying Functionality An A-expression (A) is either - a variable - a numeric constant - an addition: A + A - a subtraction: A - A - a multiplication: A * A - a division: A / A - an exponentiation: A ** A A We may want more methods than the original product provides or we may wish slightly different functionality. x5+-*/** sinx5+-*/** sin

Black Box Extensibility: More Cases what if we want visitors? Krishnamurthi, Felleisen & Friedman ECOOP 98 what if we have modules? Flatt & Findler ICFP 98 is it useful? Kathi Bohrer (IBM) San Francisco Project SYSTEMS Journal 97

Extensibility in the Functional World adding functions to a “black box” -- easy adding new variants to a “black box” -- difficult fake OO programming with protocols: Krishnamurthi and Felleisen FSE98 Hudak and Liang POPL 95 Felleisen and Cartwright TACS 94 Steele POPL94

The Winner: What’s better and Why?

The Winner: A Comparison a data-centered, safe model of computation a data-centered model of program design a rich “theory of programs” a data-centered, safe model of computation a data-centered model of program design a rich “practice of patterns” but the amazing surprise: the “theory” and the “practice” lead to nearly indistinguishable programs: - data layout induces program layout - iteration patterns or iterator functions - few (true) assignments to reflect “real world” changes (history or state) - objects as “multi-bodied, multi-entry” closures FUN:OOPS:

The Winner: Default Functionality functions with many parameters Fortran: entry points Common LISP: by-keyword Scheme: rest arguments Chez: case-lambda … but there is also Currying classes with many default methods and instance variables derived classes that override just those few that need to be modified FUN:OOPS: Your web server has 27 different parameters that can be tuned … How do you tune them?

The Winner: Extensible Products complex programming protocols problem with standard types … soft-typing works just fine default strategies extensibility patterns (hooks) derived classes that override just those strategies that need to be modified FUN:OOPS: Your product should accommodate 435 business strategies in 47 countries …. How do you accommodate them all?

The Winner: There isn’t One OOPS and FUN are equivalent for many situations FUN has a much richer theory OOPS provides the practical examples

More Comparisons: FUN –has “lambda”, which means it is simpler to abstract –functions are easier to comprehend –has “currying”, which makes up for the short- comings on extensibility Scheme has macros OOPS –can accommodate many defaults easily –is good for producing extensible systems –lacks “functions” and demands visitors

So What? How does this Help? programming: design, reasoning about programs language research: theory and implementation education: what to teach and how to teach it

Programming and Program Engineering pattern mining: functional programmers have contemplated the meta-level for much longer than oo programmers logic mining: programming in a functional style facilitates reasoning about programs; it is easy and natural to program “functionally” in an oo language

Language Research type theory: parametric polymorphism, modules program analysis: abstract interpretation implementation: closures are simple objects, functional programming environments are semantically more sophisticated than OO environments (repl, module managers)

Education: FUN first, OOPS later! functional programming is syntactically simpler than object-oriented programming functional programming is more natural than object- oriented programming: append(list1,list2) versus list1.append(list2) functional programming is traditionally more interactive than object-oriented programming (repl)

Summary functional programming and object-oriented programming are closely related their differences should lead to important synergies Let us take a closer look!

Thank You Corky Cartwright Dan Friedman Matthew Flatt Shriram Krishnamurthi Robby Findler Kim Bruce Bob Harper Ralph Johnson Scott Smith Phil Wadler