Programs as data first-order functional language type checking

Similar documents
Programs as data Parsing cont d; first-order functional language, type checking

CS:3820 Programming Language Concepts

Programs as Data 6 Imperative languages, environment and store, micro-c

CSCE 314 Programming Languages. Type System

The Substitution Model. Nate Foster Spring 2018

CS558 Programming Languages

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

Begin at the beginning

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Recap: Functions as first-class values

22c:111 Programming Language Concepts. Fall Syntax III

Project 2: Scheme Interpreter

Interpreters. Prof. Clarkson Fall Today s music: Step by Step by New Kids on the Block

Introduction to Programming Using Java (98-388)

Lecture 12: Conditional Expressions and Local Binding

Syntax Errors; Static Semantics

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

22c:111 Programming Language Concepts. Fall Functions

The Substitution Model

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

CS558 Programming Languages

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

Static Semantics. Lecture 15. (Notes by P. N. Hilfinger and R. Bodik) 2/29/08 Prof. Hilfinger, CS164 Lecture 15 1

CS558 Programming Languages

The role of semantic analysis in a compiler

Semantic Analysis. Lecture 9. February 7, 2018

Lexical Considerations

Lecture 15 CIS 341: COMPILERS

Types, Type Inference and Unification

A LISP Interpreter in ML

1 Lexical Considerations

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

Parsing Scheme (+ (* 2 3) 1) * 1

Types and Type Inference

CS558 Programming Languages

CMSC 330: Organization of Programming Languages

CSE450. Translation of Programming Languages. Lecture 11: Semantic Analysis: Types & Type Checking

22c:111 Programming Language Concepts. Fall Types I

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

Tail Recursion: Factorial. Begin at the beginning. How does it execute? Tail recursion. Tail recursive factorial. Tail recursive factorial

Side note: Tail Recursion. Begin at the beginning. Side note: Tail Recursion. Base Types. Base Type: int. Base Type: int

