CS145
CS145
CS145
September-14-10
12:35 PM
RedExp:
Reduce Expression
Eg. (+ 1 1)
REPL:
Read, Evaluate, Print Loop
( + 1 1)
Adds 1 and 1
(+ 1 2 3 4 5 )
Adds 1 through 5
(* ( + 1 1) 2)
s-expressions or RedExp
Function notation
CS 145 Page 1
Models of Computation
September-17-10
2:48 PM
Can compute any computable result. However, some programs are impossible to compute on a
Turing machine, such as the halting problem - whether a given program with halt on a given input.
- Calculus
Invented by Church
A very simple method of expressing functions.
Syntax: A -expression:
x
(variable)
(
are - expressions)
x e (function with variable x e is a -expression) - x is substituted into function
Ex. (x X y z) w w y z
x y x
"true"
x y y
"false"
"If true then a else b"
(x y x) a b (y a) b a
(x y y) a b (y y) b b
(t a b t a b) (Condition If_true If_false) "if"
(x x x) (y y y)
"infinite loop"
Combinator Theory
Using 3 functions, K, S, and I.
You can write any function with just K, S, and I
Combinator expression:
K
S
T
CS 145 Page 2
11:27 AM
Factorial
( )
Tail Recursion
(
,n
(define (fact n)
(cond
[(= n 0) 1]
[true (* n (cond (- n 1)))]))
In scheme:
(sgn -10) ;; -1
(sgn 10) ;; 1
(sgn 0) ;; 0
Define new signum function:
;; signum: number -> number
;;returns -1 if number is negative; +1 if positive; 0 if 0
;; example (signum 99) is 1
(define (signum n)
(if (< n 0) -1
(if (> n 0) 1 0)))
;; returns m k!
(define (fact-times m k)
(cond
[(= k 0) m]
[else (fact-times (* m k) ( - k 1))]))
The advantage to the second function is that it
keeps the expression constant. (fact n) produces
an expression of size n.
(signum -876);; -1
(signum 0);; 0
(signum 77);; 1
Complexity
Number of steps for factorial:
a + bn
Linear time algorithm
Digits
;; digits: number -> number
;; returns the number of digits in a given number
(define (signum n)
(cond
[(< n 0) -1]
[(> n 0) 1]
[(= n 0) 0])) or [else 0]))
(digits 2146); 4
(digits 0); 1
(digits 42) ;2
(define (digits n)
(if (< -10 n 10)
1
(+ (digits(quotient n 10)) 1)))
CS 145 Page 3
Ex.
(define (fibo n)
(case
[(= n 0) 0]
[(= n 1) 1]
[else (+ (fibo (- n 1)) (fibo (- n 2)))]))
Data Structures
September-21-10
Quadratic Field
+
12:41 PM
(define (mult-qf a b)
(if (= (quadratic-field-r a) (quadratic-field-r b))
(make-quadratic-field
(+ (* (quadratic-field-a a) (quadratic-field-a b))
(* (quadratic-field-b a) (quadratic-field-b b) (quadratic-field-r a)))
(+ (* (quadratic-field-a a) (quadratic-field-b b))
(* (quadratic-field-b a) (quadratic-field-a b)))
r)
0))
Fronks
Franks
3
(define (add-qf a b)
(if (= (quadratic-field-r a) (quadratic-field-r b))
(make-quadratic-field (+ (quadratic-field-a a) (quadratic-field-a b))
(+ (quadratic-field-b a)(quadratic-field-b b))
r)
0))
Structures are new data types and will be incompatible with most other premade functions.
42
7
2 nums:
c3
3 nums:
c2
1
c1
'hello
'there
Binary Tree
(define (bunch-many n)
(cond
[( = n 2) (make-bunch-pair 1 2)]
[else (make-bunch-pair (bunch-many (- n 1)) n)]))
(define (bunch-union b1 b2) (make-bunch-pair b1 b2))
;; is e a member of b?
CS 145 Page 4
Tree
Tree
Builtin type:
DrRacket - empty
Anything else - null
;; is e a member of b?
(define (bunch-member? e b)
(cond
[(and (number? (bunch-pair-a b)) (= e (bunch-pair-a b))) true]
[(and (number? (bunch-pair-b b)) (= e (bunch-pair-b b))) true]
[(and (bunch-pair? (bunch-pair-a b)) (bunch-member? e (bunch-pair-a b))) true]
[(and (bunch-pair? (bunch-pair-b b)) (bunch-member? e (bunch-pair-b b))) true]
[else false]))
CS 145 Page 5
Efficiency
September-24-10
2:30 PM
Examples:
( )
+
- linear
( )
+ - exponential
( )
lo
- logarithmic
( )
+
+ - polynomial time
( )
+
"More Efficient"
b is more efficient than a if for all C
such that n
( )
( )
o (little-oh)
is ( )
( )
is
( )
( )
+
is (
"More Efficient"
( )
+
( )
+
+ )
max(
+ )
[because n
If f(x) is ( )
2f(x) is ( )
( ) + is (
+
+
)
+
( )
CS 145 Page 6
[
+
(
+ )
( )
11:46 AM
Binary Tree
Empty or
t1
t2
Notation:
- empty
- one node
Note:
No overloading in Racket
Overloading is defining more than 1 function
with the same name, determine correct one by
# and type of parameters.
Order in Trees
a<b<c<d<e
n - k - 1 nodes
k
n nodes
Linear Trees
Right Linear
Infix-ordered tree
or Binary Search Tree
Tree
{}
{a}
a a
{a, b}
Can reduce the number of tree combinations by using a linear tree (right linear tree)
Down to n! ways of representing a set.
Suppose we have a total orderin Then we can represent as an ordered linear tree - 1 possibility
CS 145 Page 7
12:39 PM
List Construction
Empty or
(cons x list)
(list 10 20 30)
produces 10 -> 20 -> 30
In racket
(first x) is (car x)
(rest x) is (cdr x)
(car (cdr (cdr q)))
(caddr q)
CS 145 Page 8
Trees - Searching
Binary Tree
September-30-10
11:31 AM
N = 99 yes
N = 77 no
If so, give me the node (aka, give me the subtree rooted at the node.)
Abstract
The tree represents the set S= {1, 2, 5, 6, 10, 15, 99}
Is n S
If S is a decorated binary tree
(define-struct node (left right key))
(define (tree-member t n)
(cond
[(empty? t) false]
[(= n (node-key t)) true]
[(tree-member (node-left t) n) true]
[(tree-member (node-right t) n) true]
[else false]))
Or
(define (tree-member t n)
(and (not (empty? t))
(or (= n (node-key t))
(tree-member (node-left t) n)
(tree-member (node-right t) n))))
This search takes linear time in the size of the tree
(define (tree-member t n)
(cond
[(empty? t) false]
[(= n (node-key t)) true]
[(< n (node-key t)) (tree-member (node-left t) n)]
[else (tree-member (node-right t) n)]
This search takes linear time in the height of the tree.
From linear to logarithmic in n
Building Trees
empty
(make-node . (make-node (.. )) )
AVL Tree
A near-min height binary search tree
Pseudo-Function
(random n) some int in [ n)
Insert: 2.5
Delete 2
Reuser Functions
When combining tree, link to the tree as a whole without re-building the
entire tree.
Only have to build "spine" of tree, all of the branches off of it can be reused.
Delete min of 4-> (3, 5)
CS 145 Page 9
Midterm Topics
October-01-10
2:30 PM
Test
Not Test
Scheme expressions
Substitution
Variables
Functions
Counting Evaluation Steps
Structures and Types
Trees (Including linear trees)
Counting Trees
Building, Searching, Combining, and Destroying Trees
Models of computation
Lambda calculus
Asymptotic Analysis
Lists
CS 145 Page 10
Types of Trees
October-01-10
2:39 PM
Balanced Tree
Size-Balanced
A tree is balanced if there are the same number of nodes on each side of a node ( 1) and all sub -trees are balanced.
Path-Balanced
The shortest path from root to node is
Perfect Tree
nodes and min height
Complete Tree
A path-balanced tree such that the left sub-tree must be at least as big as the right sub-tree.
AVL Tree
A height-balanced BST
Heap (Min-Heap)
Complete tree + height ordered (not BST)
Every node is greater than its parents.
Deleting from a heap:
Remove top, promote the lowest node from its two children and repeat.
Finally, move leafs laterally until the heap is complete
CS 145 Page 11
AVL Tree
An AVL tree has the invariant:
BST
Height Balance
11:28 AM
Modules
Big-Oh Notation
( )
g is asymptotically no larger than f
( ) means O(f)
f is asymptotically no smaller than g
( ) means
(g) and
Definition of O(f)
f(n) O( (n)) if
c
f(n) c
(n)
( )
Imported via:
(require "avl-cs145.ss")
When building a module must use full language
(provide insert-avl delete-avl node-left etc)
The AVL Tree is opaque
Cannot print the tree
Cannot make-node (forgery)
Cannot change avl-tree (tampering)
Modules help reduce the complexity of your code by separating it into manageable chunks. For n
lines want approximately
modules with
Testing
Use beginning student with list abbreviations
Use Version 1.1 of av1-cs145.ss
Test!
Assignment - Implement a "set" abstract data type
~10 things to implement (functions + helpers)
Unit test:
Test each small section of code individually
Then start to test groups of code.
(check-expect (+ 1 2) (- 4 1)) <- Magic pseudo function
) etc.
(
(
+
So
is (
( )
)
Disproving:
foo bar (For all variable boolean)
foo
Significant Orders
O(1) - Constant Time
O(n) - Linear Time
O( ) - Quadratic Time
CS 145 Page 12
( )
O( ) - Quadratic Time
O( ) - Polynomial Time
O( )
O(lo ) - log
CS 145 Page 13
Functional Abstraction
October-07-10
11:30 AM
Function expressions:
Lambda Calculus
(define (myempty? l)
(if (empty? l)
mytrue
myfalse))
;; map lambda list
(define (mymap f l) (myif (myempty? l)
empty
(mycons (f (myfirst l))
(mymap f (myrest l)))))
(define a (mycons 2 (mycons 3 empty)))
(mymap add1 a)
CS 145 Page 14
Can be represented by a list of pairs. For a directed raph the pair (A B) means A B
October-14-10
To remove duplicates
(define (dedupe l)
(foldr (lambda (x y) (if (or (empty? y) (not (symbol=? x (car y))))
(cons x y)
y))
empty
(sort l symbol<?)
11:34 AM
(define (symbol<? a b)
(string-cis? (symbol->string a)(symbol->string b)))
Syntax of foldl
(foldl [function] [identity] [list])
Eg. (foldl + 0 (list 1 2 3))
Eg. (foldl max -inf.0 (list 1 2 3))
Sorting
(sort )
Ex.
(require "avl-cs145.ss")
(define (mysortd l)
(listavl (foldr (lambda (e s) (insertavl s e))
empty
Insertion Sort
(define (insert e l)
(cond
[(empty? l) (cons e l)]
[(> e (car l)) (cons (car l) (insert e (cdr l)))]
[true (cons e l)]))
(define (myinsertsort l)
(foldr insert empty l))
Invariant for Insertion Sort:
1. Elements in current + result = elements in input
2. Result is ordered
Ex
Current
Result
(2 6 3 9)
()
(6 3 9)
(2)
(3 9)
(2 6)
(9)
(2 3 6)
()
(2 3 6 9)
Selection Sort
Invariant - the same
Take the largest element in current and add it to the result
Current
Result
(2 6 3 9)
()
(2 6 3)
(9)
(2 3)
(6 9)
(2)
(3 6 9)
()
(2 3 6 9)
Merge Sort
Invariant:
1. Union of the sub-lists is equal to the input list
2. Elements in each sub-list are sorted
Steps
Result
CS 145 Page 15
((2 6) (3 9))
(( 2 3 6 9))
Streams
(define ff (+
(define (f) (+
)) - is evaluated immediately
)) - is evaluated when (f) is called
CS 145 Page 16
11:39 AM
Using gedit
Evil
Pseudo-functions
Ex. (random 10) ; magic
-procedural, not functional programming
(read) - implements a stream: input
Needs input to be of the form of a scheme expression
RunC gedit
Runtime plugin (ctrl-R)
"This software runs on Linux and it runs on Mac. It does not run on
Windows. You say 'wait a minute, I'm addicted to Windows.' Get over it."
More Evil
Assignment
(define x 3)
(set! x 4) <- changing the value of the variable x
Pure Evil
Mutation
(define-struct foo(a b) #: mutable #:transparent)
(define f (make-foo 1 2))
(define q (list f f))
(foo-a f) ;1
(foo-b f); 2
f ; (foo 1 2)
q; (list (foo 1 2) (foo 1 2)
(set-foo-b! f 42)
f ;(foo 1 42)
q; (list (foo 1 42) (foo 1 42))
(set-foo-a! f f)
q; (list #0=(foo #0# 42) #0#)
CS 145 Page 17
Data Structures
October-21-10
12:36 PM
Copy
Exercise (define copy t)
(generate
))
(define (tcopy t)
(cond
[(empy? t) empty]
[else
(make-node (node->data t)
(tcopy (node-left t))
(tcopy (node-right t)))])
Without recursion, keep a list of all the nodes stepped through from the top to the bottom
This would be a stack
Models of Computation
Finite state machine - finite stream
Finite state machine + stack push down automaton
Finite state machine + stacks Turin machine
Queue
Cons - front of list
Snoc - end of list
ADT Queue, will have mutable head pointer and mutable tail pointers
CS 145 Page 18
C - RunC
October-26-10
11:30 AM
RunC
Ctrl-R to run
Ctrl-V when you're done
#include<stdio.h>
int main()
{
int c;
c = getchar();
printf("The answer is %d.\n", c);
}
Character encoding in ASCII - 7bit
Type man ascii to see the table (in terminal)
Other character encoding:
BCD - 6bit
EBCDIC - 8bit
Ctrl-D is -1, or EOF
Comments
/* This is a comment
That spans multiple lines*/
// This is a single line comment
Functions
int mydouble(int x)
{
return x * x;
}
Modules
Specification and Definition (header)
Specification
mydouble.c
int mydouble (int x)
{
return x * x;
}
Header
mydouble.h
int mydouble(int x);
Including the Module
#include "mydouble.h"
CS 145 Page 19
Computer Architecture
October-26-10
12:14 PM
Byte
8 bits - each bit is 2 states
RAM
Stack of bytes with addresses
Operations on RAM:
Fetch: Returns a byte stored at an address
Store: Stores a byte in an address.
Typically there are addresses
- old, 16 bit
, 32 bit
, 64 bits
ram.ss
ram-init b ;; creates a new RAM with b-bit addreses
ram-fetch ram addr ;; fetches byte at addr from ram
ram-store ram addr byte ;; new ram with byte stored at addr
ram implementation is fairly similar to generate, but initial state is RAM and no result
use standard input/output
Byte Representation
Unsigned Integer 0 - 255
Signed - Two's Compliment -128 to 127
( )
( )(
)
(
)
Little Endian
1 0 1 0 1 0 1 0 (1 + 4 + 16 + 64)
Big Endian
1 0 1 0 1 0 1 0 (128 + 32 + 8 + 2)
When declaring variables, the names represent memory addresses. - Environment
In C a statement like
fib1 = tmp + fib1 + 1 is broken into:
tmp1 = tmp + fib1
tmp2 = tmp1 + 1 (where 1 is saved as a literal in ram)
fib1 = tmp2
When using a 4-byte word to represent an integer, you essentially have a base 256 number.
Can store values from
CS 145 Page 20
C Program
October-28-10
Libraries
#include <stdio.h>
#include <stdlib.h>
malloc is included in stdlib
A procedure in C:
int foo (int x){
int a = x + 1
return x + a;
}
C Memory Organization
Given a RAM
C divides the RAM into 4 sections:
Literal Pool
Static Variables
Stack
Heap
Data Storage
Literal Pool
Is where literals (e.g. numbers and explicit strings) are stored for computation
Static Variables
Location of variables that are not declared inside any procedure. The variable does not move, it is
persistent.
int a; when outside of a function/procedure will be saved here
Stack
Location for frame allocation. In the stack, frames are allocated sequentially.
int a; when inside a function/procedure will be saved here
Heap
General purpose data structures.
Accessed using malloc
ex: a = malloc(10)
-finds 10 bytes and returns the address
Memory is returned by free(a)
Memory must be freed!
int * a = malloc(sizeof(int)); will be saved in the heap
Program
Translation of C code.
Pointers
int * x; x is a pointer to an integer
x = malloc(sizeof(int));
*x = 42; (sets 42 to the memory location of x)
x = 42; (sets x to 42 - in other words *x will point to the memory location of 42)
CS 145 Page 21
CS 145 Page 22
Tutorial
October-29-10
Parts of a C program
2:44 PM
Directive
#include <stdio.h>
Compiler pastes stdio.h into your program
Declarations
int x;
Static storage in RAM
static int x;
If don't use static, if you compile the file with static int x; with another file, when you declare int x;
in the new file they will be treated as separate variables - if don't use static, they will be the same
Similar in idea to (do not provide x) - if such a function existed
Compilation
Compilation takes a bunch of .c files and runs them through a compiler (GCC) and outputs and
executable image. (.exe on windows) - Machine Code or Binary Code
The executable image is run through a loader and loaded into RAM. Then the CPU executes it.
Linking
Combining multiple executable image files.
Bootstrapping (Booting)
Aka IPL - Initial Program Load
The loader is run by a further smaller loader, that is loaded by a further smaller one, etc. Until get to
a hardcoded loader (in ROM often)
Image files created from all the .c and .h files reachable through include.
Image files is saved as a, but can be overridden with -o [name]
gcc bar.c foo.c bif.c baf.c -o x
Will create x, a executable image file with bar.c, foo.c, bif.c, and baf.c
Run with ./x
Other gcc flags: --std=c99
With RunC , after loaded into RAM, valgrind loads the file
Valgrind will prevent your program from using uninitialized RAM
Valgrind runs much slower than bare machine code, the price of security.
Computer History
Stored program computer
John van Neumann
The concept of saving the program in RAM
Jaquard, invented the programmable loom using punched holes
Player Pianos operate on a similar concept
Charles Babbage, Ada Lovelace
Creator of the Difference Engine and the Analytical Engine
Ada Lovelace programmed for these engines.
1920-1930
Telephones / Switches
Discovered you could construct mechanical relays. Used for amplification - low amount of power to
an electromagnet could close a switch allowing more power through the relay.
Latch, relay which stays in the last position it was set to. A bit
Delay line: A relay connected to a loop, sends current through the loop, when the current returns it
triggers the repeater and sends another pulse of current through the loop. Also known as a shift
register.
A modern possible alternative for solid-state RAM is to use a light-based delay line.
CS 145 Page 23
A modern possible alternative for solid-state RAM is to use a light-based delay line.
Claude Shannon
At MIT. For master's degree he discovered a way to simplify switches with boolean algebra.
Went to work for AT&T, and WWII happened. He invented a science known as information theory.
RAM storage with CRT. When the electron strikes the phosphorous screen, it will dislodge an
electron which is collected. If, however, light is shining on the phosphorous, the electron will not be
emitted.
Display all the dots with the CRT - light or dark. Then repeat to check to where the screen is lit.
CORE RAM
A grid of wires with a magnetic core at each intersection. Can pass current through the wires to
magnetize the magnetic core in one of two directions.
Modern Ram
Static Ram
A huge array of latches
Expensive but fast
Dynamic
Similar to CORE RAM, but uses capacitors instead of magnetics cores.
Dynamic because the memory is not saved long, instead the memory is constantly read and rewritten.
CS 145 Page 24
More C
November-02-10
Variables
11:32 AM
.c and .h
In .c have
directives and declarations
int x;
int *p;
0 or NULL
*p = malloc(sizeof(int));
malloc returns uninitialized memory in the heap
Procedures
int foo(int a, int b, int *c)
{
[local declarations and statements]
int q;
-4 bytes on the stack (in a frame)
q = 42;
printf("%d\n",q);
static int z;
z is stored in static memory, however it is still local, can only be accessed by foo
z is initialized to 0. So doing something like this lets you keep a counter for how
many times a function is called or keep a value between multiple calls of a function.
int *w;
w = &z;
printf("%p\n", w);
Statements (Imperative)
Assignment: x = e;
Evaluates the expression e and stores it in the memory location of x
e can be a constant, a variable name, a function call, expressions combined by operators
Boolean: false = 0, true = not zero
equality check (NOT
Logical:
&& - AND operator. Uses short-circuit evaluation
|| - OR operator. Also uses short-circuit evaluation
Bitwise:
& - Bitwise AND
| - Bitwise OR
^ - Bitwise XOR
<< - left shift,
shifts
bits to the left
>> - right shift,
shifts
bits to the right.
When shifting to the right, the signed bit is replicated on the left as new bits
The type of shifting depends on whether the number is signed or unsigned.
Expressions
*e
pointer dereference
&e
address of
+e
-e
!e
[ ]
[ ]
( + )
Control Structures
If
if (e) [statement]
else if ( ) [statement]
else if ( ) [statement]
else [statement]
Each successive if is a new if/else statement
However, suppose you wanted one of the [statements] to be an if statement. Where does the next else
match up to?
CS 145 Page 25
match up to?
if (e) if(foo) [statement] else; // else; does nothing but clarifies the usage of else
else if ( ) {if (bar) [statement]} // enclosing in braces also work.
else if ( ) [statement]
else [statement]
If/Else if structure:
if (e ) {
} else if(){
} else if (){
}else {
}
While
while (e ) [statement]
works like a generate statement over all of RAM
For
for ( ;
) [statement]
Equivalent to
while ( ){
[statement]
}
Common for idioms:
for (i=0; i < 10; i ++){
}
Do While
do [statement]
while (e)
Structures
struct foo{
int a;
int *p;
}; //MUST HAVE A SEMICOLON AT THE END
global declaration:
struct foo f;
- creates a structure in the static memory location.
f.a = 42;
f.a = f.a + 1; or f.a += 1
int bar(){
struct foo y;
y.a
}
If want to be lazy:
typedef struct foo myfoo;
myfoo ; struct foo x;
int a;
int *p;
} a, b, c; will declare a, b, and c to be struct foo in whatever location the code is written (static or frame)
CS 145 Page 27
Structures in C
November-04-10
11:31 AM
Linked List
struct node{
int data;
struct node *rest;
};
It is possible to declare
struct node *p; without the declaration of struct node in the given file.
Tree
struct node{
int data;
struct node *left, *right;
};
struct node *a = malloc(sizeof(struct node));
struct node *b = malloc(sizeof(struct node));
struct node *c = malloc(sizeof(struct node));
a->data = 3;
a->left = b;
a->right = c;
b->data = 2;
c->data=4
b->left = b->right = c->left = c->right = NULL;
could made this easier with:
struct node * make_node (int d, struct node *l, struct node *r){
struct node *temp = malloc(sizeof(struct node)); if returning memory use malloc otherwise the
frame will disappear and the memory will go with it. temp is on the frame, malloc is on the heap.
temp->data=d;
temp->left=l;
temp->right=r;
return temp;
}
struct node * t = make_node(3, make_node (2, NULL, NULL), make_node(4, NULL, NULL));
void delete_tree(struct node *t)
{
if (!t) // aka t==NULL
return;
delete_tree(t->left);
delete_tree(t->right);
free(t);
}
delete_tree(t); // must delete the tree before the program ends
struct node *x = make_node(42, NULL, NULL);
struct node *y = make_node (65, x, x); called sharing or aliasing
What happens when you try to delete y? x will be freed twice = bad
Can avoid this problem by not sharing or fixing delete
Fixing Delete:
Find all of the nodes that are reachable from t with no duplicates and delete those
Garbage Collection
Copy Collection
Break RAM into two parts, allocating new memory into one. Once that gets full copy everything into the
other - of course only that is reachable will be copied. Erase everything in the in the original area, repeat.
Requires identifying the root pointers (in C the root pointers are in the static and stack memory locations.
If something in the heap isn't reachable from those locations it isn't reachable at all)
In C there is no garbage collection - cannot move memory around.
In general, half of RAM will be usable before it starts to become slow to find new memory.
Object Oriented
struct foo { // or class
int x, y, z;
int double(int x) {return x + x} // Cannot say in C, can say in c++, called a method
}
struct bar extends foo{ //not real C/C++ syntax
int w;
}
CS 145 Page 28
}
Can do "object oriented" in scheme
(define (make-automobile steel plastic)
(define c (fabricate steel plastic))
(define (driveto city) )
(define (crush) )
(define (fill as))
(list driveto crush fill))
(define mycar s p)
((first mycar) 'Toronto)
Polymorphism
Templates, allowing you to use various types for the same purpose
CS 145 Page 29
Continuation Passing
November-05-10
2:34 PM
f is a continuation. A lambda that describes everything that remains to be done in the program.
CPS - Continuation Passing Style
(double 4 (lambda (x) (double x display)))
Steele's Masters Thesis Rabbit
Scheme turns every function you create into one of the CPS. It is possible to access the hidden
continuation function
(define (double x) (call/cc (lambda (c) (+ x x))))
(double 4)
>> 8
CS 145 Page 30
Data Types
November-09-10
11:30 AM
Types in C
short, long / int, long long, char
signed, unsigned
short - 16 bits / 2 bytes / -65536 to 65535
int - 32 bits / 4 bytes
long - 32 bits on 32-bit machine
- 64 bits on 64-bit machine
long long - 64 bits / 8 bytes
char - 8 bits / 1 byte / may be signed
char, signed char, unsigned char are all different types
getchar(); return int, not char
Returns -1 or something in 0-255
Casting
char c;
long i;
(long)c + i;
8 bits
23 bits
sign
exponent
binary fraction
-128 to 127
double: 64 bits:
1 bit
11 bits
52 bits
sign
Register
Can declare variables to be in the register
register int x;
Strings
'a' is an int
sizeof('a'); returns 4
char x = 'a';
char *s = malloc(10 * sizeof(char))
s[0] = 'h';
s[1] = 'i';
s[2] = 0;
h
\0
UTF-8
Variable length byte encoding for Unicode
8 bits, if first bit is 0 then the remaining 7 are an ASCII character.
If the first bit is 1, then there are more bytes, each byte has a 1 in front
if there is another byte used in the representation.
char *t = "hi";
this puts 'h', 'i', 0 in the literal pool
t points to the literal pool.
CS 145 Page 31
Stack Allocation
char x[10];
int y[3];
Will create memory locations in the stack
x is a char* and a pointer to 10 chars
char *p = x;
x[0] = 35; or 0[x] = 35; or *(x+0) = 35; or *x = 35;
The size of the stack frame is variable. Allowed to say something like
int y[n];
Works also in other memory locations:
global
char x[10];
static char x[10];
CS 145 Page 32
Strings
November-11-10
11:30 AM
Language
A set of strings
Have a string, is this string in the language L?
Finite state machines recognize regular languages.
Linear Grammar - have only left recursion or only right recursion.
A A a b c d or A A a b c d
regexp - regular grammar
If can answer with a stack, the language is called a context-free language (push down
automaton)
Remove the restrictions of recursion on the right
Context-sensitive language. Phrase structured grammar
N A hello B (replace then with A and B)
Unrestricted but size of left must be smaller than size of right
Two stacks: Turing machine, can do anything.
Unrestricted Language
Stick whatever on the left or on the right
NaBbCbNa
Strings
#include <string.h> // C strings, strings in general
char *x = "abc"; // literal pool
char q[] = "abc"; // stack
char *p = malloc(100)
p[0] = 'a';
p[1] = 'b';
p[2] = 'c';
p[3] = '\0';
Create string with 1000 a's
char *s = malloc(1001);
for (int i = 0; i < 1000; i++) s[i] ='a';
s[1000] = 0;
Read from input
char *s = malloc(1001);
int i, c;
for (i = 0; EOF != (c = getchar()); i++) s[i] = c;
s[i] = 0;
free(s);
// BAD, messes up with input greater than 1000 characters.
foo *q = realloc(p, n)
// p is a pointer, n is an integer - size of bytes
// malloc(n), copies everything in p to the beginning of q, frees p
in the previous for loop could say
if (i%1000 == 999)
s = realloc(s, i+1001)
However far more efficient to resize when
CS 145 Page 34
11:31 AM
ML
Stands for "Meta Language"
Designed for automatic theorem proving
Designed for LCF theorem prover
Robin Milner
Standardized in 1990, SML (Standard ML)
Forked in 1985: CaML - Categorical abstract Machine Language
Basis for F#
Implementation SML/NJ
Expressions
SML compiler has a REPL like DrRacket
Semicolons are used to tell the interpreter to evaluate the expression
They are used much more infrequently in programs
1+2;
> val it = 3 : int
Note the inference of the type
Declarations
val x = 1;
> val x = 1 : int
val y = 1.2;
> val y = 1.2 : real
x+3
> val it = 4 : int
fun sqr x = x*x;
val xqr fn : int int
We can add type annotations as needed
fun sqr (x : real) = x*x;
val sqr fn : real real
Ascription is useful in clarifying intent and debugging type errors.
ML has a fixed set of overloaded operators.
ML will use type variables for polymorphic functions
fun id x = x;
> id = fn : 'a -> 'a
val y = id 3;
> y = 3 : int
Functions in ML have exactly one parameter ("curried")
fun sumSqrs x y = x * x + y * y;
val sumSqrs fn : int int int
Tuples
val x = (true, #"z");
> val x = (true, #"z") : bool * char
There are selector functions for tuples, but they are usually deconstructed using petterns
Tuples can be used to group multiple parameters to a function
fun add(x, y)= x + y;
val add fn: int * int int
Here (x, y) is a pattern
add is the same as op +
There aren't 1-tupes but the 0-tuple () handy
Its the sole value of the type unit the equivalent of # void in Scheme
Binary tupled functions can be made into infix operators.
infix add;
> infix add
3 add 4;
> val it = 7 : int
We could also have done it this way
infix add
fun (x add y) = x+y;
CS 145 Page 35
Lists
[1, 2, 3];
> val it = [1, 2, 3] : int list
1 :: 2 :: 3 :: [];
> val it = [1, 2, 3] : int list
[1] @ [2, 3];
> val it [1, 2, 3] : int list
Ampersand is append, :: is concatenate
fun append([], ys) = ys
| append(x::xs, ys) = x:: append(sx, yx);
val append fn: 'a list * 'a list 'a list
Local definitions
fun split [] = ([], [])
| split [a] = ([a], [])
| split (a::b::cs) =
let
val (mx, nx) = split cs
in
(a::ms, b::ns)
end
Mutual recursion
fun
oddlen [] = false
|
oddlen (x::xs) = evenlen xs
and
evenlen [] = true
|
evenlen(x::xs) = oddlen xs
Exceptions
The handler must produce a value of the same type as the expression to which it is attached
exception DivByZero;
fun safeDif (_, 0) = raise DivByZero
| safeDiv (x, y) = x div y;
val quot = safeDiv (3, 0) handle DivByZero => 0
A similar mechanism is provided in Racket
I/O
the ML standard basis library proveds many I/O functions.
We will mention only one here:
print "Testin \n";
Reference Types
Like Scheme, ML is not pure, but mutation is used sparingly
the data constructor ref provides the equivalent of boxes in Scheme
val x = ref 5
> val x = ref 5 : int ref
val y = !x
> val y = 5 : int
x := y + 1;
> val it = () : uint
Types
Type errors in ML often appear incomprehensible.
Sometimes we are prevented from writing code in a fashion that seems natural to us because of
restrictions in the type system.
In order to understand how the ML compiler does type inference, we add types to the lambda
calculus.
This was first done by Church in the 1930's, but we use a style closer to that of Curry's work in the
same period
CS 145 Page 37
Logic
the statement "From the set of propositions we can prove the proposition
A proof is a tree built from applications of inference rules.
Strong Normalization
When we try to type the Y-combinator, we run into problems
Consider typin x.xx
Just because we cannot type self-application doesn't mean we can't do recursion in some other
fashion.
However, the strong normalization theorem suggests that the simply-typed lambda calculus is a
weak model of computation - not Turing Complete
Theorem
Every reduction sequence of every well-typed term of the simply-typed lambda calculus is of finite
length
To gain more power, we must extend the simply-typed lambda calculus with a construct for
recursion (which breaks strong normalization).
Extensions
We can extend the simply-typed lambda calculus to bring it closer to typed functional languages
such as ML.
For example, we can add Bool and Nat as base types, and constructs such as let and if.
We need inference rules for these.
Progress and preservation theorems can be proved for these extensions.
We still have not modelled type inference when annotations are absent or optional, as in ML
We also need many versions of, e.g., the identity function.
CS 145 Page 38
*Haskell
November-18-10
11:30 AM
expr
consOnEach y [] = []
consOnEach y (p:ps) = (y:p) : consOnEach y ps
Running Haskell
Interpreter ghci, similar to sml
ghc resembles gcc
ghc expects main to be defined:
main :: IO()
main - print (perms [1, 2, 3, 4])
To avoid parantheses, the function application operator $ (with lowest precedence) is used:
main = print $ perms [1, 2, 3, 4]
Any two-parameter curred function can be used as an operator:
5 'div' 2
CS 145 Page 39
Laziness
Scheme and ML use eager evaluation: the leftmost, innermost expression is evaluated.
This means, for example, that all arguments to a function are evaluated before the function is
applied to them.
Haskell uses lazy evaluation: the leftmost, outermost expression is evaluated.
In effect, expressions are not evaluated until necessary.
Immutable Arrays
Here's an example of crating a one-dimensional immutable array from a list of (index, value) pairs
sqrx = array (1, 100) [(I, i*i_ | i <- [1..100])]
CS 145 Page 40
--UNIX 'cat'
main = interact id
-- UNIC 'wc -1'
showln = (++) . show
main = interact $ showln . length . lines
linemap f = interact $ unlines . f . lines
-- Unix 'head -10'
main = linemap $ take 1-- Unix 'grep a'
main = linemap $ filter $ elem 'a'
Type Classes
Type classes offer a controlled approach to overloading
The Eq class
Types in this class provide == and /=
Can create a member of eq with derive Eq
Monads
The Monad type class abstracts a common computational pattern.
One of the simplest instances is the Maybe type/
We can start by thinking of it as:
data Maybe a = Nothing | Just a
The idea is to use Nothing when an error occurs, and Just to wrap a value for continued
computation.
When composing functions with maybe
chain :: Maybe Int (Int Maybe Int) Maybe Int
chain Nothing _ = Nothing
chain (Just r) f = f r
The chain function is already specified by the Monad typeclass and Maybe provides the above
definition
There, chain is called >>= (pronounced "bind")
Testing in Haskell
HUnit: unit testing (modelled on JUnit)
CS 145 Page 41
Vectors/ADTs in C
November-23-10
Vector
ADT for a fixed length sequence
Operations:
Create
Index - select element
Set - change element
11:29 AM
Scheme
(define v (vector 10 20 30))
(vector-ref v 2) ; 30 O(1) time
(vector-size v); 3
(vector-set! v 2 42) O(1) time
(vector-rev v 2) ; 42
(vector->list v)
Strings in scheme are vectors of characters
C
vector_user.c
#include "vector.h"
vector foo = vector_create(10, 20, 30);
int j = vector_ref(foo, 2);
vector_set(&foo, 2, 42);
vector.h
// 3D vectors of ints
typedef struct vector vector;
struct vector {
int i, j, k;
};
vector.c
#include "vector.h"
vector vector_create(int a, int b, int c){
vector r;
r.i = a;
r.j = b;
r.k = c;
return r;
}
int vector_ref(vector v, int i) {
if (!i) return v.i;
if (i == 1) return v.j;
return v.k
}
vector.h
// 3D vector of ints
typedef struct vector * vector;
// Hands off!
vector vector_build(int, int, int);
vector.c
#include "vector.h"
struct vector {
int x[3];
};
int vector_ref (vector v, int i) {
return v->x[i];
}
vector vector_build (int a, int b, int c) {
vector r = malloc (sizeof (struct vector));
r->x[0] = a;
r->x[1] = b;
r->x[2] = c;
return r;
}
void vector_delete (vector v) {
free(v);
}
vector.c
vector.h
#include "vector.h"
CS 145 Page 42
//Approach 1
struct vector {
int len;
#include "vector.h"
typedef struct vector * vector;
vector vector_build(int, int);
void vector_delete(vector);
int vector_len(vector);
int vector_create(int, int);
//Approach 1
struct vector {
int len;
int x[]; // woah, this has no memory malloced for it.
// It is a pointer to zero integers
// It will be at the end of the vector struct, although
// maybe not guaranteed to be so.
}
vector vector_built (int len, int *e) {
vector r = malloc(sizeof(struct vector) + len * sizeof
(int));
for (int i = 0; i < len; i++) {
r->x[i] = e[i];
r->len = len;
return r;
}
void vector_delete(vector v) {
free(v);
}
//Approach 2
vector vector_build(int len, int *e) {
vector r = malloc(sizeof(struct vector));
r->x = malloc(len * sizeof(int));
for (int i = 0; i < len; i++)
r->x[i] = e[i];
r->len = len;
return r;
}
void vector_delete(vector v) {
free(v->x);
free(v);
}
// For both approaches
int vector_len (vector v) {
return v->len;
}
// bounds checking
int vector_set(vector v, int pos, int e) {
if (pos >= 0 && pos < len) {
v->x[pos] = e;
return 0; /succeed
}
return 1; //fail
}
// or could use exit(0) - good
// exit(number 0) is bad
// ends the program, in unix can write echo $?
// to find the error code
// exit is equivalent to return from main
// alternate
#include <stdlib.h>
// has the global value errno
void vector_set (vector v, int pos, it e) {
if (pos >= 0 && pos < len) {
v->x[pos] = e;
errno = 0;
return;
}
errno = 1;
}
// perror prints an error message
int vector_ref (vector v, int pos) {
if (pos >= 0 && pos < len) {
return v->x[pos];
}
} // how do you indicate error?
// could request a flag from the user and use that
typdef struct {
int r;
int status;
} int_status;
int_status vector_ref (vector v, int pos) {
int_status stat;
if (pos >= 0 && pos < len) {
stat.status = 0;
stat.r = v->x[pos];
return stat;
}
CS 145 Page 43
}
stat.status = 1;
return stat;
} // probably the best approach to deal with errors
But what if you want to store things in the array other than ints
// Another Way
#include "t.h"
t.h
typedef struct t_struct * t;
Generic
(labmda (something)
struct vector {
int len = 3;
something x[];
}
)
struct vector {
int len;
t *x;
}
//operations on t
t_create;
t_create_array;
t_copy;
t_delete;
t.c
struct t_struct {
int i;
char c;
}; // more space than needed
Instantiation
(vector char) foo;
(vector avltree) bar;
Could build a generic as:
#define vec(t, n) \
typedef struct { \
int len = 3 \
t x[]; \
}n
union t_struct {
int i;
char c;
}// union stores i and c
// to the same place
vec(char, vecchar);
vec(int, vecint);
// defines vecchar a vector of chars
// defines vecint, a vector of ints
CS 145 Page 44
Polymorphism
November-30-10
11:29 AM
Many Types
Polymorphic Function - Works on many types
Polymorphic ADT - data structure and functions on many types
Scheme
Dynamic (Run-Time) Polymorphism
Dynamic Typing
Strong/Weak Typing
Scheme has strong typing, types
are enforced by the compiler
C has weak typing, types can be
treated as other types.
C
Static typing
Loopholes for polymorphism
Polymorphism
Parametric Polymorphism (templates, generics)
(lambda (t) ) where t is a type
Ad Hoc Polymorphism
Finite number of alternatives, each coded separately
- Unions in C
- Overloading
foo(int)
foo(char)
- Pascal variant records
- (void *)
void * x;
(char *)x[i]; // will work if you declared memory anyway
int foo (int *q) {
bar;
}
foo(x); // will also work
Inclusion Polymorphism
- Inheritance
with ops f, g, h
with ops f g h j
----------------------------C polymorphism
int sumto (int n ) {
int r = 0;
for (int i
; i n ; i++)
r += 1;
return r;
}
Specifically for integers
int sumto(int n, int *a) {
int r = 0;
for (int i = 0; i < n ; i++)
r += i[a];
return r;
}
int x[] = {10, 20, 30};
sumto(3, x);
int foo(int i ) {
return x[i];
}
sumto (3, foo);
#include "elem.h"
elem sumto (int n, elem ref(int) {
elem r = zero;// zero must be defined in elem.h (or you could pass zero as a parameter)
for (int i = 0; i < n ; i++)
r = plus(r, ref(i));
return r;
}
Void pointers!
void * sumto (int n, void * ref(int), void * accum, void * plus (void *, void *), void copy (void ** to,
void * from)) {
void * r;
copy (&r, accum);
for (int i = 0; i < n; i++)
copy(&r, plus(r, ref(i)); // copy should be destructive
return r
}
CS 145 Page 46
Mabel
December-02-10
CS 145 Page 47
(Finite Automaton)
S: A finite set of states
i S: Initial state
f S: Final states
: finite set of symbols (alphabet)
:
12:18 PM
Bubble Diagram
Spam
CS 145 Page 48