
Professor Frisby's Mostly Adequate Guide to Functional Programming (2015) - AdrianRossouw
https://mostly-adequate.gitbooks.io/mostly-adequate-guide/
======
jwarren
Great book. I'd also recommend his free video course on Egghead. It's rather
quirky, which is something that I very much enjoyed:
[https://egghead.io/courses/professor-frisby-introduces-
compo...](https://egghead.io/courses/professor-frisby-introduces-composable-
functional-javascript)

~~~
zupa-hu
ahahah, this is incredibly entertaining :D

(Skip to 0:30 in the first video, it's full of this kind of "context".)

------
vga805
Dr. Booleans guide is excellent. Another nice intro to functional programming
using JavaScript is Kyle Simpsons functional
lite:[https://github.com/getify/Functional-Light-
JS/blob/master/RE...](https://github.com/getify/Functional-Light-
JS/blob/master/README.md)

Kyle wrote the You Don't Know JS series. This book is just as good.

------
christophilus
Good read. He annotates his function with Hindley-Milner type signatures
(specified in comments). I really prefer this to, say, jsdoc. Anyone know if
there's a jsdoc-like tool that understands these comments? That'd be pretty
swank.

~~~
theoh
I'm not sure what "Hindley-Milner type signatures" means. Obviously it is
intended to refer to Haskell-style type signatures. Hindley-Milner, though,
usually refers to a system of type inference which is independent of syntax.

As I understand it, the author is using Hindley-Milner as if was the name of a
syntax, like Backus-Naur form. But this is something I've never heard, and I
wonder if the credit for the Haskell type signature style belongs just as much
to Rod Burstall or David Turner, in other words I'm inclined to believe that
it is something conventional that evolved over years.

------
dakom
The Fantasy Land spec and related libraries like Sanctuary and Fluture deserve
a mention here, even if only as a next step after reading this guide.

It helps bridge the gap between looking at all of this from the more
math/Haskell perspective and how it's implemented in javascript, without
sacrificing definitions (as much as possible).

------
blindwatchmaker
Really enjoyed this book. Once you get currying, and using curried functions
to pipe/compose, everything clicks into place. I found the examples of using
Nothing/Maybe monads for error handling pretty neat as well - is that a common
pattern, because I don't remember native support for those types when I
briefly dabbled in elixir.

Also is his explanation of monads as 'functors that can flatten' a
simplification for the purposes of teaching, or is that more or less what they
are?

~~~
jerf
There's really multiple definitions of "functional" right now, and the type of
"functional" being discussed here, Erlang isn't, and I don't think Elixir
particularly is either.

This is not a criticism of any kind; this is a point about _definitions_.
There are definitions of functional where Erlang is functional, and IIRC
Elixir can be said to support it.

(And there are definitions of "functional" where almost every language in
current use is "functional". There's even some so weak that C is "functional"
because it has "function pointers", though this one is now out-of-date and not
currently being used by anyone. But, yes, there was once a time in which C
would have been considered "unusually strong" in its "functional programming"
support, because other contemporary languages didn't even have function
pointers.)

"Also is his explanation of monads as 'functors that can flatten' a
simplification for the purposes of teaching, or is that more or less what they
are?"

A little of both. Technically it is correct, but the "flattening" in question
applies to many things that most programmers wouldn't consider "flattening".
For instance, consider monadic IO as Haskell uses. There is a way in which you
can consider the execution of an IO value as "flattening" it, and it
corresponds to the mathematical term, but it's not what most people have in
mind. There's more to "flattening" than "simplifying data structures in some
manner"; it doesn't even always involve what we'd traditionally think of as
data structures at all, such as, again, IO.

Personally I think it is an actively unhelpful metaphor for these reasons, as
it is very prone to leading to false understanding, but YMMV.

~~~
mediocrejoker
> There's really multiple definitions of "functional" right now

It would be very helpful to see an explanation of this spectrum you describe
for someone who is not really familiar with the definitions. I would love to
read an explanation of the various “functional” paradigms as they diverge from
“conventional” (ie. C) programming languages.

~~~
jerf
The weakest definition of functional is that functions are a first-class
object that can be passed around. This is the one that C conforms to in that
old sense. This is a dead definition because almost everything in modern use
conforms to this definition, and definitions are only useful to the extent
they create distinct categories. Because almost every modern language has
this, it can be difficult to imagine a language in which this is not true.
But, yes, once upon a time, languages did not in general have a data type that
could contain a function that you could call. (This is before my time, but I
caught the tail end of these arguments.)

This was also one of the reasons that assembly programmers were always banging
on about the power of assembly back in the day. Nowadays the only remnant of
that argument is the claim that you can write _more optimal_ assembly than the
compiler. But back in the day, assembly programmers enjoyed the ability to
have a pointer to a function and jump to it and/or call it (it's a bit fuzzier
in assembler) and people using high-level languages were definitely getting a
"weaker" experience. Today we expect our high level languages to also provide
us significant power advantages over assembler. (Of course you can do anything
in assembler, but not as concisely necessarily.)

When I got into computing, the definition of "functional" that excluded C
included having "closures". This is a function pointer + an environment for
the function to run in. C only has the function pointer; you don't get an
environment. It is more convenient than nothing, but vastly less useful than a
full closure. (You can do them manually, but they become problematic fast.)

Stepping up from there, you got languages that generally permitted an
imperative style of programming, but "preferred" what we would today call a
functional style, when you use map, filter, and such to perform operations.
These languages loved them some linked lists; linked lists everywhere. With
their own special names like "cons lists". They also tended to be garbage
collected, which for a while was a "functional programming" thing, but is now
also simply an accepted thing that a language may be, regardless of how
"functional" it is.

This definition is still in some usage today, though some improvement in
understanding the structure of the relevant of code ("iteration" as a concept
you can abstract, rather than accidentally conflating "a linked list" with
"the thing you can iterate on") and the fact that hardware is getting ever-
more grumpy about non-locality has erased the linked list obsession. You can
either have a "functional language" like Lisp, or you can program in a
"functional style" in a multi-paradigm language like Javascript. In the latter
case, you can do a lot of work with the functional paradigm, but technically
you always end back up at structured programming with some flavor of OO, which
is the dominant language paradigm. (Languages can be multi-paradigm, but there
is always a dominant paradigm, one that when the paradigms conflict, is the
winner. And my personal default definition of OO includes Javascript,
considering the prototype system a detail relative to the fact you still have
"collections of data with associated methods".) People who say that
"Javascript is a functional language" mean this definition.

Finally, there's the Haskell definition. Here, immutability is the default,
and possibly the only option. Type systems are very strong, able to express
types like "a block of code that does not do any IO" that other languages can
not express, or can only do very laboriously. You get "functor" and "monad"
and such being not just demonstrated on a one-off basis, but being the
foundational abstractions of libraries and entire applications. People argue
over how much category theory you have to know to practically use these
languages. F#, O'Caml, and Haskell live here. Haskell is as far as you can
currently go in this direction and get a language usable for practical tasks,
work that you can build a business on.

(As an interesting side bar, I think Erlang made an error here, although a
perfectly understandable one. When it was written, one of the reasons
immutability was favored at the academic level was that it helped write multi-
core code. At the time, only big industry and academia had multi-core systems.
But you only really need _isolation between threads_. Immutability is one way
to achieve this, but you can also make it so that it is impossible to
communicate "references" between processes/threads, so everything is a copy.
Within an Erlang process there's no reason not to allow one to "assign" to
existing variables. But at the time, "access control" and "immutable" were
sort of conflated together. Rust is the first big language that seems to be
levering those concepts apart in a really systematic way.)

However, the spectrum keeps going from here. Past Haskell there are functional
languages that get _really_ mathematical, and are focused on proving code,
creating even more elaborate type systems such as dependent types ("this
function takes a string whose length is a prime number", to give a silly
example), and constraining the abstractions even further for things like total
functional programming, which is one of the most interesting possible ways to
limit programming so that it is not Turing Complete, _but_ can still do real
work. Here you can get such exotica as ways of using the type system to
separate out what code is total, and what is not, in various principled ways.
One of the common "I've been in this industry for 20 years and it sucks and
here's what we all need to do to fix it" posts is to extol the virtues of one
or more of these things. However, while there has been some interesting
progress on many of these fronts in the past couple of decades, they remain
impractical.

~~~
galaxyLogic
Excellent exposition of the current landscape and of the notion that there is
no single definition of FP.

I'd like to add that type-systems are not a defining feature of functional
programming because you can have type-systems in what are considered "non
functional" languages as well.

Immutability it jives with functional but is really an orthogonal feature as
well.

So what is left? I would say is the ability to create closures because that
clearly MAKES IT EASY TO CREATE FUNCTIONS without having to separately type
the separate source-code of every individual function. Closures make that
easy. Closures make it easy to "calculate with functions" because it becomes
so easy to create new functions.

~~~
jerf
Yeah, I kinda think the Haskell branch ought to have its own term, because of
the number of things that are involved that don't relate to "functions" per
se, but it's not my call. "Pure functional" sort of works, but I would mean
something more like "Pure _and_ functional", that is, two separate adjectives,
not one where "pure" is modifying "functional". A pure, non-functional
language is certainly possible. "Pure imperative" is a bit hard to conceive
(Rust probably as close as you can get), but an SQL database set to a high
transaction isolation level can be seen as a pure non-functional language.
(And I say "can" because it can also be argued against. But it's at least
debatable.)

~~~
dragonwriter
> Yeah, I kinda think the Haskell branch ought to have its own term, because
> of the number of things that are involved that don't relate to "functions"
> per se, but it's not my call. "Pure functional" sort of works, but I would
> mean something more like "Pure and functional", that is, two separate
> adjectives, not one where "pure" is modifying "functional".

“Pure functional” programming is functional programming wherein the functions
are pure functions, that is: (1) the result of the function is completely
determined by the identity of the function and its arguments, and not any
other external state, and (2) the function produces no side effects that would
impact calls to the same or other functions. (On a _language_ level, only the
first is really necessary, because if everything is composed of functions and
all functions results are independent of external state, any side effects
would necessarily not be observable within the language; but functional purity
can be discussed with regard to constructs within a language where purity is
not required at the language level.)

> A pure, non-functional language is certainly possible.

You can have referential transparency in a language whose central structure is
determined by a paradigm other than the functional (e.g., referential
transparency is just as much a key feature in the logic programming paradigm
as the functional paradigm, and pure logic programming is already used to
describe logic programming with strict referential transparency in the same
way pure functional programming refers to functional programming where with
strict referential transparency.)

> "Pure imperative" is a bit hard to conceive (Rust probably as close as you
> can get),

Rust is basically an ML-family functional language that moved off in a
different direction than the one toward purity; it's closer to impure
functional than pure anything.

------
gcanti
For my fellow italians, I wrote a free "Introduction to functional
programming" PDF, check out [https://github.com/gcanti/functional-
programming](https://github.com/gcanti/functional-programming)

~~~
picardo
Is there an English translation?

------
tomduncalf
Great book for an intro to FP if you’re a JS developer. I have a talk about it
a few years ago aimed at complete newcomers to FP:
[http://blog.tomduncalf.com/posts/functional-programming-
fund...](http://blog.tomduncalf.com/posts/functional-programming-fundamentals-
talk/)

------
tw1010
This is excellent. But man, I don't think I can ever go back to not feeling
like there's a huge pedagogical gap between the local maxima the functional
programming explanations engineers are typically exposed to, and the much
higher (though probably still not a global maxima) point that pure
mathematicians have been adapted into. I just wish we'd embrace the geometric
(topological, differential geometrical) threads that a lot of these concepts
(like lifts etc) are connected to, instead of being arbitrarily tied to a
pedagogy textured by the sociological context that coding originated from
(i.e. heavily influenced by logicians etc).

~~~
AlexCoventry
What's an example of a coding problem which would benefit from all that
abstraction?

~~~
tw1010
While I sympathize with your sentiment – and share the mindset during my day
job – I believe that this type of "what practical applications does this
have"-thinking is making us short-sighted and preventing us from being able to
move past our current local maxima, to cross the adaptive valley[1].

I'm not expecting the whole engineering field to start exploring the question
of what pure mathematics (and not some watered down _for-engineers_ version)
can do to fundamentally transform the the way programmers think and talk about
what it is they do. But the fact that there are almost zero people from the
geometric side of pure mathematics (though again, there are plenty of
logicians) working together with everyday programmers, that's what I wish I
saw more of every time I see one of these explanations of functional
programming that seem almost always to be pedagogically colored by logicians
hands.

[1] [https://www.edge.org/response-
detail/23879](https://www.edge.org/response-detail/23879)

~~~
AlexCoventry
Cross the valley, sure, but what points to the valley right now? Useful
abstractions arise out of concrete issues with present approaches. What are
some of the concrete issues in software development which this abstraction
could help with?

------
projectileboy
Fogus wrote a whole book on functional programming in Javascript, which I
recommend if you liked this.

------
lainga
This may be a character flaw, but I found this book's style of teaching by
mocking random snippets found in the wild really, really entertaining.

~~~
stuntkite
You should see the videos he made for Egghead.io! Stop motion hedgehog! I know
some people complained, but Egghead backed his unconventional teaching methods
which is pretty cool.

\- [https://egghead.io/instructors/brian-
lonsdorf](https://egghead.io/instructors/brian-lonsdorf)

\-
[https://www.youtube.com/watch?v=h_tkIpwbsxY](https://www.youtube.com/watch?v=h_tkIpwbsxY)

I'm pretty sure he's the only person to make this topic so approachable. I'm
glad he's into having fun with it. Quite refreshing!

------
hackermailman
Robert Harper's 'Programming in Standard ML' free pdf off his CMU page is the
best intro I've found to really understand FP, goes into details and reasons,
like the pattern matching material. Very concisely written and SML is like
Scheme, easy to learn syntax perfect for teaching.

------
csixty4
When I started looking into Functional Programming, Professor Frisby's book
was instrumental in my learning the concepts and applying them to a language I
already know & code in.

------
allenleein
Great book, really enjoyed. For people who wanna learn more about Functional
Programming (Haskell,Purescript) from 101 to building product, I recommend
this resources:

FP
Resources:[https://github.com/functionalflow/brains/projects/9](https://github.com/functionalflow/brains/projects/9)

------
ericyang321
Excellent read for a beginner like me who wanted to learn functional
programming with an already familiar language.

------
wodenokoto
Why does he factor out the zero valued flock of birds variable?

That seems extremely dishonest. The reason why we name variables, is so that
they can hold different values. There is no guarantee that every run of the
script will have the same initial variables. If it was, you might as well just
type in the result.

------
tomrod
I wish I knew enough compsci to know why functional programming is useful. I
read about half the book, and while interesting from a learning perspective I
don't know where I can apply it.

Context: self-taught programmer in the data science/statistical modeling
world.

~~~
steve_adams_86
Since I've started applying FP (I'm not very strict about it) I've been
finding ways to reuse code more which lets me reduce my test footprint and
increase the reliability of my code. I've also found it's easier to isolate my
business logic without scoping it too strictly to an object or implementation,
allowing me to think largely in coding to interfaces or contacts. This is
totally doable with strict OO, but honestly I'm pretty lousy at that in
practice. So FP has helped me with that too.

I lean towards organizing my applications into very dumb objects which are
supported by FP-style business logic. At a glance you can infer what's going
on quite easily due to the idiomatic use of the objects, but the object
orientation mostly ends there. My business logic is organized into isolated
modules that are as pure as I can manage without being a nut about it. The
objects recruit or are operated on by that logic, so their implementation is
very light and clean as a result. Like I mentioned, tests for this kind of
code are really nice. They tend to be concise.

It's not perfect, but I feel like it's a way FP has greatly improved my code
and what I deliver to my team in general. It's an attempt to merge the
benefits of two paradigms, I suppose.

------
dagurp
Excellent book. Although it says 2015 in the title it's still actively being
worked on.

------
0xdeadbeefbabe
Since the FP crowd is here, why is loading a program into memory, writing a
register, or calling a function not seen as a side effect, but writing to disk
is seen as a side effect? Or have I got it wrong?

~~~
AnimalMuppet
I'm not really part of the FP crowd, but I'll take a stab at it. Note well,
however, that what I say here could well be wrong.

On one level, there is no such thing as FP. All there is, is assembly-language
(or binary) instructions being executed in a CPU that has access to some
memory. (Almost) every instruction creates some kind of side effect (including
changing the flags).

But nobody wants to program at that level, so we build abstractions on top of
it. All higher-level languages create an abstraction. Even C creates an
abstract machine, even though it's very close to the hardware. If the
abstraction doesn't leak, you can just think about the abstraction, and ignore
what's going on at the level(s) below it.

FP creates an abstraction that's at a higher level than many other
abstractions. Within that abstraction, (almost) all you have are functions and
values. Memory and registers are below that level. The changes to the call
stack when you call a function are below that level. Those things are
therefore not seen as side effects, because they are below the level of
abstraction you're working at.

But disk is not. Therefore writing to disk is seen as a side effect, and those
other things are not.

------
halis
This book is very good. If you like Javascript and want to further your
understanding of functional programming, then I would highly recommend it.

------
ponitozhekoni
Thanks.

------
mkirklions
I spent about 30 minutes reading, but I didnt understand why this has 140
points and is the top thread.

Can anyone explain?

~~~
brianberns
Functional programming (FP) is an important paradigm with many practical
benefits, such as preventing bugs, improving parallelization, etc.

JavaScript is a language in which one can apply the FP paradigm, with some
(considerable) effort. This book explains both the underlying FP paradigm and
how to apply it in JS.

Other languages (e.g. Haskell, Scala, F#) are designed for the FP paradigm and
make it much easier to apply. But the paradigm itself is the same for all of
them, as it arises from fundamental mathematical laws.

~~~
lloyd-christmas
> with some (considerable) effort

disclaimer: I haven't read the book and am not sure if this is mentioned
anywhere.

What helped me when thinking about functional design in javascript was
realizing that all js functions actually only have one parameter, an array of
arguments used by the caller:

    
    
        function add(x, y) {
            return x + y;
        }
    

is effectively syntactic sugar for

    
    
        function add() {
            const x = arguments[0];
            const y = arguments[1];
            return x + y;
        }
    

`add(1,2,3,4)` ignores 3 and 4 instead of being an error. While seemingly
obvious that these two functions would have different definitions:
`add1(1)(2)` and `add2(1,2)`, thinking about it in types helped me process it
when thinking out how they are actually written:

    
    
        add1 :: [Number] -> [Number] -> Number
        add2 :: [Number, Number] -> Number

~~~
brianberns
Yes. This is the essence of currying.

------
akuji1993
Actually the course on Egghead is terrible. The voice that is used to comment
on the video is very badly recorded and I have no idea why they chose that
voice for a serious video for adults.

Edit: Also fine to not have my opinion on this, but a lot of people shared my
opinion, check the Egghead comment section. I would've loved to watch that
video, with a more professional voice and walkthrough.

~~~
always_good
What's with this modern internet culture of calling everything "terrible" or
"garbage" because it has some defects, even subjective ones?

I've watched this gradual change in the users of my own forum I started over
10 years ago. People with no skin in the game think so highly of their opinion
that they use it to discredit and dismiss something as terrible garbage.

Seems related to the rise of self-entitlement culture: In this case, a free
video series is terrible because you didn't like the voice.

~~~
akuji1993
In my opinion it's more related to the fact, that people are actually creating
very good content, so if somebody pushes something that is way under that
value, you recognize and move away from it. I've watched tutorials on
functional programming that took themselves seriously and used a normal, human
voice to bring their point across and sorry, I consider those a lot better
than this.

~~~
always_good
But notice that you didn't link to any nor provide anything beyond "Actually
the course on Egghead is terrible" when someone else added value to the world
by linking to the free video courses.

Imagine if your approach, instead of knee-jerk negativity and dismissal, was
to enumerate those videos you thought were better if your intention was
actually to communicate that you've seen better ones. That would've been a
great contribution.

------
tuukkah
> _We have all the features we need to mimic a language like Scala or Haskell
> with the help of a tiny library or two._

Seems misleading at best, as you mimic only some parts of functional
programming. For example, for-loops are not used but neither are recursion and
tail calls mentioned.

> _[T]yped functional languages will, without a doubt, be the best place to
> code in the style presented by this book. JavaScript will be our means of
> learning a paradigm, where you apply it is up to you._

Surprising how they teach the typed functional programming paradigm in a
language which does not support you in it. Going from JavaScript to Haskell,
wouldn't PureScript be a better stepping stone than this? Consider tail call
elimination or all the support that type checking gives you to get the type
nestings right, especially when you are a beginner and may have issues even
with String being [Char] (unlike JavaScript) let alone Monads etc.

 _(EDIT: In case you didn 't check the contents of the book: Yes, this is a
book that teaches Monads, type classes, pointfree style, Hindley-Milner(!)
etc., not a form of FP that would be natural in JS.)_

~~~
brianberns
It seems like a good book, but I think this is fair criticism. It skips some
of the basic FP concepts that you mentioned, and is surprisingly heavy on more
advanced topics (e.g. category theory, which I personally enjoy).

Most of the book isn't really a beginner's guide. A more accurate title might
be "JavaScript for Haskell Programmers".

