Hacker News new | comments | show | ask | jobs | submit login
Professor Frisby's Mostly Adequate Guide to Functional Programming (2015) (gitbooks.io)
529 points by AdrianRossouw 7 months ago | hide | past | web | favorite | 92 comments



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...


ahahah, this is incredibly entertaining :D

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


He should make a Professor Frisby plush toy with a voice system which provides a functional API.

How do you transform someone's voice like that?


The video course is indeed very good, if you took the time to read (and understand) the book.


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...

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


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.


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.


Flow is a bolt-on on type system, not quite OCaml (which it was built in) but it's pretty good.


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).


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?


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.


> 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.


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.


I'll add to the thanks for writing this!

While I'm happy to be corrected, I get the impression that the 'threshold' for calling something FP, by those who consider themselves FP 'practitioners', lies somewhere in the area you describe right before Haskell. And for those who consider FP-style programming alien, Haskell is what they imagine.

Basically, Javascript would be considered barely-enough to do FP style programming, but it's got the kitchen-sink nature against it, offering too easy an escape hatch.

Clojure/Lisp and perhaps Elixir more-so, would be squarely in the FP world, even though they're not strict about it. I'm not too familiar with the former, but the latter makes it rather inconvenient to not write most of your code in a functional style.

Personally my next goal is to go full-on FP and dive into Haskell (or something else, if someone would recommend it!), but Elixir has been the most useful language in my journey so far. I come from Javascript (and before that PHP), and while I've always tried doing things the FP way as much as possible, it's only after getting comfortable with Elixir that I've actually started to 'think functionally'. I feel it's greatly improved my programming even when I go back to JS stuff, because I'm less likely to fall back on the imperative/OO stuff. I'm not saying the latter is bad, but at the very least being consistent in my approach seems to bear fruit.


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.


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.)


> 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.


Thanks very much for writing this.


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

> ...

>> ...monads...

There are also a couple of definitions of "monad" going around -- in array languages (J, APL, Q) a "monad" is something with arity 1 (like unary negate), to be contrasted with "dyads" which take two parameters (infix operators etc.)


Yeah, and don't confuse O'Caml "functors" with Haskell functors or you're in for several very confusing hours. Hooray terminology!


Or Prolog functors...


Haskell-style types aren't a prerequisite for functional programming. Lisp and Elixir are dynamically-typed, which is why you don't see monads in those.

That said, they do occasionally form useful abstractions.


> Haskell-style types aren't a prerequisite for functional programming.

Sure.

> Lisp and Elixir are dynamically-typed, which is why you don't see monads in those.

More to the point, Lisp and Elixir are impure functional languages, which is why you don't have some pure construct, like monads, that isolates IO.


> you don't have some pure construct, like monads, that isolates IO

In Haskell IO is isolated, and then the Monad interface is used for some particularly important ways of interacting with values of that type. That's not quite the same thing as "monads isolate IO" - the Monad interface is useful for quite a few other types of values.


Can you explain why you don't need monads if your language is dynamically typed? That's a new one to me.


I don't agree with that "not needed" explanation. But they are quite useless if the compiler can not deduce that both the values returned from the functions you are calling are monads, and what kind of binding should apply to them.


I find them to be at least somewhat useful in a language like javascript. I imagine they are more useful in a typed language with proper inference, but I wouldn't say they're entirely useless in a dynamic language.


OK, for the slow of understanding:

What I think you said is that, in an untyped language, a function will just return "something" (as far as the compiler is concerned). But in a typed language, the compiler knows that a monad was returned. So the point of the monad is to make the compiler do magic, not to make the runtime do magic.

Is that accurate?


Well.. It's like 25% accurate, and you hit the part you were most worried about. But you have been seriously misled about monads in the past.

There is no magic in monads. At the level of runtime operations, they're just a couple of functions.

The magic taking place in the compiler is type inference guiding the selection of the right pair of functions during compilation. Without that, you have to explicitly use the correct functions. It's much easier to offload that bookkeeping to a computer than it is to do it yourself.


Functors have fmap. Pointeds have pure. Monads have fmap, pure and join/flatten. So what's missing from "functors that can flatten" is pure, and monads are more precisely "pointed functors that can flatten".

This is the canonical source: https://wiki.haskell.org/Typeclassopedia


It's a pretty usefully compact definition.

In my understanding however, it's valuable to note that the chain-ability of the bind operation also sets up a continuously nested set of closures, which is where the real power comes into play to give you a useful approximation to imperative programming. (This can easily be abused, of course, to circumvent thinking and structuring code functionally.)

Related to this, SJP stressed in a talk some years back about how monads conveniently encapsulate the unavoidable messiness of side-effects in the least painful way yet discovered.


