Hacker News new | ask | show | jobs
by MaxBarraclough 2200 days ago
> I recommend starting with a gentle approach that doesn't require picking up a new language

Disagree. This is likely to 'dilute' the lessons of functional programming, as it were. If you learn to program in idiomatic Clojure/OCaml/Haskell/Scheme, you can be relatively sure you really have picked up the principles of functional programming.

If you merely attempt to apply new principles in an environment you're already comfortable in, things aren't going to 'click' in the same way.

Beside that, plenty of languages simply lack the facilities needed to effectively use the concepts of FP, as vmchale says.

3 comments

I can confirm this. Although I knew the principles of FP, concepts didn't click until I started using a functional language.

In non-FP languages, I didn't originally appreciate the benefits of the pattern. It was more work to do things functionally, so I dismissed some patterns that were actually useful.

I'm a bit biased, but would recommend Elixir as an accessible FP language. It has an accessible syntax and modern tooling.

You may be frustrated with the constraints of immutability for a few weeks, but the benefits become apparent once you're used to it.

Now when I work in non-FP languages like JavaScript, I will apply FP principles when it makes sense.

Some people say learning Latin makes you a better writer, smarter, etc. even if you're unlikely to directly use it. Dubious claims but it feels like FP can be like that.
The thing about learning Latin (not that I am great at it), at least for an English native speaker, and the epiphany English language speakers have, is the realization that language can have structure and can be discover-able, if I know a root word then I can almost be sure that I know the meaning of con, re, dom etc. There is just no equivalent to that in English other than the Latin origin words we borrowed, because we just assimilate any words we like and make up new ones as we see fit. An example would be beaucoup a Vietnamese word but most US English speakers would know it means big. Without the historical reference of a movie you would not have a reason or rhyme why an Asian origin word made it into English. There is literally no reason or rhyme to most of the spoken language and I think that is the epiphany, that some people actually thought out a logical way to create a language and via that logic it is discover-able.
Isn't beaucoup French?
Yes it is - France has colonised part of vietnam
yes, and as Army slang, it made it into American English through Vietnamese
Very cool. Did not know this. Will have to tell my Vietnamese wife. We were trying to figure out if English had any Vietnamese words. I think this counts.
I'm pretty sure in Louisiana it was already in slang through French here
Hundreds of years of French culture through Louisiana.

Other unique French US cultures:

Haitian Creole

New England French were are Canadian migrants.

Missouri French

Muskrat French from Michigan

North Dakoka Metis French

It could have come to some from 40 years old but it was already here for many.

Still it's a French word. It is like going to Germany and learning an English word but calling it German.

Sure. When learning Latin, well, you learn to read and write Latin. You absorb the language's principles by learning the language, not by trying to highlight them in a language you already know. That can only give a much shallower appreciation.
Not quite true - many complexities of grammar are shared between the languages and it is often useful to structure the learning of Latin around the English patterns of grammar.
I imagine that diligently learning a foreign language (dead or otherwise) will make you smarter, especially if the free time spent on it would otherwise be spent on less academic pursuits.

(edit: spelling)

For me I get the most benefits from using FP features. I can write one-liners that are easy to read, and replace 10's to 100's of lines of my code.

For a simple example, val newList list.map(function Call(_))

Instead of val1 = functionCall(1) valN = functionCall(N)

A side note: "Dubious" comes from Latin, sharing the root of "duo", which means two,in this case referring to the possible indecision between two things or ideas.
Even in languages where the concepts can be encoded, it can be hard to determine what aspects of a given library are the encoding and which parts are the fundamental ideas if you haven't seen the ideas used in well-suited language. For instance, I didn't really understand the use of functools.reduce[0] or itertools.starmap[1] in Python until I was familiar with zipWith[2] and foldl [3] in Haskell.

The ideas themselves are not particularly complicated, but I hadn't previously worked with abstractions where the default was to operate on whole data structures rather than on individual elements, so I didn't see how you would set up your program to make those functions useful. In addition, for abstract higher-order functions, type signatures help a lot for understanding how the function operates. I found `functools.reduce(function, iterable, initializer)` significantly more opaque than `foldl :: (b -> a -> b) -> b -> [a] -> b` because the type signature makes it clear what sort of functions are suitable for use as the first argument.

It's now easy for me to use the same abstractions in any language that provides it because I only have to learn the particular encoding of this very general idea. While I couldn't figure out why functools.reduce was useful or desirable, I couldn't figure out many parts of C++'s standard template library at all. But if you already know the core concepts and the general way that C++ uses iterators and the fact that functools.reduce, Data.Foldable.foldl, and std::accumulate[4] are all basically doing the same thing for the same reasons is a lot more readily apparent.

[0] https://docs.python.org/3/library/functools.html#functools.r...

[1] https://docs.python.org/3/library/itertools.html#itertools.s...

[2] https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-...

[3] https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-...

[4] https://en.cppreference.com/w/cpp/algorithm/accumulate

> it can be hard to determine what aspects of a given library are the encoding and which parts are the fundamental ideas if you haven't seen the ideas used in well-suited language

That's a good point. Using a proper functional programming language doesn't just enable FP ideas (you can't fake a feature like implicit capture of variables), it may also clarify them by reducing baggage.

> I found `functools.reduce(function, iterable, initializer)` significantly more opaque than `foldl :: (b -> a -> b) -> b -> [a] -> b` because the type signature makes it clear what sort of functions are suitable for use as the first argument.

I suspect you're just a better Haskell programmer than me (I've only ever dabbled), but I find the big-mess-of-arrows syntax to be pretty confusing compared to a simple tuple of descriptively named identifiers.

Perhaps related to this: I don't see the practical appeal of currying. Even C++ supports the 'bind' pattern just fine - http://www.cplusplus.com/reference/functional/bind/#example