CS558 Programming Languages

Similar documents
CS558 Programming Languages

CS558 Programming Languages

CS558 Programming Languages

CS321 Languages and Compiler Design I Winter 2012 Lecture 13

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

CSCI-GA Scripting Languages

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

Types, Type Inference and Unification

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

Values (a.k.a. data) representation. Advanced Compiler Construction Michel Schinz

Values (a.k.a. data) representation. The problem. Values representation. The problem. Advanced Compiler Construction Michel Schinz

Semantic Analysis. How to Ensure Type-Safety. What Are Types? Static vs. Dynamic Typing. Type Checking. Last time: CS412/CS413

Programming Languages Lecture 14: Sum, Product, Recursive Types

Types and Type Inference

Chapter 8 :: Composite Types

Types and Type Inference

Type Systems, Type Inference, and Polymorphism

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

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 17: Types and Type-Checking 25 Feb 08

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

Data Types. (with Examples In Haskell) COMP 524: Programming Languages Srinivas Krishnan March 22, 2011

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

Type Checking and Type Inference

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

CS321 Languages and Compiler Design I. Winter 2012 Lecture 1

Topic 9: Type Checking

Topic 9: Type Checking

Programming Languages

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

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

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

Lecture Overview. [Scott, chapter 7] [Sebesta, chapter 6]