The Option/Maybe monad is very common in FP languages. I don't know if it's native in Elixir, but apparently it's pretty easy to implement: http://www.zohaib.me/monads-in-elixir-2/#maybe

There are lots of ways to conceptualize monads. I think "functors that flatten" is accurate, but is just one way.


imo, that's basically what they are. altho the fact that they can be created via unit is actually really useful too (even tho thats technically part of applicative).


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


Is there an English translation?


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...


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).


What threads do you mean? (The only thing that comes to mind is HoTT stuff, but that's kind of over my head for now)


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


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


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?


Games


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


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.


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://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!


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.


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.


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


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.


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


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.


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.


You don't really need compsci to understand that.

A pure function is more of a declaration of truth than a list of steps. When your whole application is made up of declarations of truth, it is simpler to reason about and rearrange.

It's simply the fact that the function depends on nothing but its inputs (but includes all the surprising ramifications of that).


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


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?


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.


Loading a program into memory is part of runtime(it happens before your program starts executing; so how is that useful to model that?); Why would calling a function be a side-effect?

Not sure what exactly you mean by writing a register; if you directly mutate a location, it is considered side-effect. Otherwise any register rewrites that happen are just implementation details and if you have a different architecture than von-neumann than it could also be implemented without writing to a register.


Because it's outside the scope of how you interface with the language.

Calling these side affects is like calling Python a low level language because programs you write still use registers and raw memory access.


As long as software is executed in the real world you have side effects, including "side effects" coming in from the outside, like bits flipped in RAM. Yes. So let's just be practical. We can have the equivalent of a middle ages theological discussion or one rooted in this world :-)


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


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

Can anyone explain?


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.


> 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


Yes. This is the essence of currying.


Thank you!


Thanks.


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.


We detached this subthread from https://news.ycombinator.com/item?id=17072865 and marked it off-topic.


If you mean, you didn't like the opinion, you can just say that, instead of calling it off-topic


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.


The problem I have with his comment isn’t directly about the question of whether the video is “good” or “bad”. It’s with the fact that the comment seems partly designed to slap the face of the person he’s responding too, by starting it out with the world “actually”. He instantaneously implies that only his opinion is objectively correct, i.e. the “actual” truth, and that, therefore the poster he’s replying to is some idiot living in a fantasy world who obviously can’t discern actual quality. And all that was done to get that reprimand was express some appreciation for a free video which he learned something from. I must admit that I do wonder whether this kind of behavior, which I feel occurs far too often, is primarily a way a for person of low self-esteem to feel better about himself at someone else’s expense, from the safety of the internet. Or am I being too harsh here?


I don't think you're being too harsh. There's a weird sort of subtle trolling that goes on on online discussions to the point that I don't much engage in online communities. I don't think it's trolling in the sense that people don't consciously do it; they're just negative: "STOP LIKING WHAT I DON'T LIKE!!"

Internet discussion has become very toxic (well, perhaps it always has been). The other day I was on IRC and asked a question about Eclipse which was doing some quirky things that I didn't know how to disable and one of the people in the chat (not a huge open freenode chat but the chat of a smaller, private community) responded "Java is horrible" or something along those lines. I hadn't even mentioned that I was writing Java! What's funny is that I can't imagine anyone responding in this way were it an in-person conversation. You get much more "I don't care much for Java" or even "What are you using Eclipse for?"

I guess because if you're a nasty person AFK people will avoid you and you do face the risk of some social ostracization. However, with the internet, it's harder to prune these people from your social circle.


I kind of agree that people can be hostile or brutally honest online but just look at LinkedIn as what happens online when you can't say the truth for fear of someone disliking it.

Its an endless stream of corporate bullshit. At least my feed is just ridiculous. Nobody says the truth about anything.


I know... it really bothers me how everything becomes a binary evaluation. Something not to your taste isn't objectively terrible, it's just not to your taste. I think it's a symptom of youth and a lack of perspective - I was so much worse with that back when I was a teenager.


Absolutely.

The internet has made it so easy to share negativity or whatever opinion you're able to belt out from the hip that people mistake that for the need to do it. "What, I can't have an opinion, now?" It's almost comical how toxic Youtube and Facebook comments are for this reason.

But I also think there's some element of human nature where you see someone having fun and feel the need to snipe them with something negative. I remember a lot of that from my childhood.

I'll never forget in Boy Scouts when we were climbing down some boulders and one of my mates decided to jump down each boulder instead of climbing down. He was soon sniped with "Quit trying to be cool, Jacob" which put him in line, climbing down like the rest of us.

Not to double down so hard on a fellow HNer, but it reminds me of that:

- Person A: "Here's a link to their free video course."

- Person B: "Those videos are terrible, Jacob. Edit: What, I have opinions, too."


Everyone things they're the next Steve Jobs - well-known for his binary view of the world (where something could only be the "greatest thing ever" or "(profanity)"). He had finely tuned design sensibilities, but his complete disregard for others is what made him a world-class jerk bordering on outright psychopathy.

This sort of personae is not something to aspire to, and the world really doesn't need more of this personae, but in a culture of mimicry, that's what is honored as people try to differentiate themselves from the bland masses. Cultural erosion.


It's because most people are trained by consumerism to think of anything with a human touch as flawed. The artist Tom Sachs talks a lot about this in his work. He can't make any of his art as perfect as an iPhone, but on the flipside, Apple can't make an iPhone as imperfect as any of his art (fingerprints, spray paint, a crack, etc.). I think it's important now, more than ever, to protect our imperfect things--they tell us that humans have been involved. Spirit is far more important than perfection, the former makes us smile while the latter makes us anxious.


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.


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.


The interplay between content and presentation is a symbiotic relationship where either side can drag down the whole. I loved the content of the Frisby egghead course, but have to admit that I had trouble finishing it because the presentation became tiresome for me. I also felt like I couldn't listen to it within earshot (or view) of anyone for fear of looking like a child watching cartoons.

There's no point in attacking the course based on this aspect of its presentation. If it were super polished but made a bunch of mistakes, that's when you need to shout loudly to anyone you care about "don't watch that course! It's full of mistakes!"


I _love_ the videos on the Professor Frisbee Egghead course.

I learned a lot from the course content and the classroom stop-motion animations were refreshing; it kept me watching with a smile on my face.

It's nice to have some personality and silliness in an online classroom environment; very little differentiates the various JS teaching sites other than their media players and subject matter coverage right now.

Daniel Shiffman's unique style also breaks the “person tonelessly narrating to occasional cursor movements over a screencap” standard that lots of online courses have settled into, and is similarly engaging as a result: https://www.youtube.com/channel/UCvjgXvBlbQiydffZU7m1_aw


I really enjoyed this series by Socratica: https://www.youtube.com/playlist?list=PLi01XoE8jYohWFPpC17Z-...

Just for entertainment value, specifically https://www.youtube.com/watch?v=BfS2H1y6tzQ


I actually really loved that. This is someone who doesn't take himself too seriously but treats the subject with rigor. Life is not a dress rehearsal.


I completely understand that it could be more difficult for non-native speakers to understand. It's been sped up to match the cartoon style characters that he uses, and presumably for information density. I personally really enjoyed it, even if I did have to frequently pause the videos to recap something he had just said.


See, isn't it a negative point for you, that you have to stop and revert the video to an earlier point frequently because of this. As someone who has learned a lot through video guides (which are my favorite medium to learn, other than just reading the docs), I think that talking slowly through complex problems is the better way to go, even if that means, the video will be longer.


Tbh not really, I often stop to investigate stuff anyway. I personally prefer to have it at my pace and under my control than listen through someone laboriously explain something I know in great detail.

But this is the great thing about the internet - there's so much information on how to make more of it, you'll definitely be able to find videos which are more to your taste.

I recently watched Andrew Van Slaars series on the Maybe type: https://egghead.io/courses/safer-javascript-with-the-maybe-t... - that was much more traditional and slower paced, and still very good. Maybe give that a shot if you found the Frisby stuff too frenetic.


I'd much rather pause and rewind than have the opposite problem: bored at slow or repetitive presentation but not knowing if I can skip ahead and miss something new.

Fast paced places the viewer in control. Too slow pace is like keeping them prisoner or feeding them via drip line.


The voice effect wasn’t my cup of tea either. Found it distracting and difficult to understand, so I skipped the series.


The course on Egghead is universally excellent and beyond reproach, any suggestion otherwise can be dismissed with prejudice.

May I suggest a perspective modification? I believe you can start your journey to recovery with a healthy doze of this https://www.youtube.com/watch?v=hUes6y2b--0, more of the same, twice a day, complete the course, or until the pressure in your loins subside.


> 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.)


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".


Most people are familiar with JS, not a lot of people have experience with Haskell or OCaml, or F# (Otherwise, they wouldn't really find any of this useful.)

And to the point... how would one go about taking "Imperative Haskell" Code and making it more functional... you can't. Either you write Haskell functionally or whatever you wrote will refuse to compile. I love this book and the Egghead.io videos that followed. I love this guide and the egghead.io videos. That content made me curious about Haskell and Tacit Programming.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: