(Skip to 0:30 in the first video, it's full of this kind of "context".)
How do you transform someone's voice like that?
Kyle wrote the You Don't Know JS series. This book is just as good.
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.
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).
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?
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.
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.
> ...
>> ...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.)
That said, they do occasionally form useful abstractions.
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.
This is the canonical source: https://wiki.haskell.org/Typeclassopedia
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.
There are lots of ways to conceptualize monads. I think "functors that flatten" is accurate, but is just one way.
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.
- 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!
FP Resources:https://github.com/functionalflow/brains/projects/9
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.
Context: self-taught programmer in the data science/statistical modeling world.
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.
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).
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.
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.
Calling these side affects is like calling Python a low level language because programs you write still use registers and raw memory access.
Can anyone explain?
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.
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] -> NumberEdit: 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.
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.
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.
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
Just for entertainment value, specifically https://www.youtube.com/watch?v=BfS2H1y6tzQ
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.
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.)
Most of the book isn't really a beginner's guide. A more accurate title might be "JavaScript for Haskell Programmers".
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.