www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Idiomatic D using GC as a library writer

reply vushu <danvu.hustle gmail.com> writes:
Dear dlang community.


I am unsure about what idiomatic D is.

Some of the Dconf talks tells people just to use the GC, until 
you can't afford
it.

If there are documents that describes what idiomatic D is then I 
would appreciate it.


So my questions are:


What are your thoughts about using GC as a library writer?


If you wan't to include a library into your project aren't you 
more inclined to use a

library which is gc free?



If that is true, then idiomatic D doesn't apply for library 
writers.

Since to get most exposure as a D library writer you kinda need 
to make it gc free right?



Cheers.
Dec 04 2022
next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 What are your thoughts about using GC as a library writer?
Do it. It is lots of gain for very little loss.
 If you wan't to include a library into your project aren't you 
 more inclined to use a library which is gc free?
No, GC free means the library is necessarily more complicated to use and will likely result in a buggier program.
 Since to get most exposure as a D library writer you kinda need 
 to make it gc free right?
All of the top 5 most popular libraries on code.dlang.org embrace the GC.
Dec 04 2022
next sibling parent reply vushu <danvu.hustle gmail.com> writes:
On Sunday, 4 December 2022 at 12:37:08 UTC, Adam D Ruppe wrote:
 On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 What are your thoughts about using GC as a library writer?
Do it. It is lots of gain for very little loss.
 If you wan't to include a library into your project aren't you 
 more inclined to use a library which is gc free?
No, GC free means the library is necessarily more complicated to use and will likely result in a buggier program.
 Since to get most exposure as a D library writer you kinda 
 need to make it gc free right?
All of the top 5 most popular libraries on code.dlang.org embrace the GC.
That's great to hear thanks! I was worried if my library should be GC free or not and how it will affect the adoption of it. Seems like there is no concern.
Dec 04 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/4/22 05:58, vushu wrote:

 I was worried if my library should be GC free
May I humbly recommend you question where that thinking comes from? Ali P.S. I used to be certain that the idea of GC was wrong and the creators of runtimes with GC were simpletons. In contrast, people like me, people who could understand C++, were enlightened. Then I learned.
Dec 04 2022
parent vushu <danvu.hustle gmail.com> writes:
On Sunday, 4 December 2022 at 15:57:26 UTC, Ali Çehreli wrote:
 On 12/4/22 05:58, vushu wrote:

 I was worried if my library should be GC free
May I humbly recommend you question where that thinking comes from? Ali P.S. I used to be certain that the idea of GC was wrong and the creators of runtimes with GC were simpletons. In contrast, people like me, people who could understand C++, were enlightened. Then I learned.
I also come from C++ and as you know it, the community over there isn't quite fond of GC. So I just logical think that by excluding the GC you actually widen the range of usage. But if I only want to cater to the d ecosystem then using GC is the recommended way.
Dec 04 2022
prev sibling next sibling parent reply Sergey <kornburn yandex.ru> writes:
On Sunday, 4 December 2022 at 12:37:08 UTC, Adam D Ruppe wrote:
 All of the top 5 most popular libraries on code.dlang.org 
 embrace the GC.
Interesting. It seems that most of the community suppose that “library” should be used from D :-) But in my opinion - “foreign library experience” is much more important. The usage of D is not that wide… but if it will be possible to write library in D and use it from C/++/Python/R/JVM(JNI)/Erlang(NIF)/nameYourChoice smoothly it will be a win. Run fast (it could be Rust, Zig) extension/library from more high level/less safe/slower dynamic languages. And not only run but also write fast(here is D and Nim could be chosen). Many languages do not have GC inside.. and others have their own. And if your library is going to manipulate objects from other languages with different memory management approach - it could be tricky to do that with GC. You need to make that both GC become friends
Dec 04 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/4/22 06:27, Sergey wrote:

 if it will be possible to write
 library in D and use it from
 C/++/Python/R/JVM(JNI)/Erlang(NIF)/nameYourChoice smoothly it will be a
 win.
Years ago we tried to call D from Java. I realized that it was very tricky to introduce the calling thread to D's GC. D's GC needed to stop the world, which meant it would have to know what threads were running. You can never be sure whether your D library function is being called from a thread you've known or whether the Java runtime (or other user code) just decided to start another thread. We failed and D was replaced with C++. Ali
Dec 04 2022
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Sunday, 4 December 2022 at 16:02:28 UTC, Ali Çehreli wrote:
 D's GC needed to stop the world, which meant it would have to 
 know what threads were running. You can never be sure whether 
 your D library function is being called from a thread you've 
 known or whether the Java runtime (or other user code) just 
 decided to start another thread.
