Live data from Hacker News

Why I Prefer Functional Programming

haskellforall.com

31–40 of 129 posts

Re: Why I Prefer Functional Programming

#31
post #8

Functional programming appeals to many of us for reasons other than these practical considerations: Functional programming feels like reasoning in algebra. As in Modern Algebra for math majors (groups, rings, fields) and beyond. There's a saying in mathematics that when any field matures it turns into algebra. Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order i…

> There's a saying in mathematics that when any field matures it turns into algebra. Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order in mathematics crosses a similar threshold, as it becomes sufficiently structured to support algebraic reasoning. The subjective experience is like ice melting into a churning liquid, or a land-locked creature learning to fly. O…

Good point... The realization that chaotic systems are ubiquitous, and that many physical phenomena (motion of the planets, how chemical interactions work at the electron level etc) can't be modeled analytically (so far as we know) was a big upset to mathematics and science, and still isn't addressed well in school curriculum.

To expand on your main point: A loose, but appropriate analogy is that FP appeals to programmers in the way analytic solutions appeal to mathematicians and scientists: Neat, ideal, beautiful... but a poor fit for many practical problems.

Re: Why I Prefer Functional Programming

#33
post #25
post #23

Earlier quoted context omitted.

> To this day it has the best implementation of parallelism; one can achieve a 7x speedup on 8 cores by adding a handful of lines to a program. Eh, you can achieve the same in Rust using rayon, this isn't exclusive to Haskell or FP. Do you have an example in Haskell, where you get an effortless speedup which wouldn't be easy in another language?

Yeah, but Rust isn't exactly a counter example, I think. It's heavily inspired by Haskell, its type system, as well as FP in general. So, it sort of inherits (pun not intended) its parallelization capabilities from that.

What? No. Rust has some influence from Haskell in terms of traits and such, but Rust's parallelization capabilities comes from its tracking of mutability. (No, Haskell did not invent caring about mutability.)

Also, succinct expression of parallel algorithms isn't a particularly unique feature. Like half of the named algorithms in the C++ standard library can be parallelized by adding a single parameter.

Re: Why I Prefer Functional Programming

#34
post #25

Earlier quoted context omitted.

Yeah, but Rust isn't exactly a counter example, I think. It's heavily inspired by Haskell, its type system, as well as FP in general. So, it sort of inherits (pun not intended) its parallelization capabilities from that.

Heavily? It's actually heavily inspired by ML (SML/OCaml), not Haskell. Most of its functional programming attributes originated in SML, and has avoided most of the things that make Haskell unique. Really it is just type classes that came from Haskell.

Type classes are just a way of doing module interfaces or Objective-C protocols/categories, as prior art before Haskell or Miranda came into being.

Re: Why I Prefer Functional Programming

#35

I disagree with the higher order functions thing. Writing functions that receive other functions as input can lead to over complicated code that's really hard to read. It's literally the same thing as dependency injection just with functions instead of objects. Use sparingly. I would avoid altogether except for common ones like map, reduce and filter. Functional programming promotes the idea of composition of morphis…

Writing functions that receive other functions as input can lead to over complicated code that's really hard to read.

I work in FP languages, and I find this type of code extremely intuitive and easy to understand.

I suspect that you are just not used to thinking this way, and that with more familiarity, you would not have this opinion.

Re: Why I Prefer Functional Programming

#36
post #22

Earlier quoted context omitted.

> There's a saying in mathematics that when any field matures it turns into algebra. Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order in mathematics crosses a similar threshold, as it becomes sufficiently structured to support algebraic reasoning. The subjective experience is like ice melting into a churning liquid, or a land-locked creature learning to fly. O…

> In particular, a few years ago it seemed like the people implementing parallel Haskell features didn't understand or care about fundamental things like cache locality. That's the main issue which FP-for-parallel-execution proponents don't seem to get: Identifying independent (and therefore parallelisable) computations isn't the hard part, but planning the data layout and partitioning so that all your parallelism is…

I think it may be more accurate to say they are both hard problems. It is still open if P=NC.

Re: Why I Prefer Functional Programming

#38
post #23
post #8

Functional programming appeals to many of us for reasons other than these practical considerations: Functional programming feels like reasoning in algebra. As in Modern Algebra for math majors (groups, rings, fields) and beyond. There's a saying in mathematics that when any field matures it turns into algebra. Life crossed a threshold from chemistry to biology on Earth, and developed exponentially from there. Order i…

> To this day it has the best implementation of parallelism; one can achieve a 7x speedup on 8 cores by adding a handful of lines to a program. Eh, you can achieve the same in Rust using rayon, this isn't exclusive to Haskell or FP. Do you have an example in Haskell, where you get an effortless speedup which wouldn't be easy in another language?

From the article at https://medium.com/@s.nawaz/optimizing-ray-tracing-in-haskel...:

> let colors = fmap computeColor coordinates

to

> let colors = fmap computeColor coordinates `using` parListChunk 32 rseq

So half a line added to parallelize the mapping a pure computation including using a sensible threadpool implementation. How impressive you find this depends on how you define "easy in another language". Rayon comes pretty close but you can encode some properties about your computation in the Haskell type system that Rust does not yet support and so the safety of some computations can be statically proven in Haskell but not in Rust.

Re: Why I Prefer Functional Programming

#39
post #32

I think it all comes down to one question, do you need objects or not?

And also what is an 'object'?

Haskell has a decent system for building up complex data structures. You can write functions for those. Those data structures + those functions are kind of "an object" from the OO world (data + methods).

The differences are:

* Inheritance - well Haskell has many kinds of polymorphism so it doesn't need it.

* Hiding data - well Haskell can hide data using smart constructors, you don't need an explicit private keyword

* Interfaces - covered by typeclasses but they do a lot more!

Also without any of the above you can create object-like things with just closures. If a scope has access to 3 variables in scope, it's "kinda" like an OO object with 3 member variables. You can create new scopes in a for loop, which is like creating many new object. It's a stretch but the underlying concept of something owning other things is still there.

Re: Why I Prefer Functional Programming

#40

I disagree with the higher order functions thing. Writing functions that receive other functions as input can lead to over complicated code that's really hard to read. It's literally the same thing as dependency injection just with functions instead of objects. Use sparingly. I would avoid altogether except for common ones like map, reduce and filter. Functional programming promotes the idea of composition of morphis…

I agree to some extent. When I see this in imperative code-bases, it can be used as a way to reduce lines of code and save having to define a new class. But when debugging or trying to make sense of the code it can be awful. However it's not the passing functions to functions that is the problem, it is the division of responsibility not being though through while doing so.

As a silly made up example, you pass a callback to an XML parser to tell you when a node has been parsed, so you can pass in a callback to call an API to let it know. Doing something like that just pollutes the XML parser code for no good reason, and you then debug and find you get a 400 error when trying to parse something and 'wtf' and you have to untangle the callbacks.

I'm having a hard time summing it up right now, but I think if you try to "libraritize" "specific code", i.e. make something that does a very specific job, too generic it causes confusion.

That example has 1 callback but believe me some developers want to stack 'em high.

Post reply on HN