Live data from Hacker News

Why I Prefer Functional Programming

morgenthum.dev

111–120 of 163 posts

Re: Why I Prefer Functional Programming

#111
post #31

I think this most effectively demonstrates why I like a lot of OOP: it can be verbose. This is example function is relatively illegible: alignCenter :: [String] -> [String] alignCenter xs = map (\x -> replicate (div (n - length x) 2) ' ' ++ x) xs where n = maximum (map length xs) One of the most verbose languages I've used, Objective C, has made this a best practice. Despite the brackets (which scare people off), it…

I'm finding that in Javascript, I really enjoy map() and filter(), but map() caused some friction on code reviews at one place, from someone I don't think had any FP background. The are best when they are one liners, of the form .map((val) => someFunction(val)) or .filter((val) => val.length > 1) reduce() on the other hand is always illegible to me. I get pretty grumpy when I am 'forced' to use a reduce because the c…

> reduce() on the other hand is always illegible to me.

I used it recently in ruby to write an sql query using Rails' ORM and it seemed quite nice to me. Something like:

  foos.to_enum.with_index.reduce(initial_query) do |query, (foo, i)|
    query.joins(...).where(...)
  end

Re: Why I Prefer Functional Programming

#112
post #87

I think these sorts of examples dodge the real issue. Of course you can show a (perhaps needlessly) verbose procedural example of an algorithm that lends itself perfectly to FP and then demonstrate how FP is far more concise. But the real issue, in my view, is what happens when the algorithm is not ideally suited to FP, otherwise we're back to the cute inheritance hierarchies in OOP textbooks. Say we're dealing with…

A simple thing like a DNS resolve is much simpler in non FP. FP shines when it's more complex, but not when it's simple. I find Go-lang a reasonable crossover where you could do a lot of FP in it where it is needed and keep it simple and boring in the rest. It's like me as an engineer: Don't use me for simple tasks because I will make them really complex.

> I find Go-lang a reasonable crossover where you could do a lot of FP in it

When people talk about FP, they usually include things like pattern matching and generics, none of which golang has. Not to mention it actively prohibits chaining functions that return errors because of the botched way it decided to handle errors as a product type instead of the correct way as sum type.

golang is a very imperative language with very little going for it.

Re: Why I Prefer Functional Programming

#113

I think this most effectively demonstrates why I like a lot of OOP: it can be verbose. This is example function is relatively illegible: alignCenter :: [String] -> [String] alignCenter xs = map (\x -> replicate (div (n - length x) 2) ' ' ++ x) xs where n = maximum (map length xs) One of the most verbose languages I've used, Objective C, has made this a best practice. Despite the brackets (which scare people off), it…

