January 05, 2020
On Sunday, 5 January 2020 at 19:53:59 UTC, Ola Fosheim Grøstad wrote:
> However, the language itself is pretty primitive (for no good reason).

There are reasons. A simpler language is easier to manage, both for compiler and for IDEs, potentially allowing faster development time and better performance/reliability, even if it doesn't have powerful features. From Go's FAQ:

**Why does Go not have feature X?**

Every language contains novel features and omits someone's favorite feature. Go was designed with an eye on felicity of programming, speed of compilation, orthogonality of concepts, and the need to support features such as concurrency and garbage collection. Your favorite feature may be missing because it doesn't fit, because it affects compilation speed or clarity of design, or because it would make the fundamental system model too difficult.
January 05, 2020
On Sunday, 5 January 2020 at 20:22:14 UTC, JN wrote:
> There are reasons. A simpler language is easier to manage, both for compiler and for IDEs, potentially allowing faster development time and better performance/reliability, even if it doesn't have powerful features. From Go's FAQ:

I followed the arguments they put forth when Go first launched. People complained loudly about not having good abstraction and error handling mechanisms and they (the language designers) were rather religious about their position. They are Unix/C/Plan9 people. Go as a language design does not provide better reliability, you are not forced to handle errors properly. (Unix APIs are also not great for correctness.) The Go designers found that they had to add "exceptions". They found that they had to add "generics". Coming in Go2.

When your function gets 100% larger because of the language lacks basic abstraction/error handling features then that does not improve correctness... Hiding the basic logic flow in error handling branching is not good for correctness or maintenance either.

They have marketed what it lacks as "good design". Go-people parrot it as good design, but that does not make it true...

Fortunately, most server code is simple I/O. So it is OK for writing a service, but not great, although the runtime makes up for it. Somewhat.



January 05, 2020
Am Sun, 05 Jan 2020 19:53:59 +0000 schrieb Ola Fosheim Grøstad:

> On Sunday, 5 January 2020 at 15:02:59 UTC, Johannes Pfau wrote:
>> This certainly needs to be considered, however: Some languages such as go (server!) and C++ with std:error decided to go for error codes for error handling.
> 
> What is "std::error"? If you mean "std::error_code" then it is for wrapping OS error codes like the ones from Unix. (You can throw it if want...)
> 

As far as I know, starting from C++11 std::error_code can be extended and has been used in newer updates to the C++ standard library instead of exceptions. (e.g. there is now a future error category). See https:// akrzemi1.wordpress.com/2017/07/12/your-own-error-code/

std::expected / boost outcome proposals are also related. There certainly is a trend away from exception to error-code like systems. But I have to admit, I don't know much about C++, so maybe those are bad / non- representative examples.

> The error handling regime in Go is not something anyone should copy. The
> language lacks features that makes code maintainable over time. Lots of
> pointless error-handling boilerplate noise. Also, they didn't do it
> because of speed, Go is not that fast. They did it for no scientific
> reason, just their own (bad) taste,
> but they later found that they had to add the awful hack that resembles
> exceptions, but is a lot more ugly and clunky. Although you can hack it
> to do what you want, in a rather type-unsafe way.
> So I do that, but Go is the error handling scarecrow of modern
> languages... You don't want to write big programs in Go.
> 
> Go I useful for small web services because it has a decent runtime, stable language design, few compiler bugs, decent web-service libraries and cloud support. However, the language itself is pretty primitive (for no good reason).

That's probably true. Still, you can do a exception system with the same user facing API but without backtracing. So you get rid of unwind tables and the backtrace support code making the failure case faster while reducing the performance of the succes case. In that case the only question is whether the performance difference is important for some applications.

Of course, ideally which backend implementation is used could be an implementation detail.

-- 
Johannes
January 05, 2020
Am Sun, 05 Jan 2020 21:06:00 +0000 schrieb Johannes Pfau:

> Am Sun, 05 Jan 2020 19:53:59 +0000 schrieb Ola Fosheim Grøstad:
> 
>> On Sunday, 5 January 2020 at 15:02:59 UTC, Johannes Pfau wrote:
>>> This certainly needs to be considered, however: Some languages such as go (server!) and C++ with std:error decided to go for error codes for error handling.
>> 
>> What is "std::error"? If you mean "std::error_code" then it is for wrapping OS error codes like the ones from Unix. (You can throw it if want...)
>> 
>> 
> As far as I know, starting from C++11 std::error_code can be extended and has been used in newer updates to the C++ standard library instead of exceptions. (e.g. there is now a future error category). See https:// akrzemi1.wordpress.com/2017/07/12/your-own-error-code/

Though looking at this, it seems they often throw exceptions containing these error codes? However, Herb Sutter explicitly mentioned std::error_code as causing fragmentation in C++ (e.g. std::filesystem uses both exceptions and error_code), see slide at https://youtu.be/ os7cqJ5qlzo?t=764

