[CSUSB] >> [CompSci] >> /pool/faculty/dick/cs320/sebesta/15

CS320 Notes on Functional Programming

 http://www.csci.csusb.edu/dick/cs320/notes/15.html
Also see
 http://www.csci.csusb.edu/dick/samples/lisp.html

Contents

	 Background
	 15.1 Mathematical Functions
	 15.1.1 Simple functions.
	 15.1.2 Functional Forms
	 15.2
	 15.3 LISP: context, data, and interpreter.
	 15.3.1 AI and List processing
	 15.3.2 McCarthy!
	 15.3.3 Data Structures.
	 15.3.5
	 15.3.9
	 15.3.10
	 15.4 LISP as a Language.
	 Note: Possible error in Book

Background

We are studying three language paradigms:
	Procedural		Algol, Pascal, C, C++
	Functional		LISP, SML, FP,...
	Logic			Prolog
	Object Oriented		Simula, Smalltalk, Java, ...

The long term impact of a language a language like LISP
is that writing the code develops a way of thinking about 
programs.  This leads to a methods for designing programs.  And finally 
into new ways of developing software and understanding problems.
We call this "a new Programming Paradigm".

Being able to think and understand things according to the different
paradigms is a valuable skill.  More valuable than being a language expert!

LISP lead directly to functional programming.  Christopher 
Strachey's 1966 scientific American paper clearly presents ideas that are 
named functional decomposition.
Functional decomposition was the dominant method of
program design from about 1975 to 1985.  

In the late 1980s - following Backus's endorsement
it has undergone a rebirth and several new languages have become widespread.
We will use LISP as a vehicle for practicing functional programming.

The book shows you a mathematical notation for FP (Functional Programming).
I will introduce you to an extended EBNF notation for expressing the 
mathematics in ASCII below.

Only recently have object-oriented
methods started to enter the mainstream.  Notice that inside
objects and classes there are functions.... and so functional
programming is not gone... it is just a part of a larger scheme
of things.

15.1 Mathematical Functions


15.1.1 Simple functions.


Note. It has become common practice in ASCII to show Greek letters as a back-
slash(\) plus their English name. This comes from the TeX language of Knuth.
        \alpha, \beta, ...\lambda.

EBNF Extended  becomes XBNF. XBNF can define functions:
	For x:real, square(x) ::= x.
See
	http://www.csci.csusb.edu/dick/maths/intro_function.html

Some examples -- defining the function that cubes a number.

        For x:real, cube(x)::=x*x*x.
The above says:   for all real values x, the cube of x is equal to x*x*x;

Or we have a \lambda like notation:
      cube = fun[x:real](x*x*x).

In general, if f is a function then
		f=fun[x](f(x)).
So
		(fun[x](E))(e) = `replace x by e throughout E`

15.1.2 Functional Forms


Functions can be combined:

For f,g:functions, 
	f o g::= ` The composition of g and f`.
	For all x, (f o g)(x)=f(g(x)).
        f o g ::= fun[x]f(g(x)).
	f o g = f(g((_)))

We can add a rule that we can use functions in expressions:
	f(g) ::=(f o g).
If we use (_) for the identity function then we can define `cube` by:
	cube = (_)*(_)*(_).

15.2


How do you do FP?

Its very like learning to program all over again. Skill comes from practice.
There are few tricks... but here are some useful hints:
	(1) Work top down, breaking down each function into
		other functions using conditionals, composition and
		predefined functions.

	(2) Use a conditional to separate out the simple cases and
		work these out first.  Keep looking for special
		cases with simple expressions.  Watch out for a
		smaller version of the same problem, or the re-appearance
		of another function.

	(3) Always use the form of the input to determine the conditions,
		but the form of the result guides the compositions applied.

For example, consider:   For x:list, reverse(c)::=`x backwards`...

	Clearly
		reverse(()) = ()

		reverse((x))= (x)

		reverse(x,...)=cons(reverse(...), x)

So define three cases x=NIL, cdr(x)=NIL, and other:
	For x:list, reverse(x) ::= (x=NIL->NIL | cdr(x)=NIL -> x
				else-> `put car(x) at end of reverse(cdr(x))`)
So the LISP is

	(define (reverse x)
		(cond 
			((null x) NIL)
			((null (cdr x)) x)
			( T (append (rev (cdr x)) (cons (car x) NIL )) )
	))

The typical LISP function has a definition like this
	(define (name arguments)
		(cond
			( (null argument)  simple_case )
			( (atom argument)  simple_case )
			...
			( T  (complex case))
		)
	)

The best way to learn is by doing it in the laboratory.

15.3 LISP: context, data, and interpreter.


15.3.1 AI and List processing


IPL :-(!
I have studied the IPL-V manual and it is probably the only language that is
worse than an assembler language.

15.3.2 McCarthy!

        Pure LISP
You have access to a modern and highly impure LISP system(xlisp). In class and
in homework and in quiz you should learn to stay within the Pure Subset.

15.3.3 Data Structures.


The book does not stress a key fact.

A LISP structure is defined to be (1) an atomic symbol, or (2) empty(NIL), or
(3) a pair of two lists, the first called the 'car' and the second called the
'cdr'. In short a list (if not NIL or atomic) is a pointer to a record:

Semantics of a List in C:
	typedef struct LIST
		{ enum{null,atom,pair} type;
		  union{
			char * null;
			char * atom;
			struct{ struct LIST * car, *cdr} list; 
		  }data;
	       	} * list;
Syntax of a List
	list::="NIL"|string|"(" car "." cdr ")" | "(" car cadr caddr cadddr...")"

A structure like (A B C) is encoded so that:

        (A B C).car=A,
        (A B C).cdr.car=B,
        (A B C).cdr.cdr.car=C,
        (A B C).cdr.cdr.cdr.car=NIL.
	car[(A B C)] = A.    (CAR (QUOTE ( A B C)))=A.
	cadar::=car;cdr;car.

	cons(x,y)::='construct pair with car=x and cdr=y'.

15.3.5

	\lambda done using (LAMBDA (args) expression) in our LISP
	::= done using (DEFINE (function args) expression) in our LISP.

15.3.9

	higher order functions
		Take functions and make new functions out of them.

15.3.10

	are we having FUNARG yet?


15.4 LISP as a Language.


The book does not emphasize 'Cambridge Polish Notation' used in LISP S
expressions. This is designed to make it easy to write the LISP interpreter.

You either learn it or have problems.

        expression::="(" function # actual_parameter ")" | atom|"NIL".
	actual_parameter::=expression.

        conditional::="(" "COND" #pair ")",

        pair::="("predicate expression")",

        predicate::=expression `that sometimes returns the value T`

Our LISP has been modified to have a scheme like syntax.
It originally only had the Common LISP form(DEFUN).

DEFINE is a common way to define a function.
        "(" DEFINE "(" name arguments")" expression")"

(DEFINE (FACTORIAL N)
 (COND ((EQ N 0) 1)
       (T (* N (FACTORIAL (- N 1))))
 )
)

'xlisp' also will ignore case outside strings so the following is easier to 
read:

(define (factorial n)
 (cond ((eq n 0) 1)
       (t (* n (factorial (- n 1))))
 )
)


(define (enigma n)
   (cond ( (evenp n) (/ n 2) )
	 ( T         (+ 1 (* 3 n)))
   )
)


Note: Possible error in Book

I'm not sure that APL is really a functional language.