Re: Idiomatic D using GC as a library writer
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 :)
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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 :)
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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?
Re: Idiomatic D using GC as a library writer
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!
Re: Idiomatic D using GC as a library writer
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. I've heard stories about similar things happening with C#.
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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
Re: Idiomatic D using GC as a library writer
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 :)
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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.
Re: Idiomatic D using GC as a library writer
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.
Idiomatic D using GC as a library writer
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.
Re: Idiomatic D code to avoid or detect devision by zero
On Monday, 3 August 2020 at 15:33:54 UTC, Dominikus Dittes Scherkl wrote: [...] For really long expressions you could also split it on multiple lines: c = (b_expression == 0) ? (d_longer_expression) : (a_expression/b_expression); +1 looks clean!
Re: Idiomatic D code to avoid or detect devision by zero
On Monday, 3 August 2020 at 14:50:36 UTC, Steven Schveighoffer wrote: On 8/3/20 5:53 AM, Martin Tschierschke wrote: I prefer putting additional bracket around For really long expressions you could also split it on multiple lines: c = (b_expression == 0) ? (d_longer_expression) : (a_expression/b_expression);
Re: Idiomatic D code to avoid or detect devision by zero
On 8/3/20 5:53 AM, Martin Tschierschke wrote: On Friday, 31 July 2020 at 14:18:15 UTC, Steven Schveighoffer wrote: On 7/31/20 9:55 AM, Martin Tschierschke wrote: What would be the idiomatic way to write a floating point division occuring inside a loop and handle the case of division by zero. c = a/b; // b might be zero sometimes, than set c to an other value (d). (In the moment I check the divisor being zero or not, with an if-than-else structure, but I find it ugly and so I ask here.) c = b == 0 ? d : a/b; I don't think a function would be shorter or clearer... c = div(a, b, d); Alternatively, you could use a type to effect the behavior you want. Thanks, for the hints. I find the ? : - expressions sometimes hard to reed, especially when a and b are not so simple expressions. I prefer putting additional bracket around: c = (b_expression == 0) ? (d_longer_expression) : (a_expression/b_expression); Yes, that is fine, and up to your preference. You may actually need the parentheses if the expressions somehow override the precedence of the ?: operator. Even with symbol uses, I personally would do actually: c = (b == 0 ? d : a/b); Just because the ` = b == ` looks really bad to me. -Steve
Re: Idiomatic D code to avoid or detect devision by zero
On Friday, 31 July 2020 at 14:18:15 UTC, Steven Schveighoffer wrote: On 7/31/20 9:55 AM, Martin Tschierschke wrote: What would be the idiomatic way to write a floating point division occuring inside a loop and handle the case of division by zero. c = a/b; // b might be zero sometimes, than set c to an other value (d). (In the moment I check the divisor being zero or not, with an if-than-else structure, but I find it ugly and so I ask here.) c = b == 0 ? d : a/b; I don't think a function would be shorter or clearer... c = div(a, b, d); Alternatively, you could use a type to effect the behavior you want. -Steve Thanks, for the hints. I find the ? : - expressions sometimes hard to reed, especially when a and b are not so simple expressions. I prefer putting additional bracket around: c = (b_expression == 0) ? (d_longer_expression) : (a_expression/b_expression); ???
Re: Idiomatic D code to avoid or detect devision by zero
On Friday, 31 July 2020 at 15:19:25 UTC, Andrea Fontana wrote: On Friday, 31 July 2020 at 13:55:18 UTC, Martin Tschierschke wrote: What would be the idiomatic way to write a floating point division occuring inside a loop and handle the case of division by zero. c = a/b; // b might be zero sometimes, than set c to an other value (d). (In the moment I check the divisor being zero or not, with an if-than-else structure, but I find it ugly and so I ask here.) You should give a look at: https://dlang.org/phobos/std_experimental_checkedint.html You can try with checked!Throw and catch exceptions, for example. Andrea Thanks, I will look at it.
Re: Idiomatic D code to avoid or detect devision by zero
On Friday, 31 July 2020 at 13:55:18 UTC, Martin Tschierschke wrote: What would be the idiomatic way to write a floating point division occuring inside a loop and handle the case of division by zero. c = a/b; // b might be zero sometimes, than set c to an other value (d). (In the moment I check the divisor being zero or not, with an if-than-else structure, but I find it ugly and so I ask here.) You should give a look at: https://dlang.org/phobos/std_experimental_checkedint.html You can try with checked!Throw and catch exceptions, for example. Andrea
Re: Idiomatic D code to avoid or detect devision by zero
On 7/31/20 9:55 AM, Martin Tschierschke wrote: What would be the idiomatic way to write a floating point division occuring inside a loop and handle the case of division by zero. c = a/b; // b might be zero sometimes, than set c to an other value (d). (In the moment I check the divisor being zero or not, with an if-than-else structure, but I find it ugly and so I ask here.) c = b == 0 ? d : a/b; I don't think a function would be shorter or clearer... c = div(a, b, d); Alternatively, you could use a type to effect the behavior you want. -Steve
Idiomatic D code to avoid or detect devision by zero
What would be the idiomatic way to write a floating point division occuring inside a loop and handle the case of division by zero. c = a/b; // b might be zero sometimes, than set c to an other value (d). (In the moment I check the divisor being zero or not, with an if-than-else structure, but I find it ugly and so I ask here.)
Re: __traits(isSame, TemplateOf ...) errors and some Idiomatic D questions
On Monday, 8 January 2018 at 23:03:46 UTC, H. S. Teoh wrote: On Mon, Jan 08, 2018 at 10:59:44PM +, aliak via Digitalmars-d-learn wrote: [...] onlineapp.d(61): Error: template std.traits.TemplateOf does not match any template declaration. And I use it like this: enum r1Sorted = __traits(isSame, TemplateOf!(R1), SortedRange); This seems unnecessarily complicated. What about this instead? enum r1Sorted = is(R1 : SortedRange!T, T...); Basically, what that is-expression means is: "Is R1 a template of the form `SortedRange!T` where T is some list of template arguments". Generally, using __traits directly is usually not recommended unless there's no other way to achieve what you want. T Wow nice! Super nice :D Thanks! And ah I see, I suppose the double underscore kinda hints at that as well?
Re: __traits(isSame, TemplateOf ...) errors and some Idiomatic D questions
On Monday, 8 January 2018 at 23:22:04 UTC, Seb wrote: On Monday, 8 January 2018 at 23:14:32 UTC, Seb wrote: Your problem is that `TemplateOf!(int[])` isn't defined. It should probably be changed to return `void`. https://github.com/dlang/phobos/pull/6016 Damn that's some fast turnaround! And thanks for the explanation as well :) Cheers
Re: __traits(isSame, TemplateOf ...) errors and some Idiomatic D questions
On Monday, 8 January 2018 at 23:14:32 UTC, Seb wrote: Your problem is that `TemplateOf!(int[])` isn't defined. It should probably be changed to return `void`. https://github.com/dlang/phobos/pull/6016
Re: __traits(isSame, TemplateOf ...) errors and some Idiomatic D questions
On Mon, Jan 08, 2018 at 10:59:44PM +, aliak via Digitalmars-d-learn wrote: [...] > onlineapp.d(61): Error: template std.traits.TemplateOf does not match > any template declaration. And I use it like this: > > enum r1Sorted = __traits(isSame, TemplateOf!(R1), SortedRange); This seems unnecessarily complicated. What about this instead? enum r1Sorted = is(R1 : SortedRange!T, T...); Basically, what that is-expression means is: "Is R1 a template of the form `SortedRange!T` where T is some list of template arguments". Generally, using __traits directly is usually not recommended unless there's no other way to achieve what you want. T -- By understanding a machine-oriented language, the programmer will tend to use a much more efficient method; it is much closer to reality. -- D. Knuth
Re: __traits(isSame, TemplateOf ...) errors and some Idiomatic D questions
On Monday, 8 January 2018 at 22:59:44 UTC, aliak wrote: Hi, trying to write some idiomatic generic D code and I'm a bit stuck with using the TemplateOf to check if a range is a SortedRange or not. A bit about the code, I'm basically rewriting https://dlang.org/library/std/algorithm/setops/set_difference.html but I want to do different things based on if the passed in ranges are sorted or not. The error I'm getting is this: onlineapp.d(61): Error: template std.traits.TemplateOf does not match any template declaration. And I use it like this: enum r1Sorted = __traits(isSame, TemplateOf!(R1), SortedRange); That's happening on line 61 and the weird thing is that I'm using TemplateOf exactly (i think) the same way on lines 28 and 29 and those do not error. The code is here: https://run.dlang.io/is/9fowuP If I substitute the isSame trait with compiles, then it works: enum r1Sorted = __traits(compiles, TemplateOf!(R1), SortedRange); pragma(msg, r1Sorted); // prints true Any help would be appreciated! And on a side note, if anyone can point out any things I'm doing wrong when it comes to using D optimally/properly then please do. Cheers! And thanks for any help! PS: 1) Is there a better way to check if a predicate is unary or binary? 2) Is there an idiomatic way to check if a range is sortable or is it just "is(typeof(sort(range)))" basically it? Why don't you use the `is` Expression? https://wiki.dlang.org/Is_expression It has the handy advantage that it will return false on compile errors. is(TemplateOf!(typeof(r1)) == SortedRange); With your example: https://run.dlang.io/is/x2JWjI Your problem is that `TemplateOf!(int[])` isn't defined. It should probably be changed to return `void`.
__traits(isSame, TemplateOf ...) errors and some Idiomatic D questions
Hi, trying to write some idiomatic generic D code and I'm a bit stuck with using the TemplateOf to check if a range is a SortedRange or not. A bit about the code, I'm basically rewriting https://dlang.org/library/std/algorithm/setops/set_difference.html but I want to do different things based on if the passed in ranges are sorted or not. The error I'm getting is this: onlineapp.d(61): Error: template std.traits.TemplateOf does not match any template declaration. And I use it like this: enum r1Sorted = __traits(isSame, TemplateOf!(R1), SortedRange); That's happening on line 61 and the weird thing is that I'm using TemplateOf exactly (i think) the same way on lines 28 and 29 and those do not error. The code is here: https://run.dlang.io/is/9fowuP If I substitute the isSame trait with compiles, then it works: enum r1Sorted = __traits(compiles, TemplateOf!(R1), SortedRange); pragma(msg, r1Sorted); // prints true Any help would be appreciated! And on a side note, if anyone can point out any things I'm doing wrong when it comes to using D optimally/properly then please do. Cheers! And thanks for any help! PS: 1) Is there a better way to check if a predicate is unary or binary? 2) Is there an idiomatic way to check if a range is sortable or is it just "is(typeof(sort(range)))" basically it?
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
(( It follows from this that it will be challenging to achieve full memory safety without fixing the type system first. ))
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 14 January 2015 at 20:23:26 UTC, H. S. Teoh via Digitalmars-d-learn wrote: Huh? ints have value semantics, yet you can take the address of a local int variable. What's your point? Strictly speaking the "int" looses its value semantics if you take the address of it, hold it and give it a new name (assign it to a pointer). It is forced to be an object with an identity (cannot sit in a register and is no longer alias free and indistinguishable from other ints with same value). Same issue with your struct, you turn it into an object with identity by holding the identity, yet keep acting if it is a value. C's type system has questionable soundness, but I guess it could be corrected with behavioural typing... I.e. the preceding events and the state is part of the type and determines what actions it can participate it. Like a behavioural type for a file would make it an error at compile time to close a file before opening it. You could do something similar for taking the address of an int. (Which is kinda what linear typing tries to do.)
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wed, Jan 14, 2015 at 07:43:17PM +, via Digitalmars-d-learn wrote: > On Wednesday, 14 January 2015 at 19:36:44 UTC, H. S. Teoh via > Digitalmars-d-learn wrote: > >Moral of the story: don't have struct fields that point to the struct > >itself. This is almost always a bad idea. Structs have value > >semantics, and the implicit copying around will almost certainly > >break any self-referencing pointers, which leads to dangling > >pointers, good friends of memory corruption, et al. :-P > > If it actually had value semantics you would not be allowed to take > the address of it... :-P Huh? ints have value semantics, yet you can take the address of a local int variable. What's your point? T -- Not all rumours are as misleading as this one.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 14 January 2015 at 19:36:44 UTC, H. S. Teoh via Digitalmars-d-learn wrote: Moral of the story: don't have struct fields that point to the struct itself. This is almost always a bad idea. Structs have value semantics, and the implicit copying around will almost certainly break any self-referencing pointers, which leads to dangling pointers, good friends of memory corruption, et al. :-P If it actually had value semantics you would not be allowed to take the address of it... :-P
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wed, Jan 14, 2015 at 07:05:16PM +, Laeeth Isharc via Digitalmars-d-learn wrote: > On Tuesday, 13 January 2015 at 17:41:53 UTC, Tobias Pankrath wrote: > >On Tuesday, 13 January 2015 at 17:19:42 UTC, Laeeth Isharc wrote: > >> > >>The GC is allowed to move structs around, as I undestand it. Under > >>what circumstances do I get into trouble having a pointer to them? > > > >None, a GC that moves structs around must update every pointer > >afterwards and as far as I know, the standard GC doesn't do that > >(moving things around). > > > >You may not have a pointer inside a struct that points to the struct > >itself. This allows the compiler to elide some copies. > > Got it - thanks. Having a pointer inside a struct that points to itself can also cause unexpected and sometimes very hard to find bugs. Example from real code where this bug occurred: struct S { // Resources we wish to cleanup Resource1 r1; Resource2 r2; ... // List of cleanup routines we'd like to run when the // struct is destroyed. void delegate()[] cleanups; this(...) { // Acquire a resource r1 = acquireResource1(); // Clean it up once we're done. // N.B.: the delegate implicitly closes over // 'this' -- this is what gets us in trouble // later. cleanups ~= { freeResource1(this.r1); }; r2 = acquireResource2(); cleanups ~= { freeResource2(this.r2); }; ... } ~this() { // Cleanup resources in reverse order we // acquired them. foreach_reverse(dg; cleanups) { dg(); } } } /* This function works without any problems. */ void func1() { auto s = S(...); // create an instance of S doStuff(); // Here, S gets cleaned up, and S's dtor releases the // resources correctly. No problem. } /* The following pair of functions, however, have problems... */ S makeS() { // This is just a convenience function for creating an // instance of S. Useful for factoring out any messy // implementation details that may be needed from the // body of func2(). return S(...); } void func2() { // Make an instance of S, as before. auto s = makeS(); // Do some stuff doStuff(); // And now we are done, so s's dtor should cleanup. // ... except, it crashes instead. Why?? } func1() runs perfectly normally, no problem. However, func2() crashes upon exit. Why? The reason is that the delegates created by S.this() close over the 'this' pointer to the new instance of S. But since S is a struct, this pointer is actually a pointer to a local variable on the stack of the caller. This is not a problem in func1() because this local variable resides in the same scope as the body of func1(), so the cleanup delegates get invoked before the local variable goes out of scope. However, in makeS(), we are returning a newly-created instance of S. The compiler actually implements this by creating a temporary local variable to hold the new instance of S, which means the 'this' pointer closed over by the delegates points to this temporary local variable, and then when the new instance of S is returned to func2(), since S is a by-value type, it gets bitwise copied into *another* local variable, that is, 's' in func2(). So the instance of S that func2() sees is actually a different copy of S than the one created by makeS(). The copy created by makeS() has now gone out of scope; however, the delegates registered in s.cleanups have not been adjusted, so they are still closing over the address of the original copy of S in makeS(). Now when func2() finishes and prepares to return, s's dtor gets invoked, and it calls the cleanup delegates which attempt to access the instance of S at the original address, which is now invalid. The result is that they see garbage data instead of the real values of .r1 and .r2, and it crashes the program. (If you're lucky, that is. If you're not so lucky, it won't crash, but will corrupt memory and/or get into an inconsistent state which causes malfunctions later on. Good luck tracing down the problem then!) Moral of the story: don't have struct fields that point to the struct itself. This is almost always a bad idea. Structs have value semantics, and the implicit copying around will almost certainly break any se
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Tuesday, 13 January 2015 at 17:41:53 UTC, Tobias Pankrath wrote: On Tuesday, 13 January 2015 at 17:19:42 UTC, Laeeth Isharc wrote: The GC is allowed to move structs around, as I undestand it. Under what circumstances do I get into trouble having a pointer to them? None, a GC that moves structs around must update every pointer afterwards and as far as I know, the standard GC doesn't do that (moving things around). You may not have a pointer inside a struct that points to the struct itself. This allows the compiler to elide some copies. Got it - thanks.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Tuesday, 13 January 2015 at 17:19:42 UTC, Laeeth Isharc wrote: The GC is allowed to move structs around, as I undestand it. Under what circumstances do I get into trouble having a pointer to them? None, a GC that moves structs around must update every pointer afterwards and as far as I know, the standard GC doesn't do that (moving things around). You may not have a pointer inside a struct that points to the struct itself. This allows the compiler to elide some copies.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 7 January 2015 at 14:59:58 UTC, H. S. Teoh via Digitalmars-d-learn wrote: On Wed, Jan 07, 2015 at 02:52:51PM +, Laeeth Isharc via Digitalmars-d-learn wrote: Another schoolboy question. Suppose I am constructing a tree (in this case it is an AST). In C I would have a pointer for the child to find the parent, and an array or linked list of pointers to find the children from the parent. Obviously, I could still use pointers, but that would not be idiomatic. Not true. If you're using a tree structure, you *should* use pointers. Unless you're using classes, which are by-reference, in which case you can just use the class as-is. :-) --T The GC is allowed to move structs around, as I undestand it. Under what circumstances do I get into trouble having a pointer to them?
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
Small recommendation (apart from the reserved word issue which you fixed): it's generally considered good D style to give structs and classes names that start with capital letters, JustLikeThis. So, I suggest Node rather than node. Very minor point, and of course, your code is yours to style as you wish, but it can be helpful to meet the "standard" style conventions in order to make it as easy as possible for everyone else to understand. Thanks for the reminder. I use D Style when I am writing properly, but haven't yet internalized it for a quick example and old habits die hard.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On 07/01/15 16:02, Laeeth Isharc via Digitalmars-d-learn wrote: class node { string name; node ref; } Small recommendation (apart from the reserved word issue which you fixed): it's generally considered good D style to give structs and classes names that start with capital letters, JustLikeThis. So, I suggest Node rather than node. Very minor point, and of course, your code is yours to style as you wish, but it can be helpful to meet the "standard" style conventions in order to make it as easy as possible for everyone else to understand. See also: http://dlang.org/dstyle.html
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Thu, Jan 08, 2015 at 07:13:28PM +, Paulo Pinto via Digitalmars-d-learn wrote: > On Thursday, 8 January 2015 at 17:42:23 UTC, H. S. Teoh via > Digitalmars-d-learn wrote: [...] > >Vim supports syntax highlighting. > > > >But I don't use it either -- I find it distracts from clarity of > >thought. I use plain vanilla vim in a text-only terminal. [...] > I don't get this, then again I am using syntax highlighting editors > since MS-DOS IDEs supported it. [...] It's just a personal preference. I find that overuse of colors produces a kaleidoscopic rainbow pattern on the screen which, while pretty, distracts from the essence of the code itself, which is what I'm focusing on. It's like a webpage with every other word italicized and/or bolded -- after a while, your brain just tunes it out and it becomes just meaningless (and distracting) noise. I much rather learn to parse the text (resp. code) accurately by eye and let it speak for itself. T -- Those who've learned LaTeX swear by it. Those who are learning LaTeX swear at it. -- Pete Bleackley
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Thursday, 8 January 2015 at 17:42:23 UTC, H. S. Teoh via Digitalmars-d-learn wrote: On Thu, Jan 08, 2015 at 11:29:29AM +, Laeeth Isharc via Digitalmars-d-learn wrote: >this conversation is so funny: well what's wrong with this . >It's a >keyword... >Aa Ha ha ha ha , rol. >Seriously, is it so complicated to use a D editor ? I mean >with >syntax color... Man afraid to ask stoopid questions stays stoopid. And compiler error message far from informative. Not everyone is very visually oriented, and sometimes vi is quicker. Vim supports syntax highlighting. But I don't use it either -- I find it distracts from clarity of thought. I use plain vanilla vim in a text-only terminal. T I don't get this, then again I am using syntax highlighting editors since MS-DOS IDEs supported it. -- Paulo
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On 01/08/2015 09:40 AM, H. S. Teoh via Digitalmars-d-learn wrote: > Vim supports syntax highlighting. > > But I don't use it either -- I find it distracts from clarity of > thought. I use plain vanilla vim in a text-only terminal. I am halfway there: I use syntax highlighting in Emacs but I chose to make keywords and variables the same color. Ali
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Thu, Jan 08, 2015 at 11:29:29AM +, Laeeth Isharc via Digitalmars-d-learn wrote: > > >this conversation is so funny: well what's wrong with this . It's a > >keyword... > >Aa Ha ha ha ha , rol. > >Seriously, is it so complicated to use a D editor ? I mean with > >syntax color... > > Man afraid to ask stoopid questions stays stoopid. And compiler error > message far from informative. > Not everyone is very visually oriented, and sometimes vi is quicker. Vim supports syntax highlighting. But I don't use it either -- I find it distracts from clarity of thought. I use plain vanilla vim in a text-only terminal. T -- Those who've learned LaTeX swear by it. Those who are learning LaTeX swear at it. -- Pete Bleackley
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On 1/8/15 12:15 AM, Meta wrote: On Wednesday, 7 January 2015 at 23:27:19 UTC, anonymous wrote: Don't do this without `dup`ing. Quoting the documentation: Oh, whoops. I thought those special variadic args were always allocated on the heap. Nope, Which makes it annoying, what if the argument IS passed on the heap? Fortunately, there is a solution (one I use in dcollections): foo(T[] x...) foo(T[] x) Can be overloaded. If you ever pass in parameters one at a time, the first is called, and x is guaranteed to be on the stack. The second is called with an actual array only, you are able to not 'dup', and just warn people that x will NOT be dup'd in that case. -Steve
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Thursday, 8 January 2015 at 11:29:30 UTC, Laeeth Isharc wrote: this conversation is so funny: well what's wrong with this . It's a keyword... Aa Ha ha ha ha , rol. Seriously, is it so complicated to use a D editor ? I mean with syntax color... Man afraid to ask stoopid questions stays stoopid. And compiler error message far from informative. Not everyone is very visually oriented, and sometimes vi is quicker. don't worry about it. use whatever you're comfortable with.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
this conversation is so funny: well what's wrong with this . It's a keyword... Aa Ha ha ha ha , rol. Seriously, is it so complicated to use a D editor ? I mean with syntax color... Man afraid to ask stoopid questions stays stoopid. And compiler error message far from informative. Not everyone is very visually oriented, and sometimes vi is quicker.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
what's wrong with the code above ? i get an error no identifier for declarator node. (I have not used classes much, since structs often seem to be enough for what I need to do mostly). ref is a reserved keyword. -- Paulo this conversation is so funny: well what's wrong with this . It's a keyword... Aa Ha ha ha ha , rol. Seriously, is it so complicated to use a D editor ? I mean with syntax color... No need to make fun of anyone.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 7 January 2015 at 23:27:19 UTC, anonymous wrote: Don't do this without `dup`ing. Quoting the documentation: Oh, whoops. I thought those special variadic args were always allocated on the heap.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 7 January 2015 at 15:04:24 UTC, Paulo Pinto wrote: On Wednesday, 7 January 2015 at 15:02:34 UTC, Laeeth Isharc wrote: Not true. If you're using a tree structure, you *should* use pointers. Unless you're using classes, which are by-reference, in which case you can just use the class as-is. :-) Thanks v much. I just came to that realization also when I stepped away. class node { string name; node ref; } what's wrong with the code above ? i get an error no identifier for declarator node. (I have not used classes much, since structs often seem to be enough for what I need to do mostly). ref is a reserved keyword. -- Paulo this conversation is so funny: well what's wrong with this . It's a keyword... Aa Ha ha ha ha , rol. Seriously, is it so complicated to use a D editor ? I mean with syntax color...
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 7 January 2015 at 20:25:10 UTC, Meta wrote: struct Tree { this(string data, Tree[] children...) { this.data = data; this.children = children; Don't do this without `dup`ing. Quoting the documentation: An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned: [...] int[] test(int[] a ...) { return a; // error, array contents invalid after return return a[0..1]; // error, array contents invalid after return return a.dup; // ok, since copy is made } http://dlang.org/function#variadic } string data; Tree[] children; }
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 7 January 2015 at 16:17:47 UTC, Tobias Pankrath wrote: A slice seems overkill to refer to just one object, but is that the best way ? struct Tree { Tree[] children; } Is one way to do it. You can add some nice sugar for this as well: struct Tree { this(string data, Tree[] children...) { this.data = data; this.children = children; } string data; Tree[] children; } http://dpaste.dzfl.pl/76a8a4c44345
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
A slice seems overkill to refer to just one object, but is that the best way ? struct Tree { Tree[] children; } Is one way to do it.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
ref is a reserved keyword. doh! Thanks.
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
Not true. If you're using a tree structure, you *should* use pointers. Unless you're using classes, which are by-reference, in which case you can just use the class as-is. :-) Thanks v much. I just came to that realization also when I stepped away. class node { string name; node ref; } what's wrong with the code above ? i get an error no identifier for declarator node. (I have not used classes much, since structs often seem to be enough for what I need to do mostly).
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wednesday, 7 January 2015 at 15:02:34 UTC, Laeeth Isharc wrote: Not true. If you're using a tree structure, you *should* use pointers. Unless you're using classes, which are by-reference, in which case you can just use the class as-is. :-) Thanks v much. I just came to that realization also when I stepped away. class node { string name; node ref; } what's wrong with the code above ? i get an error no identifier for declarator node. (I have not used classes much, since structs often seem to be enough for what I need to do mostly). ref is a reserved keyword. -- Paulo
Re: idiomatic D: what to use instead of pointers in constructing a tree data structure?
On Wed, Jan 07, 2015 at 02:52:51PM +, Laeeth Isharc via Digitalmars-d-learn wrote: > Another schoolboy question. > > Suppose I am constructing a tree (in this case it is an AST). In C I > would have a pointer for the child to find the parent, and an array or > linked list of pointers to find the children from the parent. > > Obviously, I could still use pointers, but that would not be > idiomatic. Not true. If you're using a tree structure, you *should* use pointers. Unless you're using classes, which are by-reference, in which case you can just use the class as-is. :-) --T
idiomatic D: what to use instead of pointers in constructing a tree data structure?
Another schoolboy question. Suppose I am constructing a tree (in this case it is an AST). In C I would have a pointer for the child to find the parent, and an array or linked list of pointers to find the children from the parent. Obviously, I could still use pointers, but that would not be idiomatic. I also could just use integer array index references. A slice seems overkill to refer to just one object, but is that the best way ?
Re: Idiomatic D?
On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote: There is no "official" idiomatic style like, for example, in python. When I speak about idiomatic D I usually think about style Phobos is written in (omitting legacy modules) as it is the code that gets most attention from most experienced D developers. Got any tips? I'd say single most important thing is designing your API's to be range-based and making sure they work nicely with std.algorithm Preferring simple template + procedural/functional solutions over complicated object hierarchies. Treat module as your basic design and incapsulation unit, not class. Don't rely on specific types, prefer generic implmentations. Verify your all your assumptions with constraints and/or static asserts. Use DDOC + documented unittest feature. It rocks.
Re: Idiomatic D?
On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote: On Thursday, 30 January 2014 at 20:10:01 UTC, Dicebot wrote: On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote: I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D? There is no "official" idiomatic style like, for example, in python. When I speak about idiomatic D I usually think about style Phobos is written in (omitting legacy modules) as it is the code that gets most attention from most experienced D developers. Got any tips? http://qznc.github.io/d-tut/idiomatic.html
Re: Idiomatic D?
On Friday, 31 January 2014 at 04:53:48 UTC, Matt Soucy wrote: Ranges, templates and structs. ~= CTFE ~ UFCS ~= std.algorithm ~ std.range ~= immutable ~ (isProperlyImplemented!shared ? shared : repeatedlyAskAndreiWhatsGoingOnWith!shared ); // Sorry but that was going to cause a slight error. I knew I forgot something...
Re: Idiomatic D?
On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote: I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D? Here is one of the few previous threads on the topic: http://forum.dlang.org/thread/awutlttzvqaawkrjn...@forum.dlang.org
Re: Idiomatic D?
On 01/30/2014 07:17 PM, Stanislav Blinov wrote: On Friday, 31 January 2014 at 00:13:02 UTC, Meta wrote: Ranges, templates and structs. ~= CTFE ~ UFCS ~= std.algorithm ~ std.range ~= immutable ~ (isProperlyImplemented!shared ? shared : repeatedlyAskAndreiWhatsGoingOnWith!shared ); // Sorry but that was going to cause a slight error. -- Matt Soucy http://msoucy.me/
Re: Idiomatic D?
On Friday, 31 January 2014 at 00:17:47 UTC, Stanislav Blinov wrote: On Friday, 31 January 2014 at 00:13:02 UTC, Meta wrote: Ranges, templates and structs. ~= CTFE ~ UFCS ~= std.algorithm ~ std.range ~= immutable ~ (isProperlyImplemented!shared ? shared : repeatedlyAskAndreiWhatsGoingOnWith!shared Repeat these steps until you have a beautiful, elegant solution, or ten pages of compiler errors because a template constraint failed somewhere down the line.
Re: Idiomatic D?
On Friday, 31 January 2014 at 00:13:02 UTC, Meta wrote: Ranges, templates and structs. ~= CTFE ~ UFCS ~= std.algorithm ~ std.range ~= immutable ~ (isProperlyImplemented!shared ? shared : repeatedlyAskAndreiWhatsGoingOnWith!shared
Re: Idiomatic D?
On Friday, 31 January 2014 at 00:09:34 UTC, Stanislav Blinov wrote: On Friday, 31 January 2014 at 00:08:02 UTC, Meta wrote: On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote: Got any tips? Ranges, templates and structs. ~= CTFE ~ UFCS ~= std.algorithm ~ std.range
Re: Idiomatic D?
On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote: On Thursday, 30 January 2014 at 20:10:01 UTC, Dicebot wrote: On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote: I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D? There is no "official" idiomatic style like, for example, in python. When I speak about idiomatic D I usually think about style Phobos is written in (omitting legacy modules) as it is the code that gets most attention from most experienced D developers. Got any tips? Ranges, templates and structs.
Re: Idiomatic D?
On Friday, 31 January 2014 at 00:08:02 UTC, Meta wrote: On Thursday, 30 January 2014 at 22:40:24 UTC, Tofu Ninja wrote: Got any tips? Ranges, templates and structs. ~= CTFE ~ UFCS
Re: Idiomatic D?
On Thursday, 30 January 2014 at 20:10:01 UTC, Dicebot wrote: On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote: I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D? There is no "official" idiomatic style like, for example, in python. When I speak about idiomatic D I usually think about style Phobos is written in (omitting legacy modules) as it is the code that gets most attention from most experienced D developers. Got any tips?
Idiomatic D?
I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D?
Re: Idiomatic D?
On Thursday, 30 January 2014 at 20:05:11 UTC, Tofu Ninja wrote: I hear it thrown around a lot but what does it actually mean? What does the ideal D code look like? What kind of things should some one think about if they are trying to do idiomatic D? There is no "official" idiomatic style like, for example, in python. When I speak about idiomatic D I usually think about style Phobos is written in (omitting legacy modules) as it is the code that gets most attention from most experienced D developers.
Re: Idiomatic D?
On Monday, June 18, 2012 18:20:58 Matt Diesel wrote: > Today I learnt D. I have a lot of experience with other > languages, but I think D fills a gap. So far I've really liked > it, having used C# and C a lot it feels right. I'm also pretty > excited about some of the more powerful features. > > I can teach myself a language no problem, but to make it useful > it's always better to write it the way it was meant to be written. > > Firstly, is there any good resource on what idiomatic D usage is? > For instance Go has a huge page called Effective Go which tells > you how you should use features, rather than what they are. > > And secondly, I would be grateful if anyone could take a look at > this very simple program and comment on how I'm using the > language (ignoring the fact it's really simple and the lexer is > rubbish). Just stuff like interface, class and variable naming > and program structure. I haven't looked at your code at all, but probably the biggest concept that's used heavily in D (especially by the standard library) which is likely new to you is ranges (which are used rather than iterators). We need better documentation and articles about them in general, but probably the best tutorial currently available is this: http://ddili.org/ders/d.en/ranges.html - Jonathan M Davis
Re: Idiomatic D?
Thanks to both of you, that was exactly the sort of input I was looking for :) The D Style guide looks like what I wanted. It's more just about formatting but that should be enough for now. I can't really reply to each individual point, but there is a lot of new stuff there that at first glance looks very useful. I'll reformat my code and have a play. Thanks again.
Re: Idiomatic D?
On Mon, 18 Jun 2012 18:22:34 +0200, Matt Diesel wrote: > Sorry, forgot to post the code: > > http://pastie.org/4109337 > > Is there no way to edit posts? A couple of observations: - According to the D style guide (http://dlang.org/dstyle.html), you should prefer to capitalize class and struct names, constants, and template parameters while starting functions and variables lowercase. Your code betrays your C# experience (I was very similar for a long time) in that you capitalize your method names. Obviously this is a more subjective thing, but your code will blend better with the standard library if you follow the guide. - Read up on ranges. I've written a number of lexers in the past few years in D and the lazy range idiom works really great for this use case. The basic idea is to model the lexer as a range of tokens which the parser (or anything else) can consume. Turns out you can composite a parser, syntax highlighter, etc. with map/reduce and some help from std.functional. The result is super flexible and can potentially be parallelized (your mileage may vary). Overall your code was pretty easy to follow and seemed fairly well written.
Re: Idiomatic D?
Matt Diesel: Firstly, is there any good resource on what idiomatic D usage is? For instance Go has a huge page called Effective Go which tells you how you should use features, rather than what they are. I don't know any such page, but it looks like an interesting addition for the online docs. And secondly, I would be grateful if anyone could take a look at this very simple program and comment on how I'm using the language (ignoring the fact it's really simple and the lexer is rubbish). Just stuff like interface, class and variable naming and program structure. Some notes: - In D method names start with a lowercase. - For multi-line ddoc comments there is also /** ... */ - Consider the usage of some structs, where appropriate. Structs are much more used in D compared to C#. - Consider adding pure/nothrow/const/in/mmutable (and even @safe if you want) tags to methods, functions, arguments, and even normal variables, where possible. - this.input.length == 0 is better written this.input.empty, where empty for arrays (and strings) is in std.array. - Consider the usage of lambdas, to replace function int(int left, int right) { return left + right; } with (left, right) => left + right;. - Instead of free assert() consider using preconditions, postconditions and class/struct invariants. - I suggest to add some unittest{} blocks. - Instead of using Exception() consider creating one exception class for your code, or use one of the few standard ones... But I don't know how many standard ones there are in Phobos. - Overall you code looks well formatted, well commented, well written (I have not run it), it's a good start. Bye, bearophile
Re: Idiomatic D?
Sorry, forgot to post the code: http://pastie.org/4109337 Is there no way to edit posts?
Idiomatic D?
Today I learnt D. I have a lot of experience with other languages, but I think D fills a gap. So far I've really liked it, having used C# and C a lot it feels right. I'm also pretty excited about some of the more powerful features. I can teach myself a language no problem, but to make it useful it's always better to write it the way it was meant to be written. Firstly, is there any good resource on what idiomatic D usage is? For instance Go has a huge page called Effective Go which tells you how you should use features, rather than what they are. And secondly, I would be grateful if anyone could take a look at this very simple program and comment on how I'm using the language (ignoring the fact it's really simple and the lexer is rubbish). Just stuff like interface, class and variable naming and program structure. Thanks a lot, Matt