Presentation is loading. Please wait.

Presentation is loading. Please wait.

Functional Programming

Similar presentations


Presentation on theme: "Functional Programming"— Presentation transcript:

1 Functional Programming
We already visited this when we looked at LISP We return to this topic to more formally discuss why functional programming is important in a separate set of notes, we look at a related topic, closure We look at several functional programming languages in a separate set of notes, we look at F# Most programming languages, whether OO or not, whether compiled or interpreted, are imperative languages program instructions change the state of the machine state is the value of the variables Functional programming instead focuses on the application on functions to compute no local variables (or if there are, no side effects) the book refers to “mathematical” functions, but that does not necessarily mean arithmetic functions, it is more meant a function in the mathematical sense x = f(y) meaning that we pass parameters and get a value/result back

2 Why Functional? More readable
Easier to develop because code is likely to be independent of its context that is, you write a function independent of the code that might call upon it Recursion is simplified when you think in terms of a mathematical function and so functional programming *should* be easier this is probably not going to be true in most cases because its easier for us to write code using loops than using recursion More reliable because programs are simpler (fewer or no variables to have to understand) this is true if you are used to recursion, otherwise functional programming can look very cryptic More likely to be correct because it should be more readable, writable and reliable

3 The Lambda Expression Most functional languages include the lambda expression or a lambda function This is a function that is unnamed this allows you to define and invoke a function at any time, including from within an instruction (known as an in-line function) The notation mathematically looks like this (l(x) function code here) (parameter) you can have as many parameters as desired example: (l(x, y) if (x > y) x else y) (5, 10) returns 10 we briefly saw in LISP the use of a lambda expression when using mapcar, we will similarly see the use of lambda expressions in F# most functional languages allow you to formally define a function so that we do not *need* lambda expressions but can use them without the ability to define a function, we would have to write all functions as lambda expressions

4 Functional Programming Concepts
Referential transparency execution of a function will always result in the same outcome when supplied the same parameters – that is, we have no global variables or side effects Lazy evaluation delay evaluation of an expression until it is needed this allows for calling a function only if needed and also can permit a function to be called once even though it may be invoked (on the same parameter) multiple times we often implement this feature using memoization, that is, by storing the result in a table to recall it for each successive function call (again remembering that we are talking about a function call that has the same params as a previous call) – also known as dynamic programming Currying taking a function which is passed multiple parameters into several functions, each of which are passed a single parameter (see nested functions on the next slide) First class functions we cover this with closure in separate notes

5 Nested Functions A related topic to first class functions is nested functions, again we explore this in more detail when we look at closure, but let’s consider the following three examples In Pascal In F# C does not permit nested functions, the best we can do is as follows function outer(x : integer): integer; function inner(y : integer): integer; begin inner := x + y end; outer :=inner(x + 1) let outer x = let inner y = x + y inner (x + 1) int inner(int x, int y) {// notice we have to pass two parameters to inner return x + y; } int outer(int x) { // unlike in the other two languages (int)(*ptr)(int, int) = &inner; int temp = (*ptr)(x+1); }

6 ML Static scoped Strongly typed (unlike LISP which was typeless)
Functions and params can be typed, otherwise uses type inferencing function parameters use polymorphism when types are of data structures (e.g., objects, strings, types of arrays) Side effects in functions are permitted as there are no true variables (only params and constants), side effects can only occur via pointers to values and to data structures No variables, identifiers are function names, parameters and constants Automatic memory management (allocation and deallocation of heap- based structures)

7 ML Functions Functions defined using fun name(params) = expression
multiple expressions are permitted if separated by ; in which case the function returns the last expression evaluated the parameter and return value must be typed if it cannot be inferred fun add1(x : int) : int = x + 1; needed here because x could be any numeric type being a functional language, functions should operate only on parameters (we’ll see in a couple of slides how to use local variables) functions are generally going to be recursive which have the following form fun fact(0) = 1 | fact(1) = 1 | fact(n : int) : int = n * fact(n – 1);

8 Control Statements As seen in the last slide, one form of condition is in a function where we compare the parameter to a (or multiple) value(s) and use | to list options There is also an if-then-else statement there is no if-then statement because all instructions in ML must return a value and if the condition is false, there would be nothing for the if-then to return the return value of the if-then-else is the last statement evaluated in the then or else clause if x < y then 0 else x * (y – 1); The while loop has the form while condition do statement(s); being a functional language, using the while loop is generally discouraged

9 Local Variables As ML is a functional language, the intent is to only have parameters in your functions, but local variables are available All variables are reference variables to declare a variable, use val variablename to create storage for the variable, use ref initialvalue example: val x = ref 0; You must dereference your variable when obtaining its value (but not when setting it) x := !x + 1; Below is an example of computing the nth Fibonacci value val n1 = ref 1 and n2 = ref 1 and n3 = ref 0 and count = ref 2; while !count < !n do ( n3 = $n1; n1 = $n1 + $n2; n2 = $n3; count = $count + 1)

10 Data Structure Lists are denoted as [ ] with values separated by commas as in [ 1, 3, 5, 7, 9 ] or [ “apple”, “banana”, “cherry”, “date” ] sublists can be denoted using [ [ … ], [ … ], …, [ … ] ] [ ] is an empty list List operators include List.length :: - like LISP’s cons operator if x is the first list above, then 0 :: x gives us [ 0, 1, 3, 5, 7, 9 ] @ - append if x is the first list above, then 0 gives us [ 1, 3, 5, 7, 9, 0 ] Tuples are denoted using ( ) You can access a particular element from a list or tuple using the following notation [a::b] – gives you access to the head (a) and the rest (b) (_, b) – gives you access to the second item in the tuple

11 Example Code Function to convert a verb into its past tense
fun past “run” = “ran” | past “swim” = “swum” | past x = x ^ “ed” // ^ is append for strings Function which receives a list of integers and sums them together fun sum nil = 0 // base case, empty list return 0 | sum(h::t) = h + sum t // return head of list + pass rest of list to sum Function to reverse a list fun reverse nil = [ ] | reverse (x::xs) = [x]

12 Haskell We omit coverage of the Haskell syntax
Very much like ML with three differences functions can be overloaded pure functional language (no side effects allowed on any data structure) non-strict syntax is allowed a non-strict language is one in which actual parameters do not have to be evaluated prior to the function call taking place this is handled through lazy evaluation this may be more efficient for instance if a particular parameter is only used in some occasions (e.g., in an else clause) and so its evaluation may not be needed it also permits “infinite” lists (lists which are semantically infinite although in practice of course there is a finite storage space) We omit coverage of the Haskell syntax

13 Functional and Imperative Support
Many functional languages now include imperative features LISP for instance has loops, goto statements, local variables ML although it has no local variables, has data structures and permits side effects F# is actually a combination of functional, OO and procedural language Many imperative languages are now being developed to include functional components including first-class functions and closure F# C# Java 8 Ruby Python JavaScript

14 Other Strengths of Functional Programming
Should make parallel processing and multithreading easier since the execution of functions should never interact with each other (no side effects) and so we can more easily distribute code onto multiple processors Can select lazy or eager evaluation lazy evaluation, with memoization, should be more efficient and so we might prefer this, but either implementation should give us the same result Most FPs that offer data structures handle allocation/deallocation for you while this is also true of many imperative languages today, it is not true of all imperative languages, predominantly C/C++


Download ppt "Functional Programming"

Similar presentations


Ads by Google