September 20, 2014
On Saturday, 20 September 2014 at 15:05:38 UTC, Adam D. Ruppe wrote:
> On Saturday, 20 September 2014 at 14:33:21 UTC, Dicebot wrote:
>> Pretty much any time you do fibers + async I/O : to emulate blocking API one needs to catch and store exceptions from I/O routines so that later those can be re-thrown from resumed fiber context.
>
> Ah, indeed, and that could have a great many of them alive at once. Blargh, it'd need a real allocator to handle freeing them out of order.
>
> Nevertheless though, I still think the lifetime management there is simple enough for the user-programmer that freeing it manually isn't a big hassle and not worth making major changes to the language over.

I don't follow. Lifetime is totally unknown there and completely up to actual application logic - from the point of view of the caller of something like `readFile()` it just a normal allocated exception that doesn't need any explicit management. Requiring any kind of manual handling would be a huge breaking change.
September 20, 2014
On Saturday, 20 September 2014 at 09:09:38 UTC, Marc Schütz wrote:
> On Saturday, 20 September 2014 at 09:05:15 UTC, ponce wrote:
>> On Friday, 19 September 2014 at 15:32:38 UTC, Andrei Alexandrescu wrote:
>>> Please chime in with thoughts.
>>>
>>
>> Coudln't we throw value types instead? (like in C++)
>
> But how would you chain them?

Owning pointer to next exception.

> And they have to implement Throwable's interface.
One of their member would. Speculative design:

struct ValueException
{
     Unique!ValueException next;
     Unique!Throwable content;
}

Language would change to throw structs and catch them (without
matching).
At the end of a catch bloc, its destructor is called.
This breaks polymorphic catch so it need sugar unfortunately.
September 20, 2014
On 9/19/14, 11:15 PM, Walter Bright wrote:
> On 9/19/2014 10:46 PM, Andrei Alexandrescu wrote:
>>> 2. To deal with (1), existing ARC systems allow escapes from it. This
>>> has severe implications for memory safety. Rust's entire type system
>>> appears to be designed around trying to deal with this, and AFAIK
>>> they're the only ones who have tried. C++ shared_ptr and ObjectiveC's
>>> ARC are not memory safe. They are not. Not not not, and they don't even
>>> try. :-)
>>
>> That's fine. You can't have everything.
>
> You're willing to dispense with memory safety?

No.

>>> 3. ARC objects require an embedded count. This means they cannot be
>>> mixed with non-ARC objects. This is fundamentally DIFFERENT from how GC
>>> behaves, and we cannot pretend or wish this away or add a compiler
>>> switch to make it go away.
>> In nogc mode, everything is ARC so I'm not getting this.
>
> Not even ARC languages try to make everything ARC - because it is
> BLOATED and SLOW. Not C++, not ObjectiveC, not Rust.

Agreed.

>>> D can have ref counted objects, but it will not work with a compiler
>>> switch to switch them back and forth. They'll have to coexist peacefully
>>> with GC objects.
>>
>> We need to figure out a design. All I'm saying is we must not bring
>> prejudice to
>> the table. And a very basic point is: there will be a way to
>> COMPLETELY disable
>> the GC. That is a must.
>
> It doesn't have to be disabled. Just don't call it. The GC is not a
> bridge troll that is going to pop up and extract a toll even if you
> aren't allocating with it.

Well obviously there's a hierarchy of desirability:

1. Using the GC inadvertently causes a compile-time error.

2. Using the GC inadvertently causes a link-time error.

3. Using the GC inadvertently causes a run-time error.

4. Using the GC inadvertently goes undetected.

I disagree that (4) is good for everyone.


Andrei

September 20, 2014
On 9/20/14, 12:46 AM, Olivier Pisano wrote:
> If making the GC completely optional is a must, then error
> handling shouldn't rely on it at all, no? What about completely
> switching exception handling to RC ? Would it have an impact on
> memory safety since exeption handling mecanism is somehow
> "magical code generated by the compiler" ?

The more I think of it the more sensible this is. Exceptions are unlikely to create cycles, not copied extensively, and are generally short lived. So an RC scheme backed by malloc/free seems to be most appropriate.

There would be breakage, though: Throwable would not be convertible to Object. I wonder what the impact in the real world that would cause.


Andrei

September 20, 2014
On Saturday, 20 September 2014 at 15:12:45 UTC, Dicebot wrote:
> Requiring any kind of manual handling would be a huge breaking change.

