February 18, 2015
On Wednesday, 18 February 2015 at 14:46:30 UTC, Dicebot wrote:
> From my POV best proposal from last lengthy discussion was to enable reference-counted non-gc-heap Exceptions. But that needs a language change because RefCounted!T is a struct and thus neither can be thrown nor can be part of Throwable class hierarchy.
>
> Any concept that implies that exceptions an be deallocated in `catch` block is absolutely unacceptable because it conflicts with exception propagation from fibers - a very important piece of functionality.

RefCounted Exceptions would work quite nicely.  You are right that It will require work on the language to support them but I like that solution.

If you don't mind, could you explain why cleaning up exception in the catch block would break exception propogation from fibers.  Are you saying that if you throw inside a catch block and save a reference to the exception (in the new exceptions "next" field), that it will create a dangling pointer?
February 18, 2015
On Wednesday, 18 February 2015 at 09:04:38 UTC, Matthias Bentrup wrote:
> Windows SEH maintains a per-thread linked list of exception handlers, but the C++ runtime seems to install only one handler at the start of every function and resorts to lookup tables if there are multiply try{}s in the function.
>
> If you want to avoid lookup tables, you can of course add/remove catchers dynamically whenever you enter/leave a try block, that would add a small cost to every try, but avoids the (larger) table lookup cost on the catch.

You want to do this as C++ introduce a ton of implicit finally blocks for destructors. If you would setup one everytime you need one, you would trash performance in the fast path.
February 18, 2015
On Wednesday, 18 February 2015 at 14:46:30 UTC, Dicebot wrote:
> From my POV best proposal from last lengthy discussion was to enable reference-counted non-gc-heap Exceptions. But that needs a language change because RefCounted!T is a struct and thus neither can be thrown nor can be part of Throwable class hierarchy.
>

This is not satisfactory. First there is no safe way to refcount right now. Second, this has all kind of implication for the GC to scan the heap and so on. Finally this do not solve the type qualifier problem.

I don't think a language change to do this pay for itself. i understand the appeal, as this is probably simpler to implement than the alternative, but that is really building technical debt.

> Any concept that implies that exceptions an be deallocated in `catch` block is absolutely unacceptable because it conflicts with exception propagation from fibers - a very important piece of functionality.

Exception propagate the same way between thread, which is even worse :)
February 18, 2015
On Wednesday, 18 February 2015 at 17:55:49 UTC, deadalnix wrote:
> Which is true, but would be as true without the horrible mention. Adjective do not constitute arguments.

And your nonsensical point is?
February 18, 2015
On Wednesday, 18 February 2015 at 18:43:49 UTC, Ola Fosheim Grøstad wrote:
> On Wednesday, 18 February 2015 at 17:55:49 UTC, deadalnix wrote:
>> Which is true, but would be as true without the horrible mention. Adjective do not constitute arguments.
>
> And your nonsensical point is?

That you have no idea how to argue, and rely on sticking negative adjective close to things you don't like in hope that you'll fool someone.

This post I'm answering to is more evidence of that.

That's the last answer you'll get from me until you make any valuable argument.
February 18, 2015
On Wednesday, 18 February 2015 at 18:59:03 UTC, deadalnix wrote:
> That's the last answer you'll get from me until you make any valuable argument.

Excellent! I hope you keep your promise.
February 18, 2015
On Wednesday, 18 February 2015 at 18:26:34 UTC, deadalnix wrote:
> On Wednesday, 18 February 2015 at 14:46:30 UTC, Dicebot wrote:
>> From my POV best proposal from last lengthy discussion was to enable reference-counted non-gc-heap Exceptions. But that needs a language change because RefCounted!T is a struct and thus neither can be thrown nor can be part of Throwable class hierarchy.
>>
>
> This is not satisfactory. First there is no safe way to refcount right now. Second, this has all kind of implication for the GC to scan the heap and so on. Finally this do not solve the type qualifier problem.
>
> I don't think a language change to do this pay for itself. i understand the appeal, as this is probably simpler to implement than the alternative, but that is really building technical debt.

