Lec 2: functional programming 2
Computer Science
It is the wrong name for our field. It is not a science and it is not about computers.
Scientists ask questions about how the world works. For the most part what we do it more like engineering. We take as given how the world works and build software. It's not entirely true but generally it's the building not the finding out that's important.
Computer programs are abstract things which obey a fundamental set of rules. Some problems cannot be solved by computer programs.
The other side to this is computers. The field which is concerned with computers is electrical engineering. They worry about how the computer fundamentally works.
We are software engineers. But that term is taken by an ideology and comes with baggage so we are left with computer scientist.
Another thing we can call our field is complexity engineering. Because as computer scientists or software engineers we control complexity.
We control complexity by hiring 5000 programmers. But this doesn't work very well. Another way to do this is to create programming paradigms. Each of which can fit in your head if the complexity behind them cannot.
Paradigms
4 key programming paradigms:
- Functional
- Object orientated
- Client Server
- Declarative / Logical
In reality you build programs from taking bit of all the above and pulling them together as needed, but for now it's good to learn all of them as distinct paradigms.
Abstraction
- Application
- Higher level language (scheme)
- Low level language (c)
- Machine language / architecture
- Logic Gates
- Transistors
- Quantum Physics
What is a function?
0 or more inputs and 1 output.
You will always get the same output when you put the same input in.
Why use functions?
- Functions are well understood by theoreticians: You can prove theorems with functions.
- Computers do more than one thing at a time. A function does not rely on state outside of itself, it is completely self contained. So it is optimized to run as a self contained unit which is useful when parallelizing processes.
Difference in functions
A function can be the same as another yet use a difference procedure.
So for any input you will get the same output between both functions, but the steps taken are different.
True for all values of x.
- Same functions: because all we care about it output.
- Different procedures: steps taken were different.
Inside a computer there aren't really any functions. There are only procedures. Collections of steps, an algorithm to compute the function.
Often function and procedure are used interchangeably. But in some cases it is worth pointing out their difference.
When is a function not a function?
If there is a free variable in the function which comes in from outside of the function and isn't an argument to the function, then it's not a function. It's still a procedure, but what it computes isn't a function because it doesn't always produce the same answer.
Buzz game
Rules
- Count upwards
- If your number is divisible by 7 you have to say buzz.
- If your number contains a 7 you have to say buzz.
Buzz(1) = 1
Buzz(7) = Buzz
Buzz(8) = 8
Buzz(17) = Buzz
Cond keyword
This is like a case conditional in other languages.
(cond clause clause ...)
What is a clause?
(test action)
Which is often the following...
((function argument) (function argument))
Bringing this all together we get the following...
(define (buzz n)
(cond ((equal? (remainder n 7) 0) 'buzz)
((member? 7 n) 'buzz)
(else n)))
Normal Vs. Applicative order
If you write purely functional programs you get the same outcome no matter which evaluation order you use.
As soon as you start using procedures which aren't functional the order matters to the computer.
Types of order
- Applicative: Evaluates argument sub expressions first then call the function
- Normal: Evaluates arguments only at the point they are used
Function definitions
(def (f a b) (+ (g a) b))
(def (g x) (* 3 x))
Applicative order
(applic (f (+ 2 3)(- 15 6)))
(f (+ 2 3)(- 15 6))
(+ 2 3) ===> 5
(- 15 6) ==> 9
(f 5 9)
(+ (g 5) 9)
(g 5) ---->
(* 3 5) ===> 15
(+ 15 9) =====> 24
24
(normal (f (+ 2 3)(- 15 6)))
(f (+ 2 3)(- 15 6)) --->
(+ (g (+ 2 3))(- 15 6))
(g (+ 2 3)) -------->
(* 3 (+ 2 3))
(+ 2 3) =======> 3
(* 3 5) ============> 15
(+ 15 9) ==============> 24
24
For these two functions you get the same answer when evaluating in normal and applicative order. This is because they are both purely functional.
Order with non functional functions
(def (zero x)(- x x))
(applic (zero (random 10)))
(random 10) ===> 8
(zero 8) ---------->
(- 8 8) ===========> 0
0
(normal (zero (random 10)))
(- (random 10) (random 10))
(random 10) ===> 7
(random 10) ===> 8
(- 7 8) =======> -1
-1
Random is a procedure which is not a function.
If you call random with the same argument you do not always get the same answer.
If you write correctly functional programs you get the same answer no matter the evaluation order you use.
"Functional programming protects you from having to think about whats going on when inside the computer".
Projects for post lecture
- Create a pig latin generator
- Create the Buzz game