Imagine if you could write this (nonsense) code in Java:
bool a = (while (b) { if (c) { b=d;} else { b=e; }});
While it is efficient, some may balk at how “implicit” it is.
Indeed, if anything, if the intention is to communicate that the Boolean value is the result of some process that runs through a while loop, then explicitly saying that in the assignment seems to me to almost be the best way to do it :\
ymmv.
Now deeply nested while/assignment/ifs, that's a bad-pattern, but I'm not inherently convinced that's an expression/statement problem.
Because C did it, because Algol did it, because Fortran did it, because that is how assembly code works. Expressions require code to be compiled to something that uses a temporary value stack (or equivalent, like what some continuation-passing style compilers do by allocating values from garbage-collected memory), which, along with subroutines, was an exotic technology well into the 1960s.
I remember the first time I saw 'constexpr' in C++ I was excited, until I realized it's really conststatement.
The elaborate syntactical decorations of most languages drive away from this, unfortunately.
Anyone know the language design rationale behind the way Java does it? It seems much easier to make everything an expression. Ive always disliked that part of Javascript and being forced to use ternary operators to do a single line return statement for a conditional. Same with case statements.