CS 320: Concepts of Programming Languages

Similar documents
CS 320: Concepts of Programming Languages

CS 320 Homework One Due 2/5 11:59pm

CS 320: Concepts of Programming Languages

Standard ML. Data types. ML Datatypes.1

These notes are intended exclusively for the personal usage of the students of CS352 at Cal Poly Pomona. Any other usage is prohibited without

CS 320: Concepts of Programming Languages

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

CIS 194: Homework 3. Due Wednesday, February 11, Interpreters. Meet SImPL

Programming Languages and Techniques (CIS120)

Functional Programming. Pure Functional Languages

Chapter 15. Functional Programming Languages

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

CPS 506 Comparative Programming Languages. Programming Language Paradigm

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

CS 320: Concepts of Programming Languages

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Programming with Math and Logic

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

Functional Programming. Pure Functional Languages

CS 314 Principles of Programming Languages

Types and Static Type Checking (Introducing Micro-Haskell)

COMPUTING SCIENCE 3Z: PROGRAMMING LANGUAGES 3

CSE 12 Abstract Syntax Trees

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CSE341: Programming Languages Lecture 17 Implementing Languages Including Closures. Dan Grossman Autumn 2018

Flat (Draft) Pasqualino Titto Assini 27 th of May 2016

CS 360: Programming Languages Lecture 10: Introduction to Haskell

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

Introduction to Functional Programming in Haskell 1 / 56

Exercise 1 (2+2+2 points)

Types and Static Type Checking (Introducing Micro-Haskell)

Programming Languages

CS 112 Introduction to Computing II. Wayne Snyder Computer Science Department Boston University

CS 457/557: Functional Languages

CS 360 Programming Languages Interpreters

Modern Programming Languages. Lecture LISP Programming Language An Introduction

A Small Interpreted Language

Working with recursion. From definition to template. Readings: HtDP, sections 11, 12, 13 (Intermezzo 2).

Working with recursion

7. Introduction to Denotational Semantics. Oscar Nierstrasz

Functional Programming Languages (FPL)

The Substitution Model

Monads. Functional Programming (CS4011) Monads

6.001 Notes: Section 15.1

CS 11 Haskell track: lecture 1

Example Scheme Function: equal

The story so far. Elements of Programming Languages. Pairs in various languages. Pairs

Overloading, Type Classes, and Algebraic Datatypes

To figure this out we need a more precise understanding of how ML works

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Intro. Scheme Basics. scm> 5 5. scm>

Lecture #24: Programming Languages and Programs

CS 4110 Programming Languages & Logics. Lecture 17 Programming in the λ-calculus

Compiler Theory. (Semantic Analysis and Run-Time Environments)

CSCC24 Functional Programming Scheme Part 2

Documentation for LISP in BASIC

CS 342 Lecture 7 Syntax Abstraction By: Hridesh Rajan

Introduction 2 Lisp Part III

On Academic Dishonesty. Declarative Computation Model. Single assignment store. Single assignment store (2) Single assignment store (3)

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Control Structures. Lecture 4 COP 3014 Fall September 18, 2017

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

CS115 - Module 10 - General Trees

A Simple Syntax-Directed Translator

Principles of Programming Languages

Typical workflow. CSE341: Programming Languages. Lecture 17 Implementing Languages Including Closures. Reality more complicated

An introduction introduction to functional functional programming programming using usin Haskell

CSCI-GA Scripting Languages

Logic - CM0845 Introduction to Haskell

Type Systems. Pierce Ch. 3, 8, 11, 15 CSE

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

15 212: Principles of Programming. Some Notes on Continuations

CS 112 Introduction to Computing II. Wayne Snyder Computer Science Department Boston University

Local definitions and lexical scope

Local definitions and lexical scope. Local definitions. Motivating local definitions. s(s a)(s b)(s c), where s = (a + b + c)/2.

Type Inference Systems. Type Judgments. Deriving a Type Judgment. Deriving a Judgment. Hypothetical Type Judgments CS412/CS413

Section 1.3 Adding Integers

Functional Programming


Project 2: Scheme Interpreter

Fundamental Concepts. Chapter 1

Test 6. moodle.yorku.ca CSE 1020

Type Checking. Outline. General properties of type systems. Types in programming languages. Notation for type rules.

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Outline. General properties of type systems. Types in programming languages. Notation for type rules. Common type rules. Logical rules of inference

Lambda Calculus see notes on Lambda Calculus

6.001 Notes: Section 8.1

Functional Programming - 2. Higher Order Functions

Java Review. Fundamentals of Computer Science

The Calculator CS571. Abstract syntax of correct button push sequences. The Button Layout. Notes 16 Denotational Semantics of a Simple Calculator

Syntax Errors; Static Semantics

CSC/MAT-220: Lab 6. Due: 11/26/2018

To figure this out we need a more precise understanding of how ML works

More Lambda Calculus and Intro to Type Systems

