March 05, 2017
On Sunday, 5 March 2017 at 04:36:27 UTC, Anthony wrote:
> [...]
>
> Not having it guaranteed is understandable, albeit slightly disappointing.

That is the downside of community-driven development, I'm afraid.

>
> I would pick both, if I had the time to do so. I'm a college student; with that in mind, I can only really learn one right now without giving up most of my free time. I think it'd be stressful if I tried.

As a college student nearing the end of his studies I can totally understand that.

>
> I was referring to phobos. I feel intimidated by the idea of trying to code some of the functions of phobos myself in a no-gc manner. I'm sure I'd run into things way out of my knowledge domain.

I get that, though usually Phobos code is fairly readable if you've got a firm grasp of D templates.

March 05, 2017
On Saturday, 4 March 2017 at 18:09:10 UTC, Anthony wrote:
> I've been having difficulty finding an up-to-date answer to this question, so I figured I'd ask the forum: can deterministic memory management be done in D, without losing any main features?

First let's admit that C++ determinism is a strong point and that D fares a bit worse on this.

I'll give you the simplistic rules for deterministic destruction now (which is required for C++-style deterministic memory management). If you follow these rules your program destruction will be deterministic and you might even push into being exception-safe if you are so inclined. :)

- Use struct RAII wrappers and destructors to release resources. Typically structs with disabled postblit. However very often resources are classes objects because they feature virtual dispatch.

- In destructors, call .destroy on members that are class objects (reverse order of their creation if possible). Also on heap allocated struct but those are rare. The idea is that when the GC kicks in, unreachable objects on the heap should already have already been destroyed.

