Types Dynamic types Types are broken down into many categories - - PowerPoint PPT Presentation

types dynamic types
SMART_READER_LITE
LIVE PREVIEW

Types Dynamic types Types are broken down into many categories - - PowerPoint PPT Presentation

Types Dynamic types Types are broken down into many categories Static types Duck typing Dynamic types Subtypes Types are broken down into many categories Classes and subclasses Static types Strong types Dependent Duck typing


slide-1
SLIDE 1

Types

slide-2
SLIDE 2

Types are broken down into many categories

Dynamic types Static types

slide-3
SLIDE 3

Types are broken down into many categories

Dynamic types Static types Duck typing “Strong” types Classes and subclasses Subtypes

slide-4
SLIDE 4

Types are broken down into many categories

Duck typing Dynamic types Gradual types “Strong” types Static types Dependent Linear Classes and subclasses Subtypes

slide-5
SLIDE 5

A “type” is a classification that says how some data may be used

slide-6
SLIDE 6

Essentially all programming languages have the concept of a “dynamic” type

slide-7
SLIDE 7

Some languages also have “static” types In those languages, the types have to be checked before running the program

slide-8
SLIDE 8

A “dynamic” type is a piece of data’s type at runtime If I ask “what is x’s dynamic type” I am asking “what is x’s type right now”

slide-9
SLIDE 9

In the next few slides, I am only going to be talking about runtime types

slide-10
SLIDE 10

>>> x = 12 >>> type(x) <type 'int'> >>> x = "Hello" >>> type(x) <type 'str'>

Python has dynamic types

slide-11
SLIDE 11

2.4.1 :005 > x = 12 => 12 2.4.1 :006 > x.class => Integer 2.4.1 :007 > x = "Hello" => "Hello" 2.4.1 :008 > x.class => String

So does Ruby….

slide-12
SLIDE 12

Everything in C++ also has a dynamic type at runtime At compile time, C++ assigns static types

slide-13
SLIDE 13

Here’s a really key thing

slide-14
SLIDE 14

Dynamic types and static types are not necessarily the same!!!

slide-15
SLIDE 15

Basically everything in Ruby revolves around classes

slide-16
SLIDE 16

Classes are one kind of type

slide-17
SLIDE 17

But classes are just one kind of type

slide-18
SLIDE 18

We’ll learn more about classes in a few lectures…

slide-19
SLIDE 19

Even assembly languages have types They’re just really degenerate types

For example, everything in HERA is a word This is still a type, but since there’s only one dynamic type in HERA it’s not that useful

slide-20
SLIDE 20

Why do we have dynamic types?

slide-21
SLIDE 21

To prevent us from doing something we shouldn’t at runtime

slide-22
SLIDE 22

The dynamic types throw errors when the language doesn’t know how to do something

slide-23
SLIDE 23

The dynamic types throw errors when the language doesn’t know how to do something

2.4.1 :009 > 1 + "hello" TypeError: String can't be coerced into Integer from (irb):9:in `+' from (irb):9 from /Users/kmicinski/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'

slide-24
SLIDE 24

The dynamic types throw errors when the language doesn’t know how to do something

2.4.1 :009 > 1 + "hello" TypeError: String can't be coerced into Integer from (irb):9:in `+' from (irb):9 from /Users/kmicinski/.rvm/rubies/ruby-2.4.1/bin/irb:11:in `<main>'

>>> 1 + "hello" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'int' and 'str'

slide-25
SLIDE 25

> (+ 1 "hello") ; +: contract violation ; expected: number? ; given: "hello" ; argument position: 2nd ; [,bt for context]

slide-26
SLIDE 26

So a dynamic type system is a set of rules that apply to program data at runtime

slide-27
SLIDE 27

A static type system is a set of rules that assigns types to data before running it

slide-28
SLIDE 28

Every language has dynamic types

Some languages also have static types

slide-29
SLIDE 29

A lot of people act like it’s dynamic types on one end and static types on the other. But that is false

slide-30
SLIDE 30

Dynamic Types Static Types

slide-31
SLIDE 31

Dynamic Types Static Types

slide-32
SLIDE 32

So when you go out into the world, just remember, a dynamic type is just a type at runtime

slide-33
SLIDE 33

Now, what are static types?

slide-34
SLIDE 34

Question: who here has had a dynamic type error in Racket?

slide-35
SLIDE 35

Static types are all about helping you prevent those errors

slide-36
SLIDE 36

Static types help you ensure at compile time that I won’t run into a type error at runtime

slide-37
SLIDE 37

But type errors aren’t all the bugs in my program

slide-38
SLIDE 38

C++ has static types

slide-39
SLIDE 39

string get_ith(list<string> l, i) { string s; for(; i > 0; i--) { l = rest(l); } }

slide-40
SLIDE 40

string get_ith(list<string> l, i) { string s; for(; i > 0; i--) { l = rest(l); } }

If I call get_ith(ez_list(“1”,”2”),2)) the program will fail at runtime

slide-41
SLIDE 41

It turns out that you can actually beef up the types

slide-42
SLIDE 42
slide-43
SLIDE 43

Certain languages allow you to specify constraints on the list size at compile time

list(string,n)

These are called dependent types because the type “depends” on the integer value n

slide-44
SLIDE 44

These types are potentially very useful. Right now they’re too hard to use. Few people use dependent types in production

slide-45
SLIDE 45

Richard Eisenberg (BMC) and Stephanie Weirich (Penn) both work on efforts toward practical dependent types

slide-46
SLIDE 46

In this class we will stick to more conventional types Which are still very useful for most purposes

slide-47
SLIDE 47

Two popular kinds of type systems

slide-48
SLIDE 48

Two popular kinds of static type systems Nominal Structural

(Many real type systems mix the two)

slide-49
SLIDE 49

Nominal Types

Types are assigned based on name

class C { int mX; int mY; } class D { int mX; int mY; }

slide-50
SLIDE 50

Nominal Types

In C++ these are different types, because they have different names

class C { int mX; int mY; } class D { int mX; int mY; }

slide-51
SLIDE 51

Structural type systems reason about the structure of the types

slide-52
SLIDE 52
slide-53
SLIDE 53

We’re going to learn about static types by learning some typed Racket

(Typed Racket won’t be on exam, but concepts from type systems may be, I’ll tell you which)

slide-54
SLIDE 54

(struct pt (x y)) (define (distance p1 p2) (sqrt (+ (sqr (- (pt-x p2) (pt-x p1))) (sqr (- (pt-y p2) (pt-y p1)))))

Racket

slide-55
SLIDE 55

(struct pt ([x : Real] [y : Real])) (: distance (-> pt pt Real)) (define (distance p1 p2) (sqrt (+ (sqr (- (pt-x p2) (pt-x p1))) (sqr (- (pt-y p2) (pt-y p1))))))

Typed Racket

slide-56
SLIDE 56

(struct pt ([x : Real] [y : Real])) (: distance (-> pt pt Real)) (define (distance p1 p2) (sqrt (+ (sqr (- (pt-x p2) (pt-x p1))) (sqr (- (pt-y p2) (pt-y p1))))))

Structure type signature

slide-57
SLIDE 57
slide-58
SLIDE 58

The type checker prevents me from creating data that violates the type invariant

slide-59
SLIDE 59

(struct pt ([x : Real] [y : Real])) (: distance (-> pt pt Real)) (define (distance p1 p2) (sqrt (+ (sqr (- (pt-x p2) (pt-x p1))) (sqr (- (pt-y p2) (pt-y p1))))))

Function type signature

slide-60
SLIDE 60

(: distance (-> pt pt Real))

This is a type signature Read this as…

pt pt -> Real

slide-61
SLIDE 61

Function types have the form

i1 i2 i3 … in -> output

Evocative of math Sometimes called “arrow types”

slide-62
SLIDE 62
  • > Int Int Int

How would we write this in C++

slide-63
SLIDE 63

(define-type Tree (U leaf node)) (struct leaf ([val : Number])) (struct node ([left : Tree] [right : Tree]))

slide-64
SLIDE 64

(define-type Tree (U leaf node)) (struct leaf ([val : Number])) (struct node ([left : Tree] [right : Tree]))

This is a union type

slide-65
SLIDE 65

A union type is a type that includes elements of two different types

slide-66
SLIDE 66

(define-type Tree (U leaf node)) (struct leaf ([val : Number])) (struct node ([left : Tree] [right : Tree]))

“Every element of type leaf is an element of type Tree” “Every element of type node is an element of type Tree”

The union type allows you to combine two different types

slide-67
SLIDE 67

Exercise: write a union type that allows strings or reals

(define-type Tree (U leaf node)) (struct leaf ([val : Number])) (struct node ([left : Tree] [right : Tree]))

Call it string-or-real

slide-68
SLIDE 68

I can also force Racket to check the types for me

(ann (+ 1 2) Number)

“ann” means “annotate” Exercise: produce a type error with this

slide-69
SLIDE 69

> (lambda (x) x)

  • : (-> Any Any)

#<procedure> > (lambda ([x : Number]) x)

  • : (-> Number Number)

#<procedure>

slide-70
SLIDE 70

> (lambda (x) x)

  • : (-> Any Any)

#<procedure> > (lambda ([x : Number]) x)

  • : (-> Number Number)

#<procedure>

Any means “can be any type”

slide-71
SLIDE 71

Typing rules and judgements

(This won’t be on exam)

slide-72
SLIDE 72

PL uses a fairly standard notation to write out what are called typing judgements This is a standard mechanism for mathematically defining type systems

slide-73
SLIDE 73

Assumption 1 Assumption 2 Assumption 3

Conclusion

The way to read this is “If everything above the line is true, then Conclusion is true”

slide-74
SLIDE 74

Conclusion

If nothing above the line, it means I don’t have to make any assumptions I.e., conclusion is vacuously true (don’t need to do any work to prove it)

slide-75
SLIDE 75

1 : Number

slide-76
SLIDE 76

2 : Number

slide-77
SLIDE 77

n : Number

Generally…

slide-78
SLIDE 78

Typing judgements

slide-79
SLIDE 79

x : Number, y : Number |- (+ 1 x) : Number

A typing judgement

Assumptions that certain variables have certain types

slide-80
SLIDE 80

x : Number, y : Number |- (+ 1 x) : Number

A typing judgement

Assumptions that certain variables have certain types Conclusion I have drawn about expression (involving variables on left)

slide-81
SLIDE 81

x : Number, y : Number |- (+ 1 x) : Number

A typing judgement

The thing to the left of the |- is typically called an “environment”

slide-82
SLIDE 82

x : Number, y : Number |- (+ 1 x) : Number

A typing judgement

“If I assume x has type Number, and I assume y has type Number, I can show (+ 1 x) has type Number”

slide-83
SLIDE 83

x : Number |- e : t

“Under the environment where x has type Number, I have concluded e has type t”

slide-84
SLIDE 84

x : Number |- e : t

(lambda (x) e) : -> Number t

slide-85
SLIDE 85

x : Number |- e : t

(lambda (x) e) : -> Number t

“If assuming x has type number allows me to conclude e has type t”

slide-86
SLIDE 86

x : Number |- e : t

(lambda (x) e) : -> Number t

“If assuming x has type number allows me to conclude e has type t” “Then I am allowed to conclude that…

(lambda (x) e)

Has type…

  • > Number t
slide-87
SLIDE 87

We won’t do this for Typed Racket, and doing so is nontrivial because it involves some elaborate types

slide-88
SLIDE 88

Type Inference

slide-89
SLIDE 89

> (lambda ([x : Number]) (+ 1 x))

  • : (-> Number Number)

Typed Racket will do this Why is this the return type? Why not (-> Number Any)?

slide-90
SLIDE 90

The process by which a programming language ascertains types of expressions by starting with a set of annotations

Type Inference

(Begin fair-game exam stuff again..)

slide-91
SLIDE 91

Most type systems require at least some programmer annotation

slide-92
SLIDE 92

Does Java have type inference?

slide-93
SLIDE 93

Does the C++ we’ve learned have type inference?

slide-94
SLIDE 94

C++17 actually adds (some) type inference

slide-95
SLIDE 95

template<class T, class U> auto add(T t, U u) { return t + u; } // the return type is the type of operator+(T, U)

slide-96
SLIDE 96

template<auto n> // C++17 auto parameter declaration auto f() -> std::pair<decltype(n), decltype(n)> // auto can't deduce from brace-init-list { return {n, n}; }

slide-97
SLIDE 97

auto a = 1 + 2; // type of a is int auto b = add(1, 1.2); // type of b is double static_assert(std::is_same_v<decltype(a), int>); static_assert(std::is_same_v<decltype(b), double>);

slide-98
SLIDE 98

http://en.cppreference.com/w/cpp/language/auto

More at…