> which makes the code hard to read and edit IMO. Languages like Haskell and OCaml suffer from a similar problem too.
That's interesting, I've always really loved the "return last expression in a block" syntax. (Ruby and Rust can be added to your list as well.) That syntax just reads really naturally to me.
I like that too, but both Rust and Ruby allow multiple expressions/statements before the last expression. In Haskell and OCaml IIUC you need to use things like `let x = ... in <expr>` or `<expr> where x = ...`, so you still have a single expression in function bodies.
There are two things at play here (1) the implicit body and (2) being able to add new bindings in an existing scope with "def".
CL has an implicit body, but does not allow defining new bindings outside of some dedicated forms (let, etc.). I really prefer having to write "let" forms instead of having new variables added inside the body.