Live data from Hacker News

Why I Prefer Functional Programming

morgenthum.dev

61–70 of 163 posts

Re: Why I Prefer Functional Programming

#61
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 something like the UK share matching rules [1], where you can't simply process your items in sequential order (because the cost of shares sold on a particular day may depend the cost of shares purchased on or after that day).

The open question in my mind is whether pure functional languages scale well to problems of real life complexity, ugliness and the occasionally crucial optimization requirement.

Does FP fall apart completely in those circumstances or does it just degrade to the point where procedural code was all along? I don't have an answer to that, but it may depend on how dogmatically the purity constraint is enforced.

[1] https://www.accaglobal.com/uk/en/technical-activities/techni...

Re: Why I Prefer Functional Programming

#62
post #51
post #28

Earlier quoted context omitted.

I don't really like 'where n' afterwards instead of say 'let n' at the beginning, but I'm not very familiar with haskell (really just enough to know the first line is a type signature) and I found this ok. Maybe objective C is better though.

My first thought, too. OTOH, with indentation like in the example I could live with it.

Indentation is always like in the example. Haskell has either semantic whitespace of braces everywhere, and nobody uses the braces.

Re: Why I Prefer Functional Programming

#63

What I dislike about functional programming is that when objects are not supported or they are avoided I have seen poorly documented and complex hashes/collections data structures that end up reinventing the oop wheel (and the problem the wheel was solving in the first place). It feels like a false choice and you can have rich FP capabilities in a language that supports objects and relationships between objects.

> omplex hashes/collections data structures that end up reinventing the oop wheel (and the problem the wheel was solving in the first place)

I don't think I know what you mean here...Typically wheel-reinventing in FP languages happens because the stuff in the OOP/Imperative languages require a lot of mutation, which doesn't really jive in FP land for a whole plethora of reasons.

> It feels like a false choice and you can have rich FP capabilities in a language that supports objects and relationships between objects.

Sure, I'm partial to F# myself, but at some level I get frustrated when people try and mix paradigms too much. C++ has this problem of trying to be everything, and as a result it is very hard to read large C++ codebases. Scala isn't quite as bad, but it has similar problems.

Re: Why I Prefer Functional Programming

#64
post #57

Earlier quoted context omitted.

"To me this looks like perl golfing" I think that's preposterous and totally unfounded. The identifiers have names like "alignCenter", "replicate", "maximum" and "length". Those are all actual full English words, nothing remotely obfuscated about them. "map", "++" for concatenation, and "x/xs" for an arbitrary list of things are all idiomatic so can be kept short because they are used so often, like pronouns in Engli…

Ok. My problem with functional programming written like this (I admit that this example is too short) is that once there are too many functions combining with other functions it is very easy to lose thread of what is happening. My comparison with perl is more to the point that these programs are way easier to write than read. Again, this example is too simplistic to illustrate my point, but what I like with combining…

That is why the importance of being terse but following the rule of not going too far with nesting and pointfree is so valuable. I don't share your difficulty to follow the flow of the program as usually the name of the function, type, and documentation say all you need to know about it.

That said, I find it difficult to follow what is happening when using several variables as you're then likely doing something wrong in the complexity of the function. A function should say much with very little and control flow should be clear instantly. The only thing outside of this would be a procedure which do-notation allows one to express.

Imperative programming is already within Haskell with do-notation an it's composition is that of imperative. Mixing functional with something else makes it much harder to make use of combinators and other forms which ends in more messy code (in my experience). If one could go pure functional without do-notation emulating the "C monoid" it would be rather nice.

Re: Why I Prefer Functional Programming

#65
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 are ill-defined concepts.

Re: Why I Prefer Functional Programming

#66
post #11

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…

As a lisp programmer who never wrote in Haskell the snippet you quoted is crystal clear to me, while with explicit loops I always have to double check, because I am pattern matching the code "ah, a map or reduce was meant" but I still have to double check assignments and the abort condition (off by one, incrementing the wrong index etc).

I write Lisp but I have no idea what /x means in the example above for instance.

Re: Why I Prefer Functional Programming

#67

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…

Haskell is very terse, but it doesn't mean that this is true for every FP language. Code below is in Gerbil Scheme and should be readable even for OOP programmers.

    (def (alignCenter strings)
      (def n (apply max (map string-length strings)))
      (def (align s)
        (let* ((count (round (/ (- n (string-length s)) 2)))
               (whitespace (make-string count #\space)))
          (string-append whitespace s)))
      (map align strings))
Here also the same code in JS, which is almost identical.

    function alignCenter (strings) {
      const n = Math.max(...strings.map(s => s.length))
      const align = s => {
        const count = (n - s.length) / 2
        const whitespace = ' '.repeat(count)
        return whitespace + s
      }
      return strings.map(align)
    }

Re: Why I Prefer Functional Programming

#68
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…

"but map() caused some friction on code reviews at one place" Someone not familiar or comfortable with "map" should not be working as a professional programmer today. Most languages now support "map" or something very similar. Try to move to a different team or different company with actual professional developers.

That was more of a "it's not universal" comment. Sometimes the right solution is self obvious, other times it needs PR.

If I write a piece of code so others don't have to, then it's a service I'm providing. If they don't 'get' the code then the problem is not always with them. It's important to watch for patterns in the questions or complaints you get. There are often multiple acceptable ways to solve the same problem and everything goes smoother if the one you use doesn't trip people up.

In this case I pointed him to some documentation on filter and map.

Re: Why I Prefer Functional Programming

#69

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…

Agreed. My first thought was that you can do the exact same thing as the Haskell code in C++ using from the STL.

The biggest advantage I find to functional languages is they force you to write code that's more testable and modular. I now actually write almost every OOP class to have all functionality in private static methods with the public interface methods mostly only doing the work of gathering the args for the private static methods.

Re: Why I Prefer Functional Programming

#70

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…

This opinion is flameworthy and stereotypes heavily: what seems to happen in FP is that the overall community is substantially math-IQ smarter than the imperative languages. Alas, that ALSO means the overall community loses social-IQ in the process. This leads to: 1) higher barrier to entry for the general programmers, in language semantics, documentation, examples... 2) a tendency to overabstract, underdocument, and…

Maybe we just need to have more math training for people who want to become Computer Programmers.
Post reply on HN