Re: How get struct value by member name string ?
On Tuesday, 30 May 2023 at 15:43:12 UTC, Steven Schveighoffer wrote: On 5/30/23 4:46 AM, John Xu wrote: How to put above enum as a function parameter? Following code wouldn't work: string getTMember(T t, enum string memberName) { return __traits(getMember, t, memberName); } compile time parameters come before runtime parameters: ```d string getTMember(string memberName)(T t) { return __traits(getMember, t, memberName); } // used like auto v = getTMember!"name"(t); ``` -Steve Yeah I did fix it in my message right after
Re: How get struct value by member name string ?
On Tuesday, 30 May 2023 at 15:24:21 UTC, bauss wrote: On Tuesday, 30 May 2023 at 08:46:43 UTC, John Xu wrote: How to put above enum as a function parameter? Following code wouldn't work: string getTMember(T t, enum string memberName) { return __traits(getMember, t, memberName); } ... As simple as this: ``` string getTMember(T t, string memberName)() { return __traits(getMember, t, memberName); } ... writeln(getTMember!(t, "...")); ``` Noticed a mistake in my code ... ``` getTMember(T t, string memberName)() ``` Should be: ``` getTMember(T, string memberName)(T t) ``` And calling it should be like: ``` writeln(getTMember!("...")(t)); ```
Re: How get struct value by member name string ?
On Tuesday, 30 May 2023 at 08:46:43 UTC, John Xu wrote: How to put above enum as a function parameter? Following code wouldn't work: string getTMember(T t, enum string memberName) { return __traits(getMember, t, memberName); } ... As simple as this: ``` string getTMember(T t, string memberName)() { return __traits(getMember, t, memberName); } ... writeln(getTMember!(t, "...")); ```
Re: Is comparison of shared data thread-safe?
On Thursday, 16 March 2023 at 12:32:34 UTC, Nick Treleaven wrote: With -preview=nosharedaccess, I get: int y = 2; shared int x = y; // OK assert(x == 2); // no error y = x; // error So for the assignment to y, reading x is an error and atomicLoad should be used instead. But is it an oversight that reading x in the assert is not an error? I have also found this in a unittest in core.atomic: shared(size_t) i; atomicOp!"+="(i, cast(size_t) 1); assert(i == 1); Is the assert somehow thread-safe? I think it __should__ be fine since `i` cannot be in a state where it gets modified and read at the same time.
Re: Mixin helper help
On Monday, 16 January 2023 at 08:17:24 UTC, Ali Çehreli wrote: On 1/13/23 18:51, bauss wrote: That's a good one! It looks like you liked it four years ago as well. :) I found where I remembered it from: https://forum.dlang.org/post/pvdoq2$1e7t$3...@digitalmars.com Ali Looks like my memory isn't as good, as I had totally forgotten about it, but perhaps because I haven't gotten to use it :)
Re: Mixin helper help
On Friday, 13 January 2023 at 16:54:34 UTC, Ali Çehreli wrote: On 1/13/23 00:48, bauss wrote: > 1. Change your mixin template to something like this: There was a technique as a workaround for this template mixin limitation but I can't find it right now. > 2. Change the place where you instantiate to this: I think the workaround I am trying to remember would not require any change for the users. Ok, it was something like this: mixin template myStatement() { auto doIt() { import std.stdio : writeln; writeln("hi"); return 0; } auto ignoreThis = doIt(); } void main() { mixin myStatement!(); mixin myStatement!(); } Ali That's a good one!
Re: Mixin helper help
On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote: I'm obviously doing something wrong, but don't quite understand. ```d mixin template helper() { mixin("writeln(12);"); } struct Foo { void opDispatch(string name)() { import std.stdio; mixin helper!(); //mixin("writeln(12);"); } } void main() { Foo.init.opDispatch!"bar"(); } ``` The compiler emits these errors about the mixin ("writeln(12);"): unexpected `(` in declarator basic type expected, not `12` found `12` when expecting `)` no identifier for declarator `writeln(_error_)` semicolon expected following function declaration declaration expected, not `)` Why does the commented code work but the mixin not? Thanks for any pointers. Mixin templates cannot have statements directly, so you need two changes for your code to work: 1. Change your mixin template to something like this: ```d mixin template helper() { // we place the statements in this function instead void helper() { mixin("writeln(12);"); } } ``` 2. Change the place where you instantiate to this: ```d struct Foo { void opDispatch(string name)() { import std.stdio; mixin helper!(); helper(); // calling the function in the mixin template } } ```
Re: enum functions
On Tuesday, 10 January 2023 at 12:55:34 UTC, Adam D Ruppe wrote: On Sunday, 8 January 2023 at 18:42:58 UTC, Salih Dincer wrote: I'm wondering 2 things; firstly, does having an enum mean there is no auto-return? Or could it be CTFE? It means nothing. The keyword tells the parser a function is about to begin, which triggers return type inference (exactly the same as `auto`), but otherwise it is completely ignored. I'm curious about why it is allowed and whether we somehow could use it for something meaningful since it really just is an alias for auto right now. Perhaps it could be used to create functions that only live at compile-time.
Re: How to avoid variable capturing in `foreach` loop with lambdas?
On Monday, 9 January 2023 at 00:19:39 UTC, thebluepandabear wrote: Fixing this will improve the quality of the language for newcomers such as myself greatly. This not only confuses newcomers but it gave a false illusion of a bug within the code :/ It doesn't confuse newcomers only, also people who have used D for over a decade like me :) Mostly because it's not a thing in most (if not all) other languages. I think D is unique in that aspect. It should be fixed however, I don't think the current behavior is correct or expected by anyone.
Re: Is there a way to enforce UFCS?
On Wednesday, 4 January 2023 at 03:42:28 UTC, thebluepandabear wrote: ... My question is: is there a way to enforce UFCS-syntax? None of your code actually uses UFCS. This is UFCS: ``` class Foo { int bar; } void setBar(Foo foo, int value) { foo.bar = value; } void main() { foo.setBar(100); // UFCS setBar(foo, 100); // Non-UFCS (Above expands to this) } ``` This is not UFCS but just class method calling: ``` class Foo { int bar; void setBar(Foo foo, int value) { foo.bar = value; } } void main() { foo.setBar(100); // Not UFCS - just method call to the class foo.setBar = 100; // Not UFCS - simply a setter function call (equal to the above) setBar(foo, 100); // Error } ``` Also note that @property doesn't really do anything now and there's even talk about deprecating it. Althought I personally still use it, then it doesn't have much of a function and none of your code is affected if you remove it.
Re: How ptr arithmitic works??? It doesn't make any sense....
On Monday, 5 December 2022 at 06:12:44 UTC, rempas wrote: On Sunday, 4 December 2022 at 16:40:17 UTC, ag0aep6g wrote: Not quite. Adding 10 to a T* means adding 10 * T.sizeof. Oh! I thought it was addition. Is there a specific reasoning for that if you are aware of? Because it's much easier to work with. Ex. if you have an array of 4 signed 32 bit integers that you're pointing to then you can simply just increment the pointer by 1. If it was raw bytes then you'd have to increment the pointer by 4 to move to the next element. This is counter-intuitive if you're moving to the next element in a loop ex. This is how you'd do it idiomatically: ```d foreach (i; 0 .. list.length) { (*cast(int*)(ptr + i)) = i; } ``` Compared to: ```d foreach (i; 0 .. list.length) { (*cast(int*)(ptr + (i * 4))) = i; } ```
Re: raylib-d Gamepad Detection Fails
On Thursday, 1 December 2022 at 15:35:37 UTC, Steven Schveighoffer wrote: On 12/1/22 3:24 AM, bauss wrote: But probably not on every frame, have a delay between checks. It's not anything controllable by the user. The library does the check every frame regardless of whether you use it or not. When you call the raylib function, you are not actually querying the device, you are checking a boolean in a struct. https://github.com/raysan5/raylib/blob/387c06000618ef0aa3b15c5e46d1c525ba194c50/src/rcore.c#L3567 -Steve Oh yeah then it's fine :)
Re: raylib-d Gamepad Detection Fails
On Thursday, 1 December 2022 at 02:06:43 UTC, Steven Schveighoffer wrote: On 11/30/22 8:49 PM, jwatson-CO-edu wrote: Yes, following your instructions I have raylib 4.2.0 and raylib-d 4.2.4 in the project directory. I am now using the latest version of raylib-d, but this did not resolve the gamepad issue. I can ask around on the raylib channels. Oh, I think I know the issue -- you need to check inside the loop. The way raylib works is that it polls events from the glfw library. So unless you are actually calling `BeginDrawing` and `EndDrawing`, those flags won't change. -Steve But probably not on every frame, have a delay between checks.
Re: Get the class name without casting the type
On Tuesday, 15 November 2022 at 11:42:59 UTC, Alexander Zhirov wrote: Is there any way to get the name of class B? ```d interface A { string text(); } class B : A { override string text() { return ": It's ok!"; } } void main() { A[] a = cast(A[]) new B[3]; B b = new B(); fill(a, b); foreach (val ; a) { writeln(typeof(val).stringof, val.text()); } } ``` Output: ```sh A: It's ok! A: It's ok! A: It's ok! ``` If you cast to Object and use classinfo.name then you get the expected result of B. ```d interface A { string text(); } class B : A { override string text() { return ": It's ok!"; } } void main() { A[] a = cast(A[]) new B[3]; B b = new B(); fill(a, b); foreach (val ; a) { writeln((cast(Object)val).classinfo.name, val.text()); // Here is the magic. } ``` Output: ``` onlineapp.B: It's ok! onlineapp.B: It's ok! onlineapp.B: It's ok! ```
Re: Linking not working properly Windows 11
On Sunday, 6 November 2022 at 03:59:55 UTC, ryuukk_ wrote: Manually editing / moving files is not recommended for Visual Studio installs The manual editing was not for visual studio but for dmd to set a different linker.
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 22:53:33 UTC, Hipreme wrote: On Saturday, 5 November 2022 at 19:19:09 UTC, bauss wrote: On Saturday, 5 November 2022 at 14:54:52 UTC, Hipreme wrote: [...] I have both VS 2019 and 2022, but only 2019 has c++ build tools etc. I assume that should be fine? [...] You forgot to put \link.exe in the path I was totally blind-sided by that. It seems to work, except for a couple dub packages that I can't get working, I'm going to assume obsolete api calls to the win api, but overall it works like 90%.
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 19:24:54 UTC, Imperatorn wrote: On Saturday, 5 November 2022 at 13:30:43 UTC, bauss wrote: Fresh install of DMD and when trying to use ex. std.file from Phobos I get the following linking error: (I can trigger different ones depending on modules imported etc.) [...] Im also on Windows 10 and 11 and don't have any problems with dmd On my other Windows 10 machine I have never faced problems and I am not sure why I am facing these problems now. I assumed it would work just the same.
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 14:54:52 UTC, Hipreme wrote: On Saturday, 5 November 2022 at 14:14:16 UTC, bauss wrote: On Saturday, 5 November 2022 at 13:42:08 UTC, rikki cattermole wrote: Try ldc, if that works then its just a missing library that needs to be linked against regarding MS CRT. Using LDC doesn't seem to work either, it has similar linking problems. ``` lld-link: error: undefined symbol: fileno referenced by druntime-ldc.lib(dmain2.obj):(_d_print_throwable) referenced by phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File4syncMFNeZv) referenced by phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File13windowsHandleMFNdZPv) referenced 18 more times lld-link: error: undefined symbol: execv referenced by phobos2-ldc.lib(process.obj):(_D3std7process6execv_FIAyaIAQfZi) lld-link: error: undefined symbol: execve referenced by phobos2-ldc.lib(process.obj):(_D3std7process7execve_FIAyaIAQfIQeZi) lld-link: error: undefined symbol: execvp referenced by phobos2-ldc.lib(process.obj):(_D3std7process7execvp_FIAyaIAQfZi) lld-link: error: undefined symbol: execvpe referenced by phobos2-ldc.lib(process.obj):(_D3std7process8execvpe_FIAyaIAQfIQeZi) lld-link: error: undefined symbol: tzset referenced by phobos2-ldc.lib(timezone.obj):(_D3std8datetime8timezone9LocalTime9singletonFNeZ12__dgliteral4MFNaNbNiNfZOb) Error: linking with LLD failed ldc2 failed with exit code 1. ``` Not sure what to do at this point. Just posted the other day how to use the MSVC Linker on windows. Using LLD is quite complicated in my experience because I was getting a lot of undefined symbols from the libcmt. Check this post: https://forum.dlang.org/thread/frixfbbucsbgcrsvm...@forum.dlang.org Remember that for using the MSVC Linker you will need to have visual studio build tools on your PC (or install the visual studio with desktop development with C++). Then you can modify your `sc.ini` and it should work. I have both VS 2019 and 2022, but only 2019 has c++ build tools etc. I assume that should be fine? So I will try this now and see how goes. Currently having some trouble getting it to work, but probably because I am editing sc.ini wrong. Is it possible you could post your sc.ini so I can compare with mine? I get an error like the following when linking: ``` Linking... Error: can't run 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x64', check PATH C:\D\dmd2\windows\bin\dmd.exe failed with exit code 1. ``` I put this in sc.ini under [Environment] and [Environment64] ``` LINKCMD=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x64 ```
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 13:42:08 UTC, rikki cattermole wrote: Try ldc, if that works then its just a missing library that needs to be linked against regarding MS CRT. Using LDC doesn't seem to work either, it has similar linking problems. ``` lld-link: error: undefined symbol: fileno referenced by druntime-ldc.lib(dmain2.obj):(_d_print_throwable) referenced by phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File4syncMFNeZv) referenced by phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File13windowsHandleMFNdZPv) referenced 18 more times lld-link: error: undefined symbol: execv referenced by phobos2-ldc.lib(process.obj):(_D3std7process6execv_FIAyaIAQfZi) lld-link: error: undefined symbol: execve referenced by phobos2-ldc.lib(process.obj):(_D3std7process7execve_FIAyaIAQfIQeZi) lld-link: error: undefined symbol: execvp referenced by phobos2-ldc.lib(process.obj):(_D3std7process7execvp_FIAyaIAQfZi) lld-link: error: undefined symbol: execvpe referenced by phobos2-ldc.lib(process.obj):(_D3std7process8execvpe_FIAyaIAQfIQeZi) lld-link: error: undefined symbol: tzset referenced by phobos2-ldc.lib(timezone.obj):(_D3std8datetime8timezone9LocalTime9singletonFNeZ12__dgliteral4MFNaNbNiNfZOb) Error: linking with LLD failed ldc2 failed with exit code 1. ``` Not sure what to do at this point.
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 13:42:08 UTC, rikki cattermole wrote: Try ldc, if that works then its just a missing library that needs to be linked against regarding MS CRT. I will give it a try
Re: Linking not working properly Windows 11
On Saturday, 5 November 2022 at 13:30:43 UTC, bauss wrote: ``` lld-link: error: undefined symbol: tzset ``` I don't know if this is relevant, so I will just put it here just in case: ``` lld-link: error: undefined symbol: tzset referenced by phobos64.lib(timezone_151f_37a.obj):(_D3std8datetime8timezone9LocalTime9singletonFNeZ9__lambda3FNbNiNfZb) Error: linker exited with status 1 ```
Linking not working properly Windows 11
Fresh install of DMD and when trying to use ex. std.file from Phobos I get the following linking error: (I can trigger different ones depending on modules imported etc.) ``` lld-link: error: undefined symbol: tzset ``` I assume it has something to do with the C runtime or something, but everything should be setup correct, so maybe some path or something that is incorrect that I may need to modify? I have no idea what I need to do however. I am using dub as well, so basically compiling using: ``` dub build -a=x86_64 ``` Is there anything I am missing or what should I do? Currently D is unusable for me on my new machine because of this. If anybody knows how I can just get things to work, it seems like D never works out of the box, which is very unfortunate. This is literally my file: ```d module main; import std.file : readText, exists, write; void main() {} ``` It's as minimal as an example as I can give pretty much. A similar issue was with C++ runtime libraries such as libcmt.lib not being linked and I ended up having to move the files manually to my project folder, as I don't know how to fix it properly as there aren't any clear instructions anywhere on how to fix invalid paths etc. or what to do when linking just doesn't find the files despite them existing. If anyone can help me fix this then I will be very grateful.
Re: Hipreme's #4 Tip of the day - Don't use package.d
On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote: ... I disagree completely with being against package.d. Having used D for like a decade at this point, I've never experienced any issues with it. Most issues seems to be for newcomers and people who aren't entirely familiar with how D modules and packages work. package.d is absolutely essential in some cases.
Re: is dmd a virus?
On Saturday, 22 October 2022 at 07:40:39 UTC, MGW wrote: is dmd a virus? https://www.virustotal.com report: Cybereason --> Malicious.779f29 VBA32 --> BScope.Trojan.DShell Yeah it's a virus. I would stay far away from it...
Re: Float rounding (in JSON)
On Friday, 14 October 2022 at 09:00:11 UTC, Patrick Schluter wrote: On Thursday, 13 October 2022 at 19:27:22 UTC, Steven Schveighoffer wrote: On 10/13/22 3:00 PM, Sergey wrote: [...] It doesn't look really that far off. You can't expect floating point parsing to be exact, as floating point does not perfectly represent decimal numbers, especially when you get down to the least significant bits. [...] To me it looks like there is a conversion to `real` (80 bit floats) somewhere in the D code and that the other languages stay in `double` mode everywhere. Maybe forcing `double` by disabling x87 on the D side would yield the same results as the other languages? Looking through the source code then for floating points we call `parse!double` when parsing the json as a floating point. I don't see real being used anywhere when parsing. So if anything then it would have to be internally in parse or dmd. I haven't checked either yet.
Re: Replacing tango.text.Ascii.isearch
On Thursday, 13 October 2022 at 08:48:49 UTC, rikki cattermole wrote: On 13/10/2022 9:42 PM, bauss wrote: Oh and to add onto this, IFF you have to do it the hacky way, then converting to uppercase instead of lowercase should be preferred, because not all lowercase characters can perform round trip, although a small group of characters, then using uppercase fixes it, so that's a relatively easy fix. A round trip is basically converting characters from one culture to another and then back. It's impossible with some characters when converting to lowercase, but should always be possible when converting to uppercase. You will want to repeat this process with normalize to NFKC and normalize to NFD before transforming. Otherwise there is a possibility that you will miss some transformations as the simplified mappings are 1:1 for characters and not everything is representable as a single character. Yeah, text isn't easy :D
Re: Replacing tango.text.Ascii.isearch
On Thursday, 13 October 2022 at 08:35:50 UTC, bauss wrote: On Thursday, 13 October 2022 at 08:30:04 UTC, rikki cattermole wrote: On 13/10/2022 9:27 PM, bauss wrote: This doesn't actually work properly in all languages. It will probably work in most, but it's not entirely correct. Ex. Turkish will not work with it properly. Very interesting article: http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html Yes turkic languages, they require a state machine and quite a bit of LUTs to work correctly. You also need to provide a language and it has to operate on the whole string, not individual characters. I didn't think it was relevant since Ascii was in the original post ;) I think it's relevant when it comes to D since D is arguably a unicode language, not ascii. D should strive to be correct, rather than fast. Oh and to add onto this, IFF you have to do it the hacky way, then converting to uppercase instead of lowercase should be preferred, because not all lowercase characters can perform round trip, although a small group of characters, then using uppercase fixes it, so that's a relatively easy fix. A round trip is basically converting characters from one culture to another and then back. It's impossible with some characters when converting to lowercase, but should always be possible when converting to uppercase.
Re: Replacing tango.text.Ascii.isearch
On Thursday, 13 October 2022 at 08:30:04 UTC, rikki cattermole wrote: On 13/10/2022 9:27 PM, bauss wrote: This doesn't actually work properly in all languages. It will probably work in most, but it's not entirely correct. Ex. Turkish will not work with it properly. Very interesting article: http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html Yes turkic languages, they require a state machine and quite a bit of LUTs to work correctly. You also need to provide a language and it has to operate on the whole string, not individual characters. I didn't think it was relevant since Ascii was in the original post ;) I think it's relevant when it comes to D since D is arguably a unicode language, not ascii. D should strive to be correct, rather than fast.
Re: Replacing tango.text.Ascii.isearch
On Wednesday, 5 October 2022 at 17:29:25 UTC, Steven Schveighoffer wrote: On 10/5/22 12:59 PM, torhu wrote: I need a case-insensitive check to see if a string contains another string for a "quick filter" feature. It should preferrably be perceived as instant by the user, and needs to check a few thousand strings in typical cases. Is a regex the best option, or what would you suggest? https://dlang.org/phobos/std_uni.html#asLowerCase ```d bool isearch(S1, S2)(S1 haystack, S2 needle) { import std.uni; import std.algorithm; return haystack.asLowerCase.canFind(needle.asLowerCase); } ``` untested. -Steve This doesn't actually work properly in all languages. It will probably work in most, but it's not entirely correct. Ex. Turkish will not work with it properly. Very interesting article: http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html
Re: Doubt about char.min/max == typeid(char)
On Friday, 7 October 2022 at 04:40:26 UTC, matheus wrote: Hmm well I was thinking the min/max as a range/limits, in this case 0 to 255 or it could be -128 to 127 if signed char casts implicitly to int, so if you really need it as an integer type just type your variable as such. ```d int a = char.max; // valid. ``` If you don't need to assign it then you can cast it. ``` void a(int x) { ... } a(cast(int)char.max); ``` Even though in the example above the cast isn't necessary, if you want to be sure a(int) is called then you must cast it, since an overload of char will obviously be picked. , or in a case of a bool: 0 to 1, but now I see it returns the min/max value of the type itself, like the latter false/true. The same applies for a bool. I had my reasoning based on my experience with C. D isn't C, so you can't really compare it 1:1, even though a lot of C rules apply to D, then all of them doesn't. This is one of the places where it improves on top of it, because generally you don't want your min/max to be different types, but you can implicitly get the integer behavior if you desire so.
Re: Disk write in a "for" loop with RwMutex never happens
On Sunday, 28 August 2022 at 22:46:17 UTC, Gavin Ray wrote: I've put the code, stripped to a minimal example here: - https://ldc.godbolt.org/z/fzsx3Tnnn You can see that the single write + read version of the code works just fine: ``` pageData[0..4] = [1, 2, 3, 4] readData[0..4] = [1, 2, 3, 4] ``` Where here, `pageData` is the data to be written to a file, and `readData` is the result of trying to read the freshly written file data. But if the same code is placed inside of a `for` loop, suddenly no writes occur: ```d pageData[0..4] = [0, 0, 0, 0] readData[0..4] = [0, 0, 0, 0] pageData[0..4] = [0, 0, 0, 1] readData[0..4] = [0, 0, 0, 0] pageData[0..4] = [0, 0, 0, 2] readData[0..4] = [0, 0, 0, 0] pageData[0..4] = [0, 0, 0, 3] readData[0..4] = [0, 0, 0, 0] pageData[0..4] = [0, 0, 0, 4] readData[0..4] = [0, 0, 0, 0] // ... ``` Does anyone know what is happening here? It's really puzzling. You probably need to flush the output.
Re: How to build DMD/Phobos on Windows
On Wednesday, 24 August 2022 at 21:11:42 UTC, rikki cattermole wrote: For dmd you use build.d that is in the repository. For phobos win64.mak (used for 32bit by default as well): "# Makefile to build D runtime library phobos{64,32mscoff}.lib for Windows MSVC" So MSVC make. Beyond that idk, but its starting point (oh and druntime is now in dmd repo, so ugh... yeah) We really need a page in the documentation that describes how to build each component of D for each major platform.
Re: Compile time int to string conversion in BetterC
On Friday, 19 August 2022 at 13:47:41 UTC, Paul Backus wrote: On Friday, 19 August 2022 at 10:22:25 UTC, bauss wrote: Is there a reason why .stringof is implementation defined and not clearly defined in the spec how types and declarations should be treated when being "converted to a string"? I find it really odd that it's implementation defined and you essentially can't rely on it anywhere. It's something that has baffled me a lot. Like are there something I'm missing that means it cannot be specified? Basically, `.stringof` is what the compiler uses when it needs to display something in an error message. If it were locked down in the spec, then making improvements to error messages would in some cases require a deprecation cycle. That said, it might still be worth specifying the behavior in a few specific cases—e.g., guaranteeing that `.stringof` on an integer value will always produce a valid integer literal. Yeah I mean not all of its behavior has to be implementation defined.
Re: Programs in D are huge
On Friday, 19 August 2022 at 06:34:19 UTC, Patrick Schluter wrote: On Thursday, 18 August 2022 at 17:15:12 UTC, rikki cattermole wrote: On 19/08/2022 4:56 AM, IGotD- wrote: BetterC means no arrays or strings library and usually in terminal tools you need to process text. Full D is wonderful for such task but betterC would be limited unless you want to write your own array and string functionality. Unicode support in Full D isn't complete. There is nothing in phobos to even change case correctly! Both are limited if you care about certain stuff like non-latin based languages like Turkic. A general toupper/tolower for Unicode is doomed to fail. As already mentioned Turkish has its specificity, but other languages also have traps. In Greek toupper/tolower are not reversible i.e. `x.toupper.tolower == x` is not guaranteed . Some languages have 1 codepoint input and 2 codepoints as result (German ß becomes SS in most cases, capital ẞ is not the right choice in most cases). etc. etc. That's why you should implementat formatting providers for languages that handle such things. Like in C# you have the CultureInfo class that you can give to methods such as ToString, ToLower etc. which will correctly handle specific "cultures" It's one thing D really misses, but is really hard to implement when it wasn't thought of to begin with. It should have been implemented alongside functions that may change between languages and cultures.
Re: Compile time int to string conversion in BetterC
On Thursday, 18 August 2022 at 22:00:06 UTC, Paul Backus wrote: On Wednesday, 17 August 2022 at 11:38:31 UTC, Steven Schveighoffer wrote: On 8/17/22 6:38 AM, Dennis wrote: On Wednesday, 17 August 2022 at 08:44:30 UTC, Ogi wrote: Maybe I’m missing something? I had the same problem, and came up with the following trick: ```D enum itoa(int i) = i.stringof; ``` I have the same thing in my code: ```d enum intStr(int x) = x.stringof; ``` I merged a version of this into Phobos (for internal use): https://github.com/dlang/phobos/blob/v2.100.1/std/conv.d#L5986-L5987 It also comes with a unit test, so we don't get surprise breakage if the behavior of `.stringof` ever changes. Is there a reason why .stringof is implementation defined and not clearly defined in the spec how types and declarations should be treated when being "converted to a string"? I find it really odd that it's implementation defined and you essentially can't rely on it anywhere. It's something that has baffled me a lot. Like are there something I'm missing that means it cannot be specified?
Re: Acess variable that was set by thread
On Monday, 8 August 2022 at 13:55:02 UTC, ag0aep6g wrote: auto x = s.x; ``` Your problem is here and not because it was __gshared. You're copying the value and obviously it can be changed in the meantime, that's common sense. You shouldn't use it like that. You should access s.x directly instead. And in the case of shared it can leave the same result if the reading thread locks first then it will read and process the value before it's changed.
Re: Fix template parameter
On Monday, 8 August 2022 at 12:02:02 UTC, Dom Disc wrote: ```D pure @nogc @safe BigInt opAssign(T : BigInt)(T x); ``` This will only be included in the object file if used. What is the difference to declaring it like: ```D pure @nogc @safe BigInt opAssign(BigInt x); ``` This will always be in the object file. Someone can correct me if I'm wrong, but I think it's mostly linkage optimization.
Re: Acess variable that was set by thread
On Monday, 8 August 2022 at 10:17:57 UTC, ag0aep6g wrote: Never ever use `__gshared` ever. I don't agree with this entirely, it just depends on how you use it. In general you should go with shared, but __gshared does have its places. It's only problematic when it can be changed from multiple threads, but if it's only changed from a single thread but read from many then it generally isn't a problem. To sum it up: Single-write/Single-read? __gshared Single-write/Multi-read? __gshared Multi-write/Single-read? shared Multi-write/Multi-read? shared
Re: How do I initialize a templated constructor?
On Monday, 8 August 2022 at 07:37:16 UTC, rempas wrote: Thank you for all the great info! Unfortunately, while there is no problem in this example, this will not do for my real code as I need to have the argument in the constructor. Alternative, I have to change the design of the program completely Yeah I think the only template argument you can have for constructors are `this` which will refer to things like the class that inherited the current class etc. not sure what else, but you can't really pass anything to it yourself unfortunately. But I think if you end up with something where you need different constructors with different type arguments then you're probably designing your program in a "wrong" way to begin with.
Re: Verbosity in D
On Monday, 8 August 2022 at 00:11:33 UTC, pascal111 wrote: I don't have specific code but it was a general notice. Take Python as in example, the same program in Python doesn't cost much code as D code, and of course by putting in accounts that that I assume that there are some special tasks D can do, while Python can't do. Yeah I don't think this is true. The only clear difference between D and Python is the vast amount of libraries that Python has and that D is a static-typed language, Python is not (by default) You generally don't write much more code. Loops, ranges etc. are all just as pleasant to work with in D as they are in Python. I'd argue it's even easier to work with classes in D than in Python, and even easier to work with metadata in D than any other language. Python has an unnecessary amount of verbosity when it comes to OOP (because it really isn't an OOP language.) I think D only looks verbose to people who don't really understand its metaprogramming capabilities, templates and/or are new to the language and perhaps come from dynamic typed languages. But I don't think D is in particular more verbose than Python, you can write very similar expressions and some code are almost 1:1 in Python and D when you only consider syntax.
Re: How do I initialize a templated constructor?
On Monday, 8 August 2022 at 05:38:31 UTC, rempas wrote: In the following struct (as an example, not real code): ``` struct TestArray(ulong element_n) { int[element_n] elements; this(string type)(ulong number) { pragma(msg, "The type is: " ~ typeof(type).stringof); } } ``` I want to create it and be able to successfully initialize the template parameters of the constructor but until now, I wasn't able to find a way to successfully do that. Is there a way you guys know? I have tried the following: ``` void main() { // Doesn't work auto val = TestArray!(10, "int")(60); // Doesn't work either auto val = TestArray!(10).TestArray!("int")(60); // Neither this works auto val = TestArray!(10).this!("int")(60); } ``` As with every question I make, the solution must be "betterC" compatible so I can use it. Thanks a lot! ``` this(string type)(ulong number) { ``` You cannot do this. Instead your type should look like this: First let's change it up a little bit. ``` struct TestArray(ulong element_n, string type) { int[element_n] elements; this(ulong number) { pragma(msg, "The type is: " ~ typeof(type).stringof); } } ``` Now the above will still not work because you do `typeof(type)` which will always yield string because type is as string and also the typeof() is not needed in this case and will actually yield an error. If it must be a string then you can do it like this: ``` struct TestArray(ulong element_n, string type) { int[element_n] elements; this(ulong number) { mixin("alias T = " ~ type ~ ";"); pragma(msg, "The type is: " ~ T.stringof); } } ``` However the ideal implementation is probably this: ``` struct TestArray(ulong element_n, T) { int[element_n] elements; this(ulong number) { pragma(msg, "The type is: " ~ T.stringof); } } ``` To instantiate it you simply do: ``` TestArray!(10, "int") val = TestArray!(10, "int")(100); ``` Or ``` TestArray!(10, int) val = TestArray!(10, int)(100); ``` I will recommend an alias to make it easier: ``` alias IntTestArray = TestArray!(10, int); ... IntTestArray val = IntTestArray(100); ```
Re: vectorization of a simple loop -- not in DMD?
On Tuesday, 12 July 2022 at 10:32:36 UTC, ryuukk_ wrote: How do i achieve fast compile speed (results above were on windows, on linux i get much faster results): I maintain healthy project management: This - Imports of std: i simply don't, and i copy/paste functions i need - I avoid dub packages, instead i prefer import/src path, and i chery pick what i need And this. Can be argued to not be healthy project management. Of course if you're alone it doesn't matter, but if it's a larger project that will have multiple maintainers then it will never work and will tarnish the project entirely.
Re: vectorization of a simple loop -- not in DMD?
On Tuesday, 12 July 2022 at 07:06:37 UTC, Siarhei Siamashka wrote: ``` real0m34.371s user0m32.883s sys 0m1.488s ``` ``` real0m14.078s user0m12.941s sys 0m1.129s ``` Is there an open source DUB package, which can be used to reproduce a huge build time difference between LDC and DMD? You don't think this difference is huge? DMD is over 2x as fast.
Re: DIP1000
On Tuesday, 28 June 2022 at 21:58:48 UTC, Ola Fosheim Grøstad wrote: not-scoped variable (`a.next` is not `scope` since this attribute is not transitive) Well, that is a flaw, if the object is stack allocated then the fields are too. Not necessarily, especially if the fields aren't value types. You can have stack allocated "objects" with pointers to heap allocated memory (heap allocated "objects".) You can't, or rather you shouldn't have stack allocated fields within heap allocated "objects" however; as that will almost be guaranteed to lead to problems. I believe it's possible, but one should always refrain from it, but the same isn't true the for stack allocated "objects" with heap allocated fields. Ex. from your example then even if the "node struct" you pass was allocated on the stack, then the memory the "next" pointer points to might not be allocated same place. Unless I'm misunderstanding what you're trying to say.
Re: int | missing | absent
On Thursday, 23 June 2022 at 15:20:02 UTC, Jesse Phillips wrote: On Wednesday, 22 June 2022 at 01:09:22 UTC, Steven Schveighoffer wrote: There are 3 situations: 1. field in json and struct. Obvious result. 2. field in json but not in struct. 3. field in struct but not in json. I do a lot of reading JSON data in C#, and I heavily lean on optional over required. The reason optional is so beneficial is because I'm looking to pull out specific data points from the JSON, I have no use nor care about any other field. If I had to specify every field being provided, every time something changes, the JSON parser would be completely unusable for me. I do like the @extra assuming it allows reserializing the entire JSON object. But many times that data just isn't needed and I'd like my type to trim it. I'm in a similar boat as you, except for that I read a lot of big json files and I absolutely cannot read everything in the json and hold them in memory, so I must be selective in what I read from the json files, since they're read on a server and are several GB. I would be wasting a lot of RAM resources by having every field in the json file stored in memory. RAM is expensive, disk space is not.
Re: Any way to define variables from one scope in another scope?
On Monday, 20 June 2022 at 13:56:04 UTC, Ruby The Roobster wrote: Is there any way to define variables in an outer scope from an inner scope? I was thinking ```d void main() { int .y = 3; } ``` would work, but it doesn't. No and it would only lead to bugs. If you have access to an inner scope then surely you have access to the outer scope and can just add the variable there. If you need to add a variable in a nested scope, then surely you're solving a problem with the wrong solution.
Re: nested function overloading
On Friday, 17 June 2022 at 13:04:47 UTC, Chris Katko wrote: On Friday, 17 June 2022 at 12:19:33 UTC, bauss wrote: On Friday, 17 June 2022 at 12:09:33 UTC, Chris Katko wrote: I don't need this functionality, but I wanted to be sure. Does function overloading not work with nested functions? I got a compiler error (something like "function already defined") when I tried it. According to the spec then nested functions cannot be overloaded: "Nested functions cannot be overloaded." See: 19.17.1.3 https://dlang.org/spec/function.html#nested Thanks! re: documentation. That is one-line tiny footnote in a page that's over 85 pages long on my browser. :) I could easily see many people missing it until they encounter it. I agree, I didn't know about it either and only found out because I decided to search on the page for functions under nested functions.
Re: std.conv.to
On Friday, 17 June 2022 at 12:48:56 UTC, harakim wrote: On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote: I can generically convert a string to a type using to!type. I have a read function that does that. I have simplified the example below: ```d int readNumber() { return read!int(val => to!int(val), "number"); } string readTime() { return read!string(val => toTime(val), "time"); } private T read(T)(T function(string) transform, string typeName) { string input = readln(); return transform(input); } ``` However, I want to be able to convert my own custom types as well. How do I do that? Is there an operator overload I need to override for that? Do I have to static if on the template type and call the object? I have no idea why I was stuck on this problem for so long. I can specify anything I want in the transform and I even do in my own example lol. I am still curious if there is a way to make your type work with to!MyCustomType(source) Just add a constructor to your type that takes the value of what you want to convert. Working example: ```d struct Foo { int value; this(int v) { value = v; } this(string v) { this(to!int(v)); } } void main() { auto foo = to!Foo("123"); writeln(foo.value); } ```
Re: nested function overloading
On Friday, 17 June 2022 at 12:09:33 UTC, Chris Katko wrote: I don't need this functionality, but I wanted to be sure. Does function overloading not work with nested functions? I got a compiler error (something like "function already defined") when I tried it. According to the spec then nested functions cannot be overloaded: "Nested functions cannot be overloaded." See: 19.17.1.3 https://dlang.org/spec/function.html#nested
Re: UFCS limit
On Friday, 17 June 2022 at 05:17:20 UTC, Tejas wrote: On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote: Nope. The way UFCS works is that allows you to call free functions using member-function syntax, and member-function syntax is always `object.memberName`, so UFCS only works for functions that have a name, not anonymous functions. Would it be worthwhile to extend the scope of UFCS to accomodate this use case as well though?? I think it would lead to a lot of confusing and ambiguity.
Re: Comparing Exceptions and Errors
On Thursday, 16 June 2022 at 11:38:40 UTC, kdevel wrote: On Thursday, 16 June 2022 at 11:28:32 UTC, bauss wrote: [...] https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." [...] If the spec forbids it, but the compiler allows it, wouldn't it then be a bug? What does "it" referer to? The code, throwing in scope guard? The spec? The compiler? [yes, no, no] Throwing in a scope guard.
Re: Comparing Exceptions and Errors
On Thursday, 16 June 2022 at 10:07:23 UTC, kdevel wrote: On Wednesday, 15 June 2022 at 20:46:56 UTC, Steven Schveighoffer wrote: [...] It has not harmed my code though. I tried throwing inside a scope guard, and it just works, I'm not sure why you can't throw in those? You can but that is not acceptable for the spec explicitly forbids that: https://dlang.org/spec/statement.html#scope-guard-statement Quote (again): "A [...] scope(success) statement may not exit with a throw [...]." Furthermore I always thought of scope guards as a means for cleanup. Cleanup implies in my eyes removing things which have been used in a previous task. This intended use is documented here: https://tour.dlang.org/tour/en/gems/scope-guards Using scope guards makes code much cleaner and allows resource allocation and clean up code to be placed next to each other. These little helpers also improve safety because they make sure certain cleanup code is always called independent of which paths are actually taken at runtime. Performing a COMMIT is rather the opposite of cleanup: It makes (writes) changes to the database persistent. If the spec forbids it, but the compiler allows it, wouldn't it then be a bug?
Re: Closures over temporary variables
On Tuesday, 14 June 2022 at 08:26:53 UTC, Anonymouse wrote: What is the correct way of making this output `0 1 2`? ```d void delegate()[] dgs; foreach (immutable i; 0..3) { dgs ~= () => writeln(i); } foreach (dg; dgs) { dg(); // outputs: `2 2 2` } ``` You have to do it like this: ``` dgs ~= ( (n) => () { writeln(n); })(i); ``` Because D hasn't fixed their million dollar mistake after so many years: https://issues.dlang.org/show_bug.cgi?id=2043 https://issues.dlang.org/show_bug.cgi?id=23136
Re: Generating unique identifiers at compile time
On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote: There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131 You can generate unique names actually by using CTFE RNG, so it's not really necessary to have it exposed to achieve that. See my hacky example of hidden class members here: https://forum.dlang.org/thread/siczwzlbpikwlevvi...@forum.dlang.org
Re: Dynamic Arrays Capacity
On Friday, 3 June 2022 at 12:52:30 UTC, Adam D Ruppe wrote: On Friday, 3 June 2022 at 12:49:07 UTC, bauss wrote: I believe it's only true in unicode for utf-32 since all characters do fit in the 4 byte space they have Depends how you define "character". I guess that's true as well, unicode really made it impossible to just say "this string has so many characters because it has this many bytes."
Re: Dynamic Arrays Capacity
On Thursday, 2 June 2022 at 20:12:30 UTC, Steven Schveighoffer wrote: This statement suggests to me that you have an incorrect perception of a string. A string is a pointer paired with a length of how many characters after that pointer are valid. That's it. `str.ptr` is the pointer to the first element of the string. There isn't a notion of "most recent first element". -Steve This isn't correct either, at least with unicode, since 1 byte isn't equal to 1 character and a character can be several bytes. I believe it's only true in unicode for utf-32 since all characters do fit in the 4 byte space they have, but for utf-8 and utf-16 the characters will not be the same size of bytes.
Re: int | missing | absent
On Thursday, 2 June 2022 at 08:27:32 UTC, Antonio wrote: JSON properties can be - a value - null - absent What's the standard way to define a serialziable/deserializable structs supporting properties of any of this 4 kinds?: * int * int | null * int | absent * int | null | absent Whats the best library to manage this JSON requirements? (all the 4 cases)? Thanks null and absent should be treated the same in the code, it's only when serializing you should define one or the other, if you need to have null values AND absent values then attributing accordingly is the solution. Which means deserialization only has value/null and serialization has value/null by default, but can be opt-in to also have absent. One common mistake I've seen with parsers in D is that fields are often opt-out, instead of opt-in, which means you always have to declare all fields in a json object, but that's a bad implementation. All fields should be optional and only required when attributed. An example: ``` struct A { int x; } ``` Should be able to be deserialized from this json: ``` {"x":100,"y":200} ``` However a lot of parsers in D do not support that. Instead you must declare the y member as well like: ``` struct A { int x; int y; } ``` Any decent parser should not have that problem. If a field is required then it should be determined by an attribute like: ``` struct A { @JsonRequired int x; @JsonRequired int y; } ``` If that attribute isn't present then it can be absent during deserialization. Sorry I got a little off-track, but I felt like pointing these things out are important as well.
Re: static assert("nothing")
On Tuesday, 31 May 2022 at 09:11:41 UTC, JG wrote: On Tuesday, 31 May 2022 at 08:51:45 UTC, realhet wrote: Hi, In my framework I just found a dozen of compile time error handling like: ...else static assert("Invalid type"); This compiles without error. And it was useless for detecting errors because I forgot the first "false" or "0" parameter. I think it is because of the weird case of "every string casted to bool is true". There is an example in Phobos also: https://github.com/dlang/phobos/blob/master/std/uni/package.d at line 8847: static assert("Unknown normalization form "~norm); It is easy to make this mistake, but does static assert(string) has any meaningful use cases? I was going to suggest to do something like: ```d import std; string compileError(string msg) { import std.format; return format("static assert(0,%(%s%));",[msg]); } auto doGreatThings(T)(T x) { static if(is(T==int)) { return "great things!"; } else mixin(compileError("Invalid type.")); } void main() { doGreatThings!int(123).writeln; doGreatThings!string("oh dear").writeln; } ``` But (a) why should you need to and (b) this makes the message more obscure. onlineapp.d-mixin-14(14): Error: static assert: "Invalid type." onlineapp.d(20):instantiated from here: `doGreatThings!string` And then suddenly everyone has their own version of compileError. There's no reason the compiler can't check whether the first expression given evaluates to string and if so then the first argument moves to the second argument and the first argument becomes 0. `extern (D) this(const ref Loc loc, Expression exp, Expression msg)`
Re: static assert("nothing")
On Tuesday, 31 May 2022 at 08:51:45 UTC, realhet wrote: Hi, In my framework I just found a dozen of compile time error handling like: ...else static assert("Invalid type"); This compiles without error. And it was useless for detecting errors because I forgot the first "false" or "0" parameter. I think it is because of the weird case of "every string casted to bool is true". There is an example in Phobos also: https://github.com/dlang/phobos/blob/master/std/uni/package.d at line 8847: static assert("Unknown normalization form "~norm); It is easy to make this mistake, but does static assert(string) has any meaningful use cases? I agree that static assert should have a special case for handling strings, so we have both these signatures: `static assert(value, message)` and `static assert(message)`
Re: Compiler switch for integer comparison/promotion to catch a simple error
On Sunday, 29 May 2022 at 01:35:23 UTC, frame wrote: Is there a compiler switch to catch this kind of error? ```d ulong v = 1; writeln(v > -1); ``` IMHO the compiler should bail a warning if it sees a logic comparison between signed and unsigned / different integer sizes. There is 50% chance that a implicit conversion was not intended. Good luck convincing Walter that this is a mistake :)
Re: Allocate a string via the GC
On Monday, 23 May 2022 at 12:20:11 UTC, JG wrote: On Monday, 23 May 2022 at 11:39:22 UTC, Adam D Ruppe wrote: On Monday, 23 May 2022 at 09:38:07 UTC, JG wrote: Hi, Is there any more standard way to achieve something to the effect of: ```d import std.experimental.allocator; string* name = theAllocator.make!string; ``` Why do you want that? Easiest way I know of is to just wrap it in a struct, then `new that_struct`, which is also a better way for all the use cases I know but those use cases are pretty rare so there's probably a better way to do what you're trying to do. I am writing an interpreter and I needed access to a string via a pointer of type void* I ended up wrapping it in a struct since I needed another value anyway. Seems odd that one can't do it in a less unusual way. Thanks. You can take the address of the string. .ptr should do it, BUT I think it might not always work, someone can correct me on this, but I believe it depends on where the memory for the string lives whether it works or not?
Re: Allocate a string via the GC
On Monday, 23 May 2022 at 12:17:56 UTC, bauss wrote: On Monday, 23 May 2022 at 11:39:22 UTC, Adam D Ruppe wrote: On Monday, 23 May 2022 at 09:38:07 UTC, JG wrote: Hi, Is there any more standard way to achieve something to the effect of: ```d import std.experimental.allocator; string* name = theAllocator.make!string; ``` Why do you want that? Easiest way I know of is to just wrap it in a struct, then `new that_struct`, which is also a better way for all the use cases I know but those use cases are pretty rare so there's probably a better way to do what you're trying to do. My guess is @nogc in which case your solution doesn't work. Same with Ferhat's examples. Oops wait, I just saw that it says "via the GC" in the title. I completely missed that until I had of course sent my other message.
Re: Allocate a string via the GC
On Monday, 23 May 2022 at 11:39:22 UTC, Adam D Ruppe wrote: On Monday, 23 May 2022 at 09:38:07 UTC, JG wrote: Hi, Is there any more standard way to achieve something to the effect of: ```d import std.experimental.allocator; string* name = theAllocator.make!string; ``` Why do you want that? Easiest way I know of is to just wrap it in a struct, then `new that_struct`, which is also a better way for all the use cases I know but those use cases are pretty rare so there's probably a better way to do what you're trying to do. My guess is @nogc in which case your solution doesn't work. Same with Ferhat's examples.
Re: vibe.d requestHTTP in static this causes infinite loop?
On Friday, 20 May 2022 at 01:41:59 UTC, Ali Çehreli wrote: On 5/19/22 16:44, Vijay Nayar wrote: > If I remove the call from `static this()`, then the web call works as > normal. Any idea why calling vibe.d's `requestHTTP` function inside of a > module's static construction would cause an infinite loop? I am not experienced with vibe.d. 'static this' is executed per thread. If requestHTTP starts a new thread, then I can see how you would be in an infinite loop. I wonder whether it should be 'shared static this' (which is executed once per program, not per thread). Ali Static constructor shouldn't be there at all in this case, since it's not constructing anything. He shouldn't really use anything but main in this case.
Re: template? mixin? template mixins? for modifying a struct setup
On Thursday, 19 May 2022 at 10:18:38 UTC, user1234 wrote: On Thursday, 19 May 2022 at 10:15:32 UTC, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` average is a bad way to grayscale FYI ;) This is correct, you actually have to do something like this: ```d uint g = (uint)((0.3f * r) + (0.59f * g) + (0.11f * b)); ``` Where g is the new value for the current pixel's rgb value. However, OP doesn't seem to be grayscaling images, but rather just wanting to specify gray colors. In which case something like this could work: ```d COLOR GREY(float amount)() { return COLOR(amount, amount, amount, 1.0); } ... auto myColor = GREY!(0.5); myColor is COLOR(0.5, 0.5, 0.5, 1.0) ```
Re: class destructors must be @disabled?
On Wednesday, 18 May 2022 at 19:58:09 UTC, Ali Çehreli wrote: Hmm. Perhaps the guideline should be "all destructors must be @nogc". Ali It should probably just default to that and with no exception, since you will never end up in a situation where you don't want @nogc for a destructor. At least I can't imagine one, and if there is one then it's probably due to another design issue in one's program.
Re: Unexplainable behaviour with direct struct assignment.
On Wednesday, 18 May 2022 at 21:52:18 UTC, HuskyNator wrote: On Wednesday, 18 May 2022 at 21:49:14 UTC, HuskyNator wrote: After updating to `DMD 2.100.0` & `DUB 1.29.0`, I still get this behavior. Only when I use `dub run --b=debug` however (default for me). `dub run --b=release` does return what one would expect. I don't know if this matters either, but I'm using windows 10 (64 bits). Can confirm this is the case for me too on Windows 10. Release prints 50 3 times, debug prints 0, 50, nan. This is with DMD, I currently don't have LDC or GDC installed on this machine. So it looks like a Windows bug, critical at that.
Re: I need to use delete as the method name. But now it's still a keyword, right?
On Wednesday, 18 May 2022 at 15:33:09 UTC, Steven Schveighoffer wrote: On 5/18/22 2:13 AM, bauss wrote: On Wednesday, 18 May 2022 at 02:12:42 UTC, zoujiaqing wrote: https://dlang.org/changelog/2.100.0.html#deprecation_delete My code: ```D import std.stdio; class HttpClient { string get(string url) { return ""; } string delete(string url) { return ""; } } void main() { auto http = new HttpClient; string content = http.get("https://forum.dlang.org/group/general;); string content = http.delete("https://forum.dlang.org/newpost/general?;); } ``` error message ```bash % dub build --compiler=dmd Performing "debug" build using dmd for x86_64. test ~master: building configuration "application"... source/app.d(10,9): Error: no identifier for declarator `string` source/app.d(10,9): Error: declaration expected, not `delete` source/app.d(14,1): Error: unmatched closing brace dmd failed with exit code 1. ``` I wonder when I can use it. Because this will cause a software naming problem. Considering the deprecation period has ended then IMO it should be able to be used as an identifier. I would consider this a bug. No, it's intentional. https://dlang.org/changelog/2.100.0.html#deprecation_delete > Starting with this release, using the delete *keyword* will result in a *compiler error*. It's still a keyword according to that. I'm assuming a future release will remove the error, and then you can use it as a symbol. -Steve To be honest, it's not clear that it's intentional from the description of the changelog. It just says using the keyword will result in an error, not using the keyword as an identifier, which isn't the same at all.
Re: I need to use delete as the method name. But now it's still a keyword, right?
On Wednesday, 18 May 2022 at 02:12:42 UTC, zoujiaqing wrote: https://dlang.org/changelog/2.100.0.html#deprecation_delete My code: ```D import std.stdio; class HttpClient { string get(string url) { return ""; } string delete(string url) { return ""; } } void main() { auto http = new HttpClient; string content = http.get("https://forum.dlang.org/group/general;); string content = http.delete("https://forum.dlang.org/newpost/general?;); } ``` error message ```bash % dub build --compiler=dmd Performing "debug" build using dmd for x86_64. test ~master: building configuration "application"... source/app.d(10,9): Error: no identifier for declarator `string` source/app.d(10,9): Error: declaration expected, not `delete` source/app.d(14,1): Error: unmatched closing brace dmd failed with exit code 1. ``` I wonder when I can use it. Because this will cause a software naming problem. Considering the deprecation period has ended then IMO it should be able to be used as an identifier. I would consider this a bug.
Re: What are (were) the most difficult parts of D?
On Tuesday, 17 May 2022 at 11:53:40 UTC, zjh wrote: On Tuesday, 17 May 2022 at 11:50:30 UTC, zjh wrote: Right,GC is a bad idea! Endless use of memory without freeing. It's totally unreasonable waste. It's not really endless use of memory and it does free. Depending on the strategy then it does so at different times, such as when allocating, but not enough memory has been allocated already. The problem with GC is that the lifetime sometimes exceed what's expected. Personally I don't have a problem with the GC.
Re: Question on shapes
On Tuesday, 17 May 2022 at 00:10:55 UTC, Alain De Vos wrote: Let's say a shape is ,a circle with a radius ,or a square with a rectangular size. I want to pass shapes to functions, eg to draw them on the screen, draw(myshape) or myshape.draw(); But how do i implement best shapes ? In addition to all the answers, just remember that if you want to make a square class then it should inherit from the shape class and not the rectangle class. It might seem like the obvious rule is for square to inherit rectangle, since a square is a rectangle, but it's only true on the surface, not in functionality. An example is below: ```d void changeRectangle(Rectangle rectangle, int amount) { rectangle.length = rectangle.length + amount; } ... // While this works, then it's functional wrong as you must change both the length/height of a square, since they cannot differ. changeRectangle(new Square(100, 100), 50); ``` You might think that it's easy to just not call changeRectangle with a square, but what if you store the rectangles in a list, map, get it from an external data source etc. then it starts being more and more complex and for no reason at all! I know your post really isn't about such things, but I think it's a good thing to learn already.
Re: decimal type in d
On Monday, 16 May 2022 at 09:46:57 UTC, IGotD- wrote: On Sunday, 15 May 2022 at 13:26:30 UTC, vit wrote: Hello, I want read decimal type from sql db, do some arithmetic operations inside D program and write it back to DB. Result need to be close to result as if this operations was performed in sql DB. Something like C# decimal. Exists this kind of library ind D? (ideally `pure @safe @nogc nothrow`). This also something I wondered, it should be standard in the D library. Implementing it can be done straight forward with existing D language primitives, essentially a struct. For those who don't know, decimal in C# is like a floating point value but the exponent is a power of 10 (internally total 16 bytes). This means that for "simple" mathematics rational decimal values remains rational decimals values and not some rounded value that would happen if you would use normal floating point values. The decimal type is essential for financial calculations. I think D can more or less copy the C# solution. Here's the implementation if anyone needs it: https://referencesource.microsoft.com/#mscorlib/system/decimal.cs,1b2858baf311cbf9 Should be fairly straightforward to implement.
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 15:59:17 UTC, Alain De Vos wrote: Can i summarize , structs are value-objects which live on the stack. class instances are reference objects which live on the heap. But that's not entirely true as you can allocate a struct on the heap as well. The real difference is inheritance and polymorphism, not allocation and where the memory lives.
Re: What are (were) the most difficult parts of D?
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote: What are you stuck at? What was the most difficult features to understand? etc. To make it more meaningful, what is your experience with other languages? Ali dip1000
Re: Parameters declared as the alias of a template won't accept the arguments of the same type.
On Tuesday, 3 May 2022 at 07:11:48 UTC, Ola Fosheim Grøstad wrote: As you see, someone will have to write a DIP to fix this bug, as the language authors don't consider it a bug, but an enhancement. I don't believe those two words are mutually exclusive. It can be a bug __and__ an enhancement. But to deny that this is a bug is just being lazy.
Re: How to get compatible symbol names and runtime typeid names for templated classes?
On Tuesday, 3 May 2022 at 09:52:56 UTC, cc wrote: On Tuesday, 3 May 2022 at 09:42:45 UTC, cc wrote: Given a runtime typeid, how can I get the equivalent fullyQualifiedName without attempting to mangle the string myself manually? e.g. something I can pass to `Object.factory`. Actually, looking at this further, does Object.factory even support templates? I'm getting null returned from any attempt to instantiate a templated classname. It does not. Object.factory calls TypeInfo_Class.find which just loops through ModuleInfo and then looks if any of the entries in localClasses has a name that matches. So for your example it does this check: ``` if (c.name == "test.Foo!(true)") { return c; // c is the TypeInfo_Class that matches the given class name } ``` https://github.com/dlang/druntime/blob/master/src/object.d#L1661 Afterwards it calls the create function on the TypeInfo_Class which of course isn't "generic" by any means. This is where compile-time has its limits compared to runtime type creation, because templates only live during compile-time then it isn't really that easy to do something like this, where it would be trivial in other languages like C#.
Re: CTFE and BetterC compatibility
On Thursday, 28 April 2022 at 12:36:56 UTC, Dennis wrote: On Thursday, 28 April 2022 at 12:10:44 UTC, bauss wrote: On Wednesday, 27 April 2022 at 15:40:49 UTC, Adam D Ruppe wrote: but this got killed due to internal D politics. A pity. A tale as old as time itself In this case, it was actually a trailing whitespace in the changelog entry making the test suite fail, but the PR author ceased activity before fixing it and now it has merge conflicts. https://github.com/dlang/dmd/pull/11014#discussion_r427108067 The fact a trailing white-space has any impact is almost laughable.
Re: CTFE and BetterC compatibility
On Wednesday, 27 April 2022 at 15:40:49 UTC, Adam D Ruppe wrote: but this got killed due to internal D politics. A pity. A tale as old as time itself
Re: How to implement private constructor
On Monday, 25 April 2022 at 07:18:44 UTC, bauss wrote: On Monday, 25 April 2022 at 00:18:03 UTC, Vinod K Chandran wrote: Hi all, Please take a look at this code. Is this the right way to use private constructors ? ```d class Foo { int p1 ; string p2 ; bool p3 ; private this(int a, string b, bool c) { this.p1 = a this.p2 = b this.p3 = c } this(int a) { this(a, "some string", true); } this(int a, string b) { this(a, b, true); } } ``` Yes and in addition to Ali's message then remember it's private for the module only. Oops typo. What I meant is that private is module level, so it's __not__ private in the module, but it is for other modules.
Re: How to implement private constructor
On Monday, 25 April 2022 at 00:18:03 UTC, Vinod K Chandran wrote: Hi all, Please take a look at this code. Is this the right way to use private constructors ? ```d class Foo { int p1 ; string p2 ; bool p3 ; private this(int a, string b, bool c) { this.p1 = a this.p2 = b this.p3 = c } this(int a) { this(a, "some string", true); } this(int a, string b) { this(a, b, true); } } ``` Yes and in addition to Ali's message then remember it's private for the module only.
Re: stack frame & dangling pointer weirdness
On Thursday, 21 April 2022 at 05:49:12 UTC, Alain De Vos wrote: Following program: ``` import std.stdio; void main() @trusted { int *p=null; void myfun(){ int x=2; p= writeln(p); writeln(x); } myfun(); *p=16; writeln(p); writeln(*p); } ``` outputs : 7FFFDFAC 2 7FFFDFAC 32767 I don't understand why. Would it be possible to explain ? See my comment for some ELI5 of what's going on. Of course it's a bit more complicated than that, but I hope it gets the point across. ``` void main() @trusted { int *p=null; // P is null obviously void myfun(){ int x=2; p= // Sets the address of p to the address of x, which is on the stack of myfun writeln(p); // Writes the address of p writeln(x); // Writes the value of x (same as value of p) } myfun(); // We call myfun // Any memory that was in the stack of myfun is invalid here, returning to the stack of main. *p=16; // Sets the value of p to 16, but p points to the address of an invalid memory location, since x was on the stack within myfun and thus isn't valid outside of myfun writeln(p); // Writes the address of p, which is the same since the address of p was stored on the stack of main writeln(*p); // Attempts to write the value of p, which points to an "invalid" memory address, or at least it's now something completely different than it was before, considering the stack of myfun is gone, so it writes out a garbage value } ```
Re: Beginner memory question.
On Saturday, 16 April 2022 at 20:48:15 UTC, Adam Ruppe wrote: On Saturday, 16 April 2022 at 20:41:25 UTC, WhatMeWorry wrote: Is virtual memory entering into the equation? Probably. Memory allocated doesn't physically exist until written to a lot of the time. You can also exceed your RAM in a lot of cases, as the OS will just start using your disk for RAM instead, so just because you have 8 GB of ram doesn't always mean you can only use 8 GM of RAM (in theory of course.)
Re: DUB issues
On Tuesday, 19 April 2022 at 09:37:49 UTC, Mike Parker wrote: On Tuesday, 19 April 2022 at 08:58:02 UTC, bauss wrote: On Monday, 18 April 2022 at 13:41:04 UTC, Mike Parker wrote: On Monday, 18 April 2022 at 05:27:32 UTC, Danny Arends wrote: Any ideas how to get into contact/fix this issue ? I've emailed Sönke and pointed him to this thread. Wouldn't the appropriate thing to do be dub being officially a part of D, it's advertised as such, but it really isn't such. It would also make this a non-issue, or at least organizational issue and not a single person who's responsible for it all. I've posted several times about this in meeting summaries: the foundation is moving toward taking over management of all of the vital ecosystem services, including code.dlang.org. My most recent comments about it were in the summary from our quarterly meeting in March: https://forum.dlang.org/post/zfmkiqwkkexeaohjs...@forum.dlang.org See the section "D ecosystem services". In our monthly meeting on April 8 (I'll have a summary for that posted this week), we agreed to get together with the maintainers of some of those services this month to discuss how to move forward. Most of them have responded that they can attend (still waiting on a couple), so it looks like we're on for April 29th. I've already gathered resource requirements from most of them, and I've set up a foundation account with Namecheap to manage domain names. Seb has transferred dlang.io to us, and we have access to the account with dub.pm (Namecheap doesn't support .pm). Walter owns dlang.org, but will transfer it to the foundation before it comes time to renew it. So we'll be discussing hosting, migration, etc., at the meeting, and formulate a plan to get things moving. At the moment, I'm hoping we'll have everything migrated by the end of the year. Once this is complete, we'll have multiple admins in multiple time zones. So it's happening, but it's not going to happen overnight. I'll admit, I rarely read those as big walls of text just tends to go over my head, But I'm glad you're confirming that it's indeed the goal to take over those projects. So thank you.
Re: DUB issues
On Monday, 18 April 2022 at 13:41:04 UTC, Mike Parker wrote: On Monday, 18 April 2022 at 05:27:32 UTC, Danny Arends wrote: Any ideas how to get into contact/fix this issue ? I've emailed Sönke and pointed him to this thread. Wouldn't the appropriate thing to do be dub being officially a part of D, it's advertised as such, but it really isn't such. It would also make this a non-issue, or at least organizational issue and not a single person who's responsible for it all.
Re: save and load a 2d array to a file
On Tuesday, 19 April 2022 at 06:05:27 UTC, Ali Çehreli wrote: int i = 42; file.rawWrite(*cast((int[1]*)())); // Casted to be an array of 1 I assume since we don't have a rawWriteValue, that it's rarely needed. However it should be fairly trivial like: void rawWriteValue(T)(T value) { rawWrite(*cast((T[1]*)())); } Or is there some downside to this that I'm missing?
Re: How to exclude function from being imported in D language?
On Friday, 18 March 2022 at 03:24:10 UTC, Era Scarecrow wrote: On Tuesday, 8 March 2022 at 22:28:27 UTC, bauss wrote: What D just needs is a way to specify the entry point, in which it just defaults to the first main function found, but could be any function given. Which is similar to what Java does. When i was first learning Java in a company i would make main() and have it run all the unittests of that particular module, then have a different file that actually combined all the tools together to run the program. Though when making the jar I'd specify which one actually was needed. But this was... 10 years ago. Yeah, it's similar to most other languages that allows it too. It doesn't make much sense to force an entry point anyway, especially not in D where there is no real entry point anyway, but the compiler already emits a couple of different ones that are platform dependent.
Re: Make shared static this() encoding table compilable
On Monday, 14 March 2022 at 09:40:00 UTC, zhad3 wrote: Hey everyone, I am in need of some help. I have written this Windows CP949 encoding table https://github.com/zhad3/zencoding/blob/main/windows949/source/zencoding/windows949/table.d which is used to convert CP949 to UTF-16. After some research about how to initialize immutable associative arrays people suggested using `shared static this()`. So far this worked for me, but I recently discovered that DMD cannot compile this in release mode with optimizations. `dub build --build=release` or `dmd` with `-release -O` fails: ``` code windows949 function zencoding.windows949.fromWindows949!(immutable(ubyte)[]).fromWindows949 code table function zencoding.windows949.table._sharedStaticCtor_L29_C1 dmd failed with exit code -11. ``` I usually compile my projects using LDC where this works fine, but I don't want to force others to use LDC because of this one problem. Hence I'd like to ask on how to change the code so that it compiles on DMD in release mode (with optimizations). I thought about having a computational algorithm instead of an encoding table but sadly I could not find any references in that regard. Apparently encoding tables seem to be the standard. I think it's a memory issue and it's unlikely to be solved. I saw a similar issue a while ago where it worked with everything but DMD. Someone can correct me but if I remember correctly it's because DMD issues instructions for each value (or something like that) in the static array and thus runs out of memory before any optimization can happen or whatever, but LDC etc. doesn't have said issue. I can't exactly remember how it is, but I think it's something along those lines. I don't think there really is a workaround as of now and probably never will be.
Re: Template with default parameter
On Friday, 11 March 2022 at 11:55:24 UTC, Andrey Zherikov wrote: On Friday, 11 March 2022 at 07:06:15 UTC, bauss wrote: Create an alias for T!() is the best you can do. Ex. ``` alias t = T!(); ``` There isn't really any better method as far as I know. I'd like to preserve the name (`t` != `T`) but `alias T = T!()` gives me `Error: declaration `T` is already defined` Yeah you can't really do much about that. Then T would have to be something like TImpl and then you do `alias T = TImpl!();`
Re: Template with default parameter
On Friday, 11 March 2022 at 04:41:40 UTC, Andrey Zherikov wrote: I have simple template: ```d template T(int i=3) { mixin template M(int m) { enum t = i; } } { mixin T!1.M!1; pragma(msg, t); // 1 } { mixin T!().M!1; pragma(msg, t); // 3 } { mixin T.M!1; // Error: identifier `M` of `T.M` is not defined // Error: mixin `M!1` is not defined pragma(msg, t); // Error: undefined identifier `t` //while evaluating `pragma(msg, t)` } ``` What should I do to be able to write `T.M!...`? I want to omit verbose `!()` for `T`. Note that mixins are essential here. Create an alias for T!() is the best you can do. Ex. ``` alias t = T!(); ``` There isn't really any better method as far as I know.
Re: How to exclude function from being imported in D language?
On Tuesday, 8 March 2022 at 20:12:40 UTC, BoQsc wrote: I think D Language needs and lacks conditional compilation condition and attribute of "exclude". The exclude keyword or code block in the exclude, would be made sure to not be imported by any means. Now it seems all to be only workarounds. What D just needs is a way to specify the entry point, in which it just defaults to the first main function found, but could be any function given.
Re: opCast in class prevents destroy
On Tuesday, 1 March 2022 at 08:16:13 UTC, Mike Parker wrote: On Tuesday, 1 March 2022 at 07:16:11 UTC, bauss wrote: Right now if you want to add an additional cast then you have to implement ALL the default behaviors and then add your custom cast. It's two template functions like the OP used: one for T to catch everything, and one specialization. That doesn't seem correct to me at least. Depends on your perspective I guess. For the inverse, when you want to allow only one kind of cast and prevent everything else, you only have to implement one template right now. If that were not the case, then you'd have to implement an additional catch-all template that bombs out with a static assert. So either way makes sense, IMO. Though I totally understand how the current behavior can be a surprise when people expect it to behave like, e.g., C++. But D is not C++. So is `opCast` intended to expand the list of target types (like C++), or is it intended to define it? The spec says, "To define how one type can be cast to another", which doesn't really answer the question. Yes of course it's a matter of perspective. I think the solution would be to have two functions for opCast, maybe something like opAdditionalCast, idk, not to break current behavior I guess.
Re: opCast in class prevents destroy
On Tuesday, 1 March 2022 at 04:59:49 UTC, Mike Parker wrote: It makes sense to me, and I would say the bug is that it's not documented. Personally it doesn't make sense to me. I don't think it should override default behaviors, but just add onto it, so you can add an additional cast. Right now if you want to add an additional cast then you have to implement ALL the default behaviors and then add your custom cast. That doesn't seem correct to me at least. That's not how the behavior is in most other languages either.
Re: Odd behaviour of std.range
On Tuesday, 22 February 2022 at 12:48:21 UTC, frame wrote: What am I missing here? Is this some UTF conversion issue? ```d string a; char[] b; pragma(msg, typeof(a.take(1).front)); // dchar pragma(msg, typeof(b.take(1).front)); // dchar ``` Welcome to the world of auto decoding, D's million dollar mistake.
Re: Is there a way to not escape slashes when parsing JSON?
On Monday, 21 February 2022 at 15:13:52 UTC, Kagamin wrote: On Monday, 21 February 2022 at 09:04:06 UTC, bauss wrote: Why are we even escaping them by default, it should be the other way around, that slashes are only escaped if you ask for it; that's how it literally is in almost every JSON library. Really? I always see escaped slashes in JSON, e.g. wikipedia does this, but everything else too. I'm going to assume that JS is probably the most used language for JSON, since it originated from it, so a small demonstration will show you that even JS defaults to not escaping slashes: ``` let o = { a: "/path/to/something" }; console.log(JSON.stringify(o)); ``` Output: ``` {"a":"/path/to/something"} ```
Re: Why writeln can't be converted to nothrow with just catching of StdioException
On Monday, 21 February 2022 at 10:57:07 UTC, Basile B. wrote: On Monday, 21 February 2022 at 10:53:56 UTC, Basile B. wrote: On Monday, 21 February 2022 at 10:49:13 UTC, partypooper wrote: Do I completely not understand what is `nothrow` or why I can't make function nothrow with just catching StdioException? This doesn't work ```d nothrow void hello() { try { writeln("Hello, World!") } catch (StdioException) {} } ``` This doest work ```d nothrow void hello() { try { writeln("Hello, World!") } catch (Exception) {} } ``` I believe it's because it can throw ConvException as well ;) However you're totally right to open a discussion, the documentation is innacurate: in https://dlang.org/phobos/std_stdio.html#.writeln just StdioException is mentioned ;) What if we could do ex. this: ```d __traits(possibleExceptions, writeln); ``` Which would give all exceptions a function could possibly throw. That way we could build our try/catch based on that. For nothrow it should return nothing of course, for extern functions that have no source code available it should only return "Exception" of course. Just a thought I just had.
Re: Is there a way to not escape slashes when parsing JSON?
On Monday, 21 February 2022 at 03:42:55 UTC, bachmeier wrote: I tried this ``` import std.json, std.stdio; void main() { writeln(parseJSON(`{"a": "path/file"}`, JSONOptions.doNotEscapeSlashes)); } ``` but the output is ``` {"a":"path\/file"} ``` Is there a way to avoid the escaping of the forward slash? Is there some reason I should want to escape the forward slash? Why are we even escaping them by default, it should be the other way around, that slashes are only escaped if you ask for it; that's how it literally is in almost every JSON library. Escaping slashes as a default is a huge mistake IMHO.
Re: How to update Associative Array?
On Thursday, 10 February 2022 at 10:59:17 UTC, tastyminerals wrote: Not sure if the `update` method got changed but I am having trouble with understanding it now. I assumed it would work as easy as in Python:) Just do `mydic.update(dic)` or `mydic["key"].update(anotherDic)`. The docs have the following example. ``` class C{} C[string] aa; C older; C newer; aa.update("a", { newer = new C; return newer; }, (ref C c) { older = c; newer = new C; return newer; }); ``` This looks pretty scary and confusing to me tbo. Also, why is there an example with class and not simple `int[string]`? I just need to know how can I update let's say `int[string]` or nested `int[string][string]` AA. Should I also initialise and additional C classes before calling this method as in the example? Considering this is the only example in the docs I could find on how to update AA, imagine someone from Python world comes and sees this. Next thing he does, is close the page and never come back to D again :( You can just do: aa[key] = value. If the key exist then it's updated, if it doesn't then it's added. The reason for the update function is simply in cases where you want to use the oldvalue etc. perhaps it has a timestamp that you need to keep etc. But in general you shouldn't need it.
Re: Filling an array at compile time
On Wednesday, 9 February 2022 at 16:37:22 UTC, Ali Çehreli wrote: On 2/9/22 01:07, bauss wrote: > It will not run at compile-time because csvText is a runtime variable. > It should be enum to be accessible at compile-time. Yes. For the sake of completeness, any expression needed at compile time will be (attempted to be) executed at compile time. For example, an expression used as a template parameter will be executed at compile time as well. > The append operation > will be executed at runtime, which means that even if the loop runs at > compile-time then you're effectively not winning anything and it > basically just becomes a loop-unroll manually done. That's not true. It all depends on how the expression is needed. If for example, the variable were defined as enum, the compiler had to execute the code at compile time to compute its value. > The solution would be to create a function that returns a string [...] > And then simply using mixin That is unnecessary and hurts readability. :/ Most programmers see string mixins as a last resort. In any case, some people may find a compile-time file parsing example that I included in a presentation: https://youtu.be/dRORNQIB2wA?t=3157 Ali Thank you Ali for the clarifications
Re: how to handle very large array?
On Wednesday, 9 February 2022 at 10:03:21 UTC, MichaelBi wrote: day6 of the advent of code 2021 needs to handle an array of 10^12 length, or even bigger... plus change elements and append elements. normal implementation such as length, appender and ref element etc, seems cannot handle that big array? is there any alternative data structure or algorithm can handle such large array properly? thanks. Use a memorymapped file that holds the array values, in theory it can be infinite then. Since an array has a known size for each entry then you can treat the file as an array. Let's say you have an array of ints. For a memorymapped file you obviously only have bytes to work with, so each entry will be 4 bytes, since a 32 bit integer (int) is 4 bytes. So to read something at a specific index you simply do N x I where N is the size of the type and I is the index you want to read at. Otherwise the size of an array cannot exceed the RAM you have, if your system can't use diskspace as RAM of course.
Re: Filling an array at compile time
On Wednesday, 9 February 2022 at 10:01:15 UTC, Anonymouse wrote: On Wednesday, 9 February 2022 at 08:12:52 UTC, Vindex wrote: Will the loop (foreach) run at compile time? How can I make it work at compile time? ``` import std.csv, std.stdio; alias Record = Tuple!(string, string, string); immutable string[][] table; shared static this() { string csvText = import("file.csv"); foreach (record; csvReader!Record(csvText)) { table ~= [record[0], record[1], record[2]]; } } void main() { writeln(table): } ``` I would do this. ``` import std; alias Record = Tuple!(string, string, string); static immutable string[][] table = () { string[][] table; string csvText = import("file.csv"); foreach (record; csvReader!Record(csvText)) { table ~= [record[0], record[1], record[2]]; } return table; }(); pragma(msg, table); // Available at compile-time void main() { writeln(table); } ``` And then `-J{path}` to tell the compiler where to find `file.csv`. ``` dmd -J. csv.d ``` Is it guaranteed that the value is initialized at compiletime however? Something being available at compiletime isn't the same as being initialized at compiletime only. If it's guaranteed then that's indeed the best solution.