Interesting... you know, maybe D's GC should formally expose a mutex that you can synchronize on for when it is running. So you can cooperatively do this in the jni bridge or something. Might be worth considering.
Dec 04 2022
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Sunday, 4 December 2022 at 17:53:00 UTC, Adam D Ruppe wrote:
 Interesting... you know, maybe D's GC should formally expose a 
 mutex that you can synchronize on for when it is running.
.......... or compile in write barriers. then it doesn't matter if the thread is unregistered, the write barrier will protect it as-needed!
Dec 04 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/4/22 12:17, Adam D Ruppe wrote:
 On Sunday, 4 December 2022 at 17:53:00 UTC, Adam D Ruppe wrote:
 Interesting... you know, maybe D's GC should formally expose a mutex 
 that you can synchronize on for when it is running.
.......... or compile in write barriers. then it doesn't matter if the thread is unregistered, the write barrier will protect it as-needed!
That's way beyond my pay grade. Explain please. :) Ali
Dec 04 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
ALl it means is certain memory patterns (such as writes), will tell the 
GC about it.

Its required for pretty much all advanced GC designs, as a result we are 
pretty much maxing out what we can do.

Worth reading: 
https://www.amazon.com/Garbage-Collection-Handbook-Management-Algorithms/dp/1420082795
Dec 04 2022
prev sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Sunday, 4 December 2022 at 22:46:52 UTC, Ali Çehreli wrote:
 That's way beyond my pay grade. Explain please. :)
The reason that the GC stops threads right now is to ensure that something doesn't change in the middle of its analysis. Consider for example, the GC scans address 0 - 1000 and finds nothing. Then a running thread moves a reference from memory address 2200 down to address 800 while the GC is scanning 1000-2000. Then the GC scans 2000-3000, where the object used to be, but it isn't there anymore... and the GC has no clue it needs to scan address 800 again. It, never having seen the object, thinks the object is just dead and frees it. Then the thread tries to use the object, leading to a crash. The current implementation prevents this by stopping all threads. If nothing is running, nothing can move objects around while the GC is trying to find them. But, actually stopping everything requires 1) the GC knows which threads are there and has a way to stop them and 2) is overkill! All it really needs to do is prevent certain operations that might change the GC's analysis while it is running, like what happened in the example. It isn't important to stop numeric work, that won't change the GC. It isn't important to stop pointer reads (well not in D's gc anyway, there's some that do need to stop this) so it doesn't need to stop them either. Since what the GC cares about are pointer locations, it is possible to hook that specifically, which we call write barriers; they either block pointer writes or at least notify the GC about them. (And btw not all pointer writes need to be blocked either, just ones that would point to a different memory block. So things like slice iterations can also be allowed to continue. More on my blog http://dpldocs.info/this-week-in-d/Blog.Posted_2022_10_31.html#thoughts on-pointer-barriers ) So what happens then: GC scans address 0 - 1000 and finds nothing. Then a running thread moves a reference from memory address 2200 down to address 800... which would trigger the write barrier. The thread isn't allowed to complete this operation until the GC is done. Notice that the GC didn't have to know about this thread ahead of time, since the running thread is responsible for communicating its intentions to the GC as it happens. (Essentially, the GC holds a mutex and all pointer writes in generated D code are synchronized on it, but there's various implementations.) Then the GC scans 2000-3000, and the object is still there since the write is paused! It doesn't free it. The GC finishes its work and releases the barriers. The thread now resumes and finishes the move, with the object still alive and well. No crash. This would be a concurrent GC, not stopping threads that are doing self-contained work, but it would also be more compatible with external threads, since no matter what the thread, it'd use that gc mutex barrier.
Dec 04 2022
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/4/22 15:25, Adam D Ruppe wrote:

 which would trigger the write barrier. The thread isn't
 allowed to complete this operation until the GC is done.
According to my limited understanding of write barriers, the thread moving to 800 could continue because order of memory operations may have been satisfied. What I don't see is, what would the GC thread be waiting for about the write to 800? Would the GC be leaving behind writes to every page it scans, which have barriers around so that the other thread can't continue? But then the GC's write would finish and the other thread's write would finish. Ok, here is the question: Is there a very long standing partial write that the GC can perform like: "I write to 0x42, but I will finish it 2 seconds later. So, all other writes should wait?"
 The GC finishes its work and releases the barriers.
