Javascript Arrays and Functional Programming
zabanaa.github.io
zabanaa.github.io
Most functional languages feature pattern matching, algebraic data types, purity, currying, strong typing, type inference, recursion instead of loops and types that cannot be null. It's a completely different style of coding. Adding map/filter/reduce to an imperative language doesn't get you close to the level of robustness and ease of implementation for that safety you'd get in a functional language.
I guess it could be called combinator-oriented programming or similar.
> It beats complex for-loops
Nvm. I still prefer for loops in most cases, in some way it's easier to understand for me if I read it some months later. For example the reduce function I would write something like this:
getPlayersByCountry= ( footballPlayers= [], players= {} ) ->
for player in footballPlayers
if players.hasOwnProperty player.country
players[ player.country ].push player
return players
playersByCountry= getPlayersByCountry footballPlayers, {France: [], England: [], Spain: []}
I guess it's mere a matter of taste.For that example, you should really have a generic "group by" function to use anyway that plays nice with your map, filter and reduce functions.
That's the benefit of this declarative approach, it removes the relentless boilerplate, works solely with intent, and reduces cyclomatic complexity.
"In computer science, functional programming is a programming paradigm — a style of building the structure and elements of computer programs — that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data."
To that end map-reduce fits and can be referred to as 'functional programming'. The other things you mention are just great language features, but not specific to functional languages. Imperative C++ also has type safety, Swift has non-null types, etc.
All those features in combination are shared by the vast majority of languages called functional programming languages. They're pretty much the defining features of functional languages was my point. Other languages can have a subset of the features but it doesn't make them functional languages. See: https://wiki.haskell.org/Functional_programming
The Wikipedia quote is really vague.
Clojure uses dynamic typing, yet it is still considered a functional language. I agree though that the combination of features results in a better experience when using functional primitives, but not having them doesn't mean this isn't functional programming still.
> The Wikipedia quote is really vague.
I think the Wikipedia quote is clearer and FAR more precise than a common feature set. Functional programming "treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data." That is the definition of functional, and it's the whole definition. No mutation, that's it. Including the features you wrote about is not functional programming, it's other things.
That's important to consider the precise definition if you're going to critique someone for talking about functional programming in a certain way. The author was pretty clear that this is functional programming concepts as applied to arrays in JavaScript, he never claimed that this post covers functional programming in general.
Map, filter & reduce are examples of functional programming, and if they were all you used, and you had only const and no var, then you might have a functional program. @zabana didn't claim that this is all you'll ever need.
Are you meaning that "no mutation" is the definition of functional programming? That's such a vague definition I can't see how it is useful personally. "Stateless" is already a word that covers that.
If you're going to quote Wikipedia, keep going to the "Concepts" section that lists language features: "A number of concepts and paradigms are specific to functional programming, and generally foreign to imperative programming (including object-oriented programming). However, programming languages are often hybrids of several programming paradigms, so programmers using "mostly imperative" languages may have utilized some of these concepts.[40]"
> The author was pretty clear that this is functional programming concepts as applied to arrays in JavaScript, he never claimed that this post covers functional programming in general.
I even said I accept it's common usage of the phrase and I was just wondering why that was.
You can see that I was intentionally summarizing wikipedia's definition in one word to make my point more clear that functional does not mean type inference or currying, right?
> That's such a vague definition I can't see how it is useful personally. "Stateless" is already a word that covers that.
Since I'm not offering "immutable" as the complete and final definition for functional programming, maybe you can find a better one to make your original point clear? Because the list of features you offered as defining functional programming doesn't define functional programming very well.
IMO, the entire first paragraph of Wikipedia's article on functional programming is pretty good. It repeats the concept of immutability in a bunch of different ways with clarifying examples, to make it more concrete and less vague.
I don't personally like "stateless" because it's not strictly true. Functional programs have state, and the state is contained in the stack. The point of functional programming is that the language avoids side effects, and the most direct word for something that avoids side effects is "immutable", not "stateless". I can accept that common usage of stateless is sometimes referring to immutability.
Note that WP's definition of "state" agrees with that, and talks about declarative state being indirect, as opposed to being stateless: "In declarative programming languages, the program describes the desired results and doesn't specify changes to the state directly."
https://en.wikipedia.org/wiki/State_(computer_science)
> I even said I accept it's common usage of the phrase and I was just wondering why that was.
Because it's true and meets the definition? Your objection is too vague. What, exactly, is wrong with calling map/filter/reduce "functional"? In my book, referring to map as an example of functional programming doesn't stretch the strict definition of functional programming at all.
map() and reduce() were some of the very first things I learned about when I was introduced to the concept of functional programming in Scheme, more than 20 years ago.
The post didn't claim that map, filter & reduce were 'enough for code to be called "functional programming"'. He only ever implied that map, filter & reduce are part of functional programming. That is absolutely true, always has been, and isn't a matter of common usage.
A better term would be "programming with functions as first class citizens", but many years ago that got shorted to "functional programming".
> Most functional languages feature pattern matching, algebraic data types, purity, currying, strong typing, type inference, recursion instead of loops and types that cannot be null.
That's a list of what many functional languages now contain, although most don't contain all of those. But that isn't the list of "common functional programming language features" from 10 years ago, and isn't necessarily what the list will be in 10 more years, either.
I really like another poster's recommendation that it be called "combinator-oriented programming". Because, while ES, Java, and even Rust, supports rich combinator-oriented programming, I wouldn't dare call any of them functional programming languages.
Though, one has to admit, with ES6 now even supporting elegant currying, coupled with a good functional programming library like Ramda, and immutable data structures (Immutable JS), ECMAScript comes pretty close if you really want it to.
The difference is, any code anywhere can "drop out of" the functional world, whereas a functional language like Haskell enforces functional purity throughout.
Good times to be a software engineer, nevertheless!
Haskell is a single, functional programming language. It is not the definition of what a functional programming language is. If you mean Haskell, say Haskell. But don't try and redefine "functional programming" to mean "this one specific functional programming language that I happen to like".
It's only fairly recently that the set of functional programming languages for which that is even approximately true became the center of FP attention. For quite a long time, the flagship family of “functional programming” languages was the Lisp family, members of which for the most part feature none of those except possibly idiomatic recursion over iteration (though many Lisps include constructs that work like iterative loops, even though they may be implemented under the covers with recursion.)
Robust programs can be written in many languages, including 'many languages' in the sense of heterogeneity as demonstrated when a Haskell program communicates over the internet hopping through routers and switches running embedded and iOT and OS quality C code...and worse.
Functional programming techniques are great, until something else is needed. At some point databases become useful. At some point caches become important. At some point everyone winds up needing random numbers. Relying on statistics and probability isn't a bad idea either, right Siri and Cortana and Alexa?
Maybe that's enough to count as first-order functional programming ?
The Wikipedia article on Spreadsheet [1] seems to suggest that even a spreadsheet counts as first-order functional program:
>The formula may rely on the value of other cells, but those cells are likewise restricted to user-entered data or formulas. There are no 'side effects' to calculating a formula: the only output is to display the calculated result inside its occupying cell. There is no natural mechanism for permanently modifying the contents of a cell unless the user manually modifies the cell's contents. In the context of programming languages, this yields a limited form of first-order functional programming.[2]
[1] https://en.wikipedia.org/wiki/Spreadsheet
[2] https://www.cambridge.org/core/journals/journal-of-functiona...
Then, write your own recursive implementation of reduce.
I found it really helpful in grokking what these things did, and more broadly improved my understanding and use of functional composition
Now it seems we're back again with. Another example is the article explaining "this" which is on the front page again. It almost feels cyclic, like it's time for the new generation of programmers to learn the quirks.
It's probably an incorrect observation but it feels like the front page has developed with me. Like we all started on square 1, evolved together and now it's time to graduate and leave room for the new generation.
// Grab unique
[1,1,2,3,4].filter( ( item, index, array ) => array.indexOf( item ) === index )
// => [1,2,3,4]
// Flatten
[[1,2],[3,4]].reduce( ( result, item ) => result.concat(item), [] );
// => [1,2,3,4]
Not sure why the author missed `sort`. // Sort
[1,2,4,3].sort( ( a, b ) => a - b ) [1, 1, 2, 3, 4].filter(
(obj => x => {
if (obj[x]) {
return false;
}
obj[x] = true;
return true;
})({}),
);
What's happening is that you're passing an object (hashmap / hashset) into a function that returns a filtering function, and that object is used inside the closure to track the dupes. It's still a pure function because even though you're mutating the passed in object, the filtering function is still deterministic and referentially transparent. // Grab unique
[...new Set([1,1,2,3,4])] [...new Set([{x: 1}, {x: 1}])]Javascript is great but sometimes I miss the predicability of the STL.
[func(x) if x in collection if cond(x)]
makes a single pass over the data and gives you a list, but list(map(func, filter(cond, collection)))
makes two passes and requires some extra function calls.I think the real reason is perceived legibility on the part of the Python core devs. I seem to recall a document from a while ago in which GvR himself came out in favor of list comprehension style. "Explicit is better than implicit".
Too bad, JavaScript makes it hard to do it that way, in that concrete example using Object.assign() and .concat().
That depends very much on your definition of FP (or how "pure" the FP is, depending on your definition of "purity").
Would you mind expanding a bit on that point in case I totally misunderstood something?
Sometimes you just need them, e.g. when handling potentially very large vectors in finite memory. CL's (sort ...) for example mutates the input sequence (or "destructively sorts" it [2]).
[1] https://wiki.haskell.org/Mutable_variable [2] http://www.lispworks.com/documentation/HyperSpec/Body/f_sort...
Also read about using flow over chain
It also seems wrong to mutate the accumulator in the reduce example, it would just be simpler to use `forEach` and use a variable defined outside if you're going to write code this way?
1 : http://www.nicoespeon.com/en/2015/01/pure-functions-javascri...
let acc = {...}
footballPlayers.reduce(...,acc)
It should become clear: acc is an external variable that got mutated by the reduce.I'd do it like this (yay for one-ish-liners!):
const playersByCountry = footballPlayers.reduce((acc, player) => {
return {...acc, [player.country]: [...(acc[player.country] || []), player]};
}, {}); let out = ["a", "b", "c", 1, 2, 3]
// Turn letters to upper case
.map(i => {
return typeof i === "string"
? i.toUpperCase()
: i;
})
// Add one to numbers
.map(i => {
return typeof i === "number"
? i + 1
: i;
})
// split letters and numbers up
.reduce((all, i) => {
typeof i === "string"
? all.letters.push(i)
: all.numbers.push(i);
return all;
}, { "letters": [], "numbers": [] });
// => { letters: ["A", "B", "C"], numbers: [2, 3, 4] }I wish that JavaScript's map/filter/reduce functions returned lazy iterators, like in Rust, so that code like this doesn't produce intermediate arrays. Does anyone know of a library that provides this?
All I really need now is Array.map, Array.reduce, Array.filter, Array.sort, Object.keys, Object.values.
Reduce is very powerful, you just have to get to know it.
Edit: this is how I'd use reduce in this case — https://news.ycombinator.com/item?id=14919636 — talk about line numbers
yes they are both ways of iterating over the array
> I don't understand why doing this
there's more than one way to skin a cat
For those using arrow functions these days for web, most will use Babel in the build process to provide compatibility with older platforms.
I have been wondering lately what is the value of articles like this. They do not convey any meaningful idea, they do not offer any useful insight on underlying matters; why do people even write something like this, except to litter the Internet even more? Anyone, who is distinctly familiar with functional programming or even just with the concept of higher order functions, surely knows those three basic primitives; those, who are not, would benefit much more from the basic concepts of first-class functions etc, than this random abrupt post.
The article is not ground breaking or even front page worthy, but that doesn't mean it's the litter of the Internet. At absolute worst it's an exercise in thinking about a subject and trying to explain it to others.
I feel like learning is always easier in smaller bitesizes and the person wrote something very clear and digestible. Sounds like it wasn't aimed at more advanced programmers like yourself
When I first started reading Hacker News, I had never heard of functional programming...or Python.
(It's unlikely it'll benefit arkadiytehgraet, but he probably finds that with a great many things.)
* Better understanding the topic by trying to re-teach it
* Improve writing skills. Programming is basically writing but with even crazier grammar freaks.
* Employers interested in possibly hiring you will have a better idea of what you know & enjoy
* Provide yourself (and possibly your company) with documentation for the future.
Lastly if you need encouragement by someone more established than me, here's Troy Hunt at NDC Oslo 2017 - https://www.youtube.com/watch?v=-MUhcgXBj_A
If you think you have something valuable or interesting or just funny to share, that either was never discussed or written about or you know you can do better, then you absolutely should blog about it and do not let haters like me stop you.
As for the original article:
* It should have been named just "JavaScript arrays and higher-order functions" (I get that using term functional programming is very catchy nowadays, but I am trying to talk about quality here, not clickbaitness)
* As it is aimed for people unfamiliar with the concept and coming from more imperative background, where first-class functions are either not present or not that popular or handy to work with, an introduction (even the most gentle one) would be very suitable
* Then the introduction of filter/map/reduce functions would be in place, ideally compared in place with imperative implementation of the same task
* The best way to make sure a reader understands how each of this functions works is to make them implement each one of them, even the naive implementation would suffice
* Finally, you could provide some reasonably unobvious usages of any of the functions, e.g. insertion sort done with fold-only.
Sounds like you should be curating a list.
When I first started learning this stuff, I started a blog. I made maybe 3 posts before giving up on it, thinking about how much I didn't know, how that everything I could write about at the time was probably covered elsewhere and better, etc.
Several years later I regret giving up.
A lot of writing is writing for yourself. Obvious benefits to that, one of which is hopefully you get better at communication, which is huge in life in general, not just a career as a dev on a team.
Another is learning through teaching or keeping a record. I've probably forgotten a bunch of things over the years that, had I written them in my blog I may remember, or at least know where to find the post instead of scouring the internet looking for another post by someone else that I used to helped me solve a problem.
Potential employers may like seeing a blog as well. You can tell someone you're passionate about x, but where's the proof of that passion? It may not be the most in depth blog like Dr. Axel Rauschmeyer's, but it'll still show what you know. And you never know who's reading, so you may help someone in the process.
The internet is already filled with "litter" or useless things. But if you're getting use out of it then that's the main point to focus on.
It's like someone showing you multiplication and saying. See look how useful it is! See look how simple and easy it is to understand! I still don't know multiplication, or even addition for that matter.
Map and reduce are things you build up to by doing recursive functions over and over again. They are not something you learn from reading an article. Just like you can't read an article and suddenly know how to solve problems with long division.
Slagging the author for giving something to the world for free doesn't help anyone and it's almost certainly going to discourage the sharing which everyone on the internet has benefited from.
This may not provide value to you and thats completely fine. This does however provide a lot of value to the author and to others.
Writing technical thoughts in a way that is simple and understandable is a skill and I think this author did a great job of that.
Also its the internet I can write posts for myself all day long and guess what? Ain't shit you can do about it. I'll keep littering the internet with these "random abrupt posts".