Presentation is loading. Please wait.

Presentation is loading. Please wait.

Functional Programming

Similar presentations


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

1 Functional Programming
CS/COE 1520 Jarrett Billingsley

2 Today: Functional programming a (maybe new-to-you) style of coding
some practical examples of it to give us some practice with the DOM so how's the project going? run into any problems?

3 What is it?

4 When you hear "functional"…
think of it in the mathematical sense. functional programming (FP) is a coding style where… functions are black boxes. f …and their outputs only depend on the inputs. they have inputs (arguments)… in the strictest form, functional programming has no state at all, only these kinds of functions. - if there's no state, we call it………….. stateless - imagine that.

5 State other computers registers RAM files peripherals
state is the collective contents of all the storage in a computer. other computers registers RAM the whole damn WORLD is state files peripherals users but state is confusing. - peripherals: basically every part inside your computer is its own little computer with registers, RAM, persistent storage, etc. - A FRACTAL OF COMPUTATION well, that's only part of it…

6 Well, it's mutable state that's confusing
mutable means "can be changed"; immutable means it can't be. the problem is when two or more things must share state. f1 f2 two functions sharing a global variable… t1 t2 two threads sharing a data structure… c1 c2 two computers sending state over a network… in all of these cases, if one "actor" misbehaves, the other one will malfunction. - from the same root as "mutate" or "mutant" - ESPECIALLY if you have MORE than two things… and they're ALL malfunctioning in different ways. and it can be really damn hard to figure out who's at fault.

7 Side effects console.log("hi") console.log("bye") console.log("bye")
a function has side effects if it changes state. console.log("hi") console.log("bye") console.log("bye") console.log("hi") I'm calling the same function with the same arguments. will I get the same output? uh, no. a side-effecting function can cause different outcomes depending on: when you call it the order of calls to it - guess what: the DOM is one big global data structure so most of the stuff you do with client-side JS is just a ton of side effects - and I mean that last one literally... a side-effecting function can look up the phase of the moon and cause different results how many times you call it the phase of the moon

8 Pure functions

9 but you've dealt with a whole bunch of pure functions before…
have at least one argument return a value computed only from the arguments have no side effects mathematical functions satisfy these requirements easily. 3 5 + sin 8 π you've been trained to create side effects, which makes it hard to think of nontrivial pure functions. but you've dealt with a whole bunch of pure functions before… - pretty much anything you can do with numbers is pure. - imperative languages are all about side effects. the point of every line of code is to change some piece of state.

10 Any self-respecting language has
immutable strings! Java and JS have immutable strings, and all their methods are pure. String name = "Jarrett Billingsley"; String[] parts = name.split(" "); String s = parts[1] + ", " + parts[0]; String t = s.toUpperCase(); every method takes one or more strings and produces a new string based on the inputs. you can't modify strings, so once you have a string, no one else can mess it up. - basically, we made strings behave like numbers, and that solves so many problems - do you REMEMBER having to do string manipulation in C, it's the absolute worst - pure functions are easy to reason about - you never have to worry about them behaving differently each time you call them - their entire interface is specified by the arguments (no "back channels" through globals) - you never have to worry about them changing your shit - "but by creating a new string object aren't we changing the global heap and therefore modifying state" - shhhhh shhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh - theoretically, no; practically, yes (cause we have finite storage)

11 But without input or output…
if your program can't interact with the world… then your computer is just a fancy heater we have to step outside the pure subset of a language to interact with the user, store files, communicate over the network etc. CPU running beautiful code but purity is a good thing to strive for.

12 from outside this function, it looks pure.
"Effectively pure" for the pedantic, a pure function uses no mutable state at all… not even local variables! so no loops, only recursion but we're using an imperative language, and loops are more natural. function countZeros(arr) { var count = 0; for(var v of arr) { if(v == 0) count++; } return count; although we use a mutable variable and a loop where v takes on multiple values… from outside this function, it looks pure. - we don't modify arr, only read from it - we don't call any other impure functions - if it looks like a pure duck, and it quacks like a pure duck…

13 First-class functions OK enough theory, time for some practice

14 Out on their own var sin = Math.sin; class Math sin()
we say that JS has first-class functions class Math sin() var sin = Math.sin; in JS, there are no such restrictions. functions are values just like numbers, strings, and objects. in Java, functions are "trapped" inside classes. you can't* make a variable that holds a function. this makes it easy and natural to pass around actions just like anything else. * newer editions of Java let you do this, sort of. - but it's a bunch of syntactic sugar around instances of classes which implement automatically-generated interfaces.

15 Wait, passing around actions?
well… yeah. let's think about comparison-based sorting algorithms. for(i = 0 to A.length - 1) for(j = i down to 1) if(A[j - 1] > A[j]) swap(A, j, j - 1) else break by changing this comparison, we can choose the kind of sorting, the direction of the sort etc. there is a key decision in this algorithm that changes how it behaves. but do we really want to write a new sorting function every time we want to change the comparison? - no. the answer is no. that's dumb and frustrating. so no.

16 Parameterizing decisions
by passing a function as a parameter, we can customize the behavior of this sorting function. function sort(A, wrongOrder) for(i = 0 to A.length - 1) for(j = i down to 1) if(wrongOrder(A[j-1], A[j])) swap(A, j, j-1) else break the function we pass is called a predicate. A = [3, 9, 2, 1, 6] sort(A, function(a, b) { return a < b }) - this will sort the array in descending order, because our predicate says that items in ascending order are in the wrong order.

17 In JS the Array.prototype.sort() method takes a sorting predicate. var arr = [2, 7, 5, 4, 3, 9, 0, 1, 6, 8] arr.sort(function(a, b) { if(a < b) return 1 else if(a > b) return -1 else return 0 }) console.log(arr.join(', ')) the predicate behaves like Java's compareTo() method – negative for less, positive for greater, 0 for equal. - when we write A.prototype.b(), it means "a method b() on instances of A", to distinguish from e.g. Array.isArray() - the syntax in the .sort() arguments is a "lambda" or "function literal" - it makes a function right there and passes it to sort - it's not special syntax, it's like a string literal – you can use it anywhere you'd put a value.

18 Working an example

19 this is verbose and likely needed in other places. let's abstract it.
Big AND you want to check if all items in an array satisfy some condition. let's say… all items in the range [0, 100]. var arr = [17, 34, 55, 10, 2, 9, 98] var allInRange = true for(var v of arr) { if(!(v >= 0 && v <= 100)) { allInRange = false break } if(allInRange) { // do something this is verbose and likely needed in other places. let's abstract it. - we DON'T just copy and paste this everywhere we need it, right????????????????????????

20 The initial goal if(allInRange(arr, 0, 100)) { // do something }
let's say we want our calling code to look like this: if(allInRange(arr, 0, 100)) { // do something } okay, so let's take the previous code and make it into a function. (really, let's do it.) now we have this function, but… what if I wanted an exclusive range? what if I only wanted to check an upper bound? what if I wanted to check the lengths of strings? - this is bad functional programming design! - reusable, composable functions are the goal. this function is poorly abstracted. we have hard-coded a decision and limited its use.

21 Moving the goalposts (to a better place)
now let's make our goal look like this: if(all(arr, function(v){return v >= 0 && v <= 100})) { // do something } notice how now the condition is in the calling code. but it looks a bit… busy. so ES6 introduces this syntactic sugar: if(all(arr, (v) => v >= 0 && v <= 100)) { // do something } - this is a shorthand lambda - the parentheses around the argument are optional if there's only 1 argument - but idk I think it makes it stand out a bit better if you always include them

22 Stepping past the goalposts
we can make all() an Array method if we rewrite it a little… Array.prototype.all = function(p) { for(var v of this) { if(!p(v)) { return false } return true since we put this method in Array.prototype, all array objects inherit it. arr.all(v => v < 10) arr.all(v => typeof(v) === 'number') - actually this is built-in – but it's called Array.prototype.every() instead ;) - there's also Array.prototype.some() which returns true if the predicate returns true for any element

23 Using FP with the DOM

24 we can do something with every item with the forEach method.
It's a buncha arrays document.querySelectorAll() gives you an array..ish thing. arrays have a bunch of functional methods (see the links) let's try these on the main course page: document.querySelectorAll('td') .forEach(v => v.classList.add('canceled')) we can do something with every item with the forEach method. var topics = Array.from(document.querySelectorAll('td')) .map(v => v.innerText) .filter(v => v.includes('\n')) .map(v => v.split('\n', 2)[1]) - btw arrays aren't the only use for FP, it just comes up a lot with them and other basic data structures (maps, sets, trees, graphs) - Array.from() gives you an array from some array-like thing (which querySelectorAll returns) - map gives a new array which contains the output of the function called on each item in the array. - filter gives a new array which only includes those items which satisfy the predicate - so this last example finds all the table cells… - grabs their inner text… - filters out anything that doesn't have a newline in it… - and grabs only the stuff after the newline.


Download ppt "Functional Programming"

Similar presentations


Ads by Google