This gets even worse with languages where indentation matters (Python, and the horrible abomination that is YAML) — which aren't even auto-indentable, because the editor has no idea what you actually mean. I'm not sure if you can avoid going insane with those.
What Lisp helps you is grokking actual operations of computing and, especially when all you have is a really dumbed down algol, opens you up to more programming methods and techniques. All of that happens on layer high above syntax.
Computing in the theoretical sense, right? I've always heard the opposite of this claim: Lisp abstracts away how computation is done on actual hardware. Isn't that what the famous Alan Perlis quote was referring to?
Specifically, ANSI Common Lisp is equipped with a function called DISASSEMBLE, and on many implementations it will provide you not only with plain assembly dump, but also with comments regarding said assembly, for example a comment specifying "we're calling X here", "this is handler for single parameter, and this is for multiple parameters" (in case of optional arguments to function)
You just select a syntactic unit with opt-up/down, then u either type over it, copy/cut/past or press left or right to go to the beginning or the end of the selection, hence using the selection as an intermediate step achieving AST-level navigation.
And of course you can teach Emacs to behave similarly, using the Expand Region (https://wikemacs.org/wiki/Expand_region) + some hacks, but I agree, that smartparens also solves this problem quite well.
UPDATE: also use avy-jump for emacs or acejump for intellij: https://plugins.jetbrains.com/plugin/7086-acejump these in combination with expand/shrink-region operations are a significant productivity boost, which is easy to learn and teach.
By contrast, I never have these kinds of semantic issues in whitespace significant languages like F# - I make mistakes that I might make less often in Scheme, but the compiler usually sets me straight since it realizes a branch isn’t returning a value, etc.
In my view parentheses versus whitespace is really a judgment call based on how your eyes read the source code. The crucial thing is having something like s-expressions.
Having said that, there's some disadvantages to the Lisp syntax as well, rightward drift due to constant nesting is real, and can make readability and even some edits a lot more annoying, whereas the flatter structure of other syntaxes doesn't have this problem as much. I still find its pros outweighs the cons personally, but your mileage may vary.
And I think that a job where you have to constantly switch between lisp and non-lisp styles would be a lot more frustrating than just using only one style and getting used to it, so I can see your pain there.
Anyway, it's way harder to adapt to "parenthesis before the function name vs parenthesis after the function name" and "semicolons after every statement vs. never use semicolons" than "punctuation is all parenthesis and commas (or newline and space as in normal Haskell) vs. punctuation uses the entire keyboard".
Meaningful vs meaningless indentation is also one of the things that don't give me any problems at all to adapt.
Overall, I don't think you need the full power of paredit when programming. For any given language, your editor movement commands understanding what tokens in this language look like will usually already be sweet and enough.
When I edit the non s-expressions languages I mentioned I do it in IntelliJ, sometimes with the vim bindings.
#include <iostream>
int main() {
std::cout << "hello, world!" << std::endl;
}
If my cursor is after "main", then M-f will move my cursor to after "std". It completely ignored "()" and "{". Another M-f moves my cursor to after "cout". Here it ignored "::". Another M-f moves the cursor to after "hello" ("<<" and the quote-mark ignored), another to after "world", and another to after "std" (quote-mark and "::" ignored) etc. It behaves similarly when hitting C-Backspace, where sometimes half a line disappears suddenly, because it was punctuation-heavy. I think once I stumbled upon code where it deleted several lines. On the other hand, when I have a variable like "big_number", then Emacs will happily jump into the middle of it. Even though it's an indivisible token in the eyes of the language's lexer. Of course there is a well-known hack of adding the "_" character to be recognised as a "word character". But it doesn't solve the issue really. The issue is that forward-word uses just one set of word-characters, instead of several sets of characters/regexes for different syntactic categories, which would enable jumping first to "cout" and then to "<<".Now paredit has been around for decades (1991 ? I forgot) so it's not like it's rarity.
Now that said, a little bit of paredit-fu allows for some funky coding sessions.. you can swap sexps, move blocks up down the tree .. you can even process the sexp with some elisp code in emacs.. it's very very swift.
What annoys me is the people who never expanded their knowledge beside a few paradigm .. they'll stick with python only or js .. or cpp. They're stuck onto a few libs and syntax.. it's a pity.
My approach: learn 2-4 navigational moves first for a while. Then add more nav and editing moves at a later point.
As with everything: deliberate practice leads to mastery. At some point it becomes apparent that the weird syntax is a feature that has huge upsides (another one being macros for example).
I maintain an up-to-date fork of Parinfer JS here: https://github.com/oakmac/parinfer
The Rust implementation is also popular and actively maintained: https://github.com/eraserhd/parinfer-rust