Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 20:04:38 UTC, Lance Bachmeier wrote: On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic Also relevant if they're C functions: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org And this if you want to convert C headers to D code: https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com
Re: How to load a DLL file in D?
On Saturday, 11 May 2024 at 19:33:03 UTC, solidstate1991 wrote: I know that BindBC exists and otherwise would use it, but the bigger the library, the more extra hurdle it'll have. When I did a few bindings with it, I had to order the functions the right way, so I could do things much quicker with the Ctrl+Alt+Shift trick under VSCode, and even then having to write both a statically linked and dynamically linked version (the latter which required the functions to be loaded individually into function pointers). Maybe I should write some automation tool... You might find this package useful https://code.dlang.org/packages/dynamic
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 15:18:03 UTC, Steven Schveighoffer wrote: On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. `remove` https://dlang.org/phobos/std_algorithm_mutation.html#remove ```d arr = arr.remove!(v => shouldBeRemoved(v)); ``` Why the reassignment? Because `remove` removes elements *in place*, and does not change the range extents. It returns the portion of the range that contains the unremoved elements. So to give an example: ```d auto arr = [1, 2, 3, 4, 5]; auto result = arr.remove!(i => i % 2 == 1); // remove odd elements assert(result == [2, 4]); // first 2 are the slice that is stored in result // the last three are leftovers. assert(arr == [2, 4, 3, 4, 5]); ``` -Steve In case anyone comes upon this in a search, I wanted to point out a couple dangers of using remove. The first is that it mutates arr, as shown in Steve's example. The second is ``` result[0] = 4; assert(result == [4, 4]); assert(arr == [2, 4, 3, 4, 5]); // Fails arr[0] = 2; assert(result == [4, 4]); // Fails ``` Any future changes you make to result or arr change the other. You can use remove to avoid the allocation of a new array, but you better be sure you never read or modify the original array again. If you use filter ``` auto result = arr.filter!(i => i % 2 == 0).array; ``` arr is unchanged and you can use arr and result as you want.
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: This is presumably such a common task that I'm surprised it isn't easy to find the answer by searching; Is there a standard library function that removes all elements from a dynamic array that matches an input argument? In `std.array` there's the `replace` function which is supposed to replace all occurrences that match an input with another. It seems to work as described on strings, but I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with `[]` in order to remove all occurrences, but it's not allowed. Is there a Phobos function that does what I want? It would be crazy if there isn't. Does filter do what you need? https://dlang.org/phobos/std_algorithm_iteration.html#.filter
Re: Recommendations on porting Python to D
On Wednesday, 24 April 2024 at 19:50:45 UTC, Chris Piker wrote: is anyone aware of any tools that generate an abstract syntax tree which could then be converted to somewhat equivalent D code? This might give me a jump-start on the manual conversion process. Then later I can work on removing the CGI dependency. I haven't used Python much in recent years, but my recollection is that Python 2 had an ast module that would spit out the ast for you.
Re: Best way to use large C library in D as of 2024
On Friday, 12 April 2024 at 18:36:13 UTC, Chris Piker wrote: On Saturday, 30 March 2024 at 07:11:49 UTC, Mike Parker wrote: Though I appreciate the sentiment, it's much more effective and efficient for people actually using the feature, and who appreciate it, to write up a blog post about it somewhere and share that on Twitter/Reddit/HN, etc. I would, but I'm just not a social media person. I pretty much only post online content here and at github.com. You may have the problem that D doesn't attract "very-online" personality types. I do mention D in work presentations, but those are not visible to the public. If you put your writeup in a markdown file on your Github account and then post a link in the announce group, others will post it to the D subreddit and elsewhere I'm sure.
Re: Best way to use large C library in D as of 2024
On Friday, 12 April 2024 at 18:45:21 UTC, Chris Piker wrote: Even though DMD can't compile some C code, that's pretty much a non-issue for me anyway. In my environment the servers are all Linux so "apt-get" (or equivalent) typically provides a pre-compiled dependency. Being able to list a package as a system dependency and then just call it from D with no interface code is a Big Freaking Deal! Compared to Python interfaces this is a huge improvement. It makes D an even better replacement for the mixed mode python + C development I was doing before switching to D for new projects. I agree that it's really good, but the issues I listed were just examples of the things I came across, and I know there are a decent number of other open issues for ImportC. What I'd prefer to avoid is having people try it out and concluding that it's not ready. Kind of like when I tried out Zig. Everyone was saying it's this great language but my trial was brief and I haven't been tempted to try it since. Header files are a different story. They really should "just work" based on my experience. Other things like compiling large libraries or translating C code to D should probably be more in the camp of "experience reports" posted on individual blogs, and they should talk about both the successes and the edge cases.
Re: Unittests pass, and then an invalid memory operation happens after?
On Wednesday, 3 April 2024 at 21:57:00 UTC, Liam McGillivray wrote: Alright. I suppose that some of the optimization decisions I have made so far may have resulted in less readable code for little performance benefit. Now I'm trying to worry less about optimization. Everything has been very fast so far. I haven't used a profiler yet, but I may like to try it. A good example where you people will get fooled is to avoid passing structs as function arguments/return values because you're worried about copying: https://forum.dlang.org/post/jifumskhdmxkimtay...@forum.dlang.org I'm guilty of having done that regularly until I learned how the compiler actually works and how little time certain operations take. One time I even changed clear string arguments to hard-to-remember single char values inside a loop.
Re: Best way to use large C library in D as of 2024
On Saturday, 30 March 2024 at 05:01:32 UTC, harakim wrote: On Tuesday, 26 March 2024 at 20:42:00 UTC, Chris Piker wrote: On Tuesday, 26 March 2024 at 20:19:27 UTC, bachmeier wrote: Should be able to just use it, as described here: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org Create a .c file that includes the header files and then call the functions you need. Wow. **That just worked the first time!** Holy &^@$ that's easy! So why does the 2nd page returned from the google search ``` interfacing with C site:dlang.org ``` (which happens to be: https://dlang.org/spec/interfaceToC.html) still have this text: Since D can call C code directly, it can also call any C library functions, giving D access to the smorgasbord of existing C libraries. To do so, however, one needs to write a D interface (.di) file, which is a translation of the C .h header file for the C library into D. For popular C libraries, the first place to look for the corresponding D interface file is the Deimos Project. If it isn't there already, please write and contribute one to the Deimos Project. ? This lead me to believe that interfacing was a chore and I was considering going back to C for a small program I need. @D Language Foundation - This is a HUGE selling point. I had to use cups the other day and I just copied some code from a d file and linked the library. It was so easy I was suspicious but it worked. Using C from D is pretty much as easy as using C from C and I think you should advertise that better! It works well if you only need to work with a header. There are still a few rough edges that get in the way if you're compiling the full C sources (I filed bugs for all of them): - Can't handle va_arg - Can't cast to a pointer of a struct that's typedef'd - Can't use complex numbers with the ternary operator These problems should be cleaned up before heavily promoting what is an incredible feature. I don't think it's widely known that you can translate C source files into D. I think that's really cool, but in addition to the bugs listed above that ImportC can't handle, it outputs things like dpulicate aliases, function argument names that are D keywords, and declaring unions inside structs equal to void. All of these are easy to fix by hand, but it's time consuming. Once these final odds and ends are working, we have a killer language feature.
Re: Best way to use large C library in D as of 2024
On Tuesday, 26 March 2024 at 20:42:00 UTC, Chris Piker wrote: On Tuesday, 26 March 2024 at 20:19:27 UTC, bachmeier wrote: Should be able to just use it, as described here: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org Create a .c file that includes the header files and then call the functions you need. Wow. **That just worked the first time!** Holy &^@$ that's easy! So why does the 2nd page returned from the google search ``` interfacing with C site:dlang.org ``` (which happens to be: https://dlang.org/spec/interfaceToC.html) still have this text: Since D can call C code directly, it can also call any C library functions, giving D access to the smorgasbord of existing C libraries. To do so, however, one needs to write a D interface (.di) file, which is a translation of the C .h header file for the C library into D. For popular C libraries, the first place to look for the corresponding D interface file is the Deimos Project. If it isn't there already, please write and contribute one to the Deimos Project. ? This lead me to believe that interfacing was a chore and I was considering going back to C for a small program I need. It's a recent thing that it works this well. Hopefully that page gets updated.
Re: Best way to use large C library in D as of 2024
On Tuesday, 26 March 2024 at 19:24:39 UTC, Chris Piker wrote: Hi D I have a C library I use for work, it's maintained by an external organization that puts it through a very through test framework. Though source code is supplied, the intended use is to include the header files and link against pre-compiled code. What is the best way, as of 2024 to use this library with D, in particular dmd? ImportC doesn't seem like the go-to option since the C source does not need to be complied. I've seen some forum post indicating that manually generated D wrappers are no longer needed, but I'm fuzzy on the particulars. If there's any blog posts or other instructions you'd like to reference I'd be happy to check them out. For reference here's the C library in question: https://naif.jpl.nasa.gov/naif/toolkit_C_PC_Linux_GCC_64bit.html Thanks for any guidance you can provide, Should be able to just use it, as described here: https://forum.dlang.org/post/qxctappnigkwvaqak...@forum.dlang.org Create a .c file that includes the header files and then call the functions you need.
Re: Why is this code slow?
On Tuesday, 26 March 2024 at 14:25:53 UTC, Lance Bachmeier wrote: On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote: I know that benchmarks are always controversial and depend on a lot of factors. So far, I read that D performs very well in benchmarks, as well, if not better, as C. I wrote a little program that approximates PI using the Leibniz formula. I implemented the same thing in C, D and Python, all of them execute 1,000,000 iterations 20 times and display the average time elapsed. Here are the results: C: 0.04s Python: 0.33s D: 0.73s What the hell? D slower than Python? This cannot be real. I am sure I am making a mistake here. I'm sharing all 3 programs here: C: https://pastebin.com/s7e2HFyL D: https://pastebin.com/fuURdupc Python: https://pastebin.com/zcXAkSEf As you can see the function that does the job is exactly the same in C and D. Here are the compile/run commands used: C: `gcc leibniz.c -lm -oleibc` D: `gdc leibniz.d -frelease -oleibd` Python: `python3 leibniz.py` PS. my CPU is AMD A8-5500B and my OS is Ubuntu Linux, if that matters. As others suggested, pow is the problem. I noticed that the C versions are often much faster than their D counterparts. (And I don't view that as a problem, since both are built into the language - my only thought is that the D version should call the C version). Changing ``` import std.math:pow; ``` to ``` import core.stdc.math: pow; ``` and leaving everything unchanged, I get C: Avg execution time: 0.007918 D (original): Avg execution time: 0.102612 D (using core.stdc.math): Avg execution time: 0.008134 So more or less the exact same numbers if you use core.stdc.math. And then the other thing is changing ``` const int BENCHMARKS = 20; ``` to ``` enum BENCHMARKS = 20; ``` which should allow substitution of the constant directly into the rest of the program, which gives ``` Avg execution time: 0.007564 ``` On my Ubuntu 22.04 machine, therefore, the LDC binary with no flags is slightly faster than the C code compiled with your flags.
Re: Why is this code slow?
On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote: I know that benchmarks are always controversial and depend on a lot of factors. So far, I read that D performs very well in benchmarks, as well, if not better, as C. I wrote a little program that approximates PI using the Leibniz formula. I implemented the same thing in C, D and Python, all of them execute 1,000,000 iterations 20 times and display the average time elapsed. Here are the results: C: 0.04s Python: 0.33s D: 0.73s What the hell? D slower than Python? This cannot be real. I am sure I am making a mistake here. I'm sharing all 3 programs here: C: https://pastebin.com/s7e2HFyL D: https://pastebin.com/fuURdupc Python: https://pastebin.com/zcXAkSEf As you can see the function that does the job is exactly the same in C and D. Here are the compile/run commands used: C: `gcc leibniz.c -lm -oleibc` D: `gdc leibniz.d -frelease -oleibd` Python: `python3 leibniz.py` PS. my CPU is AMD A8-5500B and my OS is Ubuntu Linux, if that matters. As others suggested, pow is the problem. I noticed that the C versions are often much faster than their D counterparts. (And I don't view that as a problem, since both are built into the language - my only thought is that the D version should call the C version). Changing ``` import std.math:pow; ``` to ``` import core.stdc.math: pow; ``` and leaving everything unchanged, I get C: Avg execution time: 0.007918 D (original): Avg execution time: 0.102612 D (using core.stdc.math): Avg execution time: 0.008134 So more or less the exact same numbers if you use core.stdc.math.
Re: Beta 2.108.0
On Saturday, 16 March 2024 at 09:26:20 UTC, Iain Buclaw wrote: The RC for 2.108 has been released, which includes the following changes from the initial beta: - Named Arguments is now implemented and documented as a new feature in this release. The beta supports the feature, but was left undocumented while some remaining issues were being fixed. - Hexstrings now implicitly convert to integer arrays. The beta had introduced support to allow casting to arrays only. http://dlang.org/download.html#dmd_beta http://dlang.org/changelog/2.108.0.html As usual please report any bugs at https://issues.dlang.org -Iain on behalf of the Dlang Core Team It's only getting a quick mention in the middle of the list of bug fixes, but "Bugzilla 24397: Support C preprocessor function-like macros" is a big deal for ImportC - that was the final piece needed to use ImportC with large C files without manual intervention. (At least that's the case for the code I'm working with.)
Re: How to make a struct containing an associative array to deeply copy (for repeated usage in foreach) ?
On Friday, 15 March 2024 at 20:36:56 UTC, rkompass wrote: I'm quite new to D yet. But I have some acquaintance with Python. Therefore, together with templates the discovery of the Variant type was inspiring me to the following: I wanted to explore if it's possible to do sort of type-agnostic programming with D. This could perhaps enable a simpler translation of Python code to D. Trying with a `Variant[Variant] dct;` dictionary I observed that even simple assignment of key:value pairs was not possible as the different types are not automatically cast to a Variant. You're not the first one. There's no technical reason for the restriction. It's simply a matter of being opposed by those who make these decisions on the basis that it's the wrong way to program or something like that. Here is a recent thread: https://forum.dlang.org/post/ikwphfwevgnsxmdfq...@forum.dlang.org
Re: Is D programming friendly for beginners?
On Tuesday, 12 March 2024 at 19:07:25 UTC, M.M. wrote: I was always wondering about this debate on a suitable "first" programming language in a CS curriculum. I largely observe one dividing point: to start with a strongly-typed language or not. (After that, it probably does not matter so much which language is chosen; alas, it should be available on Windows, Linux, and Mac OS). Do you observe similar sentiment in the discussions in the university settings? I'm not a CS person so I'll have to defer to others (their needs are very different). My grad students are doing more complicated programming for data analysis and simulation. I focus on recursion and using a functional programming approach, because that simplifies things so much for these types of problems. All I need is a language that supports that.
Re: Is D programming friendly for beginners?
On Tuesday, 12 March 2024 at 17:03:42 UTC, Mike Shah wrote: As a note, the 'which language is best for CS 1' debate has long been debated -- but at least in a school setting, I've found the quality/enthusiasm/encouragement of the teacher to be the most important aspect regardless of language choice. As someone that's been teaching beginners to program at a university for a long time (but not in a CS department) I've come to see the choice of language as largely unimportant. You have to decide what you want to teach them and then eliminate the languages that aren't suitable. D is one of many languages that would work with the right content. Other languages, like C++, add unnecessary overhead and thus should not be used. It's often said "X is a complicated language" but that's the wrong way to look at it. You're teaching a set of programming concepts, not a language. The question is how well a particular language works for learning those concepts.
Re: Recommendation about templating engine library
On Monday, 11 March 2024 at 14:59:52 UTC, Ferhat Kurtulmuş wrote: You have already mentioned mustache-d. If it compiles with the recent compilers go for it. I used it some time a go for a similar task involving in d code gen. I found mustache-d easy enough and good enough for my needs. I haven't used it with a recent compiler, but it's hard to see how it would need much maintenance.
Re: length's type.
On Monday, 12 February 2024 at 18:22:46 UTC, H. S. Teoh wrote: Honestly, I think this issue is blown completely out of proportion. Only for people that don't have to deal with the problems it causes. D decided on an unsigned type. You just learn that and adapt your code accordingly, end of story. Issues like these can always be argued both ways, and the amount of energy spent in these debates far outweigh the trivial workarounds in code, of which there are many (use std.conv.to for bounds checks, just outright cast it if you know what you're doing (or just foolhardy), use CheckedInt, etc.). A terrible language is one that makes you expend your energy thinking about workarounds rather than solving your problems. The default should be code that works. The workarounds should be for cases where you want to do something extremely unusual like subtracting from an unsigned type and having it wrap around.
Re: length's type.
On Monday, 12 February 2024 at 17:26:25 UTC, Nick Treleaven wrote: On Friday, 9 February 2024 at 15:19:32 UTC, bachmeier wrote: It's been discussed many, many times. The behavior is not going to change - there won't even be a compiler warning. (You'll have to check with the leadership for their reasons.) Was (part of) the reason because it would disrupt existing code? If that was the blocker then editions are the solution. I don't want to write a speculative answer on Walter's reasoning, but I know that (a) this has come up many times, and (b) I've never seen him express an opinion that anything in the language related to unsigned types is problematic. I can't imagine that he has any intention of changing it, given the number of times it's been raised, but I can't claim any special knowledge of his views.
Re: The difference between the dates in years
On Saturday, 10 February 2024 at 21:56:30 UTC, Lance Bachmeier wrote: On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote: Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly. I'm assuming you mean you want the number of full years between the dates. If so, I use something like this: ``` import std; void main() { writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1))); writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1))); } bool earlierInYear(Date date1, Date date2) { return date1 < Date(date1.year, date2.month, date2.day); } long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year, 0); } else { return date1.year - date2.year; } } ``` should be ``` long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year - 1, 0); } else { return date1.year - date2.year; } } ```
Re: The difference between the dates in years
On Saturday, 10 February 2024 at 15:53:09 UTC, Alexander Zhirov wrote: Is it possible to calculate the difference between dates in years using regular means? Something like that ``` writeln(Date(1999, 3, 1).diffMonths(Date(1999, 1, 1))); ``` At the same time, keep in mind that the month and day matter, because the difference between the year, taking into account the month that has not come, will be less. My abilities are not yet enough to figure it out more elegantly. I'm assuming you mean you want the number of full years between the dates. If so, I use something like this: ``` import std; void main() { writeln(fullYears(Date(1999, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 2, 1))); writeln(fullYears(Date(2000, 3, 1), Date(1999, 4, 1))); writeln(fullYears(Date(2006, 4, 1), Date(1999, 4, 1))); } bool earlierInYear(Date date1, Date date2) { return date1 < Date(date1.year, date2.month, date2.day); } long fullYears(Date date1, Date date2) { assert(date1 >= date2, "The first date has to be later"); if (date1.earlierInYear(date2)) { return max(date1.year - date2.year, 0); } else { return date1.year - date2.year; } } ```
Re: length's type.
On Friday, 9 February 2024 at 11:00:09 UTC, thinkunix wrote: If your issue is that the compiler didn't catch this, shouldn't you raise the issue on a compiler internals list? Maybe I've misunderstood the purpose of d-learn "Questions about learning and using D". It's been discussed many, many times. The behavior is not going to change - there won't even be a compiler warning. (You'll have to check with the leadership for their reasons.) I think something like this, which is such an obviously bad design and hits so many new users, should be discussed in the learn forum so new users are aware of what's going on.
Re: Providing implicit conversion of - memory-safety
On Tuesday, 23 January 2024 at 23:40:55 UTC, Danilo wrote: On Tuesday, 23 January 2024 at 17:54:25 UTC, bachmeier wrote: Here's a reduced version of one of the most bizarre bugs I've dealt with in any language. The only reason I didn't move on to another language was because I was too busy at the time. The code allows for initial values if the index is less than 0, otherwise it returns the element. ``` import std; double value(T)(T index, double * x) { if (index - 5 < 0) { return 0.0; } else { return x[index-5]; } } void main() { double[] v = [1.1, 2.2, 3.3]; // Works writeln(value(3, v.ptr)); // Lucky: program segfaults writeln(value(v.length, v.ptr)); } ``` I noticed this behavior only because the program crashes. Once I figured out what was going on, I realized that the thousands of lines of code I had already written needed to be checked and possibly rewritten. If only I had a compiler to do that for me. How did you make it correct? The fix is very easy once you realize what's going on. index is ulong, so index - 5 is ulong (even though it doesn't make any sense). All you have to do is change index to index.to!long and the problem is solved.
Re: Providing implicit conversion of - memory-safety
On Tuesday, 23 January 2024 at 21:40:46 UTC, Renato wrote: While I can understand your frustration, it seems to me D is not to blame in this instance because the code is quite patently using unsafe constructs (D does not claim to be fully safe). It pretends to be safe. Consider this: ``` void main() { long y = int.max + 1; writeln(y); // -2147483648 long y2 = int.max; writeln(y2 + 1); // 2147483648 int y3 = y; // Won't compile } ``` It can only be described as a mess of inconsistency. `int y3 = y;` should be an error and it is. `int.max + 1` silently turning into a negative value is frankly insane because it's the same problem that a few lines below won't compile. Would something like this work? ```d double value(T)(T index, double* x) if (is(T : size_t)) ``` There's no way to add a template constraint. Many different types, most of which I defined myself, could be sent as an argument. that it's almost always a mistake to subract from any unsigned type - D scanner correctly warns about that). It's the inconsistency that's the problem. You have to program as if the compiler doesn't catch anything - sometimes it throws errors, sometimes it lets stuff through because maybe that's what you want. `int y3 = y` in the code above is not necessarily an error.
Re: Providing implicit conversion of - memory-safety
On Tuesday, 23 January 2024 at 19:27:26 UTC, Renato wrote: Here's a reduced version of one of the most bizarre bugs I've dealt with in any language. The only reason I didn't move on to another language was because I was too busy at the time. The code allows for initial values if the index is less than 0, otherwise it returns the element. ``` import std; double value(T)(T index, double * x) { if (index - 5 < 0) { return 0.0; } else { return x[index-5]; } } void main() { double[] v = [1.1, 2.2, 3.3]; // Works writeln(value(3, v.ptr)); // Lucky: program segfaults writeln(value(v.length, v.ptr)); } ``` I noticed this behavior only because the program crashes. Once I figured out what was going on, I realized that the thousands of lines of code I had already written needed to be checked and possibly rewritten. If only I had a compiler to do that for me. This code seems to be doing everything it can to run into undefined behaviour, though? Why is `index` of a type T that has no requirements at all (when the implementation quite clearly wants `size_t`, or at least an unsigned numerical value)? Why is it using a pointer for x when clearly you intend to use it as a slice? You probably have context that I don't, but I would never expect this sort of code to be anywhere near @safe :D There are two things things that cause the problem. One is the use of a template and the other is passing an unsigned type. The reason the first parameter uses a template is because there are a lot of types I could send as the first argument, and for some of them there was a transformation of index (for instance, you can pass a date as a long[2], or you can pass another type and pull out the length, that sort of thing). It's using a pointer because I was working with a C library, and that's how the data is stored and passed around. The data is time series. If after the transformations the index is less than zero, it returns 0.0, which is used for all pre-sample values. If it's non-negative, return the element at that position. One of the nice things about D is the ability to write this kind of code in such a natural and (I thought) intuitive style. I really like the way all this comes together. There's really no way that code should have been able to do anything wrong. What's terribly frustrating is that the compiler had full knowledge of what was happening, but by choice it didn't say anything, even though D is supposed to prevent these things that happen in C.
Re: Providing implicit conversion of - memory-safety
On Tuesday, 23 January 2024 at 12:34:38 UTC, Nick Treleaven wrote: But I'm strongly in favour of catching any bugs at compile-time (and have been since before I discovered D). I just object to anyone trying to downgrade the importance of automated memory-safety checking. I'm not downgrading the importance of memory safety. All I'm saying is that you can't sell D as a safe language if has bugs like this. Here's a reduced version of one of the most bizarre bugs I've dealt with in any language. The only reason I didn't move on to another language was because I was too busy at the time. The code allows for initial values if the index is less than 0, otherwise it returns the element. ``` import std; double value(T)(T index, double * x) { if (index - 5 < 0) { return 0.0; } else { return x[index-5]; } } void main() { double[] v = [1.1, 2.2, 3.3]; // Works writeln(value(3, v.ptr)); // Lucky: program segfaults writeln(value(v.length, v.ptr)); } ``` I noticed this behavior only because the program crashes. Once I figured out what was going on, I realized that the thousands of lines of code I had already written needed to be checked and possibly rewritten. If only I had a compiler to do that for me.
Re: Providing implicit conversion of
On Monday, 22 January 2024 at 16:39:10 UTC, Nick Treleaven wrote: I've said multiple times that it's silly to spend so much time on memory safety if the language is going to allow stuff like this without a simple way to prevent it. Memory safety issues are a worse class of bug than arithmetic bugs. The required language changes are pretty small to catch arithmetic bugs relative to implementing memory safety. Ultimately, you want the compiler to help you catch bugs in any form, and I don't think someone that wants memory safety is likely to be okay with the type of bugs in this thread. But for me, arithmetic bugs are a much larger problem than memory safety. I mostly use the GC plus calls into well-tested C libraries. I get incorrect results, and when I'm lucky, my program segfaults because I accessed something I shouldn't. When I'm not, it silently and happily gives me the wrong answer.
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:56:59 UTC, zjh wrote: On Monday, 22 January 2024 at 15:51:37 UTC, zjh wrote: I spent `too much time` on D. And some of the inherent `drawbacks` of `C++` are too hateful. It's a package deal. Everything in C++ is there because there were benefits when they added it, but those benefits came with downsides. D will end up in the same place if it emulates C++.
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:45:45 UTC, zjh wrote: On Monday, 22 January 2024 at 15:33:01 UTC, ryuukk_ wrote: it only took me 1 project to never want to touch C++ again.. D language used to have no `copy constructor`, isn't it now added in again? You have to admit the good aspects of `C++`. You should take a look at the `latest C++`. C++ has already learned many advantages of `D`, but D has not made `significant progress`! As a user, `C++` is really not much different from D, and even surpasses D `in many aspects`. `RAII `, `variable parameter` template, `coroutine, concept`, `value semantics`, very easy to understand. Moreover, the `inheritance` of C++ is very enjoyable to use in many aspects. Sounds like you should be using C++. Why are you here?
Re: Providing implicit conversion of
On Monday, 22 January 2024 at 06:43:17 UTC, thinkunix wrote: Gavin Gray via Digitalmars-d-learn wrote: The following code: ulong charlie = 11; long johnstone = std.algorithm.comparison.max(0, -charlie); writeln(format!"johnstone %s"(johnstone)); Results in (without any warning(s)): johnstone -11 However you choose to look at it, this means -11 > 0 (regardless of all arguments concerning implicit conversions, 1's and 2's complements, being efficient, etc). The language should not allow unary unsigned anything. I have no idea what your use case is for this but... WHY are you doing this?? If you declared charlie as unsigned, why would you then attempt to compare using a negative value? If you even had the possibility that charlie might be negative, why wouldn't you use a type that can accomodate the sign? I'm sure they would if the compiler had stopped and provided an error message to tell them what they were doing. Note that in this line ``` long johnstone = std.algorithm.comparison.max(0, -charlie); ``` there is no direct assignment of a negative number to an unsigned type. The comparison is carried out as ulong and then there's an implicit conversion of a ulong to long, even though that can give a very weird result. It's perfectly natural to expect that everything will be carried out as a long since that's what's specified, or that a language like D will forbid implicit conversions if they can possibly give the wrong answer. If you change the long to int, the code will no longer compile. Aside from the general statement that programmers make mistakes, D is prone to these issues because of the heavy use of auto, and because unsigned types are used for things like the length of an array.
Re: Providing implicit conversion of
On Monday, 22 January 2024 at 01:14:06 UTC, Steven Schveighoffer wrote: On Sunday, 21 January 2024 at 16:05:40 UTC, Gavin Gray wrote: The following code: ulong charlie = 11; long johnstone = std.algorithm.comparison.max(0, -charlie); writeln(format!"johnstone %s"(johnstone)); Results in (without any warning(s)): johnstone -11 However you choose to look at it, this means -11 > 0 (regardless of all arguments concerning implicit conversions, 1's and 2's complements, being efficient, etc). The language should not allow unary unsigned anything. This is unlikely to get fixed, just due to the nature of D's philosophy when it comes to C compatibility. It would also break a lot of existing code. -Steve Well there was no problem breaking my code for this (which you even proposed should be fixed): ``` foreach(int i, v; arr) { // i is not an int until you do i.to!int } ``` The compiler knows it's converting from a ulong to a long: ``` ulong a = -11; writeln(a); // 18446744073709551605 long b = a; writeln(b); // -11 ``` It's impossible for both to be the intended behavior. Anyone doing that on purpose (which I suspect is extremely rare) would be doing it because they want b equal to 18446744073709551605. I don't see why this should be treated the same as an int to long conversion because it very much changes the value. There needs to be a safe arithmetic mode because the current behavior of `double j = 10 / 3;` is not what anyone expects and is a bug 100% of the time. I've said multiple times that it's silly to spend so much time on memory safety if the language is going to allow stuff like this without a simple way to prevent it.
Re: The One Billion Row Challenge
On Thursday, 11 January 2024 at 08:57:43 UTC, Christian Köstlin wrote: Did someone already try to do this in dlang? I guess it will be very hard to beat the java solutions running with graalvm! https://news.ycombinator.com/item?id=38851337 Kind regards, Christian The problem with this challenge can be seen in the initial comments. Writing the fastest possible program *for a specific dataset* is not the same thing as writing the fastest program for an arbitrary dataset of that size. And, indeed, the fastest program is the one that does nothing but print the answer. Speed on this task doesn't tell you anything about performance with different types/sizes of data or constraints on programmer time needed to produce a correct implementation and maintain it over time.
Re: R and D interop with saucer
On Tuesday, 9 January 2024 at 19:56:38 UTC, data pulverizer wrote: I'd encourage you to approach this however you like, but for the sake of anyone else reading this, I want to correct a few points. I'm guessing you haven't spent any time understanding embedrv2. Regarding your `R.lib` file (embedrv2 and the previous version), I thought it might have something to do with Weka, the machine learning library - I got my wires crossed there. Perhaps I was reading something to do with the ML library before/while I was reading your repo. My point still stands though. I've never worked anywhere that would allow a developer to install unverified pre-compiled code from an online repo. It would pose too much of a security issue. That's not "unverified pre-compiled code". As I said, it's an import library for Windows, from an attempt long ago to call R from D on Windows. You don't call the .dll file directly on Windows, you call the .lib file. It's the same thing you do with OpenBLAS and many other popular libraries. As I explained my approach is to mirror the 'design language' of Rcpp/RInside/cpp11 libraries, because its a great approach, I'm familiar with it, and so are many others. A user (including myself) will be sensitive to on-boarding and usage friction, so I my library will present a clear, familiar, and easy to use interface. I'm familiar with Rcpp/RInside/cpp11. If you go to the CRAN page for RInside, you'll see I'm one of the authors. If you check out Dirk's 2013 book, you'll see that one of the sections in it was based on an example I gave him. I haven't done much with cpp11, but that's because I was already using D before it existed. embedrv2 does exactly the same thing. You write your D function and metaprogramming is used to create a wrapper that you can call from R without further modification. I didn't know about your betterr R package. I think it is a different approach from the one I would take. I think both Rcpp and in particular cpp11 have very good design approaches and continuous improvements to their design that gives me plenty to think about. They are at the cutting edge and are pushing the boundaries, and I think it would be cool to show that D can play in the same space with ease, finesse, and style. Since you've clearly never used it and don't know how it works, why are you trashing it? I'll let anyone else judge how awkward, complicated and lacking in style it is. Here's the example from the landing page: ``` void main() { // Initialization startR(); // Generate 100 draws from a N(0.5, sd=0.1) distribution Vector x = rnorm(100, 0.5, 0.1); // Create a 3x2 matrix and fill the columns auto m = Matrix(3,2); Column(m,0) = [1.1, 2.2, 3.3]; Column(m,1) = [4.4, 5.5, 6.6]; // Calculate the inverse of the transpose auto m2 = solve(t(m)); // Modify the second and third elements of the first column of m m[1..$,0] = [7.7, 8.8]; // Choose x and y to minimize x^2 + y^2 // Use Nelder-Mead with initial guesses 3.5 and -5.5 auto nm = NelderMead(); OptimSolution sol = nm.solve([3.5, -5.5]); // Clean up closeR(); } extern(C) { double f(int n, double * par, void * ex) { return par[0]*par[0] + par[1]*par[1]; } } ``` That's ten lines of code to generate a vector of random numbers, create and fill a matrix, take the inverse of the transpose of the matrix, mutate the matrix, and solve a nonlinear optimization problem. I don't care that you're not using it. Have fun creating your own project. That doesn't excuse writing falsehoods about the work I've done.
Re: static array is not a range
On Tuesday, 9 January 2024 at 10:11:35 UTC, Alexibu wrote: It looks like isInputRange is false for arrays with fixed length by design. I can do: ```d float[4] arr; foreach(x;arr) writefln("%s",x) ``` but not : ```d arr.each!(a => a.writefln("%s",a)); ``` Is there a good reason for this ? It took my a long time to figure out. Jonathan's been giving you good general information about this. I'm curious about your partial example. If I fix the writefln call, it works. ``` import std; float[4] arr; void main() { arr[0] = 1; arr[1] = 2; arr[2] = 3; arr[3] = 4; arr.each!(a => "%s".writefln(a)); } ```
Re: Using C header libs with importC
On Monday, 8 January 2024 at 18:53:47 UTC, Renato wrote: Is it possible to use C header-only libs from D? In C, I would need to do this: ```c #define STB_DS_IMPLEMENTATION #include "stb_ds.h" ``` The definition must be done in a single C file before including the h file. I tried this in D: ```d enum STB_DS_IMPLEMENTATION = 1; import stb_ds; ``` But it doesn't work. Any suggestions? Perhaps using an intermediate C file to do this would work, but I wanted to know if D can do it. Without knowing the specifics of what you're trying to do, this automatic translation of C headers to D might be what you want: https://forum.dlang.org/post/ugvc3o$5t3$1...@digitalmars.com The way "header-only" is usually used suggests you should change the file extension to .c and compile it directly.
Re: R and D interop with saucer
On Saturday, 30 December 2023 at 00:50:54 UTC, data pulverizer wrote: That's a great point. I really can't remember what stage I was writing saucer when I became aware of EmbedR, but one thing I didn't understand was why it had to have pre-compiled weka? code within the package this is the `R.lib` file, which is a nonstarter security-wise. I also felt that such a project should have strong syntactic similarities with Rcpp to facilitate adoption, that it should have a nicer easier interface, that it would be a good learning experience for me, and that I could (probably) do a decent job at it. I have updated the package to include a reference to EmbedR outlining these points. Interestingly enough, there is a Rust package for R and D interop called embedr as well (https://docs.rs/extendr-api/latest/extendr_api/). Here is the updated version of embedr: https://github.com/bachmeil/embedrv2 The old version you're referencing is from ages ago. I don't know what you mean by Weka code. There was an old import library from when I tried to get embedding of R inside D to work on Windows. The updated library generates the R bindings for the user. There might be something useful there, and the code isn't very long: https://github.com/bachmeil/embedrv2/blob/main/inst/embedr/r.d#L1228 There's an extern_R attribute to specify which functions to export to R. Here's an example from the readme: ``` @extern_R ar1irf(double alpha, double shock, int h) { double[] result; result ~= shock; foreach(ii; 1..h) { result ~= alpha * result.last; } return result; } mixin(exportRFunctions); double last(double[] v) { if (v.length > 0) { return v[$-1]; } else { return 0.0; } } ``` I honestly don't use D much as a replacement for Rcpp any longer. I mostly work in the other direction these days: https://bachmeil.github.io/betterr/ I've been adding Windows support lately so I can share my code with others. There are possibly things in there that are useful to you (whether D calls R or R calls D is not relevant for working with the API). For instance, if you want to pass a function to R without creating a shared library (one example being an objective function for optimization): https://bachmeil.github.io/betterr/funcptr.html Another is using a custom allocator to pass data to R even if it was allocated in D: https://github.com/bachmeil/betterr/blob/main/testing/testalloc.d There are pieces of knowledge I gained by debugging segfaults, like the fact that certain operations will change the pointer of an array and that sort of thing.
Re: D is nice whats really wrong with gc??
On Friday, 22 December 2023 at 12:53:44 UTC, bomat wrote: If you use (or even feel tempted to use) a GC, it means that you don't care about your memory. Neither about its layout nor its size, nor when chunks of it are allocated or deallocated, etc. And if you don't care about these things, you should not call yourself a programmer. You are the reason why modern software sucks and everything gets slower and slower despite the processors getting faster and faster. In fact, you probably should get another job, like flooring inspector or something. :) Given how fast computers are today, the folks that focus on memory and optimizing for performance might want to apply for jobs as flooring inspectors, because they're often solving problems from the 1990s. That's not to say it's never needed, but the number of cases where idiomatic D, Go, or Java will be too slow is shrinking rapidly. And there's a tradeoff. In return for solving a problem that doesn't exist, you get bugs, increased development time, and difficulty changing approaches. I say this as I'm in the midst of porting C code to D. The biggest change by far is deleting line after line of manual memory management. Changing anything in that codebase would be miserable.
Re: D is a great language, but I've had a bad experience getting started
On Thursday, 14 December 2023 at 12:59:32 UTC, Renato wrote: On Thursday, 14 December 2023 at 12:30:35 UTC, Renato wrote: The other compilers were also easily installable on Kubuntu using snap. It seems that the Ubuntu "snap"s are not being updated for a few years?? It seems some of my problems are related to the very old versions I got with snap :( dub - 1.19.0 (seems to be from Oct 2020) ldc2 - 1.24.0 (seems to be from Oct 2020) dmd - v2.090.1 (Feb 2020) I feel stupid for choosing snap (I don't use snaps, just felt like a convenient thing to try this time!). I will try using latest of everything on Linux (on Mac I think I was already fine on latest) and hope it works better. What's worked for me on Ubuntu is to download the .deb from the downloads page and sudo apt install ./dmd_2.106.0-0_amd64.deb. Always have the latest release and never have problems.
Re: New DUB documentation
On Wednesday, 22 November 2023 at 21:35:34 UTC, WebFreak001 wrote: the revamped DUB documentation I started a while ago is now deployed on https://dub.pm Limiting my comments to the "Getting Started" page, since that's obviously where new programmers will go first. On the very first page, there are links to the DUB registry website and assorted man pages. You've just lost half the audience right there. The best possible outcome is that the user is confused but pushes on. It says "You can also skip ahead to First steps if you already have dub installed." How do they know if it's installed? The first page has to be crystal clear. It can't have distractions or require knowledge of the installation status of this thing called "DUB". The "First Steps" page is likely to be the last steps for many. It provides a CLI command and then shows a bunch of output from an interactive session with no explanation. That's followed by a brief discussion of directories and files. There's also mention of .gitignore, so I guess that means Git is required to use DUB. Then there's discussion of two formats, with no information on how to choose, or why it's important. That's followed by a presentation of configuration files with no explanation. I wish I could be positive, but this doesn't move the needle. The two key ingredients for a getting started guide are examples and explanations, and both are missing.
Re: How do I install a package globally?
On Saturday, 11 November 2023 at 23:28:18 UTC, Trevor wrote: Thanks for the detailed reply. I guess what I'd like to do is not create a DUB package for every little project I work on. It seems like most modern languages require a package/dependency manager though. Being able to install libraries globally would avoid this but I can how that can cause it's own set of issues. It doesn't seem efficient in terms of bandwidth and hard disk space to have a new copy of a library for each project that uses it? You can download the package to your computer, for instance by cloning the repo, and add a symbolic link to your project's repo. Then you can compile with the -i option and forget about Dub. That's how I do it (though depending on the project, I might do a full copy of the dependencies into the project repo to guarantee they're always available).
Re: Symbolic computations in D
On Sunday, 29 October 2023 at 08:55:24 UTC, Dmitry Ponyatov wrote: Maybe someone played in this topic, and can give some advice: is D language with its OOP without multiple inheritance and maybe other semantic limitations able and good enough to be used with these books mechanics? The theme looks complex off the shelf, and I'm not sure to speak about D to this above student, especially I myself can't help him anyway not knowing the language in deep. Outside of the most basic functionality, this is only the type of thing you'd want to do if you're willing to put years into it. There are many such systems out there already. It looks like GiNaC (C++) might be their best choice. But note that even that library does not do the more advanced stuff. https://www.ginac.de/tutorial/ https://www.ginac.de/tutorial/#Disadvantages
Re: From the D Blog: Crafting Self-Evident Code in D
On Monday, 2 October 2023 at 17:28:19 UTC, Mike Parker wrote: It's been a long, long while since I published anything on the blog. I do intend to get pick it up again down the road, but Walter recently surprised me with plans of his own. He's taken the topic of his DConf '23 talk and derived a blog post from it: https://dlang.org/blog/2023/10/02/crafting-self-evident-code-with-d/ I guess he got impatient with the pace at which I'm getting the talk videos uploaded :-) And for anyone who'd like to engage in any Reddit discussion that comes up: https://www.reddit.com/r/programming/comments/16y2h36/crafting_selfevident_code_in_dlang/ I wonder if Walter has an opinion on this. In a .c file: ``` void *(STDVEC_DATAPTR)(SEXP x) { if (ALTREP(x)) error("cannot get STDVEC_DATAPTR from ALTREP object"); if (! isVector(x) && TYPEOF(x) != WEAKREFSXP) error("STDVEC_DATAPTR can only be applied to a vector, not a '%s'", type2char(TYPEOF(x))); CHKZLN(x); return STDVEC_DATAPTR(x); } ``` `CHKZLN(x)` only does some checks. It doesn't have any side effects. After scratching my head for a bit, I used grep to locate this in a .h file: ``` #define STDVEC_DATAPTR(x) ((void *) (((SEXPREC_ALIGN *) (x)) + 1)) ``` And of course, there were no comments to explain what is going on. Very self-evident.
Setting GTK_BASEPATH for gtkd
On Monday, 16 October 2023 at 18:28:52 UTC, dan wrote: (Now, i still think that when module initialization order is not forced, it should be something a programmer or systems integrator can choose, but i don't want to be too greedy.) Thanks again for your help!! dan I changed the subject line, so if case Mike Wey sees this, he knows it's about gtkd. If you haven't already, you make want to post your question at https://forum.gtkd.org/groups/GtkD/
Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?
On Tuesday, 10 October 2023 at 13:55:44 UTC, rempas wrote: On Tuesday, 10 October 2023 at 11:46:38 UTC, Hipreme wrote: My engine has its own implementation of toString(long), which does not have dependency with the C runtime: https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2 I have reimplemented the entire conv module since it is one of mostly used module and it pulled down a lot of things, so, with my util module I was able to make my program much smaller too. Thank you for the idea! However, your code used Phobos which I don't want to use so it will not do. Which part uses Phobos? The linked function compiles without importing anything.
Re: how to assign multiple variables at once by unpacking array?
On Saturday, 7 October 2023 at 07:31:45 UTC, mw wrote: https://stackoverflow.com/questions/47046850/is-there-any-way-to-assign-multiple-variable-at-once-with-dlang How to do this Python code in D: ``` s = "1 2 3" A,B,C = map(int, s.split(" ")) A,B,C (1, 2, 3) ``` Is there a better way (since 2017)? That functionality exists, you just have to put things in different places, but there are no more keystrokes: ``` import std; void main() { int x; double y; string z; foo(x, y, z); writeln(x); writeln(y); writeln(z); } void foo(ref int x, ref double y, ref string z) { x = 4; y = 2.6; z = "hello world"; } ``` Maybe there is an argument for `x, y, z = foo();` but it's not that it's easier to read or write. If the goal is to not have to specify the types of the variables, it's hard for me to see the advantage of ``` auto x, y, z = foo(); ``` over returning a struct.
Re: From the D Blog: Crafting Self-Evident Code in D
On Wednesday, 4 October 2023 at 19:50:55 UTC, claptrap wrote: On Wednesday, 4 October 2023 at 12:50:16 UTC, bachmeier wrote: On Wednesday, 4 October 2023 at 07:26:25 UTC, claptrap wrote: I personally found this talk very disappointing. Walter is the head honcho and he's giving talks on coding guidelines? Its like visiting the F1 engineering workshop and getting a talk on health and safety. Tell us the engine, about what you're working on, some gnarly problem you've solved, or something cool. Walter's a contributor to this open source project like anyone else. He's going to give talks on whatever strikes his interest at the time. If he was a CEO with a 7-figure salary like Mitchell Baker, things would be different. Hes not like everyone else he's... "Walter bright creator of the D Programming Language" That means he's contributed a lot in the past, so he has more freedom, not less, in choosing what to talk about. Your post is an example of a contribution tax. Those that do the most work on a project are held to a higher standard than everyone else, and they are the ones most open to criticism, including public criticism. It's one reason productive contributors leave open source projects, and why many people turn down leadership positions.
Re: From the D Blog: Crafting Self-Evident Code in D
On Wednesday, 4 October 2023 at 07:26:25 UTC, claptrap wrote: I personally found this talk very disappointing. Walter is the head honcho and he's giving talks on coding guidelines? Its like visiting the F1 engineering workshop and getting a talk on health and safety. Tell us the engine, about what you're working on, some gnarly problem you've solved, or something cool. Walter's a contributor to this open source project like anyone else. He's going to give talks on whatever strikes his interest at the time. If he was a CEO with a 7-figure salary like Mitchell Baker, things would be different.
Re: From the D Blog: Crafting Self-Evident Code in D
On Tuesday, 3 October 2023 at 12:01:56 UTC, Martyn wrote: Agreed. Even though I do like UFCS, I find the above confusing to follow despite being more pleasing to the eye. I had to break it down and, as Matheus already pointed out, looked incorrect. I normally avoid writing code like a.b.c.d.e.f because it obscures the intermediate steps. I define variables that hold the results of one or a small number of steps so I can track what the code is doing.
Re: Define a new custom operator in D Language.
On Monday, 2 October 2023 at 19:28:32 UTC, BoQsc wrote: Overloading seems to only overload behaviour of existing operator, like: ``` + - * / % ^^ & | ^ <<>>>>>~ in ``` I'm unable to see how the operator overloading would allow to define a new custom operator. And I don't expect that to change. This has come up many times. For example, https://forum.dlang.org/post/mailman.178.1688747876.3523.digitalmar...@puremagic.com Operator overloading in general is provided so that user-defined types can be used like built-in types and work with generic code that uses those operators. Domain-specific language stuff should probably be left to either a domain-specific language or just use properly named functions.
Re: Associate information with a pointer address.
On Sunday, 1 October 2023 at 09:41:39 UTC, BoQsc wrote: The package dependency `emsi_containers` that can be found in https://code.dlang.org/packages/emsi_containers might be a viable way to resolve the problem. ``` /+dub.sdl: dependency "emsi_containers" version="~>0.7" +/ import std; void main(string[] args) @nogc { import containers; DynamicArray!int arr; arr ~= 1; arr ~= 3; foreach (e; arr) printf("%i",e); } ``` The HashMap struct matches the associative array you were talking about earlier. It's been a long time since I looked at it, so I don't know if it's a complete replacement for the built-in associative array.
Re: Straight Forward Arrays
On Sunday, 1 October 2023 at 11:39:11 UTC, bachmeier wrote: On Sunday, 1 October 2023 at 09:01:53 UTC, dhs wrote: Hi, Is there a straight forward Array type in D similar to C++'s vector class? Something along the lines of the tuple: (pointer to elements, length, capacity). I tried two implementations: D's dynamic array and std.container.array. When D creates a dynamic array, it returns a slice. Functions that add or remove elements begin by asking the memory manager for the dynamic array that the slice belongs to. Only then can they go on and add elements. Have you read [this article](https://dlang.org/articles/d-array-article.html)? I'm not sure what you mean with your reference to the memory manager, but consider this program: ``` import std; void main() { int[] x; x.length = 100; foreach(ii; 0..100) { x.ptr[ii] = ii; } x.length = 100; writeln(x); } ``` Or if you want a safer version: ``` import std; void main() { int[] x; x.length = 100; foreach(ii; 0..150) { if (ii < x.length) { x.ptr[ii] = ii; } } writeln(x); } ```
Re: Straight Forward Arrays
On Sunday, 1 October 2023 at 09:01:53 UTC, dhs wrote: Hi, Is there a straight forward Array type in D similar to C++'s vector class? Something along the lines of the tuple: (pointer to elements, length, capacity). I tried two implementations: D's dynamic array and std.container.array. When D creates a dynamic array, it returns a slice. Functions that add or remove elements begin by asking the memory manager for the dynamic array that the slice belongs to. Only then can they go on and add elements. Have you read [this article](https://dlang.org/articles/d-array-article.html)? I'm not sure what you mean with your reference to the memory manager, but consider this program: ``` import std; void main() { int[] x; x.length = 100; foreach(ii; 0..100) { x.ptr[ii] = ii; } x.length = 100; writeln(x); } ```
Re: Associate information with a pointer address.
On Friday, 29 September 2023 at 14:31:54 UTC, BoQsc wrote: After being very happy about associative arrays of D Language, I encountered that they are not `@nogc`friendly. Unsure if I should wait for D language to support it, or do I need to rethink everything. You can work with AA's inside @nogc functions just fine as long as you don't do something that would cause a GC allocation. Consider this program: ``` import std; @nogc double getValue(double[string] aa, string key) { return aa[key]; } void main() { double[string] aa; aa["one"] = 1.0; aa["two"] = 2.0; writeln(aa.getValue("two")); } ``` I'm not sure why you want to add elements inside a @nogc function - hard to say without knowing your use case. When I create an AA with many elements, I disable the GC, add a bunch of elements, and then turn it back on. Once the AA has been created, I can send it to @nogc functions for processing. I have a hard time believing there would be meaningful performance benefits doing anything further. (Though I can only speak to my experience, which of course does not include all applications.)
Re: malloc error when trying to assign the returned pointer to a struct field
On Saturday, 9 September 2023 at 09:30:10 UTC, rempas wrote: Bingo! You and Brad found out! Hate to be that guy, but I posted a link to a stackoverflow question with the exact error message you were getting, and the solution. And I told you I had experienced the same error and that question fixed it.
Re: malloc error when trying to assign the returned pointer to a struct field
On Friday, 8 September 2023 at 07:59:37 UTC, rempas wrote: I do have the following struct: ```d struct Vec(T) { private: T* _ptr = null; // The pointer to the data u64 _cap = 0; // Total amount of elements (not bytes) we can store public: /* Create a vector by just allocating memory for it. The null terminator is not set for strings as, the vector is considered empty and we should first push something to it in order to use it! */ this(i64 size) { this._len = 0; this._cap = size; static if (is(T == char)) { size += 1; } // Additional space for the null terminator this._ptr = cast(T*)malloc(size); } } ``` That's some minimal code that I do have just to showcase it. So, some times, this work will works, some others, it will give me the following error: `Fatal glibc error: malloc.c:2594 (sysmalloc): assertion failed: (old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)` The problem seems to happen when the pointer that is returned from `malloc` is assigned to the `_ptr` field. If I just assign it to a variable and don't assign anything to `_ptr`, it will work! Is there any possible that there is a compiler bug? I do use ldc2 and `betterC`! I've had an error message like that before. This was the answer: https://stackoverflow.com/questions/46803671/sysmalloc-assertion Without additional code it's hard to say if that's your problem.
Re: I don't understand betterC
On Saturday, 2 September 2023 at 03:18:31 UTC, confused wrote: On Friday, 1 September 2023 at 13:31:37 UTC, bachmeier wrote: You can read the documentation for object.d [here](https://dlang.org/phobos/object.html). It's kind of important. I'm not sure which specific part of the documentation was supposed to illuminate the exact nature of that error. This was your inquiry: I have in fact defined a module called object. How is that related to this error? And at the very top of the page it says: Forms the symbols available to all D programs. Includes Object, which is the root of the class object hierarchy. This module is implicitly imported. That means there's a conflict with your module. This hasn't ever been an issue for me, so I can't tell you precisely why it gives that specific error message, but it explains how it's related, per your inquiry. The easy fix is to not name your module something other than object.
Re: I don't understand betterC
On Friday, 1 September 2023 at 13:17:08 UTC, confused wrote: On Friday, 1 September 2023 at 08:19:55 UTC, Richard (Rikki) Andrew Cattermole wrote: ``size_t`` is defined in ``object.d`` which is implicitly imported into all modules. If it cannot be found, one of three things is happening: 1) You have messed with some cli args related to picking druntime/phobos 2) You have defined a module called object. 3) You have a broken compiler install. I have in fact defined a module called ``` object ```. How is that related to this error? I'm interested in betterC as a curiosity, and trying to explore the extent to which D classes and object-oriented programming can be preserved within its bounds (because I really like classes, and I really like D, and I really hate C++, and I'm trying to learn about bare-metal programming). Thank you, by the way, for sharing your knowledge and time. You can read the documentation for object.d [here](https://dlang.org/phobos/object.html). It's kind of important.
Re: toLower
On Thursday, 17 August 2023 at 09:28:05 UTC, Joel wrote: I get an compile time error with sort after using toLower, putting in array before sort, didn’t work: ```d void main() { Import std; "EzraTezla" .to!(char[]) .byCodeUnit .map!(std.uni.toLower) .sort!"a It works for me. Modifying your code to ``` void main() { import std; "EzraTezla" .to!(char[]) .byCodeUnit .map!(std.uni.toLower) .array .sort!"acompiles and gives the expected output. https://run.dlang.io/is/85VjiL
Re: toLower
On Tuesday, 15 August 2023 at 20:09:28 UTC, Joel wrote: On Tuesday, 15 August 2023 at 16:54:49 UTC, FeepingCreature wrote: On Tuesday, 15 August 2023 at 16:47:36 UTC, Joel wrote: [...] When you pass a string to a lambda, it's evaluated in `std.functional.unaryFun`/`binaryFun`. At that point, these modules are imported for use in string expressions: ``` import std.algorithm, std.conv, std.exception, std.math, std.range, std.string; import std.meta, std.traits, std.typecons; ``` And `std.string` itself publically imports: ``` public import std.uni : icmp, toLower, toLowerInPlace, toUpper, toUpperInPlace; ``` But does *not* import `std.ascii`! So there's no ambiguity inside the `sort` string expression between the two `toLower` functions.. How do I get it to work? I tried std.ascii.toLower. And using alias toLower=std.ascii.toLower; Changing your map line to ``` .map!(c => std.uni.toLower(c)) ``` works for me.
Re: DasBetterR
On Tuesday, 1 August 2023 at 12:37:58 UTC, jmh530 wrote: You mention creating a better interface, but recall for rstan to work you need to put the data into an R list with names that match what is in your program (your stan program could be all kinds of complicated with all kinds of different naming conventions). For it to be seamless, you would need to be able to pass a named D tuple to R easily. rstanarm might be easier to create initially, but I don't use that much. That should easy using a list, [as demonstrated here](https://github.com/bachmeil/betterr/blob/main/testing/testlist.d). Anyway, it looks like you have done the hard work in terms of figuring out the code needed to pass a pointer to double[] from D to R. Is that something that you will incorporate into the broader project? I'm not sure. There are a couple of issues. First is that you have to allocate an extra 80 bits at the beginning of the array so R can use it, and that might be sufficiently inconvenient that nobody would want to use it. Second, it currently only works for vectors. I've checked the R source code and creating a new matrix or array always allocates a new vector for storage, then copies existing data into it. Data frames would be fine (they're lists holding vectors of the same length) but the matrix and array types are also important. That means I'd have to add my own matrix and array allocation functions that use custom allocators for this to be practical. Here's the function that allocates a matrix: https://github.com/wch/r-source/blob/713cbe56df52e75f7711e176749c1458e0b2bb05/src/main/array.c#L212 A matrix/array is just a wrapper around a vector plus metadata to interpret the elements. The full code that allocates the data in a matrix is `PROTECT(s = allocVector(mode, n));`. In principle, I can just change that to `PROTECT(s = allocVector3(mode, n, ));`. If it's that simple, then yes, I'll do more with this.
Re: DasBetterR
On Friday, 7 July 2023 at 21:54:12 UTC, jmh530 wrote: Cool. The main thing I want to try is rstan. They have an interface called cmdstan that you can call from the command line that would be possible to use with D. The problem is that you have to write the data to a CSV file and then read it. So it would be kind of slow and I never got around to playing around with it in D. With your tool as it is, I would just have to copy the data in memory, which I would expect not to be as bad of an overhead as IO (but again haven't gotten around to do anything with it). I just pushed an update with a minimal example of how to call RStan with the following workflow: - Allocate a double[] in D and fill it with data. - Use a custom allocator to pass a pointer to the double[] to R. - Call RStan functions using the data. - Pull the results into D. Note that: - This is the first I've used RStan. My previous (limited) usage of Stan was at the command line. In practice, you'd want to create a better interface, so that it feels like D rather than passing strings of code around. I'm not familiar enough with RStan to do that. - The custom allocator requires leaving 80 bits immediately preceding the data free for R to store its metadata related to the vector. There's no way around that as R would not know what to do without the metadata. https://github.com/bachmeil/betterr/blob/main/testing/teststan.d
Re: How can overloads be distinguished on attributes alone?
On Monday, 31 July 2023 at 16:52:03 UTC, Dennis wrote: On Monday, 31 July 2023 at 16:09:11 UTC, bachmeier wrote: Is there a reason it would be difficult to make this not compile? No, except that might result in code breakage. The only way you could have code breakage is if you have ``` void f() { } extern(C) void f() { } ``` but your program never calls f. The fix would be to comment out one of the duplicate function definitions.
Re: Designated initializers to function argument
On Friday, 28 July 2023 at 17:07:37 UTC, IchorDev wrote: On Friday, 28 July 2023 at 17:04:33 UTC, bachmeier wrote: [The DIP](https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1030.md) was approved long ago. It was waiting for an implementation. No shit, it felt like an eternity. But it's still not in the spec...? I'd expect it to appear in the spec after there's a real release. This is the first I've heard of it being supported, and it sounds like it's incomplete.
Re: Designated initializers to function argument
On Friday, 28 July 2023 at 07:35:00 UTC, IchorDev wrote: On Tuesday, 11 July 2023 at 17:43:43 UTC, Steven Schveighoffer wrote: On 7/11/23 11:22 AM, Ki Rill wrote: On Tuesday, 11 July 2023 at 15:16:54 UTC, Ki Rill wrote: apply(Appearance(color: BLACK, strokeWidth: 4)); // other fields are default initialized: strokeOpacity, fillOpacity, Yes, I was going to reply that v 2.103 has added (stealthily) named parameters *as a partial implementation*. Included in this is struct initializers, and constructors and functions that are *not* templates. If you are willing to use DMD 2.103 and above, you should be good. -Steve N-no way?! The spec makes no mention of them, is it really safe to use them yet? [The DIP](https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1030.md) was approved long ago. It was waiting for an implementation.
Re: Pre-import version statements
On Thursday, 20 July 2023 at 15:45:04 UTC, Chris Piker wrote: On Thursday, 20 July 2023 at 06:44:30 UTC, Jonathan M Davis wrote: D has nothing equivalent to that. You compile your code with whichever version of dmd (or ldc, gdc, etc.) that you want, and it either compiles or it doesn't. Thanks :) As I developer that doesn't bother me too much, though I can imagine that management would be concerned. For larger projects it's appreciated when I can point to a particular fixed standard that I'm following. In addition to the `#define` statement above, my libraries were also compiled with `gcc -std=c99`. I'll move over to a compiler specific area and broach the topic. This is one of the arguments for a LTS release. If you know you can compile your code for, say, the next four years, including dependencies, it's not likely to be a problem. If there's a new compiler released eight times a year, there's no hope for that kind of stability, particularly when there are any dependencies.
Re: DasBetterR
On Friday, 30 June 2023 at 16:14:48 UTC, jmh530 wrote: On Thursday, 29 June 2023 at 23:51:44 UTC, bachmeier wrote: [snip] Glad you're continuing to do work on this front. There's a lot of great material explaining things, which is always good. It would be cool to have another version of the link below for using a mir Slice with R. https://bachmeil.github.io/betterr/setvar.html I was wrong. They added custom allocators a while back, but didn't tell anyone. Actually, what I said before is technically correct. The SEXP struct itself still has to be allocated by R and managed by the R garbage collector. It's just that you can use a custom allocator to send a pointer to the data you've allocated, and once R is done with the data, it'll call the function you've provide to free the memory before destroying the SEXP struct that wraps it. I uploaded [an example here](https://github.com/bachmeil/betterr/blob/main/testing/testalloc.d). It's still a bit hackish because you need to adjust the pointer for a header R inserts when it allocates arrays. Adjusting by 10*double.sizeof works in this example, but "my test didn't segfault" doesn't exactly inspire confidence. Once I am comfortable with this solution, I'll do a new release of betterr. This'll be kind of a big deal if it works. For instance, if you want to use a database interface and D doesn't have one, you can use R's interface to that database without having R manage your project's memory. You could use any of the available R interfaces (databases, machine learning libraries, Qt, etc.)
Re: DasBetterR
On Friday, 30 June 2023 at 16:14:48 UTC, jmh530 wrote: On Thursday, 29 June 2023 at 23:51:44 UTC, bachmeier wrote: [snip] Glad you're continuing to do work on this front. There's a lot of great material explaining things, which is always good. It would be cool to have another version of the link below for using a mir Slice with R. https://bachmeil.github.io/betterr/setvar.html I assume you mean that you've allocated memory on the D side, like this: ``` auto a = new double[24]; a[] = 1.6; Slice!(double*, 1) s = a.sliced(); ``` and you want to pass s to R for further analysis. Unfortunately, that will not work. R functions only work with memory R has allocated. It has a single struct type, so there's no way to pass s in this example to R. The best you can do right now is something like this: ``` auto a = Vector(24); Slice!(double*,1) s = a.ptr[0..24].sliced(); // Manipulate s // Send a as an argument to R functions ``` In other words, you let R allocate a, and then you work with the underlying data array as a slice. A way around this limitation would be to implement the same struct (SEXPREC) in D, while avoiding issues with R's garbage collector. That's a more involved problem than I've been willing to take on. If someone has the interest, the SEXPREC struct is defined here: https://github.com/wch/r-source/blob/060f8b64a3a8e489d8684c18b269eea63f182e73/src/include/Defn.h#L184 and the internals are documented here: https://cran.r-project.org/doc/manuals/r-release/R-ints.html#SEXPs As much fun as it is to figure these things out, I have never had sufficient time or motivation to do so.
DasBetterR
I've been using D and R together for a decade. I wrote [a blog post for the D Blog](https://dlang.org/blog/2020/01/27/d-for-data-science-calling-r-from-d/) on the eve of the pandemic. I released the [embedrv2 library](https://github.com/bachmeil/embedrv2) in late 2021. It's useful for writing D functions that are called from R, using D's metaprogramming to write the necessary bindings for you. My programs usually take the opposite approach, where D is the primary language, and I call into R to fill in missing functionality. I've accumulated a large collection of code snippets to enable all kinds of things. The problem is that they were scattered across many projects, there was no consistency across programs, documentation didn't exist, and they were more or less useless to anyone other than me. [This Github repo](https://github.com/bachmeil/betterr) includes D modules, tests demonstrating most of the functionality, documentation, and some posts about how I do specific things. I'm sharing publicly all the things I've been doing in case it has value to anyone else. Examples of functionality: - Creating, accessing, and mutating R data structures, including vector, matrix, data frame, list, array, and time series types. Reference counting handles memory management. - Basic statistical functionality like calculating the mean. Many of these functions use Mir for efficiency. - Linear algebra - Random number generation and sampling - Parallel random number generation - Numerical optimization: direct access to the C libraries used by R's optim function - Quadratic programming - Passing D functions to R without creating a shared library. For example, you can use a D function as the objective function you pass to constrOptim for constrained optimization problems. [Project website](https://bachmeil.github.io/betterr/) There's more detail on the website, but I used the name "Better R" because the entirety of R is available inside your D program and you can use D to improve on it as much as you'd like. Feel free to hate the name. I was originally going to include all of this as part of embedrv2, but realized there was almost no overlap between the two use cases. Moreover, it would be strange to call R from D and call D functions from R in the same program. It simplifies things to keep them in different projects. If you try it and have problems, you can [create a discussion](https://github.com/bachmeil/betterr/discussions). You can also post in this forum, but I won't guarantee I'll see it.
Re: Calling C functions that modify a string
On Thursday, 15 June 2023 at 15:53:57 UTC, Steven Schveighoffer wrote: On 6/15/23 10:04 AM, Jonathan M Davis wrote: On Thursday, June 15, 2023 7:18:06 AM MDT Steven Schveighoffer via Digitalmars-d-learn wrote: But in general, if you want a mutable character array that's zero terminated, you need to make a copy with a zero terminator, but type it as mutable. I'm surprised there isn't a way to do this easily in the library. https://dlang.org/phobos/std_utf.html#toUTFz Oh nice, so `toUTFz!char` should work. Thanks! -Steve Shouldn't it be `toUTFz!(char*)`? That's what I've been using to pass strings to C after someone here recommended it.
Re: D Language Foundation April 2023 Monthly Meeting Summary
On Monday, 15 May 2023 at 18:15:54 UTC, jmh530 wrote: On Monday, 15 May 2023 at 18:02:49 UTC, ryuukk_ wrote: [snip] It can be frustrating when you are are neck deep in some complicated problem to explain to people who haven't spent the same amount of time with it as you have. That poster turns conversation after conversation into the same toxic cesspool. If human interaction is that frustrating, they should refrain from posting.
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Monday, 1 May 2023 at 00:34:03 UTC, ryuukk_ wrote: I don't think it's a misconception. It's more like a complete lack of clarity. the goal is not to use an anonymous enum, the goal is to leverage the robust type system to avoid repeting yourself, wich is bad ``` Value value; value.type = ValueType.STRING; ``` vs ``` Value value; value.type = .STRING; ``` This is another case of the "complete lack of clarity" I wrote about in my earlier comment. With an anonymous enum you could write ``` value.type = STRING; ``` Maybe you have something deeper in mind, but that example does not make a case for changing the language. Rather than shouting, you should put together a better example. I will let this conversation die. I don't think it's going to resolve anything (and I'm not the one that needs convincing anyway).
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Thursday, 27 April 2023 at 06:10:57 UTC, Basile B. wrote: It's a misconception of the problem that the DIP tried to solve. What the DIP tried to solve is that the compiler should know that you are using an enum member. Actually I even think this should work without any special syntax, as a "last resort", let's say. But as you've explained, through Mike's report, this causes problems for D because the identifier resolution is tied to a particular implementation, i.e your fast symtabs. I don't think it's a misconception. It's more like a complete lack of clarity. What would be the point of complexifying the language for the new programmer when you can just use an anonymous enum? This program runs just fine: ``` import std.stdio; enum { A1, B1, C1, D1 } enum { _A, _B, _C, _D } void main() { writeln(A1); writeln(_A); writeln(A1 == _A); auto flag = _B; switch(flag) { case _A: writeln("_A"); break; case _B: writeln("_B"); break; case _C: writeln("_C"); break; case _D: writeln("_D"); break; default: break; } } ``` What's the point in using a named enum if you want an anonymous enum? The response when this question was asked was not "because [something where it matters]". It was instead to ignore the question, give an unrealistic example that was solved by the response, and insert a bunch of unhelpful hostility.
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Thursday, 27 April 2023 at 06:10:57 UTC, Basile B. wrote: On Thursday, 27 April 2023 at 00:16:10 UTC, Walter Bright wrote: This also works: alias F = MySuperLongNameFlag; auto flag = F.A | F.B | F.C | F.D; set_flags(F.A | F.B | F.C | F.D); It's similar to setting a local variable to some complex expression, just so you don't have to repeat that expression multiple times. It's a misconception of the problem that the DIP tried to solve. What the DIP tried to solve is that the compiler should know that you are using an enum member. Actually I even think this should work without any special syntax, as a "last resort", let's say. But as you've explained, through Mike's report, this causes problems for D because the identifier resolution is tied to a particular implementation, i.e your fast symtabs. I don't think it's a misconception. It's more like a complete lack of clarity. What would be the point of complexifying the language for the new programmer when you can just use an anonymous enum? This program runs just fine: ``` import std.stdio; enum { A1, B1, C1, D1 } enum { _A, _B, _C, _D } void main() { writeln(A1); writeln(_A); writeln(A1 == _A); auto flag = _B; switch(flag) { case _A: writeln("_A"); break; case _B: writeln("_B"); break; case _C: writeln("_C"); break; case _D: writeln("_D"); break; default: break; } } ``` What's the point in using a named enum if you want an anonymous enum? The response when this question was asked was not "because [something where it matters]". It was instead to ignore the question, give an unrealistic example that was solved by the response, and insert a bunch of unhelpful hostility.
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Wednesday, 26 April 2023 at 15:07:36 UTC, ryuukk_ wrote: Again, all of this was covered and argumented during the DIP discussion The goal is to improve the language, not find excuses or workarounds, don't defend obfuscation, move forward Your proposals were built on unrealistic examples and false dichotomies. If the only choice is 48-character informative names or two-character uninformative names, the problem is not the language.
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Wednesday, 26 April 2023 at 13:08:22 UTC, Jacob Shtokolov wrote: On Wednesday, 26 April 2023 at 12:50:32 UTC, bachmeier wrote: Many other solutions were provided as well, including but not limited to - Using shorter names - Using alias - Using an IDE with autocomplete - Using copy and paste While aliases and shorter names are always good options, autocomplete and copy/paste really aren't as the end user of the code is either yourself or another developer, so reading the mess produced with copy/paste makes life much more miserable :) Unless you're using incredibly long names (which is not a reason to change the language) I find the explicit approach to be more readable. If I have to parse the code and do inference, it's a lot more work, and in some cases, more error-prone. We've had proposals to drop the semicolon requirement. I would hate that. It's easier to read code when I don't have to figure out where the lines end. I wish the `with()` operator would also be an expression, so you could do something like: ```d auto f = with(Flags) A | B | C |D; ``` This would be great, but it goes against the spirit of this DIP, since you have to explicitly type out `with(Flags)`.
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Tuesday, 25 April 2023 at 04:54:43 UTC, Mike Parker wrote: I submitted DIP1044, "Enum Type Inference", to Walter and Atila on April 1. I received the final decision from them on April 18. They have decided not to accept this proposal. This was the right decision, but it would have been nice to include as one of the reasons that it would have made it harder for new users.
Re: DIP1044---"Enum Type Inference"---Formal Assessment
On Wednesday, 26 April 2023 at 11:52:31 UTC, Jacob Shtokolov wrote: On Tuesday, 25 April 2023 at 20:15:39 UTC, ryuukk_ wrote: void set_connected() { network_connect_state = NetworkConnectState.CONNECTED } MySuperLongNameFlag flag = MySuperLongNameFlag.A | MySuperLongNameFlag.B | MySuperLongNameFlag.C | MySuperLongNameFlag.D; set_flags(MySuperLongNameFlag.A | MySuperLongNameFlag.B | MySuperLongNameFlag.C | MySuperLongNameFlag.D) Okay, I understand this is sometimes really annoying, but in this example, why can't you just: Many other solutions were provided as well, including but not limited to - Using shorter names - Using alias - Using an IDE with autocomplete - Using copy and paste
Re: ImportC issue?
On Wednesday, 19 April 2023 at 13:11:45 UTC, DLearner wrote: On Wednesday, 19 April 2023 at 12:09:44 UTC, Richard (Rikki) Andrew Cattermole wrote: On 20/04/2023 12:07 AM, DLearner wrote: Error: C preprocess command sppn.exe failed for file ex01.c, exit status 1 Did you verify that sppn is accessible in that shell? As in run it, can it be found? If not its just a PATH variable issue. SPPN.exe not visible from that command prompt, but neither (using File Explorer) anywhere on the C: drive (lots of SPPNP.DLL's, in various Windows locations). If SPPN.exe essential to a component of DMD, was it not downloaded with it (and PATH modified to point to it), by the installer? My understanding (from my occasional use of Windows) is that DMD installs the Community Edition of Visual Studio. That should solve your original issue, and you shouldn't need to mess with sppn.exe.
Re: ImportC issue?
On Wednesday, 19 April 2023 at 10:21:22 UTC, DLearner wrote: C source ex01.c: ``` #include int main() { printf("hello world\n"); return 0; } ``` 'dmc ex01.c' produces message: ``` link ex01,,,user32+kernel32/noi; ``` but does generate .obj, .map and .exe files, and the exe executes properly. However, trying to use ImportC via 'dmd ex01.c' produces messages: ``` failed launching cl.exe /P /Zc:preprocessor /PD /nologo ex01.c /FIC:\D\dmd2\windows\bin64\..\..\src\druntime\import\importc.h /Fiex01.i Error: C preprocess command cl.exe failed for file ex01.c, exit status 1 ``` This behaviour was repeated after a complete fresh re-installation of dmd & dmc from the website. Did you use the switch `-m32omf`? https://dlang.org/spec/importc.html#auto-cpp
Re: D Language Foundation March 2023 Monthly Meeting Summary
On Tuesday, 11 April 2023 at 21:53:50 UTC, Mike Parker wrote: ImportC was slowly grinding along. His priority was getting all the standard header files to compile on all the platforms. A lot of the system `.h` files on the various platforms have made a feeble attempt to be usable by different compilers but fail miserably, and each one fails in its unique fashion. They'd be easy to fix if he could edit those files, but of course, he can't. Can't the changes to those files by stored in the compiler? Walter obviously can't change the raw header files, but he can make changes to the files before they're used by the compiler. If that's not possible, can't a modified set of header files be available for download, and if you want to use a system .h file, you have to use the modified version instead?
Re: Why are globals set to tls by default? and why is fast code ugly by default?
On Friday, 31 March 2023 at 16:26:36 UTC, ryuukk_ wrote: I disagree, global mutables are not bad That the same bad advice as telling people to "embrace OOP and multiple inheritance" and all the Java BS "just put your variable into a class and make it static, and then have your singleton to access your static variables" Those of us that have been scarred by reading FORTRAN 77 code would disagree. I use global mutables myself (and even the occasional goto), but if anything, it should be `__GLOBAL_MUTABLE_VARIABLE` to increase the pain of using them.
Re: Implicit type conversion depending on assignment
On Friday, 24 March 2023 at 13:53:02 UTC, bachmeier wrote: On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote: Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a;// Implicitly convert to target type float myFloat = b;// Implicitly convert to target type ``` You're limited by the use of int and float. It works just fine for structs: ``` struct MyInt { int x; alias x this; this(MyString s) { x = s.to!int; } void opAssign(MyString s) { x = s.to!int; } } struct MyFloat { float x; alias x this; this(MyString s) { x = s.to!float; } void opAssign(MyString s) { x = s.to!float; } } struct MyString { string s; alias s this; } void main() { auto ms = MyString("100"); auto ms2 = MyString("11.2"); MyInt mi = ms; MyFloat mf = ms2; } ``` `opAssign` is not needed for this code to compile, but it would be if you had ``` MyInt mi; mi = ms; ```
Re: Implicit type conversion depending on assignment
On Thursday, 23 March 2023 at 13:38:51 UTC, Alexander Zhirov wrote: Is it possible to convert such records inside the structure to the assigned type? ```d struct MyVal { string value; // Here it would be possible to use an alias to this, but it can only be used 1 time } auto a = MyVal("100"); auto b = MyVal("11.2"); int MyInt = a;// Implicitly convert to target type float myFloat = b;// Implicitly convert to target type ``` You're limited by the use of int and float. It works just fine for structs: ``` struct MyInt { int x; alias x this; this(MyString s) { x = s.to!int; } void opAssign(MyString s) { x = s.to!int; } } struct MyFloat { float x; alias x this; this(MyString s) { x = s.to!float; } void opAssign(MyString s) { x = s.to!float; } } struct MyString { string s; alias s this; } void main() { auto ms = MyString("100"); auto ms2 = MyString("11.2"); MyInt mi = ms; MyFloat mf = ms2; } ```
Re: D Language Foundation January 2023 Quarterly Meeting Summary
On Monday, 27 February 2023 at 15:39:35 UTC, Dom Disc wrote: On Monday, 27 February 2023 at 14:27:25 UTC, bachmeier wrote: On Monday, 27 February 2023 at 10:47:04 UTC, Mike Parker wrote: Razvan [submitted a PR deprecating `alias this` in classes](https://github.com/dlang/dmd/pull/14812) the next day. Amaury [initiated a forum discussion](https://forum.dlang.org/thread/roaaoujwgkzednetb...@forum.dlang.org) a few days later. Is there a replacement? Yes. And there always was: In classes this was only an additional way to do, what should better be done with inheritance. That is not my understanding from the linked thread. For instance, someone said it can be used as a substitute for multiple inheritance. It seems that anyone using it that way would be losing working code for no reason due to this deprecation.
Re: D Language Foundation January 2023 Quarterly Meeting Summary
On Monday, 27 February 2023 at 10:47:04 UTC, Mike Parker wrote: Razvan [submitted a PR deprecating `alias this` in classes](https://github.com/dlang/dmd/pull/14812) the next day. Amaury [initiated a forum discussion](https://forum.dlang.org/thread/roaaoujwgkzednetb...@forum.dlang.org) a few days later. Is there a replacement? If not, why is this even being discussed? I'm all for breaking changes if there's a benefit and an easy path to maintain the existing functionality. This fails on both counts. If you want to enforce that it's not used, add a flag, but don't take it away just for the sake of taking it away. Martin suggested a fourth option: phase out `-betterC` because it's a "pile of hacks". Dennis considered that but thought BetterC users would not be happy when it gets deprecated without a suitable replacement. If you don't like BetterC, don't use BetterC. It *already* requires a flag. More generally, deprecation decisions like this shouldn't be made by a small group of people that write a tiny percentage of the D code running in the real world. That same process gave us a safe by default proposal that would have made it impossible to interoperate with C code.
Re: stdin.readln line editing and recall with up arrow
On Saturday, 25 February 2023 at 08:45:27 UTC, Daren Scot Wilson wrote: On Saturday, 25 February 2023 at 05:41:48 UTC, Richard (Rikki) Andrew Cattermole wrote: On 25/02/2023 6:36 PM, Daren Scot Wilson wrote: stdin.readln() works fine until I, out of habit, use the up arrow to recall an earlier input and the left/right to move around and change a character. How do I get that to work? Not with that module. You can either use GNU readline itself, or Adam's version within arsd. I went with readline. Left/right arrows work, but up arrow still does not recall earlier commands. Maybe I need also a separate input history thing? If you start your program with rlwrap, for example `rlwrap cmd`, you'll get that for free.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Thursday, 16 February 2023 at 21:23:53 UTC, ProtectAndHide wrote: Forcing programmers to use a design mechanism rather than a language mechanism to achieve the above abstraction is wrong. This seems to be the source of the disagreement, correct? There's no disagreement. It's you posting the same false claim again and again (presumably because you're hoping it will come up when someone does a search for it, or some similar reason) and others explaining why you're wrong. If you don't want to use the language, don't use it. You have your subjective preferences. You are unable to muster a good argument in favor of it. There's no reason to (yet again) post the same thing over and over.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Wednesday, 15 February 2023 at 07:13:41 UTC, thebluepandabear wrote: Time to move on to OCaml programmers telling us D doesn't have floating point arithmetic because there's no `+.` operator. that's not the same thing though, you've created a great false equivalence! Congrats. Only if you don't understand D's encapsulation. You're going on at length (apparently under multiple names in this thread) because you don't like D's implementation of encapsulation. That's no different from complaining that the `+` operator should be `+.`, and until D makes the change, it doesn't support floating point addition. There are reasonable arguments for changing and not changing D's implementation of encapsulation. Your claim that D doesn't support encapsulation is false.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Wednesday, 15 February 2023 at 19:44:50 UTC, ProtectAndHide wrote: A user-defined type is a type that has a mechanism to keep it representation private. D does not support this. It only enables it. You (and others) may well argue that D should not enable this (directly), it should only support it (indirectly), and thus allow the language to force an important design decision onto programmers. As a programmer, I don't think that is acceptable. The response was to your claim that "I think what you could say is that D lacks _encapsulation_ which is also an OOP concept. So D is partially OOP but not fully OOP due to there being no encapsulation in the language." Mike demonstrated clearly that your claim is false.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Wednesday, 15 February 2023 at 02:14:30 UTC, Mike Parker wrote: On Wednesday, 15 February 2023 at 01:16:00 UTC, thebluepandabear wrote: I think what you could say is that D lacks _encapsulation_ which is also an OOP concept. So D is partially OOP but not fully OOP due to there being no encapsulation in the language. D does not lack encapsulation, it's just that the unit of encapsulation is the module. Everything private in a module is encapsulated from the perspective of the public API. If you really want to prevent anything inside a module from accessing the private parts of a class, you can put the class in its own module. Must we continue beating this horse? Time to move on to OCaml programmers telling us D doesn't have floating point arithmetic because there's no `+.` operator.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Tuesday, 14 February 2023 at 10:16:47 UTC, ProtectAndHide wrote: In any case, there is nothing 'picky' about wanting to be able to explicately 'declare' a member of my class type as being private. That to me, is what a programmer should expect to be able to do in a language that says it supports OOP. What you are saying is that you want an implementation of a particular language that calls itself an OOP language. [There is a lot of controversy about the definition of OOP](https://wiki.c2.com/?NobodyAgreesOnWhatOoIs). I do not think the explicit ability to declare a member of a class private in a particular way has anything to do with it. You are certainly entitled to your opinion, but it doesn't help to say D is not an OOP language because you don't like some of the design decisions.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Friday, 10 February 2023 at 07:04:31 UTC, Max Samukha wrote: Having class-private doesn't preclude module-private. Dennis even submitted a PR implementing class-private, but it stalled because people couldn't agree on whether class-private should be "private to class" or "private to class instance". This is a great example of the problem. In a discussion of any five programmers, you'll have five conflicting sets of rules that are the obvious and intuitive way to do it.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Friday, 10 February 2023 at 00:18:59 UTC, Ali Çehreli wrote: On 2/9/23 15:58, thebluepandabear wrote: >> In contrast, I use D every day and love its relaxed attitude towards >> private. > > the fact that private stuff is accessible from other classes in the same > module is really really bad, and it's pretty detrimental to the language. Not everybody shares that view. Correct. I think D has made the right decision, even if others want it to be what they're used to, and even if they have never bothered to try an alternative approach. In the many discussions on this, I have only seen opinions and conjecture, never a strong argument for a change.
Re: Non-ugly ways to implement a 'static' class or namespace?
On Thursday, 9 February 2023 at 23:51:18 UTC, thebluepandabear wrote: btw. When a newbie to D raises ideas, suggestions, etc... and you counter them with (in essence) 'we don't need that in D, but go write a dip if you think we do' attitude, is a real turn off. yeah it seems like the community is closed off for feedback, which is concerning. Not at all. These things have been discussed to death and decisions have been made. Do you regularly have discussions with the folks in charge of Java, C#, or C++? Do they quickly implement your requested features? if the language wants to gain more people it needs to evolve I doubt that this would lead to a large influx of new D programmers. It would more than likely make the language more complex and less desirable, reducing the number of users.
Re: ImportC "no include path set"
On Thursday, 9 February 2023 at 06:07:35 UTC, Elfstone wrote: Maybe Walter doesn't care about Windows enough, but I thought it'd be a must to add basic tests (say, "dmd hello.c") to run on all the platforms before release. Unlikely, since his text editor [doesn't even compile on Linux](https://github.com/DigitalMars/med/issues/8). I filed that two years ago. I assume that means Windows is his main development OS. The problems you're describing might be more of a reflection of shortage of Windows users that contribute.
Re: ImportC "no include path set"
On Wednesday, 8 February 2023 at 06:49:06 UTC, Elfstone wrote: I believe all three versions (2017,2019,2022) of my VS are up to date, and I have working C/C++ projects on them. But you encouraged me to give a few more tries, and I found out I had been using ..bin64/dmd.exe. Running ..bin/dmd.exe in VS Command Prompt turned out successful. Thx! Is this documented? I don't use Windows, so I may be missing something, but this looks like one of those "death by paper cut" things. It has the smell of a rough edge that needs fixing.
Re: betterC DLL in Windows
On Sunday, 5 February 2023 at 08:48:34 UTC, Tamas wrote: I appreciate all of this... however, as a newcomer, I wish the docs were simply more honest, instead of representing wishful thinking. I guess in any programming language, experience reveals things not present in the docs, but it seems to apply much more acutely here. Technically, those pages are [the spec rather than documentation](https://dlang.org/spec/spec.html). This is the specification for the D Programming Language. I've been bitten by that a few times over the years, though to be honest, I'm not sure of the relationship of the spec to documentation. The Phobos documentation and compiler documentation appear to be actual documentation, in the sense that you can trust it to be accurate, and if not it's a bug. Maybe someone that has been around from the earliest days understands the goal of the spec.
Re: ImportC "no include path set"
On Monday, 6 February 2023 at 06:55:02 UTC, Elfstone wrote: So how am I supposed to set the include path? https://dlang.org/spec/importc.html#preprocessor The -Ppreprocessorflag switch passes preprocessorflag to the preprocessor. So if you normally use `-I/foo`, you'd add `-P-I/foo`.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Sunday, 5 February 2023 at 03:38:04 UTC, thebluepandabear wrote: On Sunday, 5 February 2023 at 03:19:43 UTC, bachmeier wrote: Something of a puzzle that it works with Arch, though, but not Ubuntu/Mint. It doesn't sound like Arch has that problem. What problem doesn't Arch have, the missing symbol or the shared library one? The earlier post in this thread implied there were no problems on Arch. I'm wondering, after downgrading, do you get the shared library issue that I am currently dealing with? I'm not sure how to downgrade. I installed the package from the repos. I can't say a bug in the Ubuntu packaging would surprise me.