no silver bullets in functional programming by brian mckenna
TRANSCRIPT
... 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.
1. No tool will fix all productivity/reliability/simplicity problems2. No tool strictly better than another
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.
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); });
def traverse[A](l: List[A], f: A => IO[Unit]) = l.foldRight( (a, acc) => bind( f(a), _ => acc ), point(unit) );
traverse(["Hello", "World"], println);
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) ) ));
"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
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.
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.