Compilers. Type checking. Yannis Smaragdakis, U. Athens (original slides by Sam

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

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Lecture #23: Conversion and Type Inference

NOTE: Answer ANY FOUR of the following 6 sections:

CS558 Programming Languages

Programming Languages Lecture 15: Recursive Types & Subtyping

COMP 181. Agenda. Midterm topics. Today: type checking. Purpose of types. Type errors. Type checking

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

Types II. Hwansoo Han

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

References and pointers

Data Types The ML Type System

Types. What is a type?

Chapter 5 Names, Binding, Type Checking and Scopes

Lecture 12: Data Types (and Some Leftover ML)

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

22c:111 Programming Language Concepts. Fall Types I

CS558 Programming Languages Winter 2018 Lecture 4a. Andrew Tolmach Portland State University

Programming Languages

CS558 Programming Languages

CS 314 Principles of Programming Languages

G Programming Languages - Fall 2012

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

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

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

CS558 Programming Languages. Winter 2013 Lecture 3

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

CS558 Programming Languages

Simply-Typed Lambda Calculus

Haskell 98 in short! CPSC 449 Principles of Programming Languages

CS558 Programming Languages

Fundamentals of Programming Languages. Data Types Lecture 07 sl. dr. ing. Ciprian-Bogdan Chirila

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

Programming Languages, Summary CSC419; Odelia Schwartz

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

Types. Type checking. Why Do We Need Type Systems? Types and Operations. What is a type? Consensus

MIDTERM EXAMINATION - CS130 - Spring 2003

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

Question No: 1 ( Marks: 1 ) - Please choose one One difference LISP and PROLOG is. AI Puzzle Game All f the given

Compiler Construction

CS 321 Homework 4 due 1:30pm, Thursday, March 15, 2012 This homework specification is copyright by Andrew Tolmach. All rights reserved.

Project Compiler. CS031 TA Help Session November 28, 2011

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

Cunning Plan. One-Slide Summary. Functional Programming. Functional Programming. Introduction to COOL #1. Classroom Object-Oriented Language

Weeks 6&7: Procedures and Parameter Passing

Lecture 16: Static Semantics Overview 1

Recap: Functions as first-class values

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

Grade Weights. Language Design and Overview of COOL. CS143 Lecture 2. Programming Language Economics 101. Lecture Outline

Chapter 7:: Data Types. Mid-Term Test. Mid-Term Test (cont.) Administrative Notes

1 Introduction. 3 Syntax

Data Types. Every program uses data, either explicitly or implicitly to arrive at a result.

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

Programming Languages

CSCI312 Principles of Programming Languages!

Overloading, Type Classes, and Algebraic Datatypes

Static Checking and Type Systems

COS 320. Compiling Techniques

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

G Programming Languages - Fall 2012

CMSC 330: Organization of Programming Languages

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

Mini-ML. CS 502 Lecture 2 8/28/08

The type checker will complain that the two branches have different types, one is string and the other is int

CSE 431S Type Checking. Washington University Spring 2013

Announcements. Working on requirements this week Work on design, implementation. Types. Lecture 17 CS 169. Outline. Java Types

Transcription:

CS558 Programming Languages Winter 2017 Lecture 7b Andrew Tolmach Portland State University 1994-2017

Values and Types We divide the universe of values according to types A type is a set of values and a set of operations on them How is each value represented? How is each operation implemented? Integers with +,-,etc. machine integer HW instruction Arrays with read,update contiguous block of memory address arithmetic + indirect addressing Booleans with &,,~ machine bit or byte HW instruction/sequence Functions with apply closures jsr instruction

Atomic vs Constructed Types Atomic (or primitive) types are those whose values cannot be taken apart or constructed by user code Can only manipulate using built-in language operators Typically includes the types that have direct hardware support e.g., integers, floats, pointers, instructions Composite types are built from other types using type constructors User code can construct values, inspect/modify internals E.g. arrays, records, unions, function

Static Type Checking High-level languages differ from machine code in that explicit types appear and type violations are usually caught at some point Static type checking is probably most common: FORTRAN, Algol, Pascal, C/C++, Java, Scala, etc. Types are associated with identifiers (variables, parameters, functions) Every use of an identifier can be checked for type-correctness before program is run Well-typed programs don t go wrong (if type system is sound) Compilers can generate efficient code because it knows how each value is represented Type declarations provide useful documentation for code

Dynamic Type Checking Dynamic type checking occurs in LISP, Smalltalk, Python, JavaScript, many other scripting languages Types are attached to values (usually as explicit tags) The type associated with an identifier can vary Correctness of operations can t (in general) be checked until run time Type violations become checked run-time errors Generating optimized code and value representations is hard Programs can be harder to read

Static Type Systems Main goal of a type system is to characterize programs that won t go wrong" at runtime Informally, we want to avoid programs that confuse types, e.g. by trying to add booleans to reals, or take the square root of a string More formally, we can give a set of typing rules (sometimes called static semantics) from which we can derive typing judgments about programs Program is well-typed if-and-only-if we can derive a typing judgment for it

Typing Judgments Each judgment has the form TE e : t Intuitively this says that expression e has type t, under the assumption that the type of each free variable in e is given by the type environment TE. We write TE(x) for the result of looking up x in TE,andTE + {x t} for the type environment obtained from TE by extending it with a new binding from x to t.

Rules for a simple language TE(x) =t TE x : t (Var) TE i : Int (Int) TE e 1 : Int TE e 2 : Int TE (+ e 1 e 2 ) : Int (Add) TE e 1 : t 1 TE + {x t 1 } e 2 : t 2 TE (let x e 1 e 2 ) : t 2 (Let) TE(x) =t TE e : t TE (:= x e) : t (Assgn) TE e 1 : Bool TE e 2 : t TE e 3 : t TE (if e 1 e 2 e 3 ) : t (If) TE e 1 : Int TE (<= e 1 TE e 2 : Int e 2 ) : Bool (Leq) TE e 1 : Bool TE e 2 : t TE (while e 1 e 2 ) : Int (While) Assumes just two types: Int and Bool

Static Type Checking We can turn the typing rules into a recursive typechecking algorithm A type checker is very similar to the evaluators we have already built: It is parameterized by a type environment It dispatches according to the syntax of the expression being checked (note there is exactly one rule for each expression form) It calls itself recursively on sub-expressions

Static Type Checking (2) But there are some differences: Type checker returns a type, not a value It must examine every possible execution path, but just once e.g. it examines both arms of a conditional expression (not just one) e.g. if our language has functions, it processes the body of each function only once, no matter how many places the function is called from Most languages require the types of function parameters and return values to be declared explicitly. The type checker can use this info to check separately that applications of the function are correctly typed and that the body of the function is correctly typed.

Flexibility of Dynamic Type Checking Static type checking offers the great advantage of catching errors early And it generally supports more efficient execution So why ever consider dynamic type checking? Simplicity. For short or simple programs, it s nice to avoid the need to declare the types of identifiers Flexibility. Static type checking is inherently more conservative about what programs it allows.

Conservative Typing For example, suppose function f happens always to return false. Then (if f() then "a" else 2) + 2 will never cause a run-time type error, but it will still be rejected by a static type system Dynamic typing allows container data structures to contain mixtures of values of arbitrary types, e.g. List(2, true, 3.14)

Type Inference Some statically typed languages, like ML (and to a lesser extent Scala), offer alternative ways to regain the flexibility of dynamic typing, via type inference and polymorphism. Type inference works like this: The types of identifiers are automatically inferred from the way they are used The programmer is no longer required to declare the types of identifiers (although this is still permitted) Method requires that the types of operators and literals is known

Inference Examples (let f (fun (x) (+ x 2)) (@ f y)) The type of x must be int because it is used as an arg to +. So the type of f must be int int (i.e. the type of functions that expect an int argument and return an int result), and y must be an int. (let f (fun (x) (cons x nil)) (@ f true)) Suppose x has some type t. Then the type of f must be t (list t). Since f is applied to a bool, we must have t = bool. For the moment, we assume that f must be given a unique monomorphic type; we will relax this later

Systematic Inference Here s a harder example: (let f (fun (x) (if x p q)) (+ 1 (@ f r))) Can only infer types by looking at both the function s body and its application In general, we can solve the inference task by extracting a collection of typing constraints from the program s AST, and then finding a simultaneous solution for the constraints using unification Extracted constraints tell us how types must be related if we are to be able to find a typing derivation. Each node generates one or more constraints

Rules for First-class Functions To handle this example, we ll need some extra typing rules: TE + {x t 1 } e : t 2 TE (fun (x) e) : t 1 t 2 (Fn) TE e 1 : t 1 t 2 TE e 2 : t 1 TE (@ e 1 e 2 ) : t 2 (Appl)

Inference Example Solution : t 1 = t 7 = t 8 = t 9 = t 3 = t 5 = t p = t 6 = t q = int t 4 = t x = t 11 = t r = bool t 2 = t f = t 10 = bool int Node Rule Constraints 1 Let t f = t 2 t 1 = t 7 2 Fun t 2 = t x t 3 3 If t 4 = bool t 3 = t 5 = t 6 4 Var t 4 = t x 5 Var t 5 = t p Let(f) 1 6 Var t 5 = t q 7 Add t 7 = t 8 = t 9 = int 8 Int t 8 = int 9 Appl t 10 = t 11 t 9 Fun(x) + 2 7 10 Var t 10 = t f 11 Var t 11 = t r If 3 1 Appl 8 9 x p q 4 5 6 f r 10 11

Drawbacks of Inference Consider this variant example: (let f (fun (x) (if x p false) (+ 1 (@ f r))) Now the body of f returns type bool, but it is used in a context expecting an int. The corresponding extracted constraints will be inconsistent; no solution can be found. Can report a type error to the programmer. But which is wrong, the definition of f or the use? No good way to associate the error message with a single program point.