Live data from Hacker News

Why I Prefer Functional Programming

morgenthum.dev

81–90 of 163 posts

Re: Why I Prefer Functional Programming

#81
post #11

Earlier quoted context omitted.

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.

It means a 1-argument lambda, where that one argument is named x

Re: Why I Prefer Functional Programming

#82
post #14

I still don't get the point of immutability. Sure state change is a problem. How about a log like data structure that stores all modifications of the data? I'm sticking to procedural coding for the next 10 years and I will try my best to unwash young coders from poop.

> I still don't get the point of immutability

If you're the sole developer, it's probably not a big deal. If you're working with a group of people, immutability is the only way to maintain your sanity.

Re: Why I Prefer Functional Programming

#83
post #21

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.

Then you should look into Scala

Scala is fine, but do you not feel that it tries to do too much sometimes?

Like, I like Scala if I'm the only person writing it; I basically write Haskell while still having access to all of Java's libraries, but I absolutely dread having to collaborate with people using Scala.

A coworker of mine (whom I respect very much) said it pretty well once: "I write Scala...but in a Java accent"...he doesn't use the functional features of the language, and basically just writes Java without semicolons. When we try and collaborate on stuff, it becomes difficult because of the sometimes-conflicting way we write code.

Personally, for functional-on-the-JVM, I prefer Clojure. You still have access to all the Java libraries, but it's a bit more decisive on what it wants to be: a functional, dynamic lisp on the JVM. While you can write OOP-style code in Clojure using records and protocols, it's often frowned upon, and not always 100% intuitive....virtually every tutorial you'll find on Clojure writes in a pure-ish functional style.

Re: Why I Prefer Functional Programming

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

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 lst)

(accumulate (lambda (x acc) (cons (fn x) acc)) '() lst) is equivalent to (map fn lst)

(accumulate (lambda (x acc) (if (fn x) (cons x acc) acc))) '() lst) is equivalent to (filter fn lst)

and so forth. The essential insight is that reduce/fold/accumulate reduces the problem of accumulation to a base accumulation and a function that only has to add a single item (i/o)nto the accumulated value. Using them to directionally processes a container is idiomatic in a functional style.

Re: Why I Prefer Functional Programming

#86
post #47

Earlier quoted context omitted.

What is illegible about that?! It just says, in code: "replace each line of text with itself prefixed by a number of spaces equal with half of the difference between its length and the length of the longest line in the text". It's like the most obvious way to think about this particular problem! Now, how well this scales to different problems, and especially to problems where mutation is a natural way to think about…

As usual in FP code, the order of your words are completely different from the order things appear in the code. Also, most developers aren't used to concise function declarations (yeah, even with JS pushing them), what further adds to the problem. This is not something people with no experience on FP can read easily. Now, calling it illegible strongly implies that people with no FP experience are the metric one shoul…

Order of words is not that relevant, in English I can say instead of the above:

"take each line of code [map ... xs] and replace it with [\x -> ...] a number of spaces equal to half the maximum line width [replicate (div (n - length x) 2) ' '] prepended to it [... + x]"

All languages have passive voice and other tools so you can make the order of words be whatever you'd want for customizable emphasis while keeping meaning the same.

Sure the order for arguments for `map` may not be the most intuitive, but that doesn't make things harder. See ReasonML for an example of functional programming with regular C-like syntax.

Now, if you want to see hard to read functional code, look into code abusing point free style (I'm not even sure there is a fine way to use it at all...), plus mind bending types (usually to satisfy some monadic style abstractions), plus over-currying stuff all over the place.

But the snippet above is only unreadable for people who stubbornly refuse to invest a couple hours of their time into learning a new notation for things! Heck, you can even translate it almost 1-to-1 to modern Javascript, or even add an extra function name and some more sensible variable names to make things more readable while keeping it functional:

    function alignCenter(lines) {
      let width = Math.max(...lines.map(ln => ln.length));
      let getPadding = len => ' '.repeat(Math.max(0, (width - len) / 2));
      return lines.map(ln => getPadding(ln.length) + ln);
    }
...the above is more like something I'd actually let pass code review in real life :)

Re: Why I Prefer Functional Programming

#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.

Re: Why I Prefer Functional Programming

#88
post #11

Earlier quoted context omitted.

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.

That's a syntax knowledge problem, not a readability problem. \x -> introduces a lambda function with a parameter x, like (x) => in javascript etc.

Re: Why I Prefer Functional Programming

#89

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 most effectively demonstrates why I like a lot of OOP: it can be verbose. Verbosity is not inherently good. In fact, I think verbosity is inherently bad . Have you read much first-year programmer code? It's absurdly verbose at the cost of legibility. The real issue is clarity . Your code should be sufficiently verbose that its purpose is self-evident, but it should not be overly verbose such that your…

> Verbosity is not inherently good.

Agreed.

> In fact, I think verbosity is inherently bad.

Here I disagree. To take it to an absurd extreme: LZW compress your source code. Hey, it's less verbose! But that's not a net win.

Instead, I think that there is an optimal value of terseness. More verbose than that, and you waste time finding the point. More terse than that, and you waste time decoding what's going on.

Now, what is "optimal" is going to depend on the reader, both on their experience and their preference. With experience, certain idioms are clear, and don't require thought. The same is true of syntax. (Both Haskell and C become more readable with experience.) But some people are still going to prefer (and do better reading) a more terse style, and others are going to prefer a more verbose style.

Re: Why I Prefer Functional Programming

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

In what sense is Haskell a "strict superset" of OOP?
Post reply on HN