no silver bullets in functional programming by brian mckenna

53
No Silver Bullets in Functional Programming

Upload: naresh-jain

Post on 11-Jan-2017

162 views

Category:

Software


0 download

TRANSCRIPT

No Silver Bullets in

Functional Programming

Brian McKenna

Atlassian

Almost always functional programming

Australia

There's no such thing as a silver bullet...

... there is no single development, in either technology ormanagement technique, which by itself promises even one orderof magnitude improvement within a decade in productivity, inreliability, in simplicity. ... Hence, although I strongly support the technology transfer andcurriculum development efforts now underway, I think the mostimportant single effort we can mount is to develop ways to growgreat designers.

Fred Brooks, 1986

The differences are not minor - it is rather like Salieri and Mozart.Study after study shows that the very best designers producestructures that are faster, smaller, simpler, cleaner and producedwith less effort. The difference between the great and theaverage approach is an order of magnitude.

Fred Brooks' experience as of 1986:

No 10x toolsBut 10x programmers

1. No tool will fix all productivity/reliability/simplicity problems2. No tool strictly better than another

Availability vs consistency

Space vs time

Git vs Mercurial

Emacs vs Vim

YAML vs JSON

Functional programming

(10 + 30) * 240 * 280

Referentially transparent expressions can be replaced with thevalue that they evaluate to.

Functions are a way of creating referentially transparentexpressions.

Functional programming is programming with referentiallytransparent expressions.

Reuse

println("Hello"); println("World"); println("Hello"); println("World");

val x = { println("Hello"); println("World"); };x;x;

Refactoring

bind(getCredentialsProvider, credentials => { val regions = Regions.fromName(streamRegion); val config = makeClientConfiguration(regions); val client = kinesis(credentials, config, regions); val proxy = kinesisProxy(credentials, client); getShardList(proxy); });

val regions = Regions.fromName(streamRegion); val config = makeClientConfiguration(regions); bind(getCredentialsProvider, credentials => { val client = kinesis(credentials, config, regions); val proxy = kinesisProxy(credentials, client); getShardList(proxy); });

Equational reasoning

def traverse[A](l: List[A], f: A => IO[Unit]) = l.foldRight( (a, acc) => bind( f(a), _ => acc ), point(unit) );

traverse(["Hello", "World"], println);

["Hello", "World"].foldRight( (a, acc) => bind( println(a), _ => acc ), point(unit) );

bind( println("Hello"), _ => ["World"].foldRight( (a, acc) => bind( println(a), _ => acc ), point(unit) ));

bind( println("Hello"), _ => bind( println("World"), _ => [].foldRight( (a, acc) => bind( println(a), _ => acc ), point(unit) ) ));

bind( println("Hello"), _ => bind( println("World"), _ => point(unit) ));

bind( println("Hello"), _ => println("World") );

println("Hello"); println("World");

Some benefits for humans:

ReuseRefactoringEquational reasoning

Compare the alternatives

Functional programming

Imperative programming

Object-oriented programming

Functional programming

Imperative programming

Object-oriented programming

In short, Haskell is the world's finest imperative programminglanguage.

Simon Peyton Jones, 2000

Functional programming

Not functional programming

Values

Side-effects

Benefits of side-effects

Argument to moderation

"Mostly functional" programming does not work. ... The idea of "mostly functional programming" is unfeasible. It isimpossible to make imperative programming languages safer byonly partially removing implicit side effects. Leaving one kind ofeffect is often enough to simulate the very effect you just tried toremove. On the other hand, allowing effects to be "forgotten" in apure language also causes mayhem in its own way.

Erik Meijer, 2014

Middle-ground between a lie and the truth is a lie.

Middle-ground between a side-effect and a value is a side-effect.

Tooling

In theory, functional programming only has benefits.

In practice, tools have trade-offs.

type Effect[a] = WriteLine String a | ReadLine (String -> a)

program = { writeLine("Hello, what's your name?"); s <- readLine writeLine("Hello " + s); };

blink :: Atom ()blink = do on <- bool "on" True period timeout . atom "blinkOn" $ do call "avr_blink" on <== not_ (value on)

Sunk cost

We have invested a lot of time and effort into using side-effects.

We have received no inherent benefit over functional programming.

We need to beware of putting any more effort into side-effects.

Success

Shift the conversation:

We already do functional programming.

If you want to use side-effects, the burden of justification is on you.

Don't fall into the "everything is about trade-offs" trap:

Functional programming gives significant benefits over side-effects.

Side-effects give zero benefits over functional programming.

We should consider side-effects to be legacy.

Functional programming should be our future.