December 13, 2016
On Tuesday, 13 December 2016 at 11:39:16 UTC, Guillaume Piolat wrote:
> On Monday, 12 December 2016 at 21:02:11 UTC, Andrei Alexandrescu wrote:
>>
>> That will come too.
>>
>>
>> Andrei
>
> Great teaser :)
>
> For reference, here is how I currently do this:
>
> - make Object.~this() @nogc with a cast
> - throw emplaced exceptions in malloc'd memory
> - release them explicitely at catch time
>
> This probably breaks chaining so maybe RC objects are needed first, dunno.

It also only works if you're the one controlling all of your code, because D code in general expects exceptions to be GC-allocated and isn't going to do anything to free it. So, it works under certain circumstances but not in general.

- Jonathan M Davis
December 13, 2016
On Tuesday, 13 December 2016 at 04:45:35 UTC, Andrei Alexandrescu wrote:
> On 12/12/16 11:07 PM, Jonathan M Davis wrote:
>> On Monday, 12 December 2016 at 15:51:07 UTC, Andrei Alexandrescu wrote:
>>> Here it is:
>>>
>>> https://github.com/dlang/druntime/pull/1710
>>>
>>> It relieves code that uses assert from needing the GC. I think all
>>> Errors should be singletons - multiple objects in that hierarchy
>>> arguably make no sense. But of course there are many situations out
>>> there. If this breaks your code, please holler.
>>
>> I don't know if that would actually work with polymorphic contracts in
>> classes.
>
> How do you mean that? Do you have an example in mind?

I mean that with virtual functions, in contracts get ||ed and out contracts get &&ed. Since that involves assertions, unless the compiler is doing something special there with assert, that involves throwing multiple AssertErrors and catching them. Depending on how that's implemented, having a singleton for AssertError would break that. If so, I expect that it's fixable, but simply turning AssertError into a singleton without verifying how that would affects contracts on virtual functions seems like a bad idea.

>> It also could be problematic with unit tests - especially unit
>> tests that catch AssertErrors (e.g. if someone wants to test the
>> contracts).
>
> What kind of problems would it create?

Well, if anyone is catching AssertErrors in unit tests, then they'll no longer be getting multiple of them. For some stuff, it wouldn't matter, but for other stuff it would break it. For instance, while the default test runner stops on the first failure in a unittest block, others are going to run them all and then print out the failures, and if AssertError is a singelton, then all of the AssertErrors that were stored to print at the end would then be the same AssertError and would print the same thing, defeating the purpose of the alternate test runner.

> Is reducing dependencies for core constructs a good thing?

It is when it reduces functionality, which this does. It puts unnecessary restrictions on AssertError which are of zero benefit for the vast majority of D programs.

>> And if we fix it so that exceptions don't need the GC (which is arguably
>> needed for @nogc to be widely used), then this whole problem goes away
>> anyway. So, I'm inclined to argue that we just fix _that_ problem and
>> not worry about the fact that assert currently triggers the GC on failure.
>
> I agree the perfect system would fix everything - problem is we don't have it yet. The per-thread singleton is a step forward (which at some point we should probably make publicly available).

We _need_ to fix the fact that exceptions require the GC, or @nogc is utterly useless for large portions of D code simply because of the exceptions, which will make it much harder to use D without the GC. If we fix it so that exceptions don't need the GC, then this problem goes away, and these changes are just an unnecessary complication in druntime.

- Jonathan M Davis
December 13, 2016
On Tuesday, 13 December 2016 at 13:59:13 UTC, Andrei Alexandrescu wrote:
> On 12/13/2016 01:34 AM, Shachar Shemesh wrote:
>> unlinking GC from phobos is not likely to happen until that happens
>
> You can avoid linking druntime today with -betterC. -- Andrei

You can avoid linking druntime _now_. And betterC is so extreme in what it's trying to do that it would arguably better off with an entirely different build of druntime if they're willing to use druntime at all.

If you really want to support betterC with druntime, I would suggest using version blocks for the areas that the betterC folks can't afford and then have a betterC build of druntime without them. And if something needs an alternate implementation for that, then it can have it. In an environment like that AssertErrors could probably even just be malloced and thrown without caring about catching them, because the program is about to die anyway. If they still want AssertErrors with contracts and unit tests though, then we really need an RC solution with malloc and not the GC or singletons.

