52
Functional Programming for busy OOP Now with obligatory kitten!

Functional Programming for Busy Object Oriented Programmers

Embed Size (px)

Citation preview

Functional Programming for

busy OOP

Now with obligatory kitten!

Hello, World!• Diego Freniche 1

• @dfreniche

• 100% remote dev (iOS / Android)

• writing new bugs @ Mobile Jazz

1 CV: git clone http://www.github.com/dfreniche/cv

BASIC days

• What I've already learnt at iOSDevUK'16:

• I'm a dinosaur

• We're getting older

• Nostalgia is in the air

GLORY days

• self taught PASCAL before starting College

• just to find C was the language of choice

• saw several languages: Ada, C, C++

• fell in love with C++ (pre-STL times...)

Wait, am I an imperative programmer?

• Cursed for life !

• Spoiled by BASIC, C++

• will never get a job in CS. Ever.

Well maybe I can call myself a REAL OOP

developer

• this book is really hard to read

• I mean, like really hard

• that's only imperative++

Wait, I was taught LISP in College

• You know:

• Lost In Stupid Parentheses

• Lots of Irritating Superfluous Parentheses

• ...

F.P.: a new thing, right? !

• invented in the late 50's (1958)

• only ALGOL is older

• derived from the Lambda Calculi (developed in the 30's)

A word (or two) on LISP

• simplest syntax in ANY programming language

• Code:

(+ 3 2)

• List of data:

'("hello", "world")

A word (or two) on LISP

• homoiconicity: "the structure of program code is represented faithfully and directly in a standard data structure"

• we have direct access to the compiler's AST

• Much power. So cool. Such compiler. Wow

• homoiconicity == less syntax to learn

• turn all your fancy { } and [ ] into ( ) and you get LISP again!

• because I've never used http://goshdarnblocksyntax.com

Eval: treat data like code, code like data

• Eval: treat data like code, code like data

CL-USER> '(+ 3 4)(+ 3 4)CL-USER> (+ 3 4)7CL-USER> (eval '(+ 3 4))7

! https://repl.it/languages/scheme

Ideas piooneered by LISP

• tree data structures

• automatic storage management

• dynamic typing

• conditionals

• higher-order functions

• recursion

• the self-hosting compiler

• REPL: Read Eval Print Loop interpreter

Greenspun's tenth rule 2

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of

Common Lisp.

2 maybe the NSA, Santa Claus, Zuck and your peers who hate F.P.

F.P. is back!

• Closures & High Order Funcions in Swift. Inmutability. Optionals.

• Blocks in Objective-C to mimic Closures.

• Scala

• C# / F#

• JavaScript?

Being a Functional Language vs. having Functional Constructs

There's no accepted definition of functional programming language._

If you define functional language as the language that supports first class functions and lambdas, then yes, JavaScript is a functional language.3

3 http://stackoverflow.com/questions/3962604/is-javascript-a-functional-programming-language

Functional Programming

... functional programming is a programming paradigm ... that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm,

Functional Programming

... the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time eliminating side effects

https://en.wikipedia.org/wiki/Functional_programming

All the talks I've been before

• Me: "Hi, I'm Diego, need to lose some weight"

• Someone at the Gym: "No problem, you can start doing this Arnold lift weigthing routines from his training to became Mister Olympia"

• Me: !

All the talks I've been before

• I know nothing about it, but want to learn! ☝

• Functors, Monads, Functional purity, etc. "

• Talks like "Type Check Removal Using Lazy Interprocedural Code Versioning" #

Why you hate FP?

• Functional programming is declarative

• we were born as imperative programmers!

• say what you want, not micromanage how to do it

• you're already doing it! (hating)

• SQL

• CSS

• Regular expressions

OK, Something practical, please?

Inmutability, avoiding state, don't shoot yourself in the foot

• Value types and immutability

• compiler can optimize your code !

• eats more memory "

• also CPU (making all those copies) "

• this can be optimized

• optimizes programmer's time #

Inmutability

• Diego's constants dumb rule

Declare everything as a constant, let compiler warn you when you're changing something. That's a variable.

// Java: final everythingfinal String s = "";s = "other thing"; // nope

// Swiftlet s: String = ""

Inmutability: nice to avoid mistakes

- (void)printAStringReallyStupidBug:(NSString *)aString { aString = nil; // stupid mistake

// really clever code // trust me, I know what I'm doing // in this 300 lines method

NSLog(@"Printing: %@", aString);}

Inmutability

