Você está na página 1de 8

Intro: Why Functional Programming?

In procedural/imperative languages (Pascal, C, . . . ) (based on Von


Neumann architecture) the basic unit is the assignment:
• get side effects: expression has different values each time evaluated,
depending on the state: current values of variables.
In (pure) functional language:
i. No side effects
– value of expression depends only on values of subexpressions
– value of expression is same each time it is evaluated (no “state”)

ii. Functions are first class objects


– can be passed as arguments
– can be value of expression

Note. ML is impure. We will use a (pure) functional sublanguage.

Advantages of all this?

• Practical: brevity and clarity of programs.


• Theoretical interest: λ-calculus is theoretical basis.

Two sorts of functional languages:


i. untyped (e.g. Lisp, Scheme): based on untyped λ-calculus
ii. typed (e.g. ML): based on typed λ-calculus

We will concentrate on (ii).

Two recomended dialects of ML:


• SML (Standard ML)
• MosML (Moscow ML)
2

Note. We recommend you work with MosML, a superset of SML which is


backwards compatible with SML.
However you are welcome to use any version of ML. (This will not affect
your solutions of homework or exam problems.)
Most of the examples here will use the MosML format. We will warn of
differences from SML occasionally, using a ‘∗ ∗ ∗’ symbol.

Types

Q. Why are (some) programming languages typed?

A. – To clarify our thinking


– To prevent errors
– To make compiling easier

Type checking may be

• static: during translation or compilation of program


• dynamic: during execution

Static checking is better — more efficient.

SML has static type checking.

Can think of types as sets (roughly):

a : T (a is an expression/object of type T ) means roughly


a ∈ T (a is an element of set T )
3

Types in ML
[ Reade, §1.3 ]

We want to generate:

• Type expressions T, T ′ , . . .
• Expressions E : T (E is an expression of type T )

First attempt (later extend and revise):

i. Basic or primitive types

int containing . . . , -2, -1, 0, 1, 2, . . .


bool containing true, false, . . .
string containing (e.g.) “hello”
real containing (e.g.) 1.0, . . .
(etc.)

Construct new types from old:

ii. Product types, containing tuples

(Type formation)

T1 is type . . . Tn is type (n ≥ 2)
T1 × · · · × Tn is type

(Tuples)
E1 : T1 E2 : T2 . . . En : Tn
(E1 , E2 , . . . , En ) : T1 × T2 × . . . × Tn
4

iii. Function types

(For sets: A → B = { f | f is a function, dom(f ) = A, ran(f ) ⊆ B }.)

(Type formation)
T1 is type T2 is type
T1 → T2 is type

(T1 is the domain type, T2 is the range type.)

(Application)
F : T1 → T2 E : T1
F E : T2

(more later)

iv. Conditionals

E1 : bool E2 : T E3 : T
if E1 then E2 else E3 : T

v. Lists or finite sequences


(For sets: A∗ is the set of all finite sequences from A)
(Type formation)
T is type
T list is type

(List construction: later)

Q. Why need both tuples and lists?


5

Predefined Functions in ML
[ Reade, p.16, Table 1.1 ]
Examples:

+ 


− 



∗ : int × int → int (infix)

div 




mod 

∼ : int → int








: int × int → bool (infix)
> 


<

not : bool → bool

andalso

: bool × bool → bool (infix)
orelse

even

: int → bool
odd

Important: = : ?

Also predefined constants:


0, 1, 2, . . . : int
true, false : bool

Note: In ML, the symbols +, −, ∼, ∗ are overloaded ,


since they also have type real (× real) → real .
In MosML, they default to int (× int) → int.
6

Function Definitions

A program in ML is just a series of function definitions.


There is automatic type checking and type inferencing .

Examples. To run MosML:


(Note: The system’s responses will be shown in italics.)
(Unix prompt) [%] mosml <enter>
Moscow ML version 2.01 (January 2004)
Enter ‘quit();’ to quit.

– 1 + 1;
> val it = 2 : int
(Note: This expression is treated as an implicit declaration of the pre-
defined variable ‘it’. So the value of the last top level expression evaluated
can be referred to by ‘it’.)

– 1 + (1.0);
! Type clash . . .
Note: No type coercion!

– fun double x = 2 ∗ x;
> val double = fn : int → int

– double 3;
> val it = 6 : int

– double true;
! Type clash . . .
– fun suc n = n + 1;
val suc = fn : int → int
– suc 3;
> val it = 4 : int
7

– triple 3;
! Unbound value identifier: triple
– fun plus(m, n) = m + n;
> val plus = fn : int ∗ int → int
Note: Overloaded operators like ‘+’ default to int!

∗ ∗ ∗ In SML, this would produce an error message:


. . . Error: overloaded variable cannot be resolved: +

and you would have to write something like:


– fun plus(m:int, n) = m + n;

Syntactic Errors

So far we have come across two types of syntactic errors:


• typing errors (“type clash” in MosML)
• undefined identifier (“Unbound value identifier ” in MosML)
In addition, in SML (but not MosML) there is
• overloading — We will ignore this!

Curried Functions

– fun plus c m n = m + n;
> val plus c = fn : int → int → int

Notes:

1. For m, n: int,
plus c m : int → int and
plus c m n = plus(m, n) = m+n.
8

2. ‘plus c’ is the curried form of ‘plus’.


All functions of 2 (or more) arguments can be in 2 forms:
uncurried or curried .

Conventions:

1. Application associates to left.


2. Arrows associate to right.
3. ‘∗’ binds more tightly than ‘→’.

Local Definitions of Functions


[ Reade §1.6 ]

(1) local fun sq x = x∗x


in fun sumsq(x, y) = sq x + sq y
end ;
Alt.
(2) fun sumsq(x, y) =
let fun sq u = u∗u
in sq x + sq y
end ;

Note: In both cases, scope of local function is restricted to end of fun def.

Notes:

1. To exit from SML: <control> D


2. To preserve a program (i.e. a series of defs), store it in a file (“script”)
and load it by:
– use "<file name>";
3. To comment: (∗ . . . ∗)

Você também pode gostar