So I assumed error codes are common in modern C++, but I don't really have first-hand experience to say for sure.


-- 
Johannes
January 05, 2020
On Sunday, 5 January 2020 at 21:06:00 UTC, Johannes Pfau wrote:
> As far as I know, starting from C++11 std::error_code can be extended and has been used in newer updates to the C++ standard library instead of exceptions. (e.g. there is now a future error category). See https:// akrzemi1.wordpress.com/2017/07/12/your-own-error-code/
>
> std::expected / boost outcome proposals are also related. There certainly is a trend away from exception to error-code like systems. But I have to admit, I don't know much about C++, so maybe those are bad / non- representative examples.

Oh! I see where you are coming from. So, in D you have the problem that large sections of the standard library cannot be used with out the GC. In C++ you have a similar problem with not being able to use most of the standard library (safely) if you turn off exceptions. So they have both tried to make the code gen for exception code better, but I believe there also is an effort to make more of the standard library usable for those who choose to turn off exceptions.


> That's probably true. Still, you can do a exception system with the same user facing API but without backtracing. So you get rid of unwind tables and the backtrace support code making the failure case faster while reducing the performance of the succes case. In that case the only question is whether the performance difference is important for some applications.
>
> Of course, ideally which backend implementation is used could be an implementation detail.

There are absolutely many paths to new (or old) interesting error handling/resource management mechanisms. E.g. some research language for system programming have used arenas with compiler backing and other have explored other alternatives.

But D has to figure out how to relate to C++. Doing the opposite of C++ just on the syntax level (throw/nothrow/noexcept), does not make much sense if D is to attract C++ developers. It has to be substantially better to have an impact, like you suggest.


January 05, 2020
On Sunday, 5 January 2020 at 21:12:39 UTC, Johannes Pfau wrote:
> So I assumed error codes are common in modern C++, but I don't really have first-hand experience to say for sure.

Well, the fun thing about C++ is that nobody can tell you exactly what modern C++ is, but it is easy to point out old-style C++... Many patterns are outdated, but there are many different "modern" patterns as well...

The C++ community is split down the middle. Those that use C++ as designed (with exceptions), and those that use C++ as a C replacement (without exceptions).

I guess some modules have  been viewed as low level and thus have been designed to be usable by both groups.

You also have additions like std::optional that can be used if you turn off exceptions. I'm sure we see more in that direction if Rust becomes more popular...

January 06, 2020
On Saturday, 4 January 2020 at 16:05:10 UTC, Steven Schveighoffer wrote:
> Just wanted to bring this up, and not muddy the other thread.
>
> What do you put if you throw? @safe by default has alternatives. nothrow does not. Are we going to get a new keyword/uda?
>
> -Steve

WHY would nothrow by the default in the first place?

Exceptions are about the best error handling mechanism and there is no better altnernative in D.

There is a rationale for making people use a safe subset (supposed to be a good thing) but what is the rationale for gently moving them to _avoid exceptions?_

The performance point is a bit strange since people that want speed without correctness doesn't neither correctness, nor speed. The solution is to make nothrow whatever is slow and will be in benchmarks... Textbook premature optimization at the expense of correctness.



January 06, 2020
On Monday, 6 January 2020 at 03:13:09 UTC, Guillaume Piolat wrote:
> On Saturday, 4 January 2020 at 16:05:10 UTC, Steven Schveighoffer wrote:
>> Just wanted to bring this up, and not muddy the other thread.
>>
>> What do you put if you throw? @safe by default has alternatives. nothrow does not. Are we going to get a new keyword/uda?
>>
>> -Steve
>
> WHY would nothrow by the default in the first place?
>
> Exceptions are about the best error handling mechanism and there is no better altnernative in D.

`nothrow` by default doesn't stop you from using exceptions, it just forces you to either catch them or mark your function as throwing.
January 06, 2020
On Sunday, 5 January 2020 at 20:22:14 UTC, JN wrote:
> **Why does Go not have feature X?**

Oh, now I remember why I completely lost faith in the Go language designers.

I asked for asserts, and they absolutely refused and said that they would never add asserts because some programmers might use it to handle errors... therefore nobody should have them.

So, not having exceptions makes error-handling so tedious that some programmers will use asserts to check errors... therefore Go also could not have asserts.

Completely backwards and arcane mentality? I think so.
January 06, 2020
On Monday, 6 January 2020 at 06:58:34 UTC, Paul Backus wrote:
> `nothrow` by default doesn't stop you from using exceptions, it just forces you to either catch them or mark your function as throwing.

It kinda does: generic programming.

Say if I want to do critical math and create a numeric class that throws on inaccuracies. Then I cannot use libraries that "forgot" to add "throws" because whenever I provide a lambda that use critical math those libraries will refuse to take them.

Attributes like "nothrow" should be for public APIs.  For most code is better to do this using semantic analysis.