func removeFromString( _ s: inout String, Character c:Character) -> Int { var nRemoved = 0

while let ix = s.characters.index(of: c) { s.removeSubrange(ix...ix) nRemoved += 1

} return nRemoved}

Inmutability: a clear example

- (void)version1 { NSString *myString = @"iOSDevUK 16";

NSLog(@"myString BEFORE: %@", myString); // BEFORE: iOSDevUK 16

[self printAStringAllGood:myString];

NSLog(@"myString AFTER: %@", myString); // AFTER: iOSDevUK 16

NSLog(@"myString BEFORE: %@", myString); // BEFORE: iOSDevUK 16

[self printAStringReallyStupidBug:myString];

NSLog(@"myString AFTER: %@", myString); // AFTER: iOSDevUK 16

NSLog(@"myString BEFORE: %@", myString); // BEFORE: iOSDevUK 16

[self printAStringEvilBug:&myString];

NSLog(@"myString AFTER: %@", myString); // AFTER: iOSDevUK 16}

- (void)printAStringAllGood:(NSString *)aString { NSLog(@"Printing: %@", aString);}

- (void)printAStringReallyStupidBug:(NSString *)aString { aString = nil; // stupid mistake

NSLog(@"Printing: %@", aString);}

- (void)printAStringEvilBug:(NSString **)aString { *aString = @"HaHa";

NSLog(@"Printing: %@", *aString);}

Inmutability lessons

• learn to use debug breakpoints

• change your code to call that function

• we can use blocks, function pointers, Swift closures...

• a little tradegy in that backward language

NSString const *myString = @"iOSDevUK 16";

⚠ Sending 'const NSString *__strong' to parameter of type 'NSString *' discards qualifiers

Inmutability: don't use ++

var i = 0print("\( ++i )")

• direct translation from assembler INC

• does several things at once

• hard to reason about

• nice syntax !

Optionals are not a new thing

• non-optionals are the new thing!

class Person { var name: String

// compiler ERROR: you can't fool me!}

Optionals are not a new thing

class Politician: Hyena { // still compiler ERROR}

High order functions

• Functions that take functions as parameters

• Map, Filter, Reduce, Flatmap

• Let's do something with these fruits

Map

• "Do THIS to every single element in the list"

• add 1 to every element in this list

• takes a function (add one) & a list

• returns a list

• with a basket of fruit: peel every fruit in this basket

• think of SQL update

Map example

let basket = ["!", """, "#", "$", "%"]

basket.map { (e: String) -> String in

return "&" + e}

Map Benefits

• map is a level of indirection

• can be run in parallel (applying a function on element n doesn't depend on element n+1)

Filter

• "I only want oranges from that basket"

• SQL select WHERE clause

Filter example

• "I only want Apples"

let basket = ["!", """, "#", "$", "%", "&"]

let newBasket = basket.filter { $0 == "!" || $0 == "&"}

Reduce

• takes a function (add) & a list

• returns just one element

• make multi-fruit juice

• think of AVG function in SQL

Reduce example

let numbers = [1, 2, 3, 4, 5, 6]

numbers.reduce(0, combine: +) --> 21

Flatmap

• Like map, but also "flattens" the list

• some of the fruits in the basket are wrapped with paper

Flatmap example

// how do you add 2 to all the numbers in this array?

let fa2 = [[1,2],[3],[4,5,6]]

let fa2m = fa2.flatMap({$0}).map({$0 + 2})fa2m

This is from Clean Coding... or not

• Functions should be:

• Small

• Smaller than that

• < 150 chars per line

• < 20 lines

Inject all your parameters

• even if you're using properties from your own class

• makes everything inmediately testable

• no side effects: everything is clear when calling

• you get your own Domain Specific Language to express your problem

So what?

• you don't need to be an athlete to run and be healthier

• you don't need to be pure to benefit from some FP goodness

So what?

• use inmutable structures where possible

• in Java, for example, final everything

• in Swift, prefer structs (value types) vs classes (reference types)

So what?

• map / filter / reduce helps sometimes

• think of it as having SQL at your fingertips

• not everything is a for loop

Use the best of OOP + the best of FP. Nobody will ever know. 2

2 maybe the NSA, Santa Claus, Zuck and your peers who hate F.P.

Thanks!

• No Trademarks were hurt during the making of this talk.

• all trademarks belong to their owners, so please don't sue me.

Additional reading

• A really good post on what F.P. is (with Swift examples!) http://five.agency/functional-programming-in-swift/

• A parallel map implementation: http://moreindirection.blogspot.com.es/2015/07/gcd-and-parallel-collections-in-swift.html