Trade-offs! Yes, FRP and concurrency are the main reasons. Also personal preference. In an interactive system, I do not think waiting to perform a computation until later is the right default (
more background). foldp is the major reason in FRP.
In a concurrent system, you also run into majorly annoying things (in my opinion). For example, say you have the following actors and communication channels:
| |
F G
\ /
H
|
Each node (F, G, H) are all doing some computation, and F and G are supposed to run concurrently. Things in F do not block things in G. Say computation F happens to be very expensive, taking a noticeable amount of time. That's fine, it does not block G right? In a lazy system, the default is, pass the unevaluated expression across every channel, so the computations escape! So everything ends up happening in H and F blocks G!
So for any FRP or concurrent program you write, you get to use laziness at its worst (in my opinion). In Elm, that is every program.
If you want to argue that adding strictness annotations is no big deal or something, I'd rather not. I've had that discussion elsewhere and can probably find a link to it.