Quick announcement. Midterm date is Wednesday Oct 24, 11-12pm.

Transcription:

CS 320: Concepts of Programming Languages Wayne Snyder Computer Science Department Boston University Lecture 02: Bare Bones Haskell Syntax: Data == Abstract Syntax Trees Functions == Rewrite Rules on ASTs Semantics: Evaluation == Rewriting Parameter Passing == Pattern-Matching

Review of Last Time. Ø Programming Language = Syntax + Semantics Ø Semantics is instantiated by another program (interpreter, compiler). Ø Imperative languages (Java, C,.) have statements that modify the state. Ø State = Entire Memory Ø Imperative program produces a sequence of state transitions. Ø Imperative languages are hard to understand because tracing state transitions is hard! Ø Functional programs remove (or control) the notion of state, using instead expressions which are rewritten by applying functions to subexpressions. Ø Referential transparency = rewriting a subexpression ONLY changes that subexpression and there are no side-effects (no changes to state).

Review of Last Time.

Our Strategy for Learning FP through Haskell Ø We are going to build a functional language (Haskell) from the ground up, starting with the simplest possible Turing complete set of features (i.e., can do any computation), and adding features as we need them. Ø These features will be syntactic sugar to make programming more convenient, and not fundamentally new ideas. Ø We will maintain referential transparency, and when we introduce state, it will be as part of the expression. The true state of beauty exists not when there is nothing left to add, but when there is nothing left to take away. Antoine de Saint-Exupery Occam s Razor: Entia non sunt multiplicanda praeter necessitatem. Less is more. Ludwig Mies van der Rohe

Making Data in Bare-Bones Haskell Recall: Programming language = Syntax + Semantics Syntax = Data + Function Definitions What is Data? Well, numbers, strings, lists, binary trees, hash tables,.. Too complicated! Suppose all we have is the ability to say what syntax (words, basic punctuation) is data and what are functions. How to create a piece of data? data Something Something

Making Data in Bare-Bones Haskell What about creating a set of data objects? We need the data objects and we need a name (the data type ): How about Booleans or Bool True Name of data type data objects in data type False In Haskell, name of data objects and data types must be capitalized!

Data in Bare-Bones Haskell More examples.. data CS320Staff = Wayne Mark Cheng data Direction = North East South West Direction North East South West data ChessPieces = Pawn Rook Knight Bishop Queen King data Color = White Black Green Blue Red Note: The actual names mean nothing! Just syntax. data A = B C D E

Data in Bare-Bones Haskell Structured data can be created by combining data declarations. Simplest kind of structured data is a pair two data objects combined together: data BoolPair = Pair Bool Bool Pair: Bool Bool What do the actual structured data objects look like? Pair is called a Value Constructor because it constructs a data type from other data types. We will sometimes just say Constructor. Pair True True Pair False True Pair True False Pair False False

Data in Bare-Bones Haskell data BoolPair = Pair Bool Bool Parentheses can be used to clarify that this is a single, structured piece of data, but are not necessary: Pair True True Pair False True Pair True False Pair False False Using parentheses: (Pair True True) Value Constructor Data types in the structure NOTE: Incorrect syntax: Pair(True, False)

Data in Bare-Bones Haskell We can create structured data from any (previously defined) data type: data Direction = North East South West data Color = White Black Green Blue Red data Arrow = Arrow Color Direction Constructor Data types in the structure Note: It is allowed, and even encouraged, to use the same name for the name of the data type and the constructor. Data objects of type Arrow: (Arrow Blue South) Arrow Green West But NOT: Arrow South Blue Arrow Color Red

Data in Bare-Bones Haskell We can then add alternatives to create various kinds of structures for a single data type: data Direction = North East South West data Color = White Black Green Blue Red data Arrow = Bare_Arrow BlackArrow Direction ColoredArrow Color Direction Data objects of type Arrow: (ColoredArrow Blue South) Black_Arrow West BareArrow

Data in Bare-Bones Haskell Note that constructors take a particular sequence of data types, and (for now) ONLY those data types. You can t give multiple definitions of a constructor! data Direction = North East South West data Color = White Black Green Blue Red data Arrow = BareArrow Arrow Direction Arrow Color Direction NOT ALLOWED! Constructors must be unique!

Data in Bare-Bones Haskell These data types have an obvious tree representation: data Arrow = Bare_Arrow BlackArrow Direction ColoredArrow Color Direction Bare_Arrow (ColoredArrow Blue South) Black_Arrow West Bare_Arrow Colored_Arrow Black_Arrow Blue South West

Data in Bare-Bones Haskell We can also create recursive types, using the data type in its own declaration (see section 8.4 in Hutton): data Nat = Zero Succ Nat The constructor Succ takes a single data object of type Nat. This can be simple data object or structured (another Nat). Data objects of type Nat: Succ Zero (Succ Zero) Succ (Succ (Succ Zero)) Zero (Succ (Succ (Succ (Succ Zero) ) ) )

