Hacker News new | ask | show | jobs
by microtonal 1318 days ago
After a few decades in SWE, however, I've become sort of a fan of designing software for that 17:00 Thursday EnKopVand mindset, and functional programming helps a lot in that regard because it kills soooo many of the complexity pitfalls that you really don't want to deal with when you're tired, lazy and incompetent.

It's so funny, because I thought your comment would lead to: when it's 17:00 on a bad day, I'd rather debug some Go code that is perhaps mundane but easy to follow than a chunk of Haskell code of a colleague that drank too much category theory kool-aid.

Which goes to show that what one wants to debug at 17:00 on a bad day is very personal?

2 comments

I mostly write Typescript these days, and being lazy, I'll just quote wikipedia, but I'd much rather debug:

  const result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    .filter(n => n % 2 === 0)
    .map(a => a * 10)
    .reduce((a, b) => a + b);
than:

  const numList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  let result = 0;
  for (let i = 0; i < numList.length; i++) {
    if (numList[i] % 2 === 0) {
      result += numList[i] * 10;
    }
  }
Maybe it doesn't make so much sense in this simple example, probably even less so if you're not familiar with Javascript, but it mostly comes down to the state of what you're working on. In FP you know what you get, how it looks while you're working with it and exactly what to expect as the outcome, in OOP, well, you sort of don't. Reading Wikipedia, though, maybe what I like is called Functional Programming with Higher-order functions and not just Functional Programming?

Like I said. I'm not extremely religious about it, and I do think a lot of OOP design principles and code practices are slowly heading toward a more FP way of thinking. In that way I think it's sort of interesting that you mention Go, because with Go you seem to mostly work with immutable states and functions, rather than mutable objects, which is more functional than imperative programming, but maybe I just haven't worked enough with Go to know better. If you ask me, everything should frankly be immutable by default, but retrain the ability to become mutable like they do it in Rust with the "mut" keyword. I really, really, enjoyed working with that for the brief period I did. Anyway, I'm not sure I'm ever going to get into religious FP, I may very rarely use classes, but it's not like an abstract class can't be healthy for your 17:00 afternoon self once in a while.

But basically every best practice in regards to OOP that I was taught at university back 20+ years ago, the stuff they still teach today (I'm an external examiner a few times a year), has proven to be sort of useless in the real world for me. Maybe it works in more professional or competent organisations but it sure hasn't worked well in any place that I've ever worked, and yes, it does feel sort of dirty to examine people in theories I disagree with, but it's good money and a good way to keep up with both the CS world and possible hires.

> Which goes to show that what one wants to debug at 17:00 on a bad day is very personal?

It really depends, it's possible to write mundane, simple functional code (though I think more common in OCaml and Erlang than Haskell) but much of the community is sort of very excited about all this higher-order stuff that might be great but is not quite as useful and obvious as the core primitives of algebraic data types and pattern matching. I imagine a lot of people probably felt similarly about the Design Patterns craze with OOP: it's not that OOP isn't useful, just that inheritance is maybe not what you want most of the time and not everything needs to involve design patterns.

I'd rather be debugging an OCaml program than a Go program for sure.

Right, but I think (a combination of) certain abstractions invite abstractionitis. OCaml and Erlang avoid that to some extend by being more restrained about what they add to the type system. On the other hand, these languages allow side-effects, removing the need to rely on monads, monad transformers, monad transformer stacks, etc.

I agree that algebraic data types and pattern matching lead to better code. But even though they were introduced (?) by ML, there is nothing holding imperative languages from adopting them (see e.g. Rust).