The ultimate goal of software is to build something useful. The "functional programming tutorial:real world uses" and "claims of superiority:adoption" ratios are suspiciously high.
The ultimate goal of software is to build something useful. The "functional programming tutorial:real world uses" and "claims of superiority:adoption" ratios are suspiciously high.
I started programming in Clojure, Clojurescript, and now messing around with OCaml. The primary language I use at work is Ruby.
The aspect of FP that really helped me even be a better Ruby developer was just having way less shared state. When you have less shared state, and small functions doing one thing with as little side effects as possible it really makes code cleaner and it makes your software behave in much more predictable ways.
I know what some are saying "Well that seems like what you should be doing anyway..." That is true but at least working with a FP language really drives this home and for me did more for code quality improvement than anything else. In fact now when I look at most Ruby code even in big high quality projects I am like why??? Ruby gives you so many ways to do things without shared state (blocks) yet so many choose to set instance variables all over, or store stuff in variables in memory.
I still am not sold on strong static typing such as in Haskell, and yes I get the opinion of what you said about that community. I am not sure though if it is because I am bad at it, or it truly takes more work than it saves you in the future. I just find with FP as in Clojure and OCaml it gives me a lot of gain without ever getting in my way. So it is worth trying, and even if you keep working in a large imperative language, FP experience will help you not fall into the holes of large shared state.
I think viewing this as a fallacy is a bit of a straw man. There are very few people who believe in a "Right Way (TM)" to write programs (although those people are probably over-represented in the comments section of online news posts about functional programming).
> Maybe a trap for contemplative people?
FP is hardly unique in this regard. Were you around in the 1990s? Recall that the OOP crowd got pretty philosophical there for a while, with elaborate treatises on software organized around some obscure book about architecture. ;-)
> The ultimate goal of software is to build something useful.
It's worth noting that the ultimate goal of functional programming (as a research field) goes beyond building software; (typed) lambda calculi are an entire alternative model for studying computation. The science of computation has many applications beyond software development.
Interesting point about software having uses outside of programming a machine to do tasks. I can see an appeal there.
I disagree; what spectrum are those on opposite ends of? Encapsulation, polymorphism, and inheritance are entirely compatible with FP, and immutability is entirely compatible with OOP. Functions and objects are equivalent. Most mainstream OO culture is centred around procedural programming, but it's the procedural parts that oppose a functional style, not the OO parts.
I also am not entirely sold on funfunfun's characterization, but if you think of this in terms of cultural hangups that cause excesses rather than concrete technical contributions then it makes some sense.
The excesses of OOP culture are distinctly different from the excesses of Functional culture.
OOP in excess looks like software architecture books with quotes from Alexander and FLW, programming as artform, etc.
Functional in excess looks like really bad descriptions of category theory promulgated by writers who couldn't tell you what group theory is good for.
So if we want to characterize these ways of programming in terms of what harmful excess looks like, then they are on sort of opposite sides of a spectrum. Where one side considers programming pure art and the other pure logic.
I'm still not sold that this is a good model of reality. But if you focus on excesses rather than useful insights, I can see what funfunfun is saying. I think.
FP is great for many little things you might have to do. But for larger architectural considerations, I still find notable advantages to creating custom classes that have their own public API, private internal implementation, and that manage their state internally. In the absence of this, you have lots of functions that are basically sitting alone with their pure inputs and outputs, and to manage state requires more effort, not less, in a lot of situations. Each of these functions has to receive the thing they are acting on, and a separate group of functions manages the actual mutation, acting as "controllers" between these more pure functions and the actual stored state. The result is a less elegant program structure sometimes.
FP enthusiasts like to say that "it's better for many functions to operate on common data structures than it is to have many custom data structures with their own functions." The problem in my experience is that often, these pure functions are only serving one purpose geared for a particular data layout, and thus they might as well be coupled to it; the lack of a backbone in larger FP architectures can be frustrating. In Clojure, you have maps, and all maps behave the same. Great. But not all maps are actually the same. Each map ultimately has its own structure, and these functions that operate on a particular map are really operating on a particular structure a lot of the time. So you end up with increased verbosity and more difficult-to-follow code structure than if you just combined the data and its functions in one place: a class. The record-protocol idea attempts to alleviate this, but I don't feel it really gets to the heart of the issue.
I think OO and FP each solve problems in equally meaningful ways and different tasks are better suited to one or the other. I particularly like languages that don't force you into a particular model. Java and Clojure are quite opinionated (in opposite ways) and thus often inflexible for certain tasks. My favorite language for blending these techniques has become C++ but I don't get to use it as much. It offers true FP-style programming with constructs like std::function. I wish Java had gone as far as C++11 did; the Java lambdas and the requirement that they can only be type defined using a static interface is not really helping to adopt the paradigm.
In OCaml, you usually do that with modules. For instance, you can easily write mutable or immutable datatypes that hide their internal representation.
> My favorite language for blending these techniques has become C++
I also like programming languages that embrace several paradigms. The problem with C++ is that it's a very complex language. Compared to C++, OCaml is a piece of cake.
Ocaml has declarative OO programming via it's module system. Typeclasses and Ocaml modules have equivalent expressive power, so you'd achieve that with typeclasses in Haskell. But Ocaml's type system is much simpler and more explicit, which makes it much easier to learn and use
> The ultimate goal of software is to build something useful. The "functional programming tutorial:real world uses" and "claims of superiority:adoption" ratios are suspiciously high.
Yes and no, what they're really getting at is declarative vs imperative programming and how declarative programming makes managing state and reasoning about code much simpler. In imperative code you often have to step through mentally or through a debugger to really understand what's going on. It also really simplifies concurrent programming (ie map-reduce).
You can have it both ways -- declarative OO programming exists with Ocaml's module system. You can even write declarative OO programming in Java, using 'static' classes (or non-static but only used to configure so it's essentially immutable), 'final' everything, and immutable data structures
Referential transparency, mutation, non-termination, coinduction, memory pointers, linear types, coroutines, continuations, blah blah blah. All of these things exist, and more.
Most PLs are biased in one way or another, many don't even let you reason formally about those things (or allow you to reason informally).
But at least if you're a working programmer, especially if you work to map an existing human domain to software, there's always the fixed point of Curry-Howard to hang on to.
At least that’s been my experience in my years of writing professional, money-making software in it.