> and yet there still don't seem to be many non-trivial apps written in any of these languages
Perhaps you are not looking hard enough? Sure, if your problem space is CRUD web apps, then you won't find many implementations. Try looking into more difficult problem spaces, such as high-frequency trading, and you'll suddenly find more FP examples.
Also, there's Erlang, which was developed by Ericsson to solve a very specific, real-world problem. Look it up.
High frequency trading is dominated by C++, Java and C#. There are a few places using F# and Ocaml but they're relatively small players. I know of only two places that seriously considered Haskell and they both decided against it in the end.
I doubt any of these languages are significantly more popular in "more difficult problem spaces."
That is sort of the worst case scenario for a FP program (though I'm sure you could write it in FP). It is almost entirely side-effects.
I agree with the sentiment that for a paradigm that has been advocated for 60 years it is really odd how little non-academia code is written in it.
In my experience you find functional code shines (and is therefore common) in places where prove-ability is of the utmost importance or where writing custom DSLs provide a lot of value. Things like nuclear systems, extremely high security applications (think custom OS level requirements) or financial modelling software.
That said in most of the places I've found the FP program is a high value prototype or proof of concept, not the actual system. I don't know if that is just a resource allocation thing or not.
There are plenty of side effect free ways of dealing with change...you can make the effects you know...explicit. Anyways, for a game like SMB, FRP should work relatively well. Just be careful with collections.
But there are no side effect free ways of changing the pixels on a screen or the sounds coming out of a speaker as those are precisely side effects.
Of course there are ways of abstracting those side effects and acting like they are the same as pure functions. Or conversely instead of hiding them, you could point them out and make them "exceptional", which is what I assume you mean by making them explicit. These machinations (of which FRP is a clear example) to deal with side effects have a price, and in a game like SMB it is entirely possible that the vast majority of the work would be this overhead.
Again, of course you can do it, but it is a problem domain not particularly suited to FP in and of itself. I've written short running, fast starting, memory constrained applications in Java, but it was a fight to do it. If the fight is worth the other advantages, it can be worth it.
"But there are no side effect free ways of changing the pixels on a screen or the sounds coming out of a speaker as those are precisely side effects."
No, those are precisely effects. They can only be side effects once you've defined how you're distinguishing side effects from effects generally.
A common way is labeling intended results "effects" and unintended results "side effects". By this definition, they're clearly effects not side effects, though this equally clearly isn't the usage in question.
Another way - common in Haskell - is to label effects that do not appear in a function's type signature "side effects". By this definition, it clearly depends on the implementation and there are "side effect free ways of changing pixels on the screen".
I don't think there is another useful definition to be had.
Without getting into a hugely semantic debate, I was using side effect imprecisely to mean the opposite of a pure function.
Many FP paradigms (including Haskell's) impose an overhead when doing operations that are not pure. In the case of a SMB clone a huge percentage of the work of the program may end up not being pure, therefore a large overhead may be imposed. Further, many of the advantages of FP paradigms (including Haskell's) are dependent on pure functions.
In the case of a SMB clone, a large percentage of the application may be intended to be impure, therefore the "worst case scenario" comment.
"Without getting into a hugely semantic debate, I was using side effect imprecisely to mean the opposite of a pure function."
That's the second sense I described. It's only meaningful if you're actually talking about a particular function. And you're still left with the question of the actual domain of the function. Semantics, but relevant semantics.
"Many FP paradigms (including Haskell's) impose an overhead when doing operations that are not pure. In the case of a SMB clone a huge percentage of the work of the program may end up not being pure, therefore a large overhead may be imposed. Further, many of the advantages of FP paradigms (including Haskell's) are dependent on pure functions."
That's somewhat true of FRP, basically false about Haskell IO generally, but either way if you can do it in PyGame someone can do it in Haskell - it's mostly a matter of working in a high level language, not a matter of functional-programming-imposed overhead.
I would recommend listening to what John Carmack had to say about implementing games in Haskell (and also Lisp, IIRC).
In FRP, you basically define your UI as a function to display pixels. Physics is a bit weirder, but that is handled by event streams over ticks and "stepping." Actually, the effect system doesn't really come into play, because you can define everything effect free.
I'm not a big FRP proponent though. In my own work [1], I believe that manipulating pixels and doing physics should be effects...even side effects that are at least explicit during run-time. Of course, to achieve this, I needed to do special things to achieve commutativity and idempotence, which is otherwise taken for granted in a pure functional program.
Perhaps you are not looking hard enough? Sure, if your problem space is CRUD web apps, then you won't find many implementations. Try looking into more difficult problem spaces, such as high-frequency trading, and you'll suddenly find more FP examples.
Also, there's Erlang, which was developed by Ericsson to solve a very specific, real-world problem. Look it up.