So, it really is explicit acquisition and releasing of these barriers... I think this is provided by the CPU, not the OS. How many explicit write barriers are there? Ali
Dec 04 2022
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Sunday, 4 December 2022 at 23:37:39 UTC, Ali Çehreli wrote:
 On 12/4/22 15:25, Adam D Ruppe wrote:

 which would trigger the write barrier. The thread isn't
 allowed to complete this operation until the GC is done.
According to my limited understanding of write barriers, the thread moving to 800 could continue because order of memory operations may have been satisfied. What I don't see is, what would the GC thread be waiting for about the write to 800?
I'm not a specialist but I have the impression that GC write barrier and CPU memory ordering write barriers are 2 different things that confusedly use the same term for 2 completely different concepts.
 Would the GC be leaving behind writes to every page it scans, 
 which have barriers around so that the other thread can't 
 continue? But then the GC's write would finish and the other 
 thread's write would finish.

 Ok, here is the question: Is there a very long standing partial 
 write that the GC can perform like: "I write to 0x42, but I 
 will finish it 2 seconds later. So, all other writes should 
 wait?"

 The GC finishes its work and releases the barriers.
So, it really is explicit acquisition and releasing of these barriers... I think this is provided by the CPU, not the OS. How many explicit write barriers are there? Ali
Dec 05 2022
prev sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Sunday, 4 December 2022 at 23:25:34 UTC, Adam D Ruppe wrote:
 On Sunday, 4 December 2022 at 22:46:52 UTC, Ali Çehreli wrote:
 That's way beyond my pay grade. Explain please. :)
The reason that the GC stops threads right now is to ensure that something doesn't change in the middle of its analysis. [snip]
That's a great explanation. Thanks.
Dec 05 2022
prev sibling parent reply Siarhei Siamashka <siarhei.siamashka gmail.com> writes:
On Sunday, 4 December 2022 at 12:37:08 UTC, Adam D Ruppe wrote:
 All of the top 5 most popular libraries on code.dlang.org 
 embrace the GC.
Do you mean the top of the https://code.dlang.org/?sort=score&category=library list? How do you know that they embrace GC? Is it possible to filter packages in this list by nogc or safe compatibility?
Dec 04 2022
next sibling parent Adam D Ruppe <destructionator gmail.com> writes:
On Sunday, 4 December 2022 at 21:55:52 UTC, Siarhei Siamashka 
wrote:
 Do you mean the top of the 
 https://code.dlang.org/?sort=score&category=library list?
Well, I was referring to the five that appear on the homepage, which shows silly instead of emsi containers.
 How do you know that they embrace GC?
I looked at the projects. Except for that arsd-official thing, that's a big mystery to me, the code is completely unreadable. But vibe and dub use it pretty broadly. Unit-threaded and silly are test runners, which isn't even really a library (I find it weird that they are consistently at the top of the list), so much of them don't need the GC anyway, but you can still see that they use it without worry when they do want it like when building the test list with ~=. emsi-containers is built on the allocators thing so it works with or without gc (it works better without though as you learn if you try to use them.)
 Is it possible to filter packages in this list by  nogc or 
  safe compatibility?
No. I do have an idea for it, searching for nogc attributes or attached nogc unittests, but I haven't gotten around to trying it.
Dec 04 2022
prev sibling parent reply Guillaume Piolat <first.last spam.org> writes:
On Sunday, 4 December 2022 at 21:55:52 UTC, Siarhei Siamashka 
wrote:
 Is it possible to filter packages in this list by  nogc or 
  safe compatibility?
You can list DUB packages for " nogc usage" https://code.dlang.org/?sort=score&limit=20&category=library.nogc
Dec 05 2022
parent vushu <danvu.hustle gmail.com> writes:
On Monday, 5 December 2022 at 10:53:33 UTC, Guillaume Piolat 
wrote:
 On Sunday, 4 December 2022 at 21:55:52 UTC, Siarhei Siamashka 
 wrote:
 Is it possible to filter packages in this list by  nogc or 
  safe compatibility?
