Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Programming is hard. A few years back, in the 90's when most of the code in my field was still mostly structured, and bad at that, a lot of people were saying that OOP would sort it out. I was skeptical, not because I'm resistant to change, but because it was obvious to me that doing OOP right was (and is) very hard. Not that structured programming was easy.

Fast forward to today: programming is still hard, and actually it probably got a lot harder. OOP did not sort it out. Most of the code in my field is object-oriented, and bad at that. A lot of people are saying that FP will sort it out. I am skeptical, not because I'm resistant to change, but because it is obvious to me that doing FP right is (and will be) very hard. Not that object oriented programming is easy.

Am I alone in thinking that fast forward a few years, once there is enough rotten FP code written, we will be reading people ditching FP because it's the root of all evil?

The facts are that programming is hard. Working with legacy code is hard. Learning a paradigm well enough so the code you write in it is not total crap is very hard, and requires years of practical experience if you are proficient at another paradigm, let alone if you simply skimmed a paradigm and moved away because it was too hard...

It's great that people want to move on from single-platform, single-paradigm monocultures, with one caveat: breadth without depth is shallowness.

I'd like to read people treating languages and platforms as tools and not as cargo cults. You don't read carpenters writing they'll ditch hammers for screwdrivers because the old cupboard they are fixing uses nails. You read carpenters debating the pros and cons of using hammers versus screwdrivers. And you read better carpenters that debate how cupboards are designed, because it is ultimately more important than whether they are glued, nailed or screwed.



Some changes are real progress:

  - automatic memory management by default
  - testing by default
  - distributed version control by default
All of these make you more productive in a typical project. (And should be turned off when not, that's why I say, by default.) I suggest that the following are also unalloyed good, and will make their way into more and more languages over time:

  - functions as first class values
  - immutability by default / copy-on-write semantics by default
  - side-effects only possible when declared (eg IO Monad)
  - powerful static typing by default
(We already see in eg git and some file systems that even when the implementation is imperative, immutability makes concepts simpler. Immutability by default virtually requires automatic memory management.)


I agree that FP will not be the solution to all problems just like OO wasn't, but what FP does is it forces the developer to think hard in every situation. There are fewer shortcuts that can lead to broken abstractions and hard to find errors.

On the other hand, with OO you are always just a few more lines of code away from shipping. It's popular because it provides easy abstractions over data (rather than operations), but as we all know it causes unnecessary coupling and broken abstractions if you aren't careful. Imperative programming (not just OO) presents a lot of problems for concurrency, which is perhaps the biggest problem in the coming decade.

OO can be done right, but when it is, it's just as "hard" as FP. In fact, a lot of good OO code is functional in nature.

What is tempting about FP is that it will make programming hard enough that bad programs won't ship. Is proponents of FP think that programming should be hard. That it should require a lot of thought up front, for every line of code.

In a good lang and framework, a complete program is a good program. This idea is likely not very welcome in an industry where deadlines are always more important than quality.


What I 'love' about object-oriented programming is that every other year there is a new pattern or paradigm that is shoved down our throats by opinion leaders and self-proclaimed OO-gurus. These architectural patterns all make sense on the surface but by the time people try to apply them in real life and realize that they are mostly a load of horse shit, the instigators have already moved on to the next "big thing". And this pattern is repeated ad infinitum.


The problem is that the pattern that are being discussed ( or a pattern in general, that's far from limited to OO ) are applied by a team of dedicated developer, combing the code meticulously, generally with near-limitless budget.

You read the story about how Linked In, Facebook, LMAX and you dream of applying that.

That won't work. Those companies decided to go with their current infrastructure after their previous one failed miserably and threatened their billion making core business.

Real life for most developer is a lot duller. Very often you will have barely enough to do what need to be done. Consistency, code gardening is difficult to justify a budget for until the house is on fire. No matter how good the pattern you use, the code will be shit if you don't have time to maintain it properly.


Any specific examples?

The patterns I know of, e.g Gamma/Beck/etc "Design Patterns" are pragmatic and useful solutions to common architectural problems.

And no, they are not "only for languages without first class support for some features", as some think. Or, actually, some of them are, others are useful regardless of language. Heck, a lot of them came from Smalltalk, a language which is expressivity wise miles ahead compared to "modern" languages like Go or Java).

That some people abuse them is not an inherent problem in them. Other people abuse macros, or gotos, or functions (the 100000 line function monstronsity) etc.


This can be called "The Professor Harold Hill problem", named for the character from "The Music Man".


> I'd like to read people treating languages and platforms as tools and not as cargo cults. You don't read carpenters writing they'll ditch hammers for screwdrivers because the old cupboard they are fixing uses nails. You read carpenters debating the pros and cons of using hammers versus screwdrivers. And you read better carpenters that debate how cupboards are designed, because it is ultimately more important than whether they are glued, nailed or screwed.

The problem with this carpenter analogy is that it simply doesn't scale - a carpenter is not going to build a skyscraper. To build skyscrapers we need engineering - the practical application of science - something which is completely missing from our field. We call ourselves software engineers, but we're really software masons - we can do good work in small quantities, but we're terrible and building big structures - which is where many of our software problems lie.

You can't build a house on some land, and later turn it into a skyscraper either - because the foundations are perhaps the most vital part of the structure - they need to be designed with some knowledge of the size, shape and mass of the structure they intend to support. The approach taken in software development is the tacking on of new systems - building structures equivalent to say, the Kowloon walled city (unsightly and unstable).

To do engineering and science, we need math - and we have no sound way of modeling imperative languages/programs in ways that makes them useful as mathematical concepts. FP is math - so building up concepts in these languages is providing a richer set of math objects and abstractions which we can later use to build our large structures. Using FP doesn't mean we need to abandon imperative coding - it just means we should clearly mark the effects of such imperative chunks of code, so we can treat them mathematically.

Carpenters are still relevant in the construction of skyscrapers - but their responsibilities are only a small part of it - they're given clearly defined boundaries of when and where they should be working. This is really how we should be doing software - we need engineers and architects to build structures, using science and math, then assigning isolated environments for the "masons" (e.g, junior programmers) to work in - in such a way that a mistake by a junior programmer cannot bring the entire skyscraper crashing down. (Turns out this was understood in the 70s, because Unix pipes and processes are still the best approach we have to this day).

Of course, this doesn't mean it should be "my Coq is better than your Twelf" - we need to separate the math from the textual representations and even the execution models.


I think your post mostly re-enforces the OP's claim that FP won't save the day. To quote the OP, "it is obvious to me that doing FP right is (and will be) very hard."

In-so-far as your claims are true and germane to FP, they merely re-enforce this critique. After all, doing math right is very hard.

> and we have no sound way of modeling imperative languages/programs in ways that makes them useful as mathematical concepts.

This simply isn't true. There exist sound logics of imperative programs, which can be used to explore mathematical concepts.

This also pre-supposes that imperative programs themselves (and machine models more generally) are not an interesting mathematical concept.

> FP is math

It's entirely unclear what this means, if anything. You probably mean to say that certain functional languages correspond to certain logics. But that's not terribly meaningful; you can establish similar correspondences with imperative languages.

And even then, logic is math does not imply that math is (just) logic. So even if you're granted this point, the rest of your argument doesn't follow.

From a more empirical perspective, plenty of mathematicians do great math without knowing anything about FP, and plenty of FP programmers write a ton of code without ever doing interesting math.

Finally, the vast majority of very mathematically informed programming is still done in languages like C and Python and Java. So I'm highly suspicious of the claim that we need programming languages which are close to foundations in order to do mathematically informed programming.


It's an analogy, not an isomorphism.


>> I'd like to read people treating languages and platforms as tools and not as cargo cults.

I really like how you put that, it basically summarizes my own opinions on programming languages and development methodologies, in more or less the most concise way I can imagine ;-)