Data in Bare-Bones Haskell How about Lists? Cons data Nat = Zero Succ Nat data List = Nil Cons Nat List Succ Cons Data objects of type List: Zero Zero Nil Nil Cons Zero Nil (Cons (Succ Zero) (Cons Zero Nil) ) So, a Python list [a 1, a 2, a 3, a 4, a 5 ] would be represented: (Cons a 1 (Cons a 2 (Cons a 3 (Cons a 4 (Cons a 5 Nil) ) ) ) )

Data in Bare-Bones Haskell How about Binary Trees? (Hutton, p.97, adapted a bit!) data Tree = Leaf Bool Node Tree Bool Tree Data objects of type Tree: Leaf True (Node (Leaf True) True (Leaf True) ) Node (Node (Leaf True) False (Leaf False)) True (Leaf False) NOT LEGAL: Node False Leaf True Leaf False

Data in Bare-Bones Haskell Hm this doesn t allow for empty trees, so let s try again. Node True Null data Tree = Null Node Bool Tree Tree Node Data objects of type the new type Tree: False Null Null Null (Node True Null Null) Node True (Node False Null Null) Null NOT LEGAL: Node True Node False Null Null Null

Functions in Bare-Bones Haskell To define a function on the data objects, we give rules for rewriting a data object to another expression (possibly containing additional function calls). not False = True not True = False When we write an expression to the interpreter using a function name, it matches the function call to the rules: > not False True > not True False

Functions in Bare-Bones Haskell not False = True not True = False > not False True > not True False > not (not False) False Which is evaluated recursively: not (not False) => not True => False

Functions in Bare-Bones Haskell Evaluation of an expression by the interpreter proceeds as follows: Scan the expression from the left (or: in post-order); If a match between a sub-expression and the left-hand side of a rule is found, replace the subexpression by the right-hand side: not (not (not False) ) => not (not True) => not False => True

Functions in Bare-Bones Haskell Evaluation of an expression by the interpreter proceeds as follows: Scan the expression from the left (or: in post-order); If a match between a sub-expression and the left-hand side of a rule is found, replace the subexpression by the right-hand side: not (not (not False) ) => not (not True) => not False => True But function definitions without parameters are very limited! So we have to add variables ( = parameters). Variables can be bound or assigned to any data object.

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) not True no match! Rule fails to match, try the next one!

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) not False no match! Rule fails to match, try the next one!

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) cond True x y matches!

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rules are tried in order. If a match is found, rewrite the expression, observing what bindings were made for variables. cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) cond True x y matches! no match! Rule fails to match, try the next one!

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) cond False x y matches!

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) cond False x y matches! matches!

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) cond False x y matches! matches! matches with x = Zero

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) cond False x y matches! matches! matches with x = Zero matches with y = (Succ Zero)

Functions as Rewrite Rules data Nat = Zero Succ Nat not True = False not False = True To rewrite an expression, look for a rule which matches it variables can match anything. Rewrite, observing what bindings were made for variables. Rules are tried in order! cond True x y = x -- this is just cond False x y = y -- an if-then-else (cond False Zero (Succ Zero) ) x = Zero y = (Succ Zero) cond False x y => (Succ Zero) ( = y, where y = (Succ Zero)) rewrites to

Functions as Rewrite Rules data Nat = Zero Succ Nat cond True x y = x cond False x y = y A more precise version of this matching-and-rewriting model of computation is that we are rewriting trees, where function names and constructors label the nodes... We traverse the trees preorder to determine matches... (cond False Zero (Succ Zero) ) cond False x y => (Succ Zero) ( = y, where y = (Succ Zero)) cond cond False Zero Succ False x y Zero

Functions as Rewrite Rules data Nat = Zero Succ Nat cond True x y = x cond False x y = y A more precise version of this matching-and-rewriting model of computation is that we are rewriting trees, where function names and constructors label the nodes... We traverse the trees preorder to determine matches... (cond False Zero (Succ Zero) ) cond False x y => (Succ Zero) ( = y, where y = (Succ Zero)) cond cond False Zero Succ False x y Zero

Functions as Rewrite Rules data Nat = Zero Succ Nat cond True x y = x cond False x y = y A more precise version of this matching-and-rewriting model of computation is that we are rewriting trees, where function names and constructors label the nodes... We traverse the trees preorder to determine matches... (cond False Zero (Succ Zero) ) cond False x y => (Succ Zero) ( = y, where y = (Succ Zero)) cond cond False Zero Succ False x y Zero matches with x = Zero

Functions as Rewrite Rules data Nat = Zero Succ Nat cond True x y = x cond False x y = y A more precise version of this matching-and-rewriting model of computation is that we are rewriting trees, where function names and constructors label the nodes... We traverse the trees preorder to determine matches... (cond False Zero (Succ Zero) ) cond False x y => (Succ Zero) ( = y, where y = (Succ Zero)) cond cond matches with y = (Succ Zero) False Zero Succ False x y Zero matches with x = Zero