- Don't let the GC release resources, with the "GC-proof resource class idiom". I remember Andrei pushing for the GC not to call destructors, to no avail. So the GC is calling destructors and you should use it as a _warning that something is wrong_ and determinisim wasn't respected, not as a safety measure and a way to actually release resources (because it's wrong thread, wrong timing, unreliable).

- Like in C++, if your ownership is in the case where it's shared, you can introduce artificial owners (eg: arena pool owns arena pool items).

- The resources that are only memory need no owner and can be managed by the GC. (eg: strings, a ubyte[] array...)

When you have deterministic destruction, it's simple to offload work from GC to manual memory management. You don't loose ANY main feature.

The GC is an efficient way to call free(), and a global owner not a way to release resources.

The problem of GC efficiency itself is separate.


March 05, 2017
On Sunday, 5 March 2017 at 00:06:04 UTC, Inquie wrote:
> Please stop making this argument. Just because one can amortize out the effect of the GC does not in any way change the fact that it is a stop the world GC and for certain applications this is provably a show stopper. One can come up with any number of commercial apps that fail using D's GC.

Which of these commercial apps fail because of the D GC?


March 06, 2017
On Sunday, 5 March 2017 at 13:32:04 UTC, Moritz Maxeiner wrote:
>> I was referring to phobos. I feel intimidated by the idea of trying to code some of the functions of phobos myself in a no-gc manner. I'm sure I'd run into things way out of my knowledge domain.
>
> I get that, though usually Phobos code is fairly readable if you've got a firm grasp of D templates.

Hmm. This is encouraging news to here, given that templates were the most recent topic I've learned in D. Maybe I'll just have to give GC-reliant areas a read. Although I don't know what those areas would be; AFAIK I'd have to look for @nogc tags, which sounds tedious.

As for Guillaume Piolat's Advice:
> - Use struct RAII wrappers and destructors to release resources. Typically structs with disabled postblit. However very often resources are classes objects because they feature virtual dispatch.

>- In destructors, call .destroy on members that are class objects (reverse order of their creation if possible). Also on heap allocated struct but those are rare. The idea is that when the GC kicks in, unreachable objects on the heap should already have already been destroyed.

>- Don't let the GC release resources, with the "GC-proof resource class idiom". I remember Andrei pushing for the GC not to call destructors, to no avail. So the GC is calling destructors and you should use it as a _warning that something is wrong_ and determinisim wasn't respected, not as a safety measure and a way to actually release resources (because it's wrong thread, wrong timing, unreliable).

>- Like in C++, if your ownership is in the case where it's shared, you can introduce artificial owners (eg: arena pool owns arena pool items).

>- The resources that are only memory need no owner and can be managed by the GC.         (eg: strings, a ubyte[] array...)

>When you have deterministic destruction, it's simple to offload work from GC to manual memory management. You don't loose ANY main feature.

>The GC is an efficient way to call free(), and a global owner not a way to release resources.

This is also encouraging! Thanks for the concrete advice. But, I think due to my inexperience, to don't really understand some of your advice. Specifically, the only-memory recourses like strings and arrays can be managed by the GC, and arena pools. I can just look these things up, but I figured it'd be easy to ask first.
March 06, 2017
On Sunday, 5 March 2017 at 04:36:27 UTC, Anthony wrote:
>
> I would pick both, if I had the time to do so. I'm a college student; with that in mind, I can only really learn one right now without giving up most of my free time. I think it'd be stressful if I tried.

This is fair, but, speaking from the field: learning how to JIT-learn and pick up languages quick is a valuable skill that you will never stop using.  It's always worth reminding yourself that languages are cheap; the conceptual underpinnings are what's important.

-Wyatt
March 06, 2017
On Monday, 6 March 2017 at 17:21:15 UTC, Wyatt wrote:
> On Sunday, 5 March 2017 at 04:36:27 UTC, Anthony wrote:
>>
>> I would pick both, if I had the time to do so. I'm a college student; with that in mind, I can only really learn one right now without giving up most of my free time. I think it'd be stressful if I tried.
>
> This is fair, but, speaking from the field: learning how to JIT-learn and pick up languages quick is a valuable skill that you will never stop using.  It's always worth reminding yourself that languages are cheap; the conceptual underpinnings are what's important.
>
> -Wyatt

I guess I should have said this earlier, but I will not be working in the coding industry. Well, it's at least not the plan. I'm a math and physics major as well, and hope that something works out in those fields.

Personally, I enjoy coding but not maintaining others' code. Consequently, I think most coding jobs would leave me unhappy, but I plan using coding as a personal hobby/skill/tool. With that in mind, C++ knowledge doesn't have some inherent value for me; I just want a tool that can do what it can do. Hence, D (almost).

-------------------------

On the main topic, I was peeking around D's blog, and found an interview of Walter Bright and Joakim, an interviewer for our D blog. One of the questions asked Walter what his response toward the "@nogc" crowd, and he says:

>It became clear that the garbage collector wasn't needed to be embedded in most things, that memory allocation could be decided separately from the algorithm. Letting the user decide seemed like a great way forward.

He then shares some information about work for extern C++ exceptions and that @nogc support remains a high priority.

So, it sounds like this is a concrete, expectable goal. And, if that really is true, I'm okay with that. I don't mind the idea of waiting, I just don't want to invest time in a tool to realize it's not the tool I was looking for.

Until this is implemented, I have a few questions that might assuage my lack of closure:

Would it be possible/practical to use another language's code within a  D program, like Rust for example, when deterministic memory management is necessary? It feels like this would be easier then finagling with D to get a similar outcome.

Does the GC run regardless of if it's used? Someone alluded to this earlier, but I just wanted clarity. If I write nogc code, will the GC just stand by idly? Or, is there an option to completely turn it off?

Future thanks for any help.

March 06, 2017
On Monday, 6 March 2017 at 17:54:25 UTC, Anthony wrote:
> Would it be possible/practical to use another language's code within a  D program, like Rust for example, when deterministic memory management is necessary? It feels like this would be easier then finagling with D to get a similar outcome.

Yes. You can call Rust code from C:
https://doc.rust-lang.org/book/ffi.html#calling-rust-code-from-c
You can do the same to call it from D. I have never done it, but I did call Rust from Ruby at one point.

> Does the GC run regardless of if it's used? Someone alluded to this earlier, but I just wanted clarity. If I write nogc code, will the GC just stand by idly? Or, is there an option to completely turn it off?

If you don't allocate with the GC, the GC doesn't run. Code marked @nogc is guaranteed not to cause the GC to run. You can turn the GC off using GC.disable, but there are extreme cases in which it can still run.
March 07, 2017
On Monday, 6 March 2017 at 16:10:51 UTC, Anthony wrote:
> This is also encouraging! Thanks for the concrete advice. But, I think due to my inexperience, to don't really understand some of your advice. Specifically, the only-memory recourses like strings and arrays can be managed by the GC, and arena pools. I can just look these things up, but I figured it'd be easy to ask first.

(Arena pools are an allocator type, unrelated to your question (though they are used to lessen GC usage) ).


When I speak about "only-memory" resources I mean resources that only hold memory transitively.


class MyClass
{
    string a;
    ubyte[] arr;
    float p;
}

There is not much reason to destroy - or release the memory of - a MyClass deterministically since it only references memory. A global owner like the GC will do.

In C++ you would find an owner for each std::string, but in D you can rely on the GC for releaseing them.

But you shalt not rely on the GC for closing files, releasing mutexes, closing sockets... etc. Any object that would hold such a resource (or holds an object that holds such a resource) is better handled in a manual/RAII way instead. Memory allocated with malloc is such a resource too.

In my mind, D programs use a hybrid style of ownership, GC + manual/RAII(aka "scoped ownership"). So it's more complex that just "scoped ownership" like in C++.
1 2
Next ›   Last »