You can list DUB packages for " nogc usage" https://code.dlang.org/?sort=score&limit=20&category=library.nogc
Cool, it looks like there is only a few nogc suitable libraries.
Dec 05 2022
prev sibling next sibling parent reply Hipreme <msnmancini hotmail.com> writes:
On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 Dear dlang community.


 I am unsure about what idiomatic D is.

 Some of the Dconf talks tells people just to use the GC, until 
 you can't afford
 it.

 If there are documents that describes what idiomatic D is then 
 I would appreciate it.


 So my questions are:


 What are your thoughts about using GC as a library writer?


 If you wan't to include a library into your project aren't you 
 more inclined to use a

 library which is gc free?



 If that is true, then idiomatic D doesn't apply for library 
 writers.

 Since to get most exposure as a D library writer you kinda need 
 to make it gc free right?



 Cheers.
"Until you can't afford", is something really extreme. There is a bunch of ways to deal with GC memory, what I would say that can't afford is when you're constantly allocating memory and because of that, making the program more prone to execute a collection. I haven't had any problem with the GC yet. If you think your program is slow, pass it on a profiler and you'll know the real problem. Don't think too much about that or else you're gonna lose a heck lot of productivity and end up creating needlessly unsafe code. If you're still gonna be hard headed against the GC, at least use slices when allocating from malloc, makes your code safe, readable and less variables to think about. Don't use raw pointers unnecessarily, and right now, the only reason pointers have been used in my code base was not for allocated memory, but for being able to modify a variable from another place when you need to store a variable reference. If you're only gonna modify it inside the function, use `ref` instead.
Dec 04 2022
parent vushu <danvu.hustle gmail.com> writes:
On Sunday, 4 December 2022 at 13:03:07 UTC, Hipreme wrote:
 On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 Dear dlang community.


 I am unsure about what idiomatic D is.

 Some of the Dconf talks tells people just to use the GC, until 
 you can't afford
 it.

 If there are documents that describes what idiomatic D is then 
 I would appreciate it.


 So my questions are:


 What are your thoughts about using GC as a library writer?


 If you wan't to include a library into your project aren't you 
 more inclined to use a

 library which is gc free?



 If that is true, then idiomatic D doesn't apply for library 
 writers.

 Since to get most exposure as a D library writer you kinda 
 need to make it gc free right?



 Cheers.
"Until you can't afford", is something really extreme. There is a bunch of ways to deal with GC memory, what I would say that can't afford is when you're constantly allocating memory and because of that, making the program more prone to execute a collection. I haven't had any problem with the GC yet. If you think your program is slow, pass it on a profiler and you'll know the real problem. Don't think too much about that or else you're gonna lose a heck lot of productivity and end up creating needlessly unsafe code.
True that makes sense, I also tried using nogc in code, but it complicates things. The code is much easier to write when I don't work against the GC.
 If you're still gonna be hard headed against the GC, at least 
 use slices when allocating from malloc, makes your code safe, 
 readable and less variables to think about. Don't use raw 
 pointers unnecessarily, and right now, the only reason pointers 
 have been used in my code base was not for allocated memory, 
 but for being able to modify a variable from another place when 
 you need to store a variable reference. If you're only gonna 
 modify it inside the function, use `ref` instead.
Thanks for the tips :)
Dec 04 2022
prev sibling next sibling parent bachmeier <no spam.net> writes:
On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 Dear dlang community.


 I am unsure about what idiomatic D is.
Idiomatic D code produces the correct result, it's readable, and it's easy for others to use.
 Some of the Dconf talks tells people just to use the GC, until 
 you can't afford
 it.
"can't afford it" in what sense? Pauses for garbage collection are one thing, overall runtime performance is something completely different. Avoiding the GC won't magically make your program faster.
 If there are documents that describes what idiomatic D is then 
 I would appreciate it.


 So my questions are:


 What are your thoughts about using GC as a library writer?
Depends on the library, but most of the time it's best to use it. D's main problem at this point is a lack of high-quality, easy-to-use libraries - not libraries that use the GC.
 If you wan't to include a library into your project aren't you 
 more inclined to use a

 library which is gc free?
The moment I have to think about memory management, I start looking for a different library. I suppose there's nothing wrong if a library avoids the GC internally (since that won't affect me). The GC has never caused problems for me. It has made my life easier.
Dec 04 2022
prev sibling next sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 Dear dlang community.


 I am unsure about what idiomatic D is.

 Some of the Dconf talks tells people just to use the GC, until 
 you can't afford
 it.

 If there are documents that describes what idiomatic D is then 
 I would appreciate it.


 So my questions are:


 What are your thoughts about using GC as a library writer?


 If you wan't to include a library into your project aren't you 
 more inclined to use a

 library which is gc free?



 If that is true, then idiomatic D doesn't apply for library 
 writers.

 Since to get most exposure as a D library writer you kinda need 
 to make it gc free right?



 Cheers.
