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

The irony is that it probably does mean better quality code for most people.

Quality in practical outcomes for building projects, that is, not code asthetics.

The problem is that 'functional code' means 'spagetti code' for many 'low skill' people, and 'write once maintain never' perl style code for many other 'smart' people.

Both are rubbish, terrible low quality useless code outcomes.

OOP doesn't fix everything, but its a great lowest common demoninator for code that does the job. Its not exciting. It has stateful bugs. ...but anyone can do it and it gets the job done at scale; orders of magnitude better than any other coding paradigm I'm aware of.

You want a hard problem to solve?

Go figure out a way to make functional programming scale the same way, you'll start a revolution.

...but in my experience, its the frustrated 'smart' folk who want to write their maintain-never code who push FP as a replacement for OOP.



> The problem is that 'functional code' means 'spagetti code' for many 'low skill' people

I don't see how that is the case. Even in the most poorly written function you have code that's working mostly on it's arguments (and maybe some global or something, since it is poorly written) and then returns a value. How is this function connected to the surrounding code? We know the answer, it's called in a single expression and given arguments. You have a single isolated call for a single run of the function.

In OOP you have to both instantiate a class and then call it's methods. By simple line count it is twice as complicated to call as a function, and it is twice as coupled to the code that calls it.

When I look into the internals of functional code I often find myself in a single isolated function and the functions tend to be on the short side. When I look into the internals of OOP code I often find myself in a large method that is part of a class in an inheritance hierarchy and the method uses a bunch of globals (err, I mean "object variables") and I have to read several other methods to understand what's happening, because the method I'm interested in depends on the state left over from other method calls.

In short, objects are a lot more powerful than functions, and thus "low skill" developers have a lot more rope to make spaghetti with.


  In OOP you have to both instantiate a class and then call 
  it's methods. By simple line count it is twice as 
  complicated to call as a function, and it is twice as 
  coupled to the code that calls it.
And in FP a state falls out of the sky?


It's not about hidden state; that's just bad OOP. You shouldn't be looking at the internals, that's the point. It's about modular encapsulation and reusable components.

> a single isolated function and the functions tend to be on the short side

I can almost guarantee that code was not written by an inexperienced or low skill coder.

If it was, you'd have a large complex function that took large complex state as its input, and probably maintained some kind of hidden internal state in some kind of async deferred loop after it returned or some combination of the above.

Have you worked with inexperienced FP programmers?

It's not fun.

Inexperienced OOP is a lot easier to deal with, because the entity level API validation is all you care about; you don't care about how hideously the internals were implemented as long as the tests pass. There can be any number of bugs and spaghetti inside the object, but you don't care, because you don't see it (until it manifests as bugs; but then you just add more tests and make them go away until all the tests pass).

I think there's a pragmatic aspect to OOP that involves large scale organizations collaborating on projects that you're not taking into account.

You could argue that a test suite for FP does the same job, and maybe it does... but the point here is that someone has to define the module level interface, and how it behaves as a state machine (regardless of if the state comes in 'pure' and is passed around or is encapsulated internally); and that's OOP, not an inheritance hierarchy.


> I can almost guarantee that code was not written by an inexperienced or low skill coder. > If it was, you'd have a large complex function that took large complex state as its input, and probably maintained some kind of hidden internal state in some kind of async deferred loop after it returned or some combination of the above. > Have you worked with inexperienced FP programmers? > It's not fun.

No pure FP language will allow you to do that without the function's type signature reflecting that - it would need to return its value in some kind of state/async monad.

Now, if you're talking about FP in a traditionally OOP language, then I agree with you, but that's an apples to oranges comparison.

> Inexperienced OOP is a lot easier to deal with, because the entity level API validation is all you care about; you don't care about how hideously the internals were implemented as long as the tests pass. There can be any number of bugs and spaghetti inside the object, but you don't care, because you don't see it (until it manifests as bugs; but then you just add more tests and make them go away until all the tests pass).

This approach doesn't work for things that are difficult to test. e.g. you can only ensure your types are thread safe by reasoning about their use of locks, volatile, etc., because any attempt to test this is dependent on the implementation details of your runtime (e.g. the JVM) and the amount of load its under. Best case you get a flaky test, worst case you miss a bug that blows up in production.

But this is a tangent, because TDD is not specific to OOP - it works just as well with FP.

> but the point here is that someone has to define the module level interface, and how it behaves as a state machine (regardless of if the state comes in 'pure' and is passed around or is encapsulated internally); and that's OOP, not an inheritance hierarchy.

Pure state is an oxymoron. The idea is not that you pass a mutable argument in, but that you don't have the ability to mutate data at all. At best, you can return some instructions on how to mutate (e.g. the state monad), but its the consumer of your code who decides what to do with that, which prevents you from hiding side-effects, and simplifies testing.

Defining a module level interface and behaviour is just API design, not OOP.




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

Search: