September 20, 2014
On Saturday, 20 September 2014 at 06:28:11 UTC, Paulo Pinto wrote:
> This is one of the reasons why the Objective-C GC failed.
>
> Mixing Frameworks compiled with both modes never worked properly.

Yeah, mixing is bad unless you template eveything. But in pure nogc it would work.

Except, I think most pure nogc projects want to eliminate rtti/exceptions too...
September 20, 2014
On Saturday, 20 September 2014 at 07:35:47 UTC, Ola Fosheim Grostad wrote:
> Except, I think most pure nogc projects want to eliminate rtti/exceptions too...

It should be possible to do on top of plain @nogc Phobos by simply hooking into druntime _d_throw function and providing some own domain-specific handler instead. Of course it doesn't help if exceptions are used to indicate casual data processing signals but it is something else to be fixed in Phobos :)
September 20, 2014
On Saturday, 20 September 2014 at 06:28:11 UTC, Paulo Pinto wrote:
>
> This is one of the reasons why the Objective-C GC failed.
>
> Mixing Frameworks compiled with both modes never worked properly.
>
> --
> Paulo

Yes this was a huge failure to take into account.

Linking code where Throwable inherits from Object with code where
Throwable inherits from RCObject... :(

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" ?
September 20, 2014
On 9/20/2014 1:43 PM, Andrei Alexandrescu wrote:
> On 9/19/14, 7:20 PM, Walter Bright wrote:
>> On 9/19/2014 6:48 PM, Andrei Alexandrescu wrote:
>>> On 9/19/14, 6:18 PM, Walter Bright wrote:
>>>> Having a compiler switch to change the behavior of every module in
>>>> incompatible ways would be a disastrous balkanization. It has to be
>>>> done
>>>> in such a way that the ARC and the existing exceptions can coexist.
>>>
>>> Could you please elaborate why the disaster? -- Andrei
>>>
>>
>> 1. Every library for D will have to come in two versions. One which
>> works, and the other is likely untested. This will divide the D
>> community in half.
>
> I understand where you're coming from. And you're right that we're
> looking at an important change - as big as -m64 vs. -m32 or porting to a
> new platform. It's big. But it's needed, soon. And it would be, it seems
> to me, a mistake to approach this big change as a small change that we
> can sneak in.
>
> This judgment - that RC vs. GC would balkanize the community - has
> become a prejudice that is worth revisiting. Just trotting it out again
> won't do.

Unless I'm missing something, Walter is referring specifically to the -nogc switch (or any such switch) and not to the concept of RC vs GC in general. And on that I am in strong agreement, FWIW.

Recall back during the D1/D2, Phobos/Tango period, library maintainers had to either choose which D version and library to support (D1/Phobos, D1/Tango, D2/Phobos) or come up with a means of supporting all of them. Wrapper modules and mixins were a workable (though terribly annoying) solution for some cases, but not all. It was a nasty mess.

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.

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com

September 20, 2014
19-Sep-2014 19:32, Andrei Alexandrescu пишет:
> As discussed, having exception objects being GC-allocated is clearly a
> large liability that we need to address. They prevent otherwise careful
> functions from being @nogc so they affect even apps that otherwise would
> be okay with a little litter here and there.
>
> The Throwable hierarchy is somewhat separate from everything else, which
> makes it a great starting point for investigating an automated reference
> count approach. Here's what I'm thinking.
>
> First, there must be some compiler flag -nogc or something, which
> triggers the RC exceptions. All modules of an application must be
> compiled with this flag if it is to work (such that one module can throw
> an exception caught by the other). Of course a lot of refinement needs
> to be added here (what happens if one tries to link modules built with
> and without -nogc, allowing people to detect the flag programmatically
> by using version(nogc) etc).
>
> If -nogc is passed, the compiler severs the inheritance relationship
> between Throwable and Object, making it impossible to convert a
> Throwable to an Object. From then henceforth, Throwable and Object form
> a two-rooted forest. (In all likelihood we'll later add an RCObject root
> that Throwable inherits.)
>
> 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. Null
> checking may be left to either the compiler or the library (in the
> latter case, the functions must be nonmember). However it seems the
> compiler may have an advantage because it can elide some of these checks.
>
> Once we get this going, we should accumulate good experience that we can
> later apply to generalizing this approach to more objects. Also, if
> things go well we may as well define _always_ (whether GC or not)
> Throwable to be reference counted; seems like a good fit for all programs.
>

All good, it wasn't a good idea to have GC-ed exceptions in the first place (It's a truly rare thing to have cycles of exceptions). It doesn' t matter GC or @nogc - this must go.

