Concise languages can be more challenging to read because you have to understand more about each symbol/word in the language. But verbose languages can be more challenging to comprehend because there's a lot of symbols which don't signify anything.
I suppose concise / implicit is fine when the thing that's being hidden can't go wrong, like in:
[i * 2 for i in 1...10]
The loop counter increment logic can't possibly go wrong, so it's fine to not think about it.
Regarding error-handling, don't you want to think about? If you're calling a() followed by b(), what should you do if a() fails? In some cases, b() shouldn't be called, but in others, it should, like deleting a temp file. And if you have to think about it, it's better to be explicit?
To put it more simply: yes, the developer should have to think about what they do in the case of an error. And then the amount of work they do -- and the code produced, and thus the work reviewers have to do -- should be proportionate to how unusual the necessary error handling is. When I see explicit error handling, that signals to me "hey, this is an important case that we need to handle in a particular way".
Great comment. I would add how unusual _and critical_.
One of the things I love about Python is that while I know errors can occur on practically every statement written, I only have to add error handling for likely / expected / critical errors. Any unlikely errors that occur, even in production, will show a detailed stack trace (lots of context), making them easy to fix.
In my experience, things work as expected 98% of the time. For some software, like a pacemaker, checking the execution of every single line of code and even having redundant error checking is not overkill. For other software, like the backup software I work on, having one customer out of 1000 get a weird error is something I'd rather deal with as a support ticket rather than having to anticipate it while writing code.
Of course error handling is important, but requiring 3 lines of error handling for every 1 line of actual code has kept me from investigating Go to replace Python for HashBackup. I'd love to get the performance increase, but not for a 4x expansion of LOC.
Or try Rust. ^.^
In this case, I don't think anyone is arguing that error handling should be implicit. They're saying there should be an explicit way of saying "handle this error in the common way." This actually makes the distinction between common and uncommon cases more explicit, because their differences aren't buried in boilerplate.
But yeah, Go dev do not see VB's features as being "features."
VB's biggest problem IMO is that it tried to compete with C# instead of maintaining its original raison d'être which was to be a highly productive tool that required very little programming skill to be able to start building real solutions for business use.
But I digress...
It's similar in Go since you can't compile with unused variable so you need to explicitly discard the error with _. Ex: result, _ := func() This is for multi-value returns, for single value you can even omit the _
Your example re Go errors is incorrect. The go compiler allows you to ignore errors in returns without any compiler error.
For example
err := doThingThatErrs()
and
doThingThatErrs()
are both valid Go code.
Try Return [Bla(), null] Catch err Return [null, err] End
I do like this syntax better, bc the different scopes cause a lot of nesting