functional programming for busy object oriented programmers

52
Functional Programming for busy OOP Now with obligatory kitten!

Upload: diego-freniche-brito

Post on 23-Jan-2018

345 views

Category:

Technology


2 download

TRANSCRIPT

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