
Functional Programming Patterns - ique
http://www.slideshare.net/ScottWlaschin/fp-patterns-buildstufflt
======
tel
This is one of the reasons why Higher-Kinded Types are such a boon in the
languages which have them. It allows you to translate "patterns" into
straight-up libraries. This slideshow is good documentation for what the
patterns are, but if you go use them in Haskell (e.g.) then you'll start to
see that libraries are designed to completely contain that pattern and ensure
compatibility between your use of it and others.

Usually this is achieved by representing the pattern exactly in the language.
Usually the patterns are just maths. Usually math happily quantifies over
higher-kinded types. Thus, you really want HKTs in your language.

And to be fair, Haskell does not go tremendously far in this direction. The
languages which will truly profit from this are still in gestation.

~~~
Dewie
> And to be fair, Haskell does not go tremendously far in this direction. The
> languages which will truly profit from this are still in gestation.

What are examples of taking it further?

~~~
tel
Generally what we're talking about is the ability to say something like "for
all types X which satisfy a predicate P, we have this code". The ability to
quantify over "all" types is a key property of dependently typed languages.
Likewise, a lot of Haskell's ability to simulate DT languages comes from its
ability to reason about HKTs.

In a DT language you have something called a Pi type which is a bit like a
function type. An example would be to compare the types of two functions
which, essentially, determine whether two integers are coprime

    
    
        coprime1 :      Int  ->      Int  -> Bool
        coprime2 : (a : Int) -> (b : Int) -> Maybe (IsCoPrime a b)
    

The important part is to look past the syntax and note that IsCoPrime is a
type which _depends upon_ the values of the first two arguments. Another way
of reading this is as follows

    
    
        coprime3 : forall (a b : Int), Maybe (IsCoPrime a b)
    

this emphasizes that the type of `coprime3` is quantifying over all values in
Int.

Then we can take this idea to the higher-kinded level by looking at the type
of, say, monoids

    
    
         monoid : forall (A : Type), 
                  { zero : A
                  , plus : A -> A -> A
                  , leftId  : forall (a : A), plus zero a = a
                  , rightId : forall (a : A), plus a zero = a
                  , assoc   : forall (a b c : A) , plus a (plus b c) =
                                                   plus (plus a b) c
                  }
    

Here we can see that the `forall` notation lets us freely abstract over "all
types" just like we previously abstracted over "all values". This continues to
work at every level. For instance, we can note that `monoid` above is "a type
of types" or maybe a "specification" and we can abstract over all "all
specifications" as well

    
    
        specProperty : forall (S : Type -> Type), P S

~~~
ejenk
Surely your monoid example should be a Sigma type (`exists`), not a Pi type
(`forall`), since a monoid is a specification of data for a single type A, not
for all types A. Indeed, the empty type has no monoid structure, so the Pi
type you wrote down is necessarily empty.

~~~
tel
Oh, yup. Surely indeed! I need my checker clearly

------
adwf
I quite liked the types section, particularly the bit about making illegal
states unrepresentable so you can enforce business rules, eg. validating email
addresses.

One of the things I'm always thinking when people talk about the merits of
various type systems and the problems they solve is: "But I don't have those
problems". However, there are a few good examples in there that opened my eyes
a little and I'll give type-centric programming a go on my next project. Not
necessarily solving problems that I have, but certainly presenting a
different, hopefully clearer, way of writing some functionality.

