I've been coding in JavaScript where functions are treated as first-class citizens, they also play the role of implementing the key OOP concepts (encapsulation/inheritance/polymorphism), but does that make JavaScript a functional language?
Those who have coded in other functional languages like haskell say that JS isn't a "true" functional language. I'd like to know what are these features that make a language truly functional?
Top comments (11)
I think the functional vs non-functional is kind of a spectrum, rather than a binary thing.
There are some features of programming languages that are considered "functional": higher order functions, immutable data structures, recursion + tail call optimization
There are some features that are considered "non-functional", like functions with side effects, mutable data structures etc.
Some languages implement most of the functional features and few non-functional, for example Haskell is a strongly functional language, it does not allow you to mutate state, and side effects are done via monads
On the other side we have languages like C, which are strongly imperative: there are no built-in immutable data structures, higher order function are possible, functions are not first-class citizens (you can't pass a function as an argument, although you can pass a pointer to the function).
So now after this long introduction, the question is where to put JavaScript on this spectrum?
JS has some built-in functional features: high order functions, first-class functions, anonymous functions, etc. At the same time, the built-in data structures like objects and arrays are mutable and you can write imperative code in JS. Therefore I would say that JavaScript allows you to write functional code, but it does not force you to do that (so I would put it closer to "imperative/OO" than "functional" on the spectrum)
I have never written haskell but I have been reading about functional programming for a while now. Here a the things I think javascript is not truly functional.
The keyword
function
exists and we use that word to describe them but the blocks of code we write are more like procedures, that is just a group of instructions. "Pure functions" in javascript only exists by convention.In haskell for example, one does not simply print something in the screen. A function in haskell can't change anything in the outside world (not without help). You actually have to make an effort to produce any kind of side effect.
Things like partial application and function composition are second class citizens in javascript. There is support for them, you can make them yourself, but the language doesn't give a very special treatment to them.
They're everywhere in javascript. The language was built for them. It's just the way it is. This isn't bad, it makes javascript fun to work with and very practical. Functional languages go to extreme lenghts to push those side effects to the "edge" of every program, or at the very least control them and make them predictable.
What is functional programming?
In Wikipedia, "In computer science, functional programming is a programming paradigm where programs are constructed by applying and composing functions."
With Js you have the option to construct your program by composing and applying functions but,
I don't really understand what truly functional language means. In my point of view, the functional programming is more on the programmer and less on the language.
It's a combination of both.
Functional programming is a programming paradigm: it's a specific way of writing code, where you follow certain rules.
You can write functional programs in many object-oriented languages, such as JavaScript and Python, but these programs aren't truly functional since their constructs don't fully mesh with the framework and rules of functional programming.
That's where languages like Haskell and Clojure come in — these are purely functional programming languages that do not have the traditional OOP constructs, and force the functional programming paradigm's rules, such as never mutating state directly and always keeping functions pure.
But yes, functional programming is essentially the composition of pure functions. Rather than telling the computer how to do something, you define what the program is to do.
The one thing I miss the most when using non-functional languages is pattern matching. It's everywhere in FP and makes life so easy. And along with that comes sum types that you can easily pattern match on. Sum types are basically enums but you can have some values of different types associated with the different choices.
Partial application. It's incredibly useful, especially when using higher-order functions like
map
. And it's used everywhere.Forced immutability. It can help avoid so many pitfalls, and it doesn't let you fall back to using mutability if you don't know how to do it with immutability. The main problem I see with learning FP using a language like JS or Python is that you can easily fall back into their comfort zone if you don't know how to solve something. It also gets rid of those pesky global variables.
Haskell takes the functional aspect to the next level, but a lot of it isn't shared with most other functional languages. Like monads and other category theory things. If you are looking to learn a true functional language I would recommend F# or Clojure. Haskell is also a good alternative but it has a very steep learning curve.
That's a really good topic!
You can do functional programming in all general purpose languages nowadays.
I think JavaScript is the best programming language for functional programming of the top 10 most popular languages in use today.
Though I use JavaScript functionally every day, and it's a fantastic language for it, there are a few things on my wish-list that would make it even better.
Some wishlist items include...
design-time strong typing (unfortunately TypeScript is modeled on C# and geared for the Object-Oriented paradigm)
run-time strong typing
read-only input params (the design-time linter helps out here though)
first-class JSDoc support for nested lambas
callbacks do not play well with FP, but async-await alleviates that
the built-in functions have to be converted into free functions, so they can be composable
currying a first-class construct
JS is pretty much LISP, or better say Scheme, with C-like syntax. I guess you can call it functional... Oh yeah, you also get closures.
Javascript is a procedural language with good support for a functional programming style.
In this regard it is like scheme and common lisp.
Definitely functional enough for me.