Right now I don't care for full memory safety or type safety of any proposed solution. I will be glad to have any that actually works - and I have not heard of any idea that allows to do that without language changes. Your push for owned is also hardly relevant because exceptions are good examples of data with shared / non-determenistic ownership and thus won't benefit from it.
February 18, 2015
On Wednesday, 18 February 2015 at 09:04:38 UTC, Matthias Bentrup wrote:
> If you want to avoid lookup tables, you can of course add/remove catchers dynamically whenever you enter/leave a try block, that would add a small cost to every try, but avoids the (larger) table lookup cost on the catch.

There are many ways to get better performance than the current regime, both dynamic and static approaches, with little execution costs, but since most C++ programs don't rely on exceptions where speed matters there is little incentive to improve considering the complications in the backend. So I don't expect the C++ crowd to do anything about it.

As a result C++ programmers that need speed can keep pretending exceptions don't exist, and if you don't need speed, why are you using C++? :-). Thus status quo persists and nothing interesting happens.

D has made C/C++ compatibility a goal... so nothing is going to happen with D either...

In most programs the possible call trees at a given point are quite limited, like a regular expression, so with whole program optimization you only need to special case catch blocks where the program may stop unwinding. I.e. you could detect which of the possible call trees you are in and unwind "multiple stack frames" from the same code location. If only a few functions can call you, you most certainly don't need to look up anything, right? If the compiler is allowed to move beyond "the peephole separate compilation viewpoint"...
February 18, 2015
On Wednesday, 18 February 2015 at 18:02:14 UTC, Jonathan Marler wrote:
> On Wednesday, 18 February 2015 at 14:46:30 UTC, Dicebot wrote:
>> From my POV best proposal from last lengthy discussion was to enable reference-counted non-gc-heap Exceptions. But that needs a language change because RefCounted!T is a struct and thus neither can be thrown nor can be part of Throwable class hierarchy.
>>
>> Any concept that implies that exceptions an be deallocated in `catch` block is absolutely unacceptable because it conflicts with exception propagation from fibers - a very important piece of functionality.
>
> RefCounted Exceptions would work quite nicely.  You are right that It will require work on the language to support them but I like that solution.

It will likely trigger whole load of other issues being totally new language concept but so far I am not aware of any better proposal.

Of course to truly address @nogc you need also some sort of object pool for exceptions instances where those get returned upon release - otherwise it would simply move allocations from GC heap to plain heap. Which you can do already and does not really fix the problem.

But that is a relatively simple library solution that can be built if reference counted exception become reality.

> If you don't mind, could you explain why cleaning up exception in the catch block would break exception propogation from fibers.  Are you saying that if you throw inside a catch block and save a reference to the exception (in the new exceptions "next" field), that it will create a dangling pointer?

Imagine application like vibe.d which uses fibers to imitate blocking API for async operations (we have something similar in Sociomantic projects too). Callbacks execute in the context of event loop but if any of those throws you want exception trace to point to original "blocking" call that registered callback.

Right now doing this is relatively simple. You catch all exception in callbacks and store exception instance in relevant fiber-local data. Upon resuming that fiber it checks if there are any pending exceptions and re-throws if there is one. There are probably more tricky details but basic principle should be like this.
February 18, 2015
On Wednesday, 18 February 2015 at 20:25:07 UTC, Dicebot wrote:
> Right now I don't care for full memory safety or type safety of any proposed solution. I will be glad to have any that actually works - and I have not heard of any idea that allows to do that without language changes. Your push for owned is also hardly relevant because exceptions are good examples of data with shared / non-determenistic ownership and thus won't benefit from it.

I think it make sense to require that something thrown to be owned. That means ownership can be transferred from one thread to the other. That also mean that the compiler can free the exception when it goes out of scope, which is what is wanted for exception and @nogc to work together.

The invalid operation in @nogc would become promoting owned to Tl/shared/immutable rather than not allocating at all.

This has added benefit to allow for way more code to be @nogc, and in many cases transfers the GCness of something in the caller, which makes for @nogc compatible libraries that can be used in both @nogc and gc situation.

If we are gonna add something in the language, it'd better be worth it.