D gives you the choice But the most important thing is your usecase, what kind of library are you making? Once you answer this question, you can then ask what your memory strategy should be, and then it is based on performance concerns D scale from microcontrollers to servers, drivers, games, desktop apps Your audience will determine what you should provide For a desktop app, a GC is an advantage For a driver or a game, it's not
Dec 04 2022
parent vushu <danvu.hustle gmail.com> writes:
On Sunday, 4 December 2022 at 17:47:38 UTC, ryuukk_ wrote:
 On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 [...]
D gives you the choice But the most important thing is your usecase, what kind of library are you making? Once you answer this question, you can then ask what your memory strategy should be, and then it is based on performance concerns D scale from microcontrollers to servers, drivers, games, desktop apps Your audience will determine what you should provide For a desktop app, a GC is an advantage For a driver or a game, it's not
I agree with you i depends on the usecase, I will consider that thanks.
Dec 05 2022
prev sibling next sibling parent reply Guillaume Piolat <first.last spam.org> writes:
There are legitimate uses cases when you can't afford the runtime 
machinery (attach/detach every incoming thread in a shared 
library), more than not being able to afford the GC from a 
performance point of view.

GC gives you higher productivity and better performance with the 
time gained.

Now,  nogc code is good for performance since (even in a GC 
program) you will have no hidden allocation anymore, if you also 
disable postBlut and copy ctor, unlike in C++ where hidden copies 
are rempant.


On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 What are your thoughts about using GC as a library writer?
I don't use it always, but wish I could do it. Meanwhile, I make plenty of nothrow nogc code. On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 If you wan't to include a library into your project aren't you 
 more inclined to use a library which is gc free?
Yes I am, but my needs are very specific and only the "betterC" subset fits it, and it's certainly not the nominal case in D, nor should it be. Some of the D target have strict requirements, for example Hipreme engine use audio-formats (nothrow nogc), but audio-formats uses exceptions internally, maybe that will be an issue, depending on the flavour of D runtime it uses.
Dec 05 2022
parent vushu <danvu.hustle gmail.com> writes:
On Monday, 5 December 2022 at 10:48:59 UTC, Guillaume Piolat 
wrote:
 There are legitimate uses cases when you can't afford the 
 runtime machinery (attach/detach every incoming thread in a 
 shared library), more than not being able to afford the GC from 
 a performance point of view.

 [...]
Thanks for the description of your usecase, good to know your perspective when considering using a library :)
Dec 05 2022
prev sibling parent reply cc <cc nevernet.com> writes:
On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 What are your thoughts about using GC as a library writer?
If your program runs, does some stuff, and terminates, use the GC. If your program runs, stays up for a while with user occasionally interacting with it, use the GC. If your program runs, and stays up 24/7 doing things in the background, use the GC. If your program is a game meant to run at 60+fps, and any sudden skip or interrupt is unacceptable, no matter how minor (which it should be), plan carefully about how to manage your game objects, because naive GC instantiation and discarding isn't going to cut it. malloc/free, pre-allocated lists, and other strategies come into play here. In a desperate pinch you can also manually `GC.free` your GC-allocated objects but this is not recommended. The GC can still be used for allocations that are not likely to significantly affect performance every frame (strings, occasional user-generated information requests, first-load data instantiation, Steam avatars, etc) -- but also be even more careful when you start mixing and matching. I find that nogc is a bit of a false idol though, even in situations where the GC is deliberately being avoided. It simply adds too much pain to trying to make everything compliant, and certain things just plain don't work (amazingly, the non-allocating form of toString can't be nogc), so I simply avoid it and "be careful" (and/or hook into the GC so I can monitor if an unexpected allocation happens). If you're writing code that's going to run on a space shuttle or life support system, then yeah you might consider the extra effort, but in my use cases it simply fails the cost-benefit analysis. For any strategy, it's still a good idea to have a good understanding of or profile your allocations/deallocations so you're not just spending memory haphazardly or generating excessive collections.
Dec 05 2022
parent vushu <danvu.hustle gmail.com> writes:
On Monday, 5 December 2022 at 14:48:33 UTC, cc wrote:
 On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:
 [...]
If your program runs, does some stuff, and terminates, use the GC. If your program runs, stays up for a while with user occasionally interacting with it, use the GC. If your program runs, and stays up 24/7 doing things in the background, use the GC. [...]
Thanks a lot for your advice :)
Dec 05 2022