Typed Recursion {with {mk-rec : (((num -> num) -> (num -> num)) -> (num -> num)) {fun {body : ((num -> num) -> (num -> num))} {{fun {fx :

Variables and Bindings

The Environment Model. Nate Foster Spring 2018

CS 360 Programming Languages Interpreters

The Environment Model

Static Semantics. Winter /3/ Hal Perkins & UW CSE I-1

Types and Type Inference

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

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Lexical Considerations

Functional Programming. Pure Functional Programming

Principles of Programming Languages

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Agenda. CS301 Session 9. Abstract syntax: top level. Abstract syntax: expressions. The uscheme interpreter. Approaches to solving the homework problem

CMSC 330: Organization of Programming Languages. Operational Semantics

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler so far

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

CMSC 330: Organization of Programming Languages

FOFL and FOBS: First-Order Functions

Implementing a VSOP Compiler. March 20, 2018

Principles of Programming Languages 2017W, Functional Programming

Midterm 2 Solutions Many acceptable answers; one was the following: (defparameter g1

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

COMP520 - GoLite Type Checking Specification

Type Checking and Type Inference

Comp 311: Sample Midterm Examination

Mid-Term 2 Grades

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

Supplementary Notes on Exceptions

CS558 Programming Languages

COMP520 - GoLite Type Checking Specification

Chapter 1. Fundamentals of Higher Order Programming

UNIVERSITY OF CALIFORNIA Department of Electrical Engineering and Computer Sciences Computer Science Division

Chapter 2 Interpreters and Compilers

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Metaprogramming assignment 3

cs242 Kathleen Fisher Reading: Concepts in Programming Languages, Chapter 6 Thanks to John Mitchell for some of these slides.

Implemen'ng a Func'onal Language. A Basic Func2onal Language. Goal: illustrate and understand the features of the run-2me support

CS 415 Midterm Exam Spring 2002

Computer Science Department Carlos III University of Madrid Leganés (Spain) David Griol Barres

Lecture 16: Static Semantics Overview 1

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

Dynamically-typed Languages. David Miller

Programs as Data 8 A stack machine for micro-c; compiling micro-c to stack machine code

The Compiler So Far. Lexical analysis Detects inputs with illegal tokens. Overview of Semantic Analysis

Outline. Introduction Concepts and terminology The case for static typing. Implementing a static type system Basic typing relations Adding context

Writing Evaluators MIF08. Laure Gonnord

Programming Languages

Compilers. Compiler Construction Tutorial The Front-end

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values

CS 242. Fundamentals. Reading: See last slide

Flang typechecker Due: February 27, 2015

Prof. Mohamed Hamada Software Engineering Lab. The University of Aizu Japan

Transcription:

Programs as data first-order functional language type checking Copyright 2013-18, Peter Sestoft and Cesare Tinelli. Created by Cesare Tinelli at the University of Iowa from notes originally developed by Peter Sestoft at the University of Copenhagen. These notes are copyrighted materials and may not be used in other course settings outside of the University of Iowa in their current form or modified form without the express written permission of one of the copyright holders. During this course, students are prohibited from selling notes to or being paid for taking notes by any person or commercial firm without the express written permission of one of the copyright holders. 1

Micro-ML: A small functional language First-order: A value cannot be a function Dynamically typed, so this is OK: if true then 1+2 else 1+false Eager, or call-by-value: In a call f(e) the argument e is evaluated before f is called Example Micro-ML programs (an F# subset): 5+7 let f x = x + 7 in f 2 end let fac x = if x=0 then 1 else x * fac(x - 1) in fac 10 end 2

Abstract syntax of Micro-ML type expr = CstI of int CstB of bool Var of string Let of string * expr * expr Prim of string * expr * expr If of expr * expr * expr Letfun of string * string * expr * expr Call of expr * expr let f x = x + 7 in f 2 end (f, x, fbody, letbody) Letfun ("f", "x", Prim ("+", Var "x", CstI 7), Call (Var "f", CstI 2))

Runtime values, function closures Run-time values: integers and functions type value = Int of int Closure of string * string * expr * value env Closure: a package of a function s body and its declaration environment A name should refer to a statically enclosing binding: Should always have value 11 let y = 11 in let f x = x + y in let y = 22 in f 3 end end end (f, x, x+y, [(y,11)]) Evaluate as 3 + y

Interpretation of Micro-ML Constants, variables, primitives, let, if: as for expressions Letfun: Create function closure and bind f to it Function call f(e): Look up f, it must be a closure Evaluate e Create environment and evaluate the function s body let rec eval (e : expr) (env : value env) : int = match e with Letfun (f, x, e1, e2) -> let env2 = (f, Closure(f, x, e1, env)) :: env in eval e2 env2... Call (Var f, e) -> Evaluate fbody in let c = lookup env f in match c with declaration environment Closure (f, x, b, fenv) -> let v = Int (eval e env) in let envf = (x, v) :: (f, c) :: fenv in eval b envf _ -> failwith "eval Call: not a function"

Evaluation by logical rules In environment ρ, expression x evaluates to v 6

Evaluation by logical rules: Function declaration and call Compare these with the eval interpreter: Also, note recursive evaluation of f's body 7

Dynamic scope (instead of static) With static scope, a variable refers to the lexically, or statically, most recent binding With dynamic scope, a variable refers to the dynamically most recent binding: let y = 11 in let f x = x + y in let y = 22 in f 3 end end end Evaluate as 3 + y 8

A dynamic scope variant of Micro-ML Very minimal change in interpreter: let rec eval (e : expr) (env : value env) : int =... Call(Var f, earg) -> let fclosure = lookup env f in match fclosure with Closure (f, x, fbody, fdeclenv) -> let xval = Int(eval earg env) Evaluate fbody in call environment let fbodyenv = (x, xval) :: (f, fclosure) :: env in eval fbody fbodyenv fdeclenv is ignored; function is just (f, x, fbody) Good and bad: simple to implement (no closures needed) makes type checking difficult makes efficient implementation difficult Used in macro languages, and Lisp, Perl, Clojure 9

Lexer: Lexer and parser for Micro-ML Nested comments, as in F#, Standard ML 1 + (* 33 (* was 44 *) *) 22 Parser: To parse applications e1 e2 e3 correctly, distinguish atomic expressions from others Problem: f(x-1) parses as f(x(-1)) Solution: FunLex.fsl: make CSTINT just [0-9]+ without sign FunPar.fsy: add rule Expr := MINUS Expr 10

An explicitly typed fun. language let f (x : int) : int = x+1 in f 12 end type typ = TypI TypB TypF of typ * typ Letfun("f", "x", TypI, Prim("+", Var "x", CstI 1), TypI, Call(Var "f", CstI 12));; TypF (TypI, TypI) type tyexpr = CstI of int (f, x, xt, b, bt, letb) CstB of bool Var of string Let of string * tyexpr * tyexpr Prim of string * tyexpr * tyexpr If of tyexpr * tyexpr * tyexpr Letfun of string * string * typ * tyexpr * typ * tyexpr Call of tyexpr * tyexpr 11

Type checking by recursive function Using a type environment [( x, TypI)]: let rec typ (e : tyexpr) (env : typ env) : typ = match e with CstI i -> TypI CstB b -> TypB Var x -> lookup env x Prim(op, e1, e2) -> let t1 = typ e1 env let t2 = typ e2 env in match (op, t1, t2) with ("*", TypI, TypI) -> TypI ("+", TypI, TypI) -> TypI ("-", TypI, TypI) -> TypI ("=", TypI, TypI) -> TypB ("<", TypI, TypI) -> TypB ("&&", TypB, TypB) -> TypB _ -> failwith "unknown primitive, or type error"...

Type checking, part 2 Checking let x=erhs in letbody end Checking if e1 then e2 else e3 let rec typ (e : tyexpr) (env : typ env) : typ = match e with Let(x, xe, b) -> let xt = typ xe env in typ b ((x, xt) :: env) If(e1, e2, e3) -> match typ e1 env with TypB -> let t2 = typ e2 env in let t3 = typ e3 env in if t2 = t3 then t2 else failwith "If: branch types differ" _ -> failwith "If: condition not boolean"... 13

Type checking, part 3 Checking let f x = fb in letb end Checking f ea let rec typ (e : tyexpr) (env : typ env) : typ = match e with... Letfun(f, x, xt, fb, bt, letb) -> let ft = TypF(xT, bt) in let fbe = (x, xt) :: (f, ft) :: env in let letbe = (f, ft) :: env in if typ fb fbe = rt then typ letb letbe else failwith "Letfun: wrong return type in function" Call(Var f, ea) -> match lookup env f with TypF(xT, bt) -> if typ ea env = xt then bt else failwith "Call: wrong argument type" _ -> failwith "Call: unknown function" Call(_, _) -> failwith "Call: illegal function in call"

Type checking versus evaluation The type checker typ and the interpreter eval have similar structure Type checking can be thought of as abstract interpretation of the program We calculate TypI + TypI gives TypI instead of Int 3 + Int 5 gives Int 8 One major difference: Type checking a function call f(e) does not require type checking the function s body again Interpreting a function call f(e) does require interpreting the function s body Type checking always terminates 15

Type checking by logical rules

How to read a type rule Environment (rho) Judgement: In environment ρ, expression e 2 has type int Premises Conclusion IF in environment ρ, expression e 1 has type int, and in environment ρ, expression e 2 has type int THEN in environment ρ, expression e 1 <e 2 has type bool

Joint exercise: How read these? An integer constant has type int 18

Combining type rules to trees Stacking type rules on top of each other One rule s conclusion is another s premise Checking let x=1 in x<2 end : bool in some environment ρ: The typ function implements the rules, from conclusion to premise! 19

Joint exercises: Invent type rules For e 1 && e 2 (logical and) For e 1 :: e 2 (list cons operator) For match e with [] -> e 1 x::xr -> e 2 20

Dynamically or statically typed Dynamically typed: Types are checked during evaluation (micro-ml, Postscript, JavaScript, Python, Ruby, Scheme, ) if (true) {return 11} else {return 22+false} Statically typed: OK, gives 11 Types are checked before evaluation (our typed fun. language, F#, most of Java and C#) if true then 11 else 22+false true? 11 : (22 + false) Compile-time type error Compile-time type error 21

Dynamic typing in Java/C# arrays For a Java/C# array whose element type is a reference type, all assignments are typechecked at runtime void M(Object[] a, Object x) { a[0] = x; } Type check needed at run-time Why is that necessary? String[] s = new String[1]; M(s, new Object()); String s0 = s[0]; 22