I'm totally oblivious to FP languages, but from CS theory I remember they are not always fun and joy to work with at all, at least not for a sizable class of practical (real-world) problems, and often require you to build these crazy hard-to-follow mathematical abstractions/contortions to be able to do things that are downright trivial in other languages. Sometimes you actually want to have mutable state and the problem you are modelling does require you to allow side-effects or explicit synchronization.

From my years of experience with programming languages my conclusion is that whatever paradigm you can come up with, some problems will be hard, and some will be easy, but no matter what, you will still need to know what you are doing and tread carefully. IMO the best language is not one that is 'safe' or 'strictly [insert programming paradigm here]', but one that allows you to do whatever you like but at least provides you with the tools to 'do it right (tm)'. From there it's all up to the developer to actually use the available tools correctly.

This may be a little unsympathetic to unexperienced developers, but I don't believe in programming languages that are supposed to make programming 'easier' or 'more accessible'. Allowing you to write safer code is invaluable, but IMO it should be up to the developer to ensure he/she uses the tool correctly.


I am skeptical, not because I'm resistant to change, but because it is obvious to me that doing FP right is (and will be) very hard.

Doing FP right is hard, but not for everyone. Library writers have the hardest job because FP (especially pure, statically typed FP) forces you to plan ahead of time instead of cobbling things together. The reward of doing this is the ability to make very robust, stable, easy-to-use domain-specific languages that make it hard even for novice programmers to screw up.


Quite right for many computing tasks OO is pointless and adds extra overhead and complexity.

Today a lot of IT is still take a set of inputs perform some operation on it and output it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: