- MORE TYPES
- STATIC VERSUS DYNAMIC TYPING
- TYPES IN HISTORY OF PROGRAMMING LANGUAGES

- What if S were a record instead of an n-tuple?

What is difference from an array? *Efficiency, esp. w/update.*

update f arg result x = if x = arg then result else f x

update f arg result = fn x => if x = arg then result else f xProcedure can be treated as having type S -> unit for uniformity.

set of elt_type;Typically implemented as bitset or linked list of elts

Operations and relations: All typical set ops, :=, =, subset, .. in ..

Why need base set to be primitive type? What if base set records?

tree = Empty | Mktree of int * tree * treeIn most lang's built by programmer from pointer types.list = Nil | Cons of int * list

Sometimes supported by language (e.g. Miranda, Haskell, ML).

Why can't we have direct recursive types in ordinary imperative languages?

OK if use ref's:

list = POINTER TO RECORD first:integer; rest: list END;

Recursive types may have many sol'ns

E.g. `list = {Nil} union (int x list)` has following sol'ns:

- finite sequences of integers followed by
`Nil`: e.g.,`(2,(5,Nil))` - finite or infinite sequences, where if finite then end with
`Nil`

Theoretical result: Recursive equations always have a least solution - though infinite set if real recursion.

Can get via finite approximation. I.e.,

listVery much like unwinding definition of recursive function_{0}= {Nil}list

_{1}= {Nil}union(int x list_{0}) = {Nil}union{(n, Nil) | ninint}list

_{2}= {Nil}union(int x list_{1}) = {Nil}union{(n, Nil) | ninint}union{(m,(n, Nil)) | m, ninint}...

list =

Union_{n}list_{n}

fact = fun n => if n = 0 then 1 else n * fact (n-1) factNotice solution to_{0}= fun n => if n = 0 then 1 else undef fact_{1}= fun n => if n = 0 then 1 else n * fact_{0}(n-1) = fun n => if n = 0, 1 then 1 else undef fact_{2}= fun n => if n = 0 then 1 else n * fact_{1}(n-1) = fun n => if n = 0, 1 then 1 else if n = 2 then 2 else undef ... fact =Union_{n}fact_{n}

In spite of that, however, it can be used in Computer Science,

datatype univ = Base of int | Func of (univ -> univ);

operations: `hd, tail, cons, length,` etc.

Persistent data - files.

Are strings primitive or composite?

- Composite (arrays) in Pascal, Modula-2, ...
- Primitive in ML
- Lists in Miranda and Prolog: provides more flexibility (no length bound)

- more readable
- Easy to modify if localized
- Factorization - why copy same complex def. over and over (possibly
making mistakes)
- Added consistency checking in many cases.

The variable can only hold values of that type. (Pascal/Modula-2/C, etc.)varx : integer {bound at translation time}

FORTRAN has implicit declaration using naming conventions

- If start with "I" to "N", then integer, otherwise real.

In either case, run real danger of problems due to typos.

Example in ML, if

datatype Stack ::= Nil | Push of int;then define

fun f Push 7 = ...What error occurs?

*Answer:* Push is taken as a parameter name, not a constructor.

Therefore f is given type: `A -> int -> B` rather than the
expected: `Stack -> B`

*Dynamic*: Variables typically do not have a declared type.
Type of value may vary during run-time.
Esp. useful w/ heterogeneous lists, etc. (LISP/SCHEME).

Dynamic more flexible, but more overhead since must check type before performing operations (therefore must store tag w/ value).

Dynamic binding found in APL and LISP.

- Type of variable may change during execution.
- E.g., may have
`x := 0`at one point and`x := [5,2,3]`at some other point, yet x is only declared once.

no characters or strings, no user-defined of any sort.

Arrays - at most 3-dim'l of built-in type. Subscripts begin at 1

Orig., restricted form of subscript expressions.

No records or sets. Many holes in typing.

Arrays of built-in types - no limit on dim'n, bounds any integers, semi-dynamic arrays

No records or sets. Strongly and statically typed.

Array [1..10, 'a'..'z'] of Real = Array [1..10] of Array ['a'..'z'] of RealUser fooled into thinking

Any discrete type as index.

No semi-dynamic arrays. Result of 2 principles:

- All types must be determinable at compile time.
- Array bounds are part of type.

Type of actual parameters must agree w/ type of formals

Therefore, no general sort routines, etc.

*The* major problem with Pascal

Procedure x(...;Fixed in (new) ANSI standard.procedurey;...)

:

y(a,2);

No checking if type of file read in matches what was originally written.

2. Problems w/ type compatibility

Assignment compatibility:

When is x := y legal? x : integer, y : 1..10? reverse?

What if **type** hex = 0..15; ounces = 0..15;

**var** x : hex; y : ounces;

Is x := y legal?

Original report said both sides must have identical types.

When are types identical?

Ex.:

Which variables have the same type?TypeT = Array [1..10] of Integer;VarA, B : Array [1..10] of Integer; C : Array [1..10] of Integer; D : T; E : T;

--> A, B and D, E only.

Structural not always easy. Let

T1 = record a : integer; b : real end; T2 = record c : integer; d : real end; T3 = record b : real; a : integer end;Which are the same?

Worse:

T = record info : integer; next : ^T end; U = record info : integer; next : ^V end; V = record info : integer; next : ^U end;

Ada uses Name Equivalence_{A}

Pascal & Modula-2 use Name Equivalence for most part. Check!

Modula-3 uses Structural Equivalence

Two types are assignment compatible iff

- have equivalent types or
- one subrange of other or
- both subranges of same base type.

e.g., type Boolean is (False, True)

Can overload values:

Color is (Red, Blue, Green) Mood is (Happy, Blue, Mellow)If ambiguous can qualify w/ type names:

Color(Blue), Mood(Blue)Subranges Declared w/range attribute.

i.e., `Hex is range 0..15`

Other attributes available to modify type definitions:

Accurate is digits 20 Money is delta 0.01 range 0.00 .. 1000.00 -- fixed pt!Can extract type attributes:

Hex'FIRST -> 1 Hex'LAST -> 15

declare k : integer := 0

type Two_D is array (1..10, 'a'..'z') of Realor "Unconstrained" (what we called semi-dynamic earlier)

type Real_Vec is array (INTEGER range <>) of REAL;

Of course, to use, must specify bounds,

declare x : Real_Vec (1..10)or, inside procedure:

Procedure sort (Y: in out Real_Vec; N: integer) is -- Y is open array parameter Temp1 : Real_Vec(1..N); -- depends on N Temp2 : Real_Vec (Y'FIRST..Y'LAST); -- depends on parameter Y begin for I in Y'FIRST ..Y'LAST loop ... end loop; ... end sort;Note Ada also has local blocks (like ALGOL 60)

All unconstrained types (w/ parameters) elaborated at block entry (semi-dynamic)

String type is predefined open array of chars:

array (POSITIVE range <>) of character;

Can take *slice* of 1-dim'l array.

E.g., if

Line : string(1..80)Then can write

Line(10..20) := ('a','b',.'c','d','e','f','g','h','i','j') -- gives assignment to sliceBecause of this structure assignment, can have constant arrays.