I think this is a question that's orthogonal to OOP-versus-functional-programming, but is rather about programming style. Haskell programmers like being terse, but there's also nothing stopping you from writing Haskell like this: alignCenter :: [String] -> [String] alignCenter lines = let maxLineLength = maximum (map length lines) in [ leftPadding ++ line | line You could have verbose and easy-to-read functional code…

Honestly...how is that more readable? It's more verbose sure but the first example is much more readable and straightforward. Here, you have to remember Haskell's list comprehension syntax and you have to scan up and down a few times to keep track of the variables.

Re: Why I Prefer Functional Programming

#114
post #112
post #87

Earlier quoted context omitted.

A simple thing like a DNS resolve is much simpler in non FP. FP shines when it's more complex, but not when it's simple. I find Go-lang a reasonable crossover where you could do a lot of FP in it where it is needed and keep it simple and boring in the rest. It's like me as an engineer: Don't use me for simple tasks because I will make them really complex.

> I find Go-lang a reasonable crossover where you could do a lot of FP in it When people talk about FP, they usually include things like pattern matching and generics, none of which golang has. Not to mention it actively prohibits chaining functions that return errors because of the botched way it decided to handle errors as a product type instead of the correct way as sum type. golang is a very imperative language w…

Agreed, it's still relatively possible to invent stuff that is missing though. It will grow :)

Re: Why I Prefer Functional Programming

#115
post #17

Earlier quoted context omitted.

To me this looks like perl golfing, but for some reason perl golfing is bad but writing extremely terse functional programs is not. Personally I like to combine both approaches. In swift I would write something like this: let l = ["abc", "ab", "abcdef", "abcdefgh"] width = l.reduce(0, { max($0, $1.count) }) let centered = l.map({ (line: String) -> String in var padding = (width - line.count) / 2 return String(repeati…

Obligatory C#: var input = new string[] { "abc", "ab", "abcdef", "abcdefgh" }; var maxLength = input.Select(e => e.Length).Max(); var output = input.Select(e => { var padding = (maxLength - e.Length) / 2; return new String(' ', padding) + e; }); Most modern `oop` languages these days all support functional constructs and achieve the same thing in same amount of code & style. Language and oop/functional style are not…

Sadly C# is still missing a few important ML features that making functional programming more difficult than in a true ML.

Re: Why I Prefer Functional Programming

#116

I think these sorts of examples dodge the real issue. Of course you can show a (perhaps needlessly) verbose procedural example of an algorithm that lends itself perfectly to FP and then demonstrate how FP is far more concise. But the real issue, in my view, is what happens when the algorithm is not ideally suited to FP, otherwise we're back to the cute inheritance hierarchies in OOP textbooks. Say we're dealing with…

Haskell is perfectly capable of expressing imperative algorithms and mutable state. Such algorithms are still expressed using pure functions, pure functions that return IO actions.

And x86 assembler is perfectly capable of expressing pure functions. Such algorithms are still expressed using subroutines, subroutines that save and restore all state to its start state.

The question isn't whether a language can express an algorithm, Church and Turing already proved that. The question is whether the language can do so scalably. We want to see nontrivial examples of FP applied to messy, side-effect-laden domains in a way that rivals other representations for clarity and maintainability.

Re: Why I Prefer Functional Programming

#117
post #42

As someone strongly favoring a functional or even purely functional approach, I strongly dislike the flood of pro-functional-programming blog posts that attack the straw man of "imperative programming wrapped in classes". I don't want to believe that is what experts of the paradigm consider object-oriented programming. I would love to read an honest comparison of both, judging benefits and cost.

> I don't want to believe that is what experts of the paradigm consider object-oriented programming. Once you get to the scientific literature about the subject (where actual experts reside), it tends to be much more common to see the conclusions of "there isn't any formal difference between OOP and FP languages", or that in Haskell in particular "implements an strict superset of OOP". The problem is that FP and OOP…

Formal differences don't capture how awkward something can be to use. For applied programming this matters. Maybe I can do functional programming in Java, but if it's much more verbose than Haskell and the type checker occasionally falls over then it's not a good choice.

Re: Why I Prefer Functional Programming

#118
post #17

I think this most effectively demonstrates why I like a lot of OOP: it can be verbose. This is example function is relatively illegible: alignCenter :: [String] -> [String] alignCenter xs = map (\x -> replicate (div (n - length x) 2) ' ' ++ x) xs where n = maximum (map length xs) One of the most verbose languages I've used, Objective C, has made this a best practice. Despite the brackets (which scare people off), it…

To me this looks like perl golfing, but for some reason perl golfing is bad but writing extremely terse functional programs is not. Personally I like to combine both approaches. In swift I would write something like this: let l = ["abc", "ab", "abcdef", "abcdefgh"] width = l.reduce(0, { max($0, $1.count) }) let centered = l.map({ (line: String) -> String in var padding = (width - line.count) / 2 return String(repeati…

Personally, I’d replace

  width = l.reduce(0, { max($0, $1.count) })
with

  l.map { $0.count }.max()

Re: Why I Prefer Functional Programming

#119
post #84
post #31

Earlier quoted context omitted.

I'm finding that in Javascript, I really enjoy map() and filter(), but map() caused some friction on code reviews at one place, from someone I don't think had any FP background. The are best when they are one liners, of the form .map((val) => someFunction(val)) or .filter((val) => val.length > 1) reduce() on the other hand is always illegible to me. I get pretty grumpy when I am 'forced' to use a reduce because the c…

If you think of 'reduce' as instead 'accumulating' a value, then it takes a function that adds a single element to the accumulation, and a base accumulation to use if the list is empty, and a list, and returns an accumulation of all of the elements of the list in a directional (in this case right-to-left) order. (accumulate plus 0 lst) is equivalent to (sum lst) (accumulate multiply 1 lst) is equivalent to (product l…

C++ even calls it std::accumulate. (There’s a std::reduce in C++17, but it’s just std::accumulate with the restriction that the operation is commutative.)

Re: Why I Prefer Functional Programming

#120

Earlier quoted context omitted.

You almost never use `new` in modern C++, and you would never use it as you suggest because it wouldn't compile, you would simply say: MyType x; C++ is nothing at all like Java.

Sorry, you'd need to use the MyType* x to use the `new` keyword; it's been awhile. It doesn't really deter from my point though; in order to heap-allocate something you have to use a pointer, and you end up doing something not that dissimilar from Java . > C++ is nothing at all like Java. Is that supposed to be a joke? Java was marketed specifically towards C++ engineers...

> in order to heap-allocate something you have to use a pointer

Usually the heap allocation is hidden behind a handle.

Post reply on HN