Regardless, I really don't want to see functionality removed from druntime or Phobos because of betterC. I'm fine with supporting betterC if it's not impacting normal D stuff, but the position of betterC is so extreme that it could very quickly negatively impact normal D if we start catering to it.

- Jonathan M Davis
December 13, 2016
On Tuesday, 13 December 2016 at 18:52:05 UTC, Andrei Alexandrescu wrote:
> * People have noticed that certain simple uses of D trigger calls into druntime that are not quite justified. For example, assigning an array of int to another array of int issues a call into a function that uses dynamic introspection (!) to copy any array into any other array. A template present in object.d would trivially do this using introspection to boil down to memcpy.

I am in favor of templatizing more of druntime.
But please keep those templates simple.
I have noticed severe code-bloat at ctfe, and worse when ctfe-codegen miscompiles those templates,
there in way to know why!

It will work fine if the bodys are
- very simple (C-subset of D)
- use static if moderately
- please minimize the use of constraints they are wired when it comes to ctfe interaction
December 13, 2016
On Tuesday, 13 December 2016 at 22:15:13 UTC, Stefan Koch wrote:
> I have noticed severe code-bloat at ctfe, and worse when ctfe-codegen miscompiles those templates,
> there in way to know why!

Was meant to say.
there is no way to know why.


December 13, 2016
On Tuesday, 13 December 2016 at 06:36:47 UTC, Shachar Shemesh wrote:
> On 13/12/16 02:57, Andrei Alexandrescu wrote:
>>
>> You can catch AssertError. There's no guarantees dtors have been called
>> during unwinding. -- Andrei
>
> That makes no sense to me, unless you only want to catch it in order to do something right before exiting anyways.
>
> Also, please note that not all non-Exception Throwables are terminal for the process. We use a Throwable that is not an Exception in order to force termination of a fiber from outside in a clean way. If proper unwinding is not guaranteed under this condition, we have a problem.

_Errors_ do not guarantee that the stack is unwound properly. It's been Walter's stance for years that it's bad for the program to do any cleanup when an Error is thrown and that it's not guaranteed that the cleanup happens. However, someone working on the exception stuff at one point _did_ make it so that the cleanup is always done (which Walter doesn't like but hasn't fixed). So, for code that doesn't use nothrow, Errors currently result in full cleanup but it's not actually, officially guaranteed that it will, and it could change in the future (though that would be a problem in the case of AssertError for contracts and unittest blocks).

For nothrow code, it _is_ currently the case that full cleanup doesn't necessarily happen when an Error is thrown, because the compiler doesn't emit the exception stuff for nothrow functions.

As for Throwable, I think that it's mostly ignored and not really thought about in discussions like this. Most everything is either an Exception or an Error. So, I don't know what Walter would say about it. However, Throwables do _not_ work with nothrow. This function

void func() nothrow
{
    throw new Throwable("blah");
}

will fail to compile. That being the case, it would seem that Throwables are treated more like Exceptions than Errors, which implies that you're fine, but Walter would have to weigh in to be sure. Part of the question probably comes down to when it's valid to derive from Throwable directly, which it rarely is. But I don't think that it would be hard to convince Walter that you have a valid use case that requires that Throwable clean up correctly and that only Errors should not do proper cleanup - particularly since the whole reason that Errors don't guarantee full cleanup is because it's an unrecoverable error condition, and if a Throwable is an unrecoverable error condition, it really should be derived from Error, not Throwable.

- Jonathan M Davis
December 13, 2016
On 12/13/2016 05:05 PM, Jonathan M Davis wrote:
> I mean that with virtual functions, in contracts get ||ed and out
> contracts get &&ed. Since that involves assertions, unless the compiler
> is doing something special there with assert, that involves throwing
> multiple AssertErrors and catching them. Depending on how that's
> implemented, having a singleton for AssertError would break that. If so,
> I expect that it's fixable, but simply turning AssertError into a
> singleton without verifying how that would affects contracts on virtual
> functions seems like a bad idea.

Yeah, that's the kind of feedback I was hoping for. Thanks.

Recall that all AssertError instances are equivalent up to file and line. It is possible that that causes issues but the likelihood is low. Overally I'm not too worried about this because contract handling is also under the control of the compiler/runtime so it doesn't break client code.

