Object: A way to encapsulate state and behavior.
State: Fields, instance variables, etc. Behavior: What you do with state (methods, etc)
Objects are responsible for manipulating internal state.
Objects interact with each other
class BankAccount
attr_reader :balance
def initialize
@balance = 0
end
def deposit amount
@balance += amount
end
def withdraw amount
@balance -= amount
end
end
class CashRegister
attr_reader :drawer
def initialize
@drawer = [2000, 1000,
500, 100,
25, 10,
5, 1]
end
def make_change owed, tendered
difference = tendered - owed
change = []
i = 0
denomination = @drawer[i]
while difference > 0 do
if difference < denomination
i += 1
denomination = @drawer[i]
next
end
change << denomination
difference -= denomination
end
change
end
end
Functions take in data and output data
Pure functional - functions don't store state and don't mutate incoming data
Data and procedures are separated
Infix vs. Prefix:
(define (square n)
(* n n))
(square 5)
25
(define (abs x)
(cond
((> x 0)
x)
((= x 0)
0)
(else
(- x))))
Lists in racket:
'(1 2 3)
(car '(1 2 3))
1
(cdr '(1 2 3))
'(2 3)
(cons '1 '(2 3))
'(1 2 3)
(define (fact n)
(cond
((<= n 1)
1)
(else
(* n (fact (- n 1))))))
(define (fib n)
(cond ((<= n 0)
0)
((= n 1)
1)
(else
(+
(fib (- n 1))
(fib (- n 2))))))
Don't have to worry about concurrency and threading because everything is a read operation
Easier to test because state doesn't matter
Reusability
Brevity
(define (make-change x denoms)
(cond
((= x 0)
'())
((empty? denoms)
false)
((< x (car denoms))
(make-change x (cdr denoms)))
(else
(cons (car denoms)
(make-change (- x (car denoms)) denoms)))))
Formal Logic (like in philosophy/math)
Prolog functions are made up of facts and clauses
Describe the what of the situation, not how
Variables start with capital
Constants start lowercase
Facts end with period
state(washington).
border(washington, oregon).
border(washington, idaho).
border(oregon, california).
Rules specify relationships between facts:
adjacent(X, Y) :- border(X, Y).
:-
is a logical implication
Pattern matching!
border(washington, oregon).
border(washington, idaho).
adjacent(X, Y) :- border(X, Y).
?- adjacent(washington, oregon).
yes
?- adjacent(oregon, washington).
no
Prolog is very literal, does not know when reflexive cases are true.
father(homer, bart).
father(homer, lisa).
mother(marge, bart).
mother(marge, lisa).
?- mother(X, bart).
X = marge
?- mother(marge, Y).
Y = bart ? ;
Y = lisa
sibling(X, Y) :-
mother(Z, X),
mother(Z, Y),
X \== Y.
sibling(X, Y) :-
father(Z, X),
father(Z, Y),
X \== Y.
?- sibling(X, Y).
X = bart
Y = lisa
[]
[1, 2, 3]
[apples, bananas]
[apples, [1, 3], mangos]
Bar notation
[1, 2, 3][f | r] F = 1 R = [2, 3]
Racket can also use _
to say you don't care about a variable
member(X, [X | _).
member(X, [_ | R) :- member(X, R).
change(amount, coins, change)
change(0, _, []).
change(A, [F | R], [F | X]) :-
A >= F,
B is A - F,
change(B, [F | R], X).
change(A, [_ | R], X) :-
A > 0,
change(A, R, X).
Limited vocabulary, limited standard library
Two registers:
car
- Contents of A register
cdr
- Contents of D register
A + D
D - A
A - D
[A or D] + 1
[A or D] - 1
bitwise !&|
-[A or D]
(Any place you can use A, you can use M)
No multiplication, no division, no lists.
Can assign to values
constants: @Integer (can only go into A register) val;jump type
Jumps:
@2
D=A
@3
D=D+A
@0
M=D
@0
M=0
@5
D=A
@1
M=D
(LOOP)
@1
D=M
@0
M=M+D
@1
MD=M-1
@END
D;JLE
@LOOP
0;JMP
@67
D=A
@R0
M=D
// Load Denominations
@25
D=A
@R1
M=D
@10
D=A
@R2
M=D
@5
D=A
@R3
M=D
@1
D=A
@R4
M=D
(QUARTERS)
@R0
D=M
@R1
D=D-M
@DIMES
D;JLT
@R0
M=D
@R5
M=M+1
@QUARTERS
0;JMP
(DIMES)
@R0
D=m
@R2
D=D-M
@NICKELS
D;JLT
@R0
M=D
@R6
M=M+1
@DIMES
0;JMP
(NICKELS)
@R0
D=M
@R3
D=D-M
@PENNIES
D;JLT
@R0
M=D
@R7
M=M+1
@NICKELS
0;JMP
(PENNIES)
@R0
D=M
@R4
D=D-M
@END
D;JLT
@R0
M=D
@R8
M=M+1
@PENNIES
0;JMP
(END)
@END
0;JMP