Re: Preventing the Compiler from Optimizing Away Benchmarks
On Monday, 13 March 2023 at 14:17:57 UTC, jmh530 wrote: I was looking at [1] for ways to prevent the compiler from optimizing away code when trying to benchmark. It has the following C++ code as a simpler version: ``` inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { asm volatile("" : "+r,m"(value) : : "memory"); } ``` I made an attempt to make a D version of it, but failed. Apparently DMD doesn't like the `""` in the first part of the asm instruction. I'm also not sure the `volatileLoad` command is right, but I didn't know of any other way to have volatile work in D (and I couldn't figure out how it actually worked from looking at the code). ``` void DoNotOptimize(T)(T* ptr) { import core.volatile: volatileLoad; T value = volatileLoad(ptr); asm {"" : "+r,m"(value) : : "memory";} } ``` [1] https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html that's illegal code. You mix GCC/LLVM syntax with D asm block and the front-end wont recognize that. LDC recognizes a syntax similar to what is described in your link, see https://wiki.dlang.org/LDC_inline_assembly_expressions. GDC has it too (since that the syntax invented by GCC in first place) but I cant find the documentation ATM.
Re: Can nice D code get a bit slow?
On Wednesday, 8 March 2023 at 12:46:53 UTC, Hipreme wrote: On Wednesday, 8 March 2023 at 10:49:32 UTC, Markus wrote: Hi, sorry for the broad and vague question. I have read in some reddit post about benchmarks, that some code didn't use the final keyword on methods in a sense that final would make it faster, I believe. [...] Don't bother with it. This kind of optimization is done when compiling with -O, No they are not, simple example : https://godbolt.org/z/xfPqnWrrv Obviously in a library `test` might be called with a derived so `v1()` target address must be read in the vtbl of the argument. and I really doubt about your bottleneck being that you're calling a virtual call. That is more true. vcalls dont add complexity. Wait when you actually need to optimize before making your code ugly.
Re: ELIZA Chatbot Implementation From C to D Lang
On Friday, 17 February 2023 at 17:03:34 UTC, ron77 wrote: Hello, I succeeded in converting an ELIZA code from C to D, and here are the results. although I'm sure there are better ways to code it or to convert it... [...] Among the things to do the first is to drop C-style strings, so that you can get rid of `strlen()` and `strcat()` for example. Then maybe try to rewrite your for-loops as UFCS pipes. Have fun.
Re: Template alias parameter: error: need 'this' for ...
On Friday, 24 February 2023 at 12:00:41 UTC, Elfstone wrote: Seems like the same bug is still there after ten years. ```d struct Bar { @("hello") int t; } static bool hasAttribute(alias F, T)() { bool result = false; foreach (a; __traits(getAttributes, F)) { static if (is(typeof(a) : T)) { result = true; // couldn't simply return true, 'cause the compiler complains about "unreachable code". } } return result; } void main() { import std.stdio; writeln(hasAttribute!(Bar.t, string)); } ``` you can break using `goto`, restore `static` everywhere, and using local introspection determine whether the result exists. ```d struct Bar { @("hello") int t; } static bool hasAttribute(alias F, T)() { static foreach (a; __traits(getAttributes, F)) { static if (is(typeof(a) : T)) { enum result = true; goto L0; } } L0: static if (is(typeof(result))) return result; else return false; } void main() { import std.stdio; writeln(hasAttribute!(Bar.t, string)); } ```
Re: compile: link dynamic OR static library in Windows
On Sunday, 5 February 2023 at 11:52:01 UTC, Alexander Zhirov wrote: On Saturday, 4 February 2023 at 15:56:41 UTC, Richard (Rikki) Andrew Cattermole wrote: [...] I don't understand why the compiler doesn't see the library. ```sh User@WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source # ls -la "C:\Program Files\PostgreSQL\15\lib\libpq.lib" -rw-r--r-- 1 User Отсутствует 37002 Nov 9 06:45 'C:\Program Files\PostgreSQL\15\lib\libpq.lib' User@WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source # dmd -i app.d -L'C:\Program Files\PostgreSQL\15\lib\libpq.lib' lld-link: error: could not open 'pq.lib': no such file or directory Error: linker exited with status 1 ``` try ``` dmd -i app.d -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq ``` the first linker command gives a search path, the second a libname.
Re: Function Composition
On Wednesday, 24 January 2024 at 21:12:20 UTC, atzensepp wrote: [...] what a bummer! Have you tried https://dlang.org/phobos/std_functional.html#compose ?
Re: Function Composition
On Wednesday, 24 January 2024 at 21:30:23 UTC, user1234 wrote: On Wednesday, 24 January 2024 at 21:12:20 UTC, atzensepp wrote: [...] what a bummer! Have you tried https://dlang.org/phobos/std_functional.html#compose ? Well this violates the second requirement: the composition itself requires additional lambda expressions I would like to write compose(f,g) I just realize, as this requires template specialization with `!`. But this is how D works with these kind of things.
Re: Synchronisation help
On Monday, 1 January 2024 at 15:48:16 UTC, Anonymouse wrote: I have a `shared string[int]` AA that I access from two different threads. The function I spawn to start the second thread takes the AA as an argument. [...] What is the common solution here? Do I add a module-level `Object thing` and move everything accessing the AA into `synchronized(.thing)` statements? Or maybe add a `shared static` something to `Foo` and synchronise with `synchronize(Foo.thing)`? Do not use `shared` AA. Use `__gshared` + sync primitives. `shared` AA will lead to all sort of bugs: - https://issues.dlang.org/show_bug.cgi?id=20484#c1 - https://issues.dlang.org/show_bug.cgi?id=17088 - https://issues.dlang.org/show_bug.cgi?id=16597 - etc.
Re: Synchronisation help
On Tuesday, 2 January 2024 at 11:39:12 UTC, Anonymouse wrote: On Tuesday, 2 January 2024 at 11:05:33 UTC, user1234 wrote: Do not use `shared` AA. Use `__gshared` + sync primitives. `shared` AA will lead to all sort of bugs: - https://issues.dlang.org/show_bug.cgi?id=20484#c1 - https://issues.dlang.org/show_bug.cgi?id=17088 - https://issues.dlang.org/show_bug.cgi?id=16597 - etc. Hmm, I see. Is `shared` safe to use with AAs *provided* I use sync primitives, or should I favour `__gshared` over `shared`? I was under the impression `__gshared` was only really meant for interfacing with C. The semantics of __gshared in this context is "no-TLS". You meant to access the AA in several threads right ? So you dont want each thread to have its own copy.
Re: Indirect access to variables.
On Friday, 29 December 2023 at 17:11:49 UTC, DLearner wrote: Compile-time: [...] Is there a 'foo1' that yields 1 from the snippet below? [...] Similarly, execution-time, is there a foo2 that wields 2 from the snippet below: [...] **compile-tome** ```d void main() { import std.stdio; size_t var1 = 1; size_t var2 = 8; writeln(mixin(var1.stringof)); writeln(mixin(var2.stringof)); } ``` **run-tome** Given the information you provide I'd say you can use an associative array: ```d size_t*[string] registry; void main() { import std.stdio; size_t var1 = 1; size_t var2 = 8; registry[var1.stringof] = registry[var2.stringof] = writeln(*registry[var1.stringof]); writeln(*registry[var2.stringof]); } ``` but take care to the entries lifetime, that's basically not safe as this escapes stack addresses.
Re: `static` function ... cannot access variable in frame of ...
On Monday, 15 January 2024 at 18:34:58 UTC, H. S. Teoh wrote: On Mon, Jan 15, 2024 at 06:16:44PM +, Bastiaan Veelo via Digitalmars-d-learn wrote: Hey people, I can use some help understanding why the last line produces a compile error. ```d import std.stdio; struct S { static void foo(alias len)() [...] The trouble is with the `static` here. A context pointer is necessary in order to have access to the context of main() from the body of this function; but `static` precludes this possibility. T I dont agree, problem is S_foo that get automagically monomorphized in `main` scope. That's a very classic D problem.
Re: `static` function ... cannot access variable in frame of ...
On Monday, 15 January 2024 at 18:16:44 UTC, Bastiaan Veelo wrote: [...] It seems to me this should just work. Thanks! --Bastiaan. The two calls are not equivalent. To be equivalent you need to set `S_foo` static too, otherwise `S_Foo` is instanciated in `main` scope, proof: ```d import std.stdio; struct S { static void foo(alias len)() { writeln(len); } } static void S_foo(alias len)() { writeln(len); } void main() { const five = 5; S_foo!five; // Error too now S.foo!five; // Error } ``` so what is passed as alias need to be static too. But to be frank, I agree this is a less ideal situation. There are like 20 bugs reports opened related to that. The way a non-static `S_foo` behaves is under-specified.
Re: Understanding the Use of Nested Import and Selective Import in D
On Tuesday, 16 January 2024 at 13:19:59 UTC, Orfeo wrote: I found myself a bit perplexed when it comes to the usage of "nested imports" and selective imports. It seems that prominent D programmers have varied opinions on the matter. I would love to hear your insights and experiences on this topic. Here's a quick summary of what I've come across from three influential D programmers: - Adam Ruppe: In his blog post titled [D's selective imports have effects you may not want](http://dpldocs.info/this-week-in-arsd/Blog.Posted_2023_11_06.html) have effects you may not want, Adam advises against the use of selective imports. He highlights potential unwanted side effects and suggests caution when employing them. - Atila Neves: At DConf 2023, Atila Neves recommended the use of nested imports. He argues that nested imports can make refactoring easier and help in assessing the dependencies a function has. - Rober Schadek: Also at DConf 2023, Rober Schadek discouraged the use of nested imports, taking a stance different from Atila Neves. Now, the big question is: What's your preferred approach? Another point is that the use of selective imports tends to be "a refactoring". You start with a global or local import. Once everything is fine you'll think that's it's a good idea to make the import selective, i.e "because I only use that in there". Problem is, if someone else at some point work on your code: 1. he needs to add more to the selection 2. completion may not work anymore (will only show what's selected) So it's a bit a thing of expert. Given these arguments I think that global imports should not be selective, only local ones should. Implementation detail. D frontend resolves identifiers using associative arrays (that's called symtabs in the compiler IIRC), hence the only complexity is the scope (plus the import decls found while going back to the module scope).
Re: Understanding the Use of Nested Import and Selective Import in D
On Tuesday, 16 January 2024 at 13:37:59 UTC, user1234 wrote: Implementation detail. D frontend resolves identifiers using associative arrays (that's called symtabs in the compiler IIRC), hence the only complexity is the scope (plus the import decls found while going back to the module scope). oops forgot to say: so it's fast.
Re: Inversion of conditional compilation statements
On Saturday, 2 December 2023 at 13:16:26 UTC, Johannes Miesenhardt wrote: Hello, [...] I see the way why it doesn't work, but I think it should. Considering that `version (Test) {} else {` works without any issue but looks very ugly. Can somebody explain if this is an intended decision or what I should do instead of using my ugly replacement? It's an intended decision that's often debated, a.k.a "version algebra". The official position on version algebra is that complex conditions (think `&&` and `||`) would be a source of bugs.
Re: How to hash SHA256 from string?
On Saturday, 2 December 2023 at 16:17:08 UTC, user1234 wrote: On Saturday, 2 December 2023 at 15:30:39 UTC, zoujiaqing wrote: [...] sign is binary, you have to use the toHexString utility : ```d import std.stdio; import std.digest.sha; void main() { SHA256 sha256; sha256.start(); string appKey = "1"; sha256.put(cast(ubyte[])appKey); ubyte[32] sign = sha256.finish(); writeln("sign: %s", toHexString(sign)); } ``` also you add a range error on data assignment. and a last error I have not initially catch, use writefln: ```d writefln("sign: %s", toHexString(sign)); ```
Re: How to hash SHA256 from string?
On Saturday, 2 December 2023 at 15:30:39 UTC, zoujiaqing wrote: ```D import std.stdio; import std.digest.sha; void main() { SHA256 sha256; sha256.start(); string appKey = "1"; ubyte[1024] data = cast(ubyte[])(appKey.dup[0..$]); sha256.put(data); ubyte[32] sign = sha256.finish(); string sign1 = cast(string) sign[0..$]; writeln("sign: %s", sign1); } ``` The result varies when you run the code repeatedly and the display is garbled: ``` zoujiaqing@mac test % ./test Getui access sign: %s>tM?a?j,???ߥm?8l~??uzU?|9?~ˡ zoujiaqing@mac test % ./test Getui access sign: %s1-??U? ?d<3^3??נ? ??P%u/Iv zoujiaqing@mac test % ./test Getui access sign: %s1?ϻN?ށ?`O?p!?O?4U :8J~%ʬ zoujiaqing@mac test % ./test Getui access sign: %s??k#O?;?ڋ?5T?"=??;???e ``` sign is binary, you have to use the toHexString utility : ```d import std.stdio; import std.digest.sha; void main() { SHA256 sha256; sha256.start(); string appKey = "1"; sha256.put(cast(ubyte[])appKey); ubyte[32] sign = sha256.finish(); writeln("sign: %s", toHexString(sign)); } ``` also you add a range error on data assignment.
Safety is not what you think
I want to share a stupid program to show you that D safety is more complex than you might think: ```d module test; void test() @safe { int i; int b = (*&(*&++i))++; } void main() @safe { test(); } ``` I'm not showing a deficiency of D, that program is undeniably safe ;)
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote: Why am I forced to visit this D Lang thread, why this deprecation warning still appears in my console window in the latest version of DMD. Does not make any sense from the developer's perspective to show this warning and pollute the already polluted logging entries of the compiler. How am I suppose to program anything effectively if half of the screen are some nonsensical deprecation warnings without guidance or sane explanations. This is not better ``` foreach (i, row; arr) ``` than ``` foreach (int i, row; arr) ``` Hides the datatype and makes the D language appear in-explicit and annoying. What is this language becoming. A completely weak typed language or something? I would use JavaScript if I would want that. How are we suppose to make whole sane Operating Systems with such syntaxes. Do everyone just enjoy having bugs with some implicit size_t, or do everyone just enjoy deprecation warnings in their logging systems when there are way more important problems to solve, that are actually project related. You can specify the index type, just choose the right one. For now there's a deprecation message but after some while you'll get a proper error message, e.g _"index type for arr must be of type T because arr.length type is T"_. What's is happening now is to help people updating their code and prevent abrupt breakages.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 14:59:57 UTC, BoQsc wrote: On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote: On Friday, 3 May 2024 at 10:50:03 UTC, BoQsc wrote: [...] **You can specify the index type, just choose the right one.** For now there's a deprecation message but after some while you'll get a proper error message, e.g _"index type for arr must be of type T because arr.length type is T"_. What's is happening now is to help people updating their code and prevent abrupt breakages. So how would you update this example, what is the right index type here to choose? ``` import std.stdio : writefln; void main() { auto arr = [ [5, 15], // 20 [2, 3, 2, 3], // 10 [3, 6, 2, 9], // 20 ]; foreach (i, row; arr) { double total = 0.0; foreach (e; row) total += e; auto avg = total / row.length; writefln("AVG [row=%d]: %.2f", i, avg); } } ``` Example taken from https://tour.dlang.org/tour/en/basics/foreach Isn't that obvious ? ```d foreach (const size_t i, row; arr) ``` `arr` is not a static array, it is a dynamic one, consequently its `.length` type is `size_t`, even if you have the feeling that, in the present situation, `int` bitwidth would be sufficient.
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 3 May 2024 at 15:19:13 UTC, user1234 wrote: On Friday, 3 May 2024 at 14:59:57 UTC, BoQsc wrote: On Friday, 3 May 2024 at 13:18:02 UTC, user1234 wrote: [...] So how would you update this example, what is the right index type here to choose? ``` import std.stdio : writefln; void main() { auto arr = [ [5, 15], // 20 [2, 3, 2, 3], // 10 [3, 6, 2, 9], // 20 ]; foreach (i, row; arr) { double total = 0.0; foreach (e; row) total += e; auto avg = total / row.length; writefln("AVG [row=%d]: %.2f", i, avg); } } ``` Example taken from https://tour.dlang.org/tour/en/basics/foreach Isn't that obvious ? ```d foreach (const size_t i, row; arr) ``` `arr` is not a static array, it is a dynamic one, consequently its `.length` type is `size_t`, even if you have the feeling that, in the present situation, `int` bitwidth would be sufficient. even better: ```d foreach (const typeof(arr.length) i, row; arr) ``` Otherwise I respect your POV, it's just that here I have no problem with the way that works. I dont see any issue with the type system. D type system is static, strong, but optionally inferred. And that's it.
Why is Phobos `Flag` so overthought ?
I think this just works: ```d enum Flag : bool { no, yes } alias AllowVancancy = Flag; // example usage ``` Also this is completion friendly whereas Phobos version does not permit DCD completion as it's based on opDispatch. Compare to phobos version: ```d template Flag(string name) { enum Flag : bool { no = false, yes = true } } struct Yes { template opDispatch(string name) { enum opDispatch = Flag!name.yes; } } struct No { template opDispatch(string name) { enum opDispatch = Flag!name.no; } } ``` must be a reason but I cant find it RN ;)
Re: Why is Phobos `Flag` so overthought ?
On Monday, 6 May 2024 at 18:06:53 UTC, Julian Fondren wrote: On Monday, 6 May 2024 at 17:55:49 UTC, user1234 wrote: I think this just works: ```d enum Flag : bool { no, yes } alias AllowVancancy = Flag; // example usage ``` ```d import std.stdio : writeln; enum Flag : bool { no, yes } alias Traditional = Flag; alias Color = Flag; void hello(Traditional traditional, Color color) { if (traditional && color) { writeln("\x1b[31;1mhello world\x1b[0m"); } else if (traditional && !color) { writeln("hello world"); } else if (!traditional && color) { writeln("\x1b[31;1mHello, world!\x1b[0m"); } else { writeln("Hello, world!"); } } void main() { hello(Color.yes, Traditional.yes); // this is wrong, but accepted } ``` Ah yes I see, strongly typed bools. Thanks .
Re: aliasing private
On Wednesday, 1 May 2024 at 12:07:26 UTC, NotYouAgain wrote: I want to do a C like #define on private, but I can't ie. #define private fileprivate // --- module m; alias fileprivate = private; // grr! class myClass { fileprivate int n; } // --- You cant. That is simply not supported.
Re: static functions?
On Monday, 11 March 2024 at 16:51:48 UTC, Andy Valencia wrote: On Monday, 11 March 2024 at 16:25:13 UTC, Jonathan M Davis wrote: ... But what exactly static means varies based on the context. Thank you for the list! But none of those appear to apply to a function defined in the outermost scope of the module. Is static accepted here--but has no actual effect? Yes module-level `static` (for what is aka "free-functions", but also variables) is a noop. Module-level is implicitly static. I will look at the privacy controls--thanks again. No need to ;) D `static` is a storage class, not a visibility attribute. Andy
Re: How to add a character literal to a string without ~ operator?
On Thursday, 4 April 2024 at 19:56:50 UTC, Ferhat Kurtulmuş wrote: On Thursday, 4 April 2024 at 18:14:54 UTC, BoQsc wrote: I'm looking for more readable standard function to add a **character** literal to a **string**. The `~` operator is clearly not great while reading a source code. I'm not here to discuss that. I'm looking for a function inside standard library. The function should be straightforward, up to two words. Here is what I expect from a programming language: Pseudo example: ``` import std; void main(){ string word = hello; join(word, 'f', " ", "World"); writeln(word); // output: hellof World } ``` My favorite d feature is lazy ranges. No allocation here. ``` auto s = chain("as ", "df ", "j"); // s is lazy writeln(s); ``` Of course you can allocate a new string from the chained range: ``` string str = cast(string)s.array.assumeUnique; // without a cast it is a dstring (why though?) ``` ```d module runnable; import std.stdio : writeln; import std.range : chain; void main() @nogc { auto s = chain("as ", "df ", "j"); // s is lazy writeln(s); } ``` Bad example. The range is indeed a `@nogc` lazy input range but `writeln` is not a `@nogc` consumer. /tmp/temp_7F91F8531AB0.d(9,12): Error: `@nogc` function `D main` cannot call non-@nogc function `std.stdio.writeln!(Result).writeln` /bin/ldc2-/bin/../import/std/stdio.d(4292,6):which calls `std.stdio.trustedStdout` The input range consumer has to be @nogc as well.
Re: New update fix
On Saturday, 2 March 2024 at 08:41:40 UTC, Salih Dincer wrote: SLM, What exactly did this patch with the new update fix? Nothing, it looks like what happened is that the issue was wrongly referenced by a dlang.org PR (https://github.com/dlang/dlang.org/pull/3701/commits/4e8db30f0bf3c330c3431e83fe8a75f843b40857).