>>> It also could be problematic with unit tests - especially unit
>>> tests that catch AssertErrors (e.g. if someone wants to test the
>>> contracts).
>>
>> What kind of problems would it create?
>
> Well, if anyone is catching AssertErrors in unit tests, then they'll no
> longer be getting multiple of them. For some stuff, it wouldn't matter,
> but for other stuff it would break it. For instance, while the default
> test runner stops on the first failure in a unittest block, others are
> going to run them all and then print out the failures, and if
> AssertError is a singelton, then all of the AssertErrors that were
> stored to print at the end would then be the same AssertError and would
> print the same thing, defeating the purpose of the alternate test runner.

Would be quite cool if all failed assertions showed the same file and line, eh? :o)

I'm actually of a mind to push this in the language specification - Error objects are not guaranteed to be distinct. Errors already have a number of concessions and shouldn't be used naively.

>> Is reducing dependencies for core constructs a good thing?
>
> It is when it reduces functionality, which this does. It puts
> unnecessary restrictions on AssertError which are of zero benefit for
> the vast majority of D programs.

Probably a negation was meant somewhere.

>>> And if we fix it so that exceptions don't need the GC (which is arguably
>>> needed for @nogc to be widely used), then this whole problem goes away
>>> anyway. So, I'm inclined to argue that we just fix _that_ problem and
>>> not worry about the fact that assert currently triggers the GC on
>>> failure.
>>
>> I agree the perfect system would fix everything - problem is we don't
>> have it yet. The per-thread singleton is a step forward (which at some
>> point we should probably make publicly available).
>
> We _need_ to fix the fact that exceptions require the GC, or @nogc is
> utterly useless for large portions of D code simply because of the
> exceptions, which will make it much harder to use D without the GC. If
> we fix it so that exceptions don't need the GC, then this problem goes
> away, and these changes are just an unnecessary complication in druntime.

This kind of argument I honestly don't put too much in the balance because it promotes paralysis of analysis. Right now I don't know what to do to make all exceptions not use GC. I do know what to do to avoid using the GC in assert, and in my opinion at a negligible cost in amenities. We can't afford to refuse to take a step just because the journey is long.


Andrei

December 14, 2016
On Tuesday, 13 December 2016 at 22:47:55 UTC, Andrei Alexandrescu wrote:
> On 12/13/2016 05:05 PM, Jonathan M Davis wrote:
> Recall that all AssertError instances are equivalent up to file and line.

They also have a message. AssertErrors aren't any more the same as each other than any other exception type.

> Would be quite cool if all failed assertions showed the same file and line, eh? :o)

LOL. Not so much, no.

> I'm actually of a mind to push this in the language specification - Error objects are not guaranteed to be distinct. Errors already have a number of concessions and shouldn't be used naively.

I might agree if we weren't talking about AssertErrors, but assertions are used in contracts and unit tests where they do not kill the program and potentially need mupltiple instances to work properly with anyone who wants to show all failures rather than just one per module.

Also, aside from the fact that nothrow let's you throw Errors, there's really nothing special about Errors at this point. nothrow does have the side effect that you don't always get full stack cleanup with Errors (and Walter would like that to be the case for cleanup with Errors in general), but the Error objects themselves are not special, and not having full cleanup with AssertErrors with contracts and unit tests would be a big problem for some people. There are people who test their contracts and other Errors with unit tests to make sure that they fail when and how they're supposed to. Either skipping the cleanup in that case or making Errors singletons would break such code, and I don't know how anyone could test their contracts if your proposal went through.

> Right now I don't know what to do to make all exceptions not use GC.

Wouldn't the reference counting solution that you and Walter agreed needed to be done make it possible to fix it so that exceptions don't have to use the GC?

> I do know what to do to avoid using the GC in assert, and in my opinion at a negligible cost in amenities. We can't afford to refuse to take a step just because the journey is long.

Well, this seems to only be of benefit to the folks trying to use betterC, and it's going to cause problems for D programmers that don't care about betterC at all. Given the kind of restrictions and feature-reduction that the folks using betterC are looking for, it seems to me to make a lot more sense to take advantage of version statements  so that the betterC folks can have a stripped down build of druntime without negatively impacting D's features for the rest of us.

- Jonatan M Davis
1 2 3 4
Next ›   Last »