I'm not talking about *requiring* it; I want it to be a garbage collected object that 1) allocating it never triggers a collection cycle (so it is a @nogc allocation) and 2) you're allowed to explicitly free it if you want to, but if you don't, the gc will get around to it eventually.

We have #2 already: delete (though I'd like it to not be something which is allegedly deprecated). #1 is fairly easy too: just offer a new @nogc allocation function which creates garbage but does not garbage collect.

This could be a new function or the new keyword could be modified to suppress collection when allocating Throwable or whatever.

Maybe I'm missing something though.
September 20, 2014
On 9/20/14, 12:48 AM, Mike Parker wrote:
> I don't know yet what the ultimate impact of a -nogc switch would be on
> library maintenance, but I have a strong suspicion that simple wrapper
> modules and mixins wouldn't be enough to maintain compatibility. If
> there is even the slightest possibility that library maintainers will
> find themselves in that same situation of having to choose a or b
> because maintaining both is too troublesome to bother, then all the
> implications need to be hashed out beforehand.

We need to explore that. A possibility is to support coexistence and then have the option to use a tool statically pinpoint the uses of GC. -- Andrei
September 20, 2014
On 9/20/14, 12:48 AM, Mike Parker wrote:
> I don't know yet what the ultimate impact of a -nogc switch would be on
> library maintenance, but I have a strong suspicion that simple wrapper
> modules and mixins wouldn't be enough to maintain compatibility. If
> there is even the slightest possibility that library maintainers will
> find themselves in that same situation of having to choose a or b
> because maintaining both is too troublesome to bother, then all the
> implications need to be hashed out beforehand.

Agreed. -- Andrei
September 20, 2014
On 9/20/14, 1:20 AM, "Marc Schütz" <schuetzm@gmx.net>" wrote:
> On Friday, 19 September 2014 at 22:14:08 UTC, Andrei Alexandrescu wrote:
>> On 9/19/14, 12:42 PM, Jacob Carlborg wrote:
>>> On 2014-09-19 17:32, Andrei Alexandrescu wrote:
>>>
>>>> Whenever a reference to a Throwable is copied about, passed to
>>>> functions, the compiler inserts appropriately calls to e.g. incRef and
>>>> decRef. (Compiler may assume they cancel each other for optimization
>>>> purposes.) Implementation of these is up to the runtime library.
>>>
>>> Are you suggesting we implement ARC?
>>
>> Yes. -- Andrei
>
> I don't think ARC is needed.
>
> library RC + borrowing + uniqueness/moving = WIN

s/WIN/Rust/
September 20, 2014
On Saturday, 20 September 2014 at 15:28:10 UTC, ponce wrote:
> On Saturday, 20 September 2014 at 09:09:38 UTC, Marc Schütz wrote:
>> On Saturday, 20 September 2014 at 09:05:15 UTC, ponce wrote:
>>> On Friday, 19 September 2014 at 15:32:38 UTC, Andrei Alexandrescu wrote:
>>>> Please chime in with thoughts.
>>>>
>>>
>>> Coudln't we throw value types instead? (like in C++)
>>
>> But how would you chain them?
>
> Owning pointer to next exception.
>
>> And they have to implement Throwable's interface.
> One of their member would. Speculative design:
>
> struct ValueException
> {
>      Unique!ValueException next;
>      Unique!Throwable content;
> }
>
> Language would change to throw structs and catch them (without
> matching).
> At the end of a catch bloc, its destructor is called.
> This breaks polymorphic catch so it need sugar unfortunately.

Ah, now I see, you just want a wrapper that contains a Throwable.
I thought you wanted to throw _any_ value types, like in C++.
September 20, 2014
On Saturday, 20 September 2014 at 16:15:45 UTC, Andrei Alexandrescu wrote:
> We need to explore that. A possibility is to support coexistence and then have the option to use a tool statically pinpoint the uses of GC. -- Andrei

What, *exactly*, does "uses of GC" mean? In other words, what specifically makes GC.malloc evil that must be avoided at any cost while C malloc (+ GC.addRange most likely) is an acceptable replacement?

A few things that come to mind are:

1) Obviously, GC.malloc can trigger a collection. But this can be easily disabled.

2) The GC lock? I don't know how malloc handles this though.

3) Is GC.free substantially different than C's free?

4) Programmers don't typically explicitly free GC memory... but we could.

5) Bookkeeping overhead? I know malloc has some too though, is this really a dealbreaker?

6) Public relations.

...that's all I can think of. What am I missing? Which one of these is actually causing the problem that we're supposed to be fixing here?