Professional Documents
Culture Documents
Programming
Part 1:
Single-assignment and Recursive
Techniques
What is Functional
Programming?
•
Functions return values
Given a set of values in the parameter list,
the function can only have one possible
result.
•
Functions have no side-effects
•
Do not modify variables passed to them
Do not modify any global variable
•
Variables only assigned once
Principle of Least
Surprise
Principle
•
of Least
All possible inputs to any function are listed in
the parameter list - no worries about global
Surprise
state
Single assignment means that you never have
to wonder how a variable got its definition
since it is only defined one place in the entire
function
•
Loops much easier to comprehend and debug
Simpler execution model makes program
proving easier, both for computers and
Explicitly mention stateless. Might also talk
humans (i.e. debugging)
about theoretical statelessness of the web, but
also why it isn’t truly stateless.
No assignments! How
do you loop?
•
Functional programs are usually heavily
Functional programs are usually heavily
recursive
Looping is either done with a looping construct
(such as map, each, select, etc.) or with
recursion
•
Rather than setting values on each iteration,
the loop itself is a function that calls itself
recursively
Need to mention that
mpute answer return 1 else #Get us closer to the bas
mpute answer return 1 else #Get us closer to the ba
Note that we didn’t do ANY assignment in the whole program
-- we just passed parameters. Function calls create new
variables, so if we think we want to do assignment, in
functional programming you usually want to call a function
or create a different variable.
Selection Sort Example
•
Two lists: already-sorted values and unsorted
values
First list will start empty
•
Each iteration, find the smallest unsorted value
and put it at the end of the sorted list
Base case: unsorted values list is empty - just
return the sorted values
Selection Sort Example
def select_sort(values) select_sort_loop([], values)enddef
select_sort_loop(sorted_values, unsorted_values) if unsorted_values.empty?
#BASE CASE! return sorted_values else
#FIND SMALLEST VALUE AND ITS INDEX smallest_value_index =
find_smallest_value_index(unsorted_values) smallest_value =
unsorted_values[smallest_value_index]
#CREATE NEW SORTED AND UNSORTED ARRAYS new_sorted_values =
add_element(sorted_values, smallest_value) new_unsorted_values =
remove_element_index(unsorted_values, smallest_value_index)
#LOOP WITH NEW VALUES return select_sort_loop(new_sorted_values,
new_unsorted_values) endend
select_sort([1,5,23,8,3,5,6,8,34,65,2,5,3])
Selection Sort:
Utility Functions
Utility Functions
def add_element(ary, val) ary.dup.push(val)enddef
remove_element_index(ary, idx) idx == 0 ? ary[1..1] : (idx ==
(ary.size 1)) ? ary[1..2] : ary.slice(0, idx
1).concat(ary.slice(idx + 1, ary.size 1))enddef
find_smallest_value_index(ary) smallest_idx = 0 ary.each_index do
|idx| if ary[idx] < ary[smallest_idx] smallest_idx = idx
smallest_val = ary[idx] end end return smallest_idxend
Basic Recursive Loop
In this basic example, it looks like
A standard loop: the standard loop is better. But as
i = 0
while(i < 10) { the loop gets more complicated,
#Do Stuff
knowing exactly what defines your
i = i + 1 variables makes all the difference
}
between an understandable and a
A recursive loop: totally incoherent loop.
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end
myloop(0, other, changeable, initial, values)
Basic Recursive Loop
Loop
A standard loop: Definition
Note that the recursive loop explicitly
i = 0
while(i < 10) {
#Do Stuff
names its inputs, while the standard
loop does not, meaning that to truly
i = i + 1
} know what contributes to the standard
loops functionality requires full
A recursive loop: inspection of the whole loop.
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
Loop Definition with
end
Parameter Declaration
myloop(0, other, changeable, initial, values)
Basic Recursive Loop
A standard loop:
i = 0
while(i < 10) {
Loop Initialization
#Do Stuff
i = i + 1
}
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end
Loop Initialization
myloop(0, other, changeable, initial, values)
Basic Recursive Loop
An explicit invocation
A standard loop: step is not needed for
i = 0
while(i < 10) { standard loops, as the
#Do Stuff
while statement invokes
i = i + 1 it implicitly.
}
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end Loop Invocation
myloop(0, other, changeable, initial, values)
Basic Recursive Loop
A standard loop:
i = 0
while(i < 10) {
#Do Stuff
Loop Condition
i = i + 1
}
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
Loop Condition
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end
myloop(0, other, changeable, initial, values)
Basic Recursive Loop
A standard loop:
i = 0
while(i < 10) {
#Do Stuff Loop Body
i = i + 1
}
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
Loop Body
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end
myloop(0, other, changeable, initial, values)
Basic Recursive Loop Note that in the standard loop
assignments can occur anywhere, while
in recursive loops they only occur by
A standard loop: passing new parameters as part of the
i = 0
while(i < 10) {
loop iteration process. Which do you
#Do Stuff think leads to easier bug detection in
i = i + 1 large loops?
}
Modification of Loop Variables
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end Modification of Loop Variables
myloop(0, other, changeable, initial, values)
Recursive loops can create new definitions for new
variables within the loop, but cannot modify already-
assigned variables.
Basic Recursive Loop
A standard loop:
i = 0
while(i < 10) {
#Do Stuff Control Variable
i = i + 1
}
Modification
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff Control Variable Modification
Note that since this is
return myloop(i + 1, other, changeable, loop, vars)
else done as a function
return whatever #exit loop parameter, no
end
end assignment needs to be
myloop(0, other, changeable, initial, values) made. The new value is
placed into a new
variable (with the same
name) in the next
Basic Recursive Loop
Not e that since the loop
myloop(0, other, changeable, initial, values)
Basic Recursive Loop
A standard loop: Note that the loop exit is
i = 0
while(i < 10) {
explicit in the standard
#Do Stuff loop but implicit in the
i = i + 1 recursive loop.
}
A recursive loop:
def myloop(i, other, changeable, loop, vars)
if i < 10
#Do Stuff
return myloop(i + 1, other, changeable, loop, vars)
else
return whatever #exit loop
end
end Loop Exit
myloop(0, other, changeable, initial, values)
Packaged Looping Should I give an example
Constructs somewhere?
•
These put all of the loop control in a function,
These put all of the loop control in a function,
and thus out of your hands
In these, the loop logic is guaranteed reliable,
and you are only responsible for the per-
iteration logic
•
These take a block (or in other languages, a
function or lambda expression) which is the
per-iteration code
This usually (but not always) do not carry state
from iteration to iteration
Packaged Looping Include upto?
Constructs
Somewhere I need to talk about fold
and unfold, but that is probably for a
different talk.
•
Single assignment of all variables
•
Disadvantages: a little more typing, a lot less
familiarity
General Functional
Programming Issues
•
Input/output difficult to deal with
Mention Monads briefly
•
Mastering Recursive Programming
http://www-128.ibm.com/developerworks/linux/library/l-recurs.html
•
Introduction to Haskell (includes recursive techniques)
http://www-128.ibm.com/developerworks/edu/os-dw-linuxhask-i.html
•
Recursion Examples
http://www.juniata.edu/faculty/kruse/cs2java/recursion2.htm
•
More Recursion Examples
http://www.sparknotes.com/cs/recursion/examples/