------
virtualwhys
Excellent presentation. Of the leading type safe functional languages
(Haskell, F#, and OCaml) I find F# to be far and away the most accessible in
terms of syntax and application.

Writing Scala in my day job currently (which, for the most part, I quite
enjoy) but can see jumping ship if Microsoft's move to Linux is successful.
Being able to develop and deploy F# applications on Linux with full blown Type
Providers and _decent_ IDE support? Pretty compelling combo, and that's just
the tip of the iceberg.

~~~
imanaccount247
Do you know if it is possible to use F# on windows without having to install
several GB of crap? I'd like to be able to try it out, but the same way I
would try any other language, install the compiler and try it out. All I can
find is huge packages including visual studio and all kinds of other junk.

~~~
jackfoxy
Take a look at option 3 on this page, have not tried it myself, since I use VS
daily [http://fsharp.org/use/windows/](http://fsharp.org/use/windows/)

------
skybrian
These slides explain the usual functional patterns but it seems like a bit of
a cheat, because it doesn't really explain how to do anything hard (dealing
with time, persistence, logging, and so on).

The comparison between Slides 81 and 82 is particularly unfair because the
"object soup" actually does deal with the database, SMTP, and so on and the
functional version doesn't. If you add those in, you're going to get something
complicated: perhaps a bunch of monad transformers or some such?

Slide 104 is misleading. In an imperative language, you can write a decorator
function that logs a function's inputs and outputs, and it will have the same
API. In a pure language, you can't do that because a function that does I/O
has a different type. The flexibility or sloppiness (depending on your point
of view) that allows you to do I/O anywhere is really a feature of imperative
languages rather than pure functional languages.

~~~
mercurial
You're mixing up functional and pure. Plenty of "functional" languages let you
do IO everywhere.

> The comparison between Slides 81 and 82 is particularly unfair because the
> "object soup" actually does deal with the database, SMTP, and so on and the
> functional version doesn't. If you add those in, you're going to get
> something complicated: perhaps a bunch of monad transformers or some such?

You clearly need state somewhere (something needs to be able to reach the
connection pool), so, yes, the comparison is unfair.

~~~
skybrian
I think it's the terminology that's mixed up, actually. Functions are first-
class datatypes in many imperative languages, including Python, Go, or
JavaScript, but they mostly aren't mathematical functions.

~~~
mercurial
There is no clear-cut definition of what makes a language functional, but
popular opinion says that F#, OCaml or Clojure are functional languages, none
of which are pure.

------
zniperr
A good read, I especially like the parts about error handling and
maps/applicatives. They are well-illustrated and tackle some difficult common
problems I had shortly after I started using functional languages.

The part about functors/monads/monoids is also nice, although I feel like it
would be better with the accompanying talk to bind it together a bit more.

~~~
zniperr
By the way, I do think pattern matching could have been discussed more
extensively. Pattern matching is one of the reasons I love functional
programming so much, since combined with algebraic types they can be much more
expressive than imperative control-flow statements (e.g. if-else). For
programmers that are used to imperative programming, discovering the power of
pattern matching can be quite a hurdle.

------
fbomb
The talk is here: [https://skillsmatter.com/skillscasts/4971-domain-driven-
desi...](https://skillsmatter.com/skillscasts/4971-domain-driven-design-with-
scott-wlaschin)

~~~
azdle
That actually seems to be a different presentation, although one seems to have
taken one or two slides from the other near the beginning.

------
taeric
Ok, I'm sure the slides get better as they go on. But what the hell? The
difference between the patterns that are compared and contrasted are... well,
tenuous, at best.

Seriously, it gives off the impression not that these are going to be better
patterns. But that someone simply has a bias against "patterns" as they are
promoted in Java and then rails against it saying that they are going back to
the root of the word patterns. Ignoring that this is the same path.

------
estefan
This a good read. I like the railway analogy.

"Functional Programming in Scala" is also well worth a read as well if you're
trying to learn FP... I've found it to be excellent, especially since it has
lots of exercises to use for practice.

------
robert_tweed
There's a book with the same name plus "... In Scala and Clojure". It is based
on the wrong sort of patterns (trying to shoehorn GoF into FP). This
presentation is much more what I had hoped that book was going to be.

------
KurtMueller
I am currently taking EdX's Intro to Functional Programming mooc, taught by
Erik Meijer (with his crazy shirts), which uses Haskell to teach functional
programming concepts.

I am wondering if there are any other good resources for teaching the
functional programming paradigms. Anybody care to recommend me some resources?

Also, I mainly work with Ruby and Javascript in my full time job. Currently,
in school, I use Java (in the context of Android, which is on Java 6) and
Objective-C (iOS programming). If anybody has any resources regarding
functional programming and the previously mentioned languages, it would be
most appreciated.

Thanks people!

~~~
hexasquid
How are you finding the mooc? Can you recommend it?

~~~
m0nastic
I'm not the OP, but I am also currently taking the FP101X Mooc with Erik
Meijer. So far, I'm enjoying it tremendously. I've signed up for several moocs
the past couple years, but have never been able to stick with any. This is the
furthest I've been able to actually stay with it, which is probably indicative
of something.

The lectures are basically laid out 1:1 with Hutton's Programming in Haskell
book, so if you're familiar with that book, you're familiar with the way the
course is structured. I find the actual experience of doing all the homework
questions very helpful, even if so far nothing has been particularly
difficult.

------
fdsary
I thank the lord every day that the language I work in (Javascript) supports
functions! I try to write pure functions as often as possible, so it's easy to
refactor the code when I come back three months later.

But is there, except for Clojurescript, any true (like Haskell) FP language
for browsers? Something that has the tools, and community to back it, so it's
viable to actually make projects in it?

~~~
kasbah
The most Haskell-like and popular are:

\- [http://www.purescript.org/](http://www.purescript.org/)

\- [https://github.com/faylang/fay](https://github.com/faylang/fay)

\- [https://github.com/ghcjs/ghcjs](https://github.com/ghcjs/ghcjs)

\- [http://elm-lang.org/](http://elm-lang.org/)

Each has it's own focus and strengths and weaknesses.

There is a long page on the Haskell wiki on the subject:
[https://www.haskell.org/haskellwiki/The_JavaScript_Problem](https://www.haskell.org/haskellwiki/The_JavaScript_Problem)

Michael Snoyman gave a really good talk recently which covers GHCJS and Fay:
[https://www.youtube.com/watch?v=XfINRj5OzGw](https://www.youtube.com/watch?v=XfINRj5OzGw)

~~~
TazeTSchnitzel
PureScript has the advantage that it has a very lightweight runtime and maps
to JS quite well.

------
mercurial
Interesting but not always correct.

Eg: slide 64 encourages the reader to "Using sum vs inheritance", and then
goes on to show the "good" algebraic datatypes (no behaviour, just data) vs
the "bad"... multiple class implementing the same interface (which I wouldn't
call inheritance).

------
1971genocide
I Really found the book "Learn you a haskell" to be an really fast way to get
functional programming into production.

I did not however continue to use haskell since it doesnt have key libraries I
need.

I instead adopted livescript,underscore into javascript and was good to go.

~~~
codygman
Out of curiosity, what libraries did you need?

~~~
1971genocide
I wanted to use a library to do simple linear algebra, quick and dirty regular
expression.

With linear algebra the library HMatrix is broken in more than one place, it
also requires me to learn a lot of new types just to do simple matrix
decomposition.

Regular expression in haskell requires me to learn a completely new way to do
them, I am not under the impression that regular expression is broken in any
way in python or javascript that it requires new syntax.

Haskell also does not have access to the browser runtime which is key if you
are want maximum exposure for your work - ( no one is interested in binaries
anymore ).

There is purescript but its a large layer over javascript and even a simple
hello world results in a 2000 LOC compilation of javascript.

I am not a computer programmer, I am an applied Mathematician and haskell
requires a lot of work before it can be used for serious work the type of work
I do.

Haskell doesnt have the use of use that is offered by things like npm,
browserify which are the most awesome tools I have used.

~~~
purescript
> There is purescript but its a large layer over javascript and even a simple
> hello world results in a 2000 LOC compilation of javascript.

This really depends on which compilation route you take. `psc-make` will
include all of the Prelude and compile to CommonJS modules, which can result
in quite a bit of code, but `psc` will trim out all unused functions, and
should result in about 10 LOC for Hello World.

------
nathell
For some reason, when I got to slide 16 I immediately thought "Scala."

------
dschiptsov
Some guy almost 20 years ago argued, that if you end up with a bunch of
"design patterns" then your language is not good enough.)

[http://norvig.com/design-patterns/design-
patterns.pdf](http://norvig.com/design-patterns/design-patterns.pdf)

~~~
jarcane
_16 of 23 patterns have qualitatively simpler implementation in Lisp or Dylan
than in C++ for at least some uses of each pattern_

Things like this are literally why I switched from Python to Racket almost
immediately once I discovered the latter. So much time spent fighting an
imperative language to do something that seemed like it should just be easier
in the first place.

~~~
taeric
Racket is an imperative language, as well. Right? Don't get me wrong, I love
Racket. Just I don't think of it as !imperative.

I am also unconvinced that the imperative nature of many languages is the
problem. Not sure what it is.

~~~
jarcane
Goodness. My apologies for instigating a terminology war, I should not have
been so imprecise.

I think tel is mostly on the right track of what I mean when I compare Racket
to traditional ALGOL languages, but it is also true to say that Racket is not
strictly non-imperative either: it is ultimately a multi-paradigm language,
just one that culturally leans harder towards a functional-declarative style.
My early projects were just as lousy with mutable state and in-order
processing as anything I wrote in Python; but I got better.

I think what really drove me to Lisp and FP languages was the notion of nearly
everything being first-class values, from functions to objects, and it's this
quality, compared to the tedium of building yet another !"¤&¤&! constructor
pattern that really attracted me. This, plus things like macros, the way the
language allows for function composition so readily, is what made Lisp feel
like 'how programming should've been all along' for me. Haskell as well
induced that same reaction in other ways (mmm ... curry ...), though I'm still
not entirely convinced that such strict purity is practical.

~~~
taeric
If my subthread sounded at all like an attack against Lisp and Racket, than I
humbly apologize. So far, I am loving the language and what can do with it.

And I like currying and such, as well. Even use it in Racket quote often.
Isn't too uncommon to see something like in my projects.

    
    
        ((compose
            (curry func1 val1)
            func2
            func3) seed)
    

I think what really makes Racket so amazing to me is just how easy it is to
iteratively write a function. Start with a core, and gradually append around
it more and more till it is done. Testing with values throughout the whole
process.

I also like the literature around Lisp. Land of Lisp and SICP are both very
well written and just plain fun to read.

~~~
jarcane
Yes. I find sometimes that programming in Racket and other Lisps is so
efficient, that whenever something starts looking tedious, I start
reconsidering if there's a more elegant way I'm missing to implement it.
Learning it, hacking it, and reading about it (and Scheme and other Lisps as
well as Haskell) have done marvelous things for my programming skills.

Today I wrote a struct system in 29 lines of code. Kinda hard sometimes to do
that and then even think about going back to, well, much of anything but
another Lisp or composable FP language, really.

------
k__
lol, the Patterns of GoF seemed like those of tailoring to me.

------
ExpiredLink
Patterns exist to compensate for a programming language’s lack of
expressiveness!

~~~
marcosdumay
For everybody else that didn't read the presentation, it's about how to remove
patterns from your code.

It also carries the best explanation for why one would want to use monads that
I've seen.

