Philosophy:
Computation is functional (map values to values(has type, sit in space), or map space(equivalent of type, values) to space)
Programming is an explanatory linguistic process
Imperative: execute command -> give effect Functional: evaluate function, has no effect
explanatory: write specs in terms of input and output, and will make sense
parallelism: parallel processing
Span: running time if you have infinite processors (combine value takes time), longest critical path Type: a prediction about the kind of value an expression will have if it winds up reducing to a value Type Error: catch things before run-time (do type checking before evaluation) (ML compiler does that) Compound Type (connectives): build types from other types Value: most simplified form of an expression Well-typed (type-checks): if an expression has at least one type
Standard ML (SML): pure fragment (pure = effect-free) REPL: command line feedback in real time
ML Expression:
\hat{}: string concat ("a"^"b" -> "ab")
:: has type (e has type t)
\hookrightarrow evaluate to (e evaluate to ...)
\Rightarrow reduce to (e reduce to e)
\simeq expression equivalence (two expression can swap)
\sim negative
Well-formed ML expression e
:
has type t
: e : t
may have a value v
: e |-> v
may have an effect such as printing, error (not for effect free fragment)
Well-typed expression may have no value: eg. 5/0, f(x) = f(x)+1
infinite loops are well-typed
a function that gives exception is still well-typed
Expression equivalence:
Example:
Basic Types: int
, real
, bool
, char
, string
Constructed Types:
product types: a combination of types (expressed by tuple)
function types
user-defined types
[1, 2, 3, 4]
is a value
[1+1 ,2, 3]
is an expression
note ((3, 1.1), Ture) : (int * real) * bool
but (3, 1.1, True) : (int * real * bool)
Type has:
name
value (a range of value)
operation
typing rules
reduction rules (evaluation rules)
Type of function: t1 -> t2
if t1
, t2
are types
A -> B
takes arguments of type A to result of type B
Value of function: functionTotality: f
is total if f(x)
return a value for all value x
in X
. (for every argument)
exception are not total
infinite loop are not total
second binding of x "shadows" first binding
first binding has been shadowed
The important lesson here is that function only know variables before the function is created. So if you have a variable in a function, and the variable is changed at a later time, the function will still use the variable as if it is unchanged. See below code:
sml Standard ML of New Jersey (64-bit) v110.99 [built: Tue Feb 09 08:36:14 2021] val x = 1; (* val x = 1 : int *) fun add (a : int) : int = x + a; (* val add = fn : int -> int *) add 1; (* val it = 2 : int *) add 2; (* val it = 3 : int *) val x = 2; (* val x = 2 : int *) add 1; (* val it = 2 : int *) add 2; (* val it = 3 : int *)
lambda function: function meat that is actually a function function
environment: context that has a list of variables that can be used within a function
Table of Content