Datatypes, Patterns, and Parametric Polymorphism Topics Tuples Tuple

Total Page:16

File Type:pdf, Size:1020Kb

Datatypes, Patterns, and Parametric Polymorphism Topics Tuples Tuple CS 251 Fall 20192019 Principles of of Programming Programming Languages Languages Ben Wood Topics λ Ben Wood • Tuples and records Datatypes, Patterns, • Positional vs. nominal and Parametric Polymorphism • Datatypes • Pattern matching • Parametric polymorphic types (generics) • Lists and options • Equality types Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 1 2 https://cs.wellesley.edu/~cs251/f19/ Polymorphism Polymorphism Tuples Tuple bindings Syntax: (e1, …, en) Syntax: val (x1, x2) = e Type checking: Evaluation: If e has type t1 * t2, 1. Evaluate e1 to v1, …, and en to vn. then #1 e has type t1 and #2 e has type t2 2. The result is (v1, …, vn) Evaluation: Type checking: 1. Evaluate e to a pair of values (v1, v2) in the current dynamic environment If e1 has type t1, …, and en has type tn, 2. Extend the current dynamic environment by then the pair expression has type ta * … * tn binding x1 to v1 and x2 to v2. Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 3 4 Polymorphism Polymorphism Poor style. Tuple accessors Examples Syntax: #1 e #2 e fun swap (pr : int*bool) = let val (x,y) = pr in (y,x) end fun sum_two_pairs (pr1 : int*int, pr2 : int*int) = Type checking: let val (x1,y1) = pr1 If e has type t1 * t2, val (x2,y2) = pr2 then #1 e has type t1 and #2 e has type t2 in x1 + y1 + x2 + y2 end fun div_mod (x : int, y : int) = (x div y, x mod y) Evaluation: 1. Evaluate e to a pair of values v1 and v2 in the fun sort_pair (pr : int*int) = let val (x,y) = pr current dynamic environment in 2. The result v1 if using #1; v2 if using #2 if x < y then pr else (y,x) end Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 5 6 Polymorphism Polymorphism Records Example Record values have fields (any name) holding values {name = "Wendy", id = 41123 - 12} {f1 = v1, …, fn = vn} Record types have fields (any name) holding types Has type {id : int, name : string} {f1 : t1, …, fn : tn} Evaluates to {id = 41111, name = "Wendy"} Order of fields in a record value or type never matters Building records: If an expression, e.g. variable x, has this type, then get fields with: {f1 = e1, …, fn = en} #id x #name x Accessing components: No record type declarations! #myfieldname e – The same program could also make a (Evaluation rules and type-checking as expected) {id=true,ego=false} of type {id:bool,ego:bool} Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 7 8 Polymorphism Polymorphism Design Choice By position vs. by name Tuples are sugar (structural/positional) (nominal) (4,7,9) {f=4,g=7,h=9} (e1,…,en) desugars to Common syntax decision {1=e1,…,n=en} Common hybrid: function/method arguments t1*…*tn desugars to {1:t1,…,n:tn} Records with contiguous fields 1...n printed like tuples Can write {1=4,2=7,3=9}, bad style Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 9 10 Polymorphism Polymorphism Lists How to build bigger data types Racket: (cons 1 (cons 2 (cons 3 null))) Data type building blocks in any language – Product types (“Each of”): ML has a "no value" value written (), pronounced Value contains values of each of t1 t2 … tn "unit," with type unit Value contains a t1 and a t2 and … and a tn – Sum types (“One of”): What is the type of: (1, (2, (3, ()))) Value contains values of one of t1 t2 … tn Value is t1 xor a t2 xor … xor a tn What is the type of: (1, (2, (3, (4, ())))) – Recursive types (“Self reference”): A t value can refer to other t values Why is this a problem? Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 11 12 Polymorphism Polymorphism Datatype bindings Datatypes: constructing values datatype mytype = TwoInts of int * int datatype mytype = TwoInts of int * int | Str of string | Str of string | Pizza | Pizza Algebraic Data Type – Values of type mytype produced by one of the constructors • Adds new type mytype to environment – Value contains: • Adds constructors to environment: TwoInts, Str, Pizza − Tag: which constructor (e.g., TwoInts) − Carried value (e.g., (7,9)) • Constructor: function that makes values of new type (or is a – Examples: value of new type): − TwoInts (3+4,5+4) evaluates to TwoInts (7,9) – TwoInts : int * int -> mytype − Str if true then “hi” else “bye” – Str : string -> mytype evaluates to Str “hi” – Pizza : mytype − Pizza is a value Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 13 14 Polymorphism Polymorphism Datatypes: using values Pattern matching Rad!! 1. Check what variant it is (what constructor made it) Case expression and pattern-matching 2. Extract carried data (if that variant has any) fun f x = (* f has type mytype -> int *) case x of ML could create functions to get parts of datatype values Pizza => 3 | TwoInts(i1,i2) => i1+i2 – Like to pair? or cdr in Racket | Str s => String.size s – Instead it does something much better... All-in-one: – Multi-branch conditional, picks branch based on variant. – Extracts data and binds to branch-local variables. – Type-check: all branches must have same type. Datatypes, Patterns, and Parametric – Gets even better later. Datatypes, Patterns, and Parametric 15 16 Polymorphism Polymorphism Pattern matching Pattern matching rocks. case e0 of Syntax: p1 => e1 1. Cannot forget a case | p2 => e2 … (inexhaustive pattern-match warning) | pn => en 2. Cannot duplicate a case • (For now), each pattern pi is: (redundant pattern type-checking error) – a constructor name followed by the right number of variables: – C or D x or E (x,y) or … 3. Cannot forget to test the variant correctly • Patterns are not expressions. and get an error ((car null) in Racket) – We do not evaluate them. – We match e0 against their structure. 4. It's much more general. Supports elegant, concise code. • Precise type-checking/evaluation rules later... Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 17 18 Polymorphism Polymorphism Useful examples Lists! Enumerations, carrying other data A list is either: datatype suit = Club | Diamond | Heart | Spade – The empty list; or datatype card_value = Jack | Queen | King | Ace | Num of int – A pair of a list element and a list that holds the rest of the list. Alternate ways of identifying real-world things/people datatype mylist = Empty datatype id = StudentNum of int | Cons of int * mylist | Name of string * (string option) datatypes can be recursive * string val some_ints = Cons (1, Cons (2, Cons (3, Empty))) Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 19 20 Polymorphism Polymorphism Accessing Lists Syntactic sugar for lists: build The empty list is a value: [] val some_ints = Cons (1, Cons (2, Cons (3, Empty))) A list of expressions/values is an fun length (xs : mylist) = expression/value: case xs of Empty => 0 [e1,e2,…,en] [v1,v2,…,vn] | Cons (x, xs') => 1 + length xs' If e1 evaluates to v fun sum (xs : mylist) = case xs of and e2 evaluates to a list [v1,…,vn], Empty => 0 then e1::e2 evaluates to [v,v1,…,vn] | Cons (x, xs') => x + sum xs' Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 21 22 Polymorphism Polymorphism Syntactic sugar for lists: access Type-checking list operations For any type t, type t list describes lists where all val some_ints = [1,2,3] elements have type t note the space between int and list int list bool list int list list (int * int) list (int list * int) list fun length (xs : int list) = case xs of [] : t list list for any type t [] => 0 SML uses type 'a list to indicate this (“quote a” or “alpha”) | x::xs' => 1 + length xs' e1::e2 : t list if and only if: fun sum (xs : int list) = – e1 : t and case xs of – e2 : t list [] => 0 | x::xs' => x + sum xs' More on 'a soon! (Nothing to do with 'a in Racket.) Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 23 24 Polymorphism Polymorphism (type?) Example list functions (types?) Example higher-order list functions fun countdown (x : int) = if x=0 fun map (f : int -> int, xs : int list) = then [] case xs of else x :: countdown (x-1) [] => [] | x::xs' => f x :: map (f, xs') fun append (xs : int list, ys : int list) = case xs of [] => ys • These examples only work on lists of ints. | x::xs' => x :: append (xs', ys) • Should be more general: work on any list fun rev (xs : int list) = – and any function for map... let fun revtail (acc : int list, xs : int list) = case xs of [] => acc | x::xs' => revtail (x :: acc, xs') in revtail ([], xs) Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric end 25 26 Polymorphism Polymorphism Polymorphic types + type inference Polymorphic types + type inference The identity function: fun id (x : int) = x fun swap pair = val id : int -> int let val (x,y) = pair in (y,x) end val swap : ('a * 'b) -> ('b * 'a) Omit the type: fun id x = x Works on any type of pair! val id : 'a -> 'a val pair = swap (4,"hello") General! is more general than . • 'a is a polymorphic type variable ('a * 'b) (int * string) stands in for any type • "id takes an argument of any type and returns a Here, int instantiates 'a and string instantiates 'b. result of that same type." Datatypes, Patterns, and Parametric Datatypes, Patterns, and Parametric 27 28 Polymorphism Polymorphism Polymorphic datatypes Polymorphic list functions (types?) Lists that can hold elements of any one type. fun append (xs, ys) = case xs of datatype 'a mylist = Empty [] => ys | Cons of 'a * 'a mylist | x::xs' => x :: append (xs', ys) fun rev (xs) = A list of "alphas" is either: let fun revtail (acc : int list, xs : int list) = – the empty list; or case xs of – a pair of an "alpha" and a list of "alphas" [] => acc | x::xs' => revtail (x :: acc, xs') in revtail [] xs end datatype 'a list = [] | :: of 'a * 'a list fun map (f, xs) = case xs of The type int list is an instantiation of the type 'a list, where [] => [] the type variable 'a is instantiated with int.
Recommended publications
  • Design and Implementation of Generics for the .NET Common Language Runtime
    Design and Implementation of Generics for the .NET Common Language Runtime Andrew Kennedy Don Syme Microsoft Research, Cambridge, U.K. fakeÒÒ¸d×ÝÑeg@ÑicÖÓ×ÓfغcÓÑ Abstract cally through an interface definition language, or IDL) that is nec- essary for language interoperation. The Microsoft .NET Common Language Runtime provides a This paper describes the design and implementation of support shared type system, intermediate language and dynamic execution for parametric polymorphism in the CLR. In its initial release, the environment for the implementation and inter-operation of multiple CLR has no support for polymorphism, an omission shared by the source languages. In this paper we extend it with direct support for JVM. Of course, it is always possible to “compile away” polymor- parametric polymorphism (also known as generics), describing the phism by translation, as has been demonstrated in a number of ex- design through examples written in an extended version of the C# tensions to Java [14, 4, 6, 13, 2, 16] that require no change to the programming language, and explaining aspects of implementation JVM, and in compilers for polymorphic languages that target the by reference to a prototype extension to the runtime. JVM or CLR (MLj [3], Haskell, Eiffel, Mercury). However, such Our design is very expressive, supporting parameterized types, systems inevitably suffer drawbacks of some kind, whether through polymorphic static, instance and virtual methods, “F-bounded” source language restrictions (disallowing primitive type instanti- type parameters, instantiation at pointer and value types, polymor- ations to enable a simple erasure-based translation, as in GJ and phic recursion, and exact run-time types.
    [Show full text]
  • Parametric Polymorphism Parametric Polymorphism
    Parametric Polymorphism Parametric Polymorphism • is a way to make a language more expressive, while still maintaining full static type-safety (every Haskell expression has a type, and types are all checked at compile-time; programs with type errors will not even compile) • using parametric polymorphism, a function or a data type can be written generically so that it can handle values identically without depending on their type • such functions and data types are called generic functions and generic datatypes Polymorphism in Haskell • Two kinds of polymorphism in Haskell – parametric and ad hoc (coming later!) • Both kinds involve type variables, standing for arbitrary types. • Easy to spot because they start with lower case letters • Usually we just use one letter on its own, e.g. a, b, c • When we use a polymorphic function we will usually do so at a specific type, called an instance. The process is called instantiation. Identity function Consider the identity function: id x = x Prelude> :t id id :: a -> a It does not do anything with the input other than returning it, therefore it places no constraints on the input's type. Prelude> :t id id :: a -> a Prelude> id 3 3 Prelude> id "hello" "hello" Prelude> id 'c' 'c' Polymorphic datatypes • The identity function is the simplest possible polymorphic function but not very interesting • Most useful polymorphic functions involve polymorphic types • Notation – write the name(s) of the type variable(s) used to the left of the = symbol Maybe data Maybe a = Nothing | Just a • a is the type variable • When we instantiate a to something, e.g.
    [Show full text]
  • CSE 307: Principles of Programming Languages Classes and Inheritance
    OOP Introduction Type & Subtype Inheritance Overloading and Overriding CSE 307: Principles of Programming Languages Classes and Inheritance R. Sekar 1 / 52 OOP Introduction Type & Subtype Inheritance Overloading and Overriding Topics 1. OOP Introduction 3. Inheritance 2. Type & Subtype 4. Overloading and Overriding 2 / 52 OOP Introduction Type & Subtype Inheritance Overloading and Overriding Section 1 OOP Introduction 3 / 52 OOP Introduction Type & Subtype Inheritance Overloading and Overriding OOP (Object Oriented Programming) So far the languages that we encountered treat data and computation separately. In OOP, the data and computation are combined into an “object”. 4 / 52 OOP Introduction Type & Subtype Inheritance Overloading and Overriding Benefits of OOP more convenient: collects related information together, rather than distributing it. Example: C++ iostream class collects all I/O related operations together into one central place. Contrast with C I/O library, which consists of many distinct functions such as getchar, printf, scanf, sscanf, etc. centralizes and regulates access to data. If there is an error that corrupts object data, we need to look for the error only within its class Contrast with C programs, where access/modification code is distributed throughout the program 5 / 52 OOP Introduction Type & Subtype Inheritance Overloading and Overriding Benefits of OOP (Continued) Promotes reuse. by separating interface from implementation. We can replace the implementation of an object without changing client code. Contrast with C, where the implementation of a data structure such as a linked list is integrated into the client code by permitting extension of new objects via inheritance. Inheritance allows a new class to reuse the features of an existing class.
    [Show full text]
  • INF 102 CONCEPTS of PROG. LANGS Type Systems
    INF 102 CONCEPTS OF PROG. LANGS Type Systems Instructors: James Jones Copyright © Instructors. What is a Data Type? • A type is a collection of computational entities that share some common property • Programming languages are designed to help programmers organize computational constructs and use them correctly. Many programming languages organize data and computations into collections called types. • Some examples of types are: o the type Int of integers o the type (Int→Int) of functions from integers to integers Why do we need them? • Consider “untyped” universes: • Bit string in computer memory • λ-expressions in λ calculus • Sets in set theory • “untyped” = there’s only 1 type • Types arise naturally to categorize objects according to patterns of use • E.g. all integer numbers have same set of applicable operations Use of Types • Identifying and preventing meaningless errors in the program o Compile-time checking o Run-time checking • Program Organization and documentation o Separate types for separate concepts o Indicates intended use declared identifiers • Supports Optimization o Short integers require fewer bits o Access record component by known offset Type Errors • A type error occurs when a computational entity, such as a function or a data value, is used in a manner that is inconsistent with the concept it represents • Languages represent values as sequences of bits. A "type error" occurs when a bit sequence written for one type is used as a bit sequence for another type • A simple example can be assigning a string to an integer
    [Show full text]
  • Parametric Polymorphism (Generics) 30 April 2018 Lecturer: Andrew Myers
    CS 4120/5120 Lecture 36 Parametric Polymorphism (Generics) 30 April 2018 Lecturer: Andrew Myers Parametric polymorphism, also known as generics, is a programming language feature with implications for compiler design. The word polymorphism in general means that a value or other entity that can have more than one type. We have already talked about subtype polymorphism, in which a value of one type can act like another (super)type. Subtyping places constraints on how we implemented objects. In parametric polymorphism, the ability for something to have more than one “shape” is by introducing a type parameter. A typical motivation for parametric polymorphism is to support generic collection libraries such as the Java Collection Framework. Prior to the introduction of parametric polymorphism, all that code could know about the contents of a Set or Map was that it contained Objects. This led to code that was clumsy and not type-safe. With parametric polymorphism, we can apply a parameterized type such as Map to particular types: a Map String, Point maps Strings to Points. We can also parameterize procedures (functions, methods) withh respect to types.i Using Xi-like syntax, we might write a is_member method that can look up elements in a map: contains K, V (c: Map K, V , k: K): Value { ... } Map K, V h m i h i ...h i p: Point = contains String, Point (m, "Hello") h i Although Map is sometimes called a parameterized type or a generic type , it isn’t really a type; it is a type-level function that maps a pair of types to a new type.
    [Show full text]
  • Polymorphism
    Polymorphism A closer look at types.... Chap 8 polymorphism º comes from Greek meaning ‘many forms’ In programming: Def: A function or operator is polymorphic if it has at least two possible types. Polymorphism i) OverloaDing Def: An overloaDeD function name or operator is one that has at least two Definitions, all of Different types. Example: In Java the ‘+’ operator is overloaDeD. String s = “abc” + “def”; +: String * String ® String int i = 3 + 5; +: int * int ® int Polymorphism Example: Java allows user DefineD polymorphism with overloaDeD function names. bool f (char a, char b) { return a == b; f : char * char ® bool } bool f (int a, int b) { f : int * int ® bool return a == b; } Note: ML Does not allow function overloaDing Polymorphism ii) Parameter Coercion Def: An implicit type conversion is calleD a coercion. Coercions usually exploit the type-subtype relationship because a wiDening type conversion from subtype to supertype is always DeemeD safe ® a compiler can insert these automatically ® type coercions. Example: type coercion in Java Double x; x = 2; the value 2 is coerceD from int to Double by the compiler Polymorphism Parameter coercion is an implicit type conversion on parameters. Parameter coercion makes writing programs easier – one function can be applieD to many subtypes. Example: Java voiD f (Double a) { ... } int Ì double float Ì double short Ì double all legal types that can be passeD to function ‘f’. byte Ì double char Ì double Note: ML Does not perform type coercion (ML has no notion of subtype). Polymorphism iii) Parametric Polymorphism Def: A function exhibits parametric polymorphism if it has a type that contains one or more type variables.
    [Show full text]
  • Obstacl: a Language with Objects, Subtyping, and Classes
    OBSTACL: A LANGUAGE WITH OBJECTS, SUBTYPING, AND CLASSES A DISSERTATION SUBMITTED TO THE DEPARTMENT OF COMPUTER SCIENCE AND THE COMMITTEE ON GRADUATE STUDIES OF STANFORD UNIVERSITY IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE DEGREE OF DOCTOR OF PHILOSOPHY By Amit Jayant Patel December 2001 c Copyright 2002 by Amit Jayant Patel All Rights Reserved ii I certify that I have read this dissertation and that in my opin- ion it is fully adequate, in scope and quality, as a dissertation for the degree of Doctor of Philosophy. John Mitchell (Principal Adviser) I certify that I have read this dissertation and that in my opin- ion it is fully adequate, in scope and quality, as a dissertation for the degree of Doctor of Philosophy. Kathleen Fisher I certify that I have read this dissertation and that in my opin- ion it is fully adequate, in scope and quality, as a dissertation for the degree of Doctor of Philosophy. David Dill Approved for the University Committee on Graduate Studies: iii Abstract Widely used object-oriented programming languages such as C++ and Java support soft- ware engineering practices but do not have a clean theoretical foundation. On the other hand, most research languages with well-developed foundations are not designed to support software engineering practices. This thesis bridges the gap by presenting OBSTACL, an object-oriented extension of ML with a sound theoretical basis and features that lend themselves to efficient implementation. OBSTACL supports modular programming techniques with objects, classes, structural subtyping, and a modular object construction system. OBSTACL's parameterized inheritance mechanism can be used to express both single inheritance and most common uses of multiple inheritance.
    [Show full text]
  • Polymorphism
    Chapter 4 Polymorphism Previously, we developed two data structures that implemented the list abstract data type: linked lists and array lists. However, these implementations were unsatisfying along two dimensions: 1. Even though a linked list and array list provide the same functions to a user, they are not interchangable in user code. If the user wanted the flexibility of choosing between a linked list or array list (because they have different performance characteristics), they would need to duplicate code who’s only difference would be the type of the list it uses. 2. The carrier type of either list implementation is fixed. If we wanted a list that held integers as well as a list that contained strings, we would need two separate implementations of the list that only differed in the type of the value at each node. To solve both these problems, Java provides us mechanisms to write polymorphic code. Polymorphic code is code that can operate over multiple types. In particular, the two problems described above are addressed with two types of polymorphisms: subtype polymorphism and parametric polymorphism. 4.1 Subtype Polymorphism The list abstract data type defined a number of operations that all “list-like” objects ought toimplement: • int size(), • void add(int x), • void insert(int x, int index), • void clear(), • int get(int index), and • int remove(int index). Our linked list and array list classes implemented these methods. However, there was no enforcement by the compiler that these classes actually implemented these operations. Furthermore, even though the two list implementations provided the exact same set of methods to the user, we could not interchange one list for another because they are different types.
    [Show full text]
  • First-Class Type Classes
    First-Class Type Classes Matthieu Sozeau1 and Nicolas Oury2 1 Univ. Paris Sud, CNRS, Laboratoire LRI, UMR 8623, Orsay, F-91405 INRIA Saclay, ProVal, Parc Orsay Universit´e, F-91893 [email protected] 2 University of Nottingham [email protected] Abstract. Type Classes have met a large success in Haskell and Is- abelle, as a solution for sharing notations by overloading and for spec- ifying with abstract structures by quantification on contexts. However, both systems are limited by second-class implementations of these con- structs, and these limitations are only overcomed by ad-hoc extensions to the respective systems. We propose an embedding of type classes into a dependent type theory that is first-class and supports some of the most popular extensions right away. The implementation is correspond- ingly cheap, general and integrates well inside the system, as we have experimented in Coq. We show how it can be used to help structured programming and proving by way of examples. 1 Introduction Since its introduction in programming languages [1], overloading has met an important success and is one of the core features of object–oriented languages. Overloading allows to use a common name for different objects which are in- stances of the same type schema and to automatically select an instance given a particular type. In the functional programming community, overloading has mainly been introduced by way of type classes, making ad-hoc polymorphism less ad hoc [17]. A type class is a set of functions specified for a parametric type but defined only for some types.
    [Show full text]
  • Lecture Notes on Polymorphism
    Lecture Notes on Polymorphism 15-411: Compiler Design Frank Pfenning Lecture 24 November 14, 2013 1 Introduction Polymorphism in programming languages refers to the possibility that a function or data structure can accommodate data of different types. There are two principal forms of polymorphism: ad hoc polymorphism and parametric polymorphism. Ad hoc polymorphism allows a function to compute differently, based on the type of the argument. Parametric polymorphism means that a function behaves uniformly across the various types [Rey74]. In C0, the equality == and disequality != operators are ad hoc polymorphic: they can be applied to small types (int, bool, τ∗, τ[], and also char, which we don’t have in L4), and they behave differently at different types (32 bit vs 64 bit compar- isons). A common example from other languages are arithmetic operators so that e1 + e2 could be addition of integers or floating point numbers or even concate- nation of strings. Type checking should resolve the ambiguities and translate the expression to the correct internal form. The language extension of void∗ we discussed in Assignment 4 is a (somewhat borderline) example of parametric polymorphism, as long as we do not add a con- struct hastype(τ; e) or eqtype(e1; e2) into the language and as long as the execution does not raise a dynamic tag exception. It should therefore be considered some- what borderline parametric, since implementations must treat it uniformly but a dynamic tag error depends on the run-time type of a polymorphic value. Generally, whether polymorphism is parametric depends on all the details of the language definition.
    [Show full text]
  • Lecture 5. Data Types and Type Classes Functional Programming
    Lecture 5. Data types and type classes Functional Programming [Faculty of Science Information and Computing Sciences] 0 I function call and return as only control-flow primitive I no loops, break, continue, goto I instead: higher-order functions! Goal of typed purely functional programming: programs that are easy to reason about So far: I data-flow only through function arguments and return values I no hidden data-flow through mutable variables/state I instead: tuples! [Faculty of Science Information and Computing Sciences] 1 Goal of typed purely functional programming: programs that are easy to reason about So far: I data-flow only through function arguments and return values I no hidden data-flow through mutable variables/state I instead: tuples! I function call and return as only control-flow primitive I no loops, break, continue, goto I instead: higher-order functions! [Faculty of Science Information and Computing Sciences] 1 I high-level declarative data structures I no explicit reference-based data structures I instead: (immutable) algebraic data types! Goal of typed purely functional programming: programs that are easy to reason about Today: I (almost) unique types I no inheritance hell I instead of classes + inheritance: variant types! I (almost): type classes [Faculty of Science Information and Computing Sciences] 2 Goal of typed purely functional programming: programs that are easy to reason about Today: I (almost) unique types I no inheritance hell I instead of classes + inheritance: variant types! I (almost): type classes
    [Show full text]
  • Type Systems, Type Inference, and Polymorphism
    6 Type Systems, Type Inference, and Polymorphism Programming involves a wide range of computational constructs, such as data struc- tures, functions, objects, communication channels, and threads of control. Because programming languages are designed to help programmers organize computational constructs and use them correctly, many programming languages organize data and computations into collections called types. In this chapter, we look at the reasons for using types in programming languages, methods for type checking, and some typing issues such as polymorphism and type equality. A large section of this chap- ter is devoted to type inference, the process of determining the types of expressions based on the known types of some symbols that appear in them. Type inference is a generalization of type checking, with many characteristics in common, and a representative example of the kind of algorithms that are used in compilers and programming environments to determine properties of programs. Type inference also provides an introduction to polymorphism, which allows a single expression to have many types. 6.1 TYPES IN PROGRAMMING In general, a type is a collection of computational entities that share some common property. Some examples of types are the type Int of integers, the type Int!Int of functions from integers to integers, and the Pascal subrange type [1 .. 100] of integers between 1 and 100. In concurrent ML there is the type Chan Int of communication channels carrying integer values and, in Java, a hierarchy of types of exceptions. There are three main uses of types in programming languages: naming and organizing concepts, making sure that bit sequences in computer memory are interpreted consistently, providing information to the compiler about data manipulated by the program.
    [Show full text]