Speaking of RC-ed Throwable - why adding a switch? Just make a transition in 2 steps - all exceptions inherit from RCObject (but stay essentially GC-ed), then hack compiler to perform ARC on RCObject descendants (maybe even with  GC.malloc/GC.free for starters, i.e. the same heap). Then we can mess with custom allocation of these.

I can understand a transitory switch, say -exception-ongc for the minority of folks that indeed DO rely on exceptions being GC and not counted.


-- 
Dmitry Olshansky
September 20, 2014
On Saturday, 20 September 2014 at 05:46:44 UTC, Andrei Alexandrescu wrote:
>> 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.

The ref counted objects still need to be considered as roots for the GC. This limits how much "completely" can be achieved.
September 20, 2014
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
September 20, 2014
On Saturday, 20 September 2014 at 08:20:47 UTC, Marc Schütz 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

You can't do polymorphic entity RC (like exceptions) without at least some help from compiler because language currently does not provide tools for lifetime control of classes. At least _some_ form of ARC is necessary.
September 20, 2014
On 9/20/2014 12:17 AM, Ola Fosheim Grostad wrote:
> On Saturday, 20 September 2014 at 06:01:19 UTC, Walter Bright wrote:
>> This doesn't address any of the 3 concerns.
>
> 1. RC efficiency is architecture dependent.

Please show me the efficient assembler for the x86.


> E.g. TSX is coming even if there is
> a bug in lower end CPUs. Suggest making performance oriented prototypes on
> different architectures before concluding.

I'd love to see it.


> 2. As long as you have a RC pointer to an obj on the stack you can switch to
> regular references. No magic involved for the easy case, just semantic analysis.

As soon as you pass a reference to a function, that all goes out the window. There's a reason why Rust has invested so much effort in the notion of a "borrowed" pointer.


> 3. True, but you can keep the refcount at a negative offset for new-based
> allocations. Besides it only affects those who do @nogc and they should know
> what they are doing.

If this is so simple, why doesn't everyone do it?
September 20, 2014
I'm quite a noobie in memory models but from position of user of D language I have some ideas about syntax of switching between memory models. I think that having everywhere declarations using wrapper structs (like RefCounted) is not very user-friendly. But still we need some way to say to compiler how we want to do memory management. I have read tutorial about Rust language. It looks not very clear for me, but I like the idea that type of memory management is included in variable declaration.

Intead of wrapper struct like scoped!A or RefCounted!A we could declare variables with annotations (attributes in D) to say what memory model we want to use. Compiler should understand this annotation and create some code for memory management. I thing it's possible to declare some interface (maybe struct with compile-time duck typing) to support some user-defined memory models or modifications of basic (implemented in a language) memory models.

Why I am saying about annotations? Because we can annotate some function, class or just block at the module scope that should use some sort of memory management and compiler will create corresponding code. In that case we don't need to put wrapper struct around all variables that use ref counting. We just annotate some function or class declaration as ref-counted and that's it!

It's just a concept of what I like to see in the language design of D in future)) Of course there are a lot of problems in a practice.

Also I think that we shouldn't impose some way of memory model to programmer and let him choose his approach but syntax should be simple and clear as much as it could be. Also some defaults should be for most common cases and for *novice* users of D.

Waiting for critic or thoughts!!!))