Re: How to unpack a tuple into multiple variables?
On Wednesday, 7 February 2024 at 05:03:09 UTC, Gary Chike wrote: ... But overall it's an elegant way to indirectly add names to tuples in D for ergonomic access. Nice find! --- Refactored it a bit to have a ready to run and easy to grasp code. Enjoy! ```d import std.stdio : writefln; import std.typecons: tuple; // Name a Tuple's fields post hoc by copying the original's fields into a new Tuple. template named(names...) { auto named(T)(ref auto T t) if (names.length <= T.Types.length) => tuple!names(t.expand[0..names.length]); } // Define variables corresponding to a Tuple's fields in the current scope, // whose identifiers are given by `names`. mixin template Unpack(alias t, names...) if (names.length <= t.Types.length) { static foreach (i, n; names) mixin("auto ", n, " = t[i];"); } void main() { auto getUser() => tuple("John Doe", 32); // auto u = getUser().named!("name", "age"); writefln("%s (%d)", u.name, u.age); // John Doe (32) // You could also do this. with (getUser().named!("name", "age")) writefln("%s (%d)", name, age); // John Doe (32) // mixin Unpack!(u, "name", "age"); writefln("%s (%d)", name, age); // John Doe (32) } ```
Re: length's type.
On Thursday, 8 February 2024 at 05:56:57 UTC, Kevin Bailey wrote: I don't think it's productive to compare the behavior to C. C is now 50 years old. One would hope that D has learned a few things in that time. How many times does the following loop print? I ran into this twice doing the AoC exercises. It would be nice if it Just Worked. ``` import std.stdio; int main() { char[] something = ['a', 'b', 'c']; for (auto i = -1; i < something.length; ++i) writeln("less than"); return 0; } ``` This is horrible, even if you use `int i`, it still won't work as you have thought (ok, I thought): ``` import std.stdio; int main() { char[] something = ['a', 'b', 'c']; for (int i = -1; i < something.length; ++i) writeln("less than"); writeln("done"); return 0; } ``` it will just output ``` done ```
Re: length's type.
On Wednesday, 7 February 2024 at 20:13:40 UTC, Gary Chike wrote: On Wednesday, 7 February 2024 at 20:08:24 UTC, Gary Chike wrote: On Wednesday, 7 February 2024 at 19:32:56 UTC, Gary Chike wrote: double c = (double)sumArray(a, aLength) / aLength; If I don't cast explicitly: `double c = sumArray(a, aLength) / aLength;` then I will get a similar result as the D code: `Average: 9223372036854773760.00` I don't think it's productive to compare the behavior to C. C is now 50 years old. One would hope that D has learned a few things in that time. How many times does the following loop print? I ran into this twice doing the AoC exercises. It would be nice if it Just Worked. ``` import std.stdio; int main() { char[] something = ['a', 'b', 'c']; for (auto i = -1; i < something.length; ++i) writeln("less than"); return 0; } ```
Re: How to get the client's MAC address in Vibe
On Wednesday, 7 February 2024 at 22:16:54 UTC, Alexander Zhirov wrote: Is there a way to identify a client by MAC address when using the Vibe library? The `NetworkAddress` [structure](https://vibed.org/api/vibe.core.net/NetworkAddress) does not provide such features. Or did I miss something? That doesn't have anything to do with the server side if I am not mistaken as you should receive that via the browser that actually allows you to receive the mac address -via an extension- or some private API exposed by the browser. I don't know the use case but you may be better off with browser fingerprinting if you'd like to have a unique way of identifying the visitors. Or, if it's a local network, maybe you can use tcpdump/libpcap.
How to get the client's MAC address in Vibe
Is there a way to identify a client by MAC address when using the Vibe library? The `NetworkAddress` [structure](https://vibed.org/api/vibe.core.net/NetworkAddress) does not provide such features. Or did I miss something?
Re: length's type.
On Wednesday, 7 February 2024 at 20:08:24 UTC, Gary Chike wrote: On Wednesday, 7 February 2024 at 19:32:56 UTC, Gary Chike wrote: double c = (double)sumArray(a, aLength) / aLength; If I don't cast explicitly: `double c = sumArray(a, aLength) / aLength;` then I will get a similar result as the D code: `Average: 9223372036854773760.00`
Re: length's type.
On Wednesday, 7 February 2024 at 19:32:56 UTC, Gary Chike wrote: On Wednesday, 7 February 2024 at 19:20:12 UTC, Gary Chike wrote: The output wasn't quite right. So I tweaked it a bit: ```c long sumArray(long arr[], size_t size) { long total = 0; for (size_t i = 0; i < size; ++i) { total += arr[i]; } return total; } int main(void) { long a[] = {-5000, 0}; size_t aLength = sizeof(a) / sizeof(a[0]); double c = (double)sumArray(a, aLength) / aLength; printf("Average: %.2lf\n", c); // -2500.00 return 0; } ```
Re: length's type.
On Wednesday, 7 February 2024 at 19:20:12 UTC, Gary Chike wrote: I just had to transcribe this to C just for grins :D ```c #include int sumArray(int arr[], size_t size) { int total = 0; for (size_t i = 0; i < size; ++i) { total += arr[i]; } return total; } int main(void) { long a[] = {-5000, 0}; size_t aLength = sizeof(a) / sizeof(a[0]); double c = (double)sumArray((int*)a, aLength) / aLength; printf("Average: %.2lf\n", c); // -2500 <- correct output return 0; } ```
Re: length's type.
On Sunday, 28 January 2024 at 17:25:49 UTC, mw wrote: See the result here: https://forum.dlang.org/post/cagloplexjfzubncx...@forum.dlang.org I knew this outlandish output had to do with mixing of signed and unsigned types with resulting overflow. But I like the way Anthropic Claude2 explains it: --- The **outlandish output** you're observing in the D code occurs due to an **integer overflow**. Let's break down what's happening: 1. **Sum Calculation**: - The `sum(elem)` function correctly calculates the sum of all elements in the `elem` array, which is **15** (1 + 2 + 3 + 4 + 5). - So far, so good! 2. **Average Calculation**: - Next, you calculate the average of the `a` array using the expression `sum(a) / a.length`. - The `sum(a)` part correctly computes the sum of the elements in `a`, which is **-5000** (since `-5000 + 0 = -5000`). - The issue arises with `a.length`. 3. **Array Length and Unsigned Types**: - In D, the `.length` property of an array returns an unsigned integer (`ulong`), which is an unsigned 64-bit integer. - The length of the `a` array is **2** (since it has two elements: -5000 and 0). 4. **Integer Division**: - When you perform `sum(a) / a.length`, the division is done using integer division rules. - The result of `-5000 / 2` is **-2500** (integer division truncates the decimal part). 5. **Overflow**: - The result of `-2500` is stored in the `c` variable, which is of type `ulong`. - Since `ulong` is an unsigned type, the value wraps around due to overflow. - The actual value stored in `c` is **9223372036854773308**, which is the result of wrapping around from -2500 to a large positive value. 6. **Explanation**: - The overflow occurs because `-2500` (as a signed integer) is equivalent to a large positive value when interpreted as an unsigned 64-bit integer. - The result is not what you intended for the average calculation. To fix this, you can explicitly cast the sum to a signed integer before dividing to ensure correct behavior: ```d auto c = cast(double)(sum(a)) / a.length; ``` This will correctly compute the average and prevent overflow. The output should now match your expectations! The corrected code: ```d module array_length_forum; import std.algorithm; import std.stdio; void main() { auto elem = [1, 2, 3, 4, 5]; writeln(sum(elem)); // 15 <- // The sum of all the elements in the range long[]a = [-5000, 0]; //auto c = sum(a)/a.length; // length() returns 'ulong', inferred as 'ulong' auto c = cast(double)(sum(a)) / a.length; writeln(typeid(c)); // double writeln(c); // -2500 correct output } ```
Re: How to unpack a tuple into multiple variables?
On Wednesday, 7 February 2024 at 13:18:00 UTC, ryuukk_ wrote: There was a DIP for native tuples in D, hopefully we'll get it soon I just wanted to define DIP for newbs since we're in a new users thread. If they look it up, they will see: Dependency Inversion Principle, Dip programming language, etc.. In the D language context, DIP means: [D Improvement Proposal (DIP)](https://github.com/dlang/DIPs) which is a formal document that details a potential feature or enhancement to the language,
Re: std.uni CodepointSet toString
On 08/02/2024 6:11 AM, H. S. Teoh wrote: Do we know why the compiler isn't getting it right? Shouldn't we be fixing it instead of just turning off elision completely? Of course we should. It has been reported multiple times, with different examples trigger the switch symbol error.
Re: std.uni CodepointSet toString
On Thu, Feb 08, 2024 at 05:44:59AM +1300, Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn wrote: > On 08/02/2024 5:36 AM, Carl Sturtivant wrote: [...] > > ``` > > $ dmd --help | grep allinst > > -allinst generate code for all template instantiations > > ``` > > Unclear exactly how -allinst does this, given type parameters, and > > it will affect all of the many templates I use in source with > > CodepointSet. > > > > Can you shed any light? > > Basically the compiler will by default try to elide templates it > thinks isn't used. > > However it doesn't always get this right, which this flag overrides by > turning it off. Do we know why the compiler isn't getting it right? Shouldn't we be fixing it instead of just turning off elision completely? T -- Let's call it an accidental feature. -- Larry Wall
Re: std.uni CodepointSet toString
On 08/02/2024 5:36 AM, Carl Sturtivant wrote: On Wednesday, 7 February 2024 at 11:49:20 UTC, Richard (Rikki) Andrew Cattermole wrote: ``` undefined reference to `_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv' collect2: error: ld returned 1 exit status Error: linker exited with status 1 ``` Use ``-allinst``, that is a template emission bug. ! Thanks, at least I can continue now, though presumably the cure has its own problems. ``` $ dmd --help | grep allinst -allinst generate code for all template instantiations ``` Unclear exactly how -allinst does this, given type parameters, and it will affect all of the many templates I use in source with CodepointSet. Can you shed any light? Basically the compiler will by default try to elide templates it thinks isn't used. However it doesn't always get this right, which this flag overrides by turning it off.
Re: std.uni CodepointSet toString
On Wednesday, 7 February 2024 at 11:49:20 UTC, Richard (Rikki) Andrew Cattermole wrote: ``` undefined reference to `_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv' collect2: error: ld returned 1 exit status Error: linker exited with status 1 ``` Use ``-allinst``, that is a template emission bug. ! Thanks, at least I can continue now, though presumably the cure has its own problems. ``` $ dmd --help | grep allinst -allinst generate code for all template instantiations ``` Unclear exactly how -allinst does this, given type parameters, and it will affect all of the many templates I use in source with CodepointSet. Can you shed any light?
Re: How to unpack a tuple into multiple variables?
On Wednesday, 7 February 2024 at 05:29:45 UTC, Gary Chike wrote: On Wednesday, 7 February 2024 at 01:17:33 UTC, zjh wrote: Officially, there should be an unpacking solution, like ```d //C++ auto[a,b,c]=tuple. ``` Wouldn't that be nice? I hope a clean and terse direct-implementation comes in the near future. :) There was a DIP for native tuples in D, hopefully we'll get it soon
Re: std.uni CodepointSet toString
https://issues.dlang.org/show_bug.cgi?id=20802
Re: std.uni CodepointSet toString
On 07/02/2024 7:27 PM, Carl Sturtivant wrote: Need help working around a linkage problem. ```d import std.uni, std.conv, std.stdio, std.format; void main() { //auto c1 = unicode.InBasic_latin; auto c1 = CodepointSet('a','z'+1); writeln(c1.to!string); writeln(format("%d", c1)); writeln(format("%#x", c1)); writeln(format("%#X", c1)); writefln("%s", c1); } ``` doesn't link, but does link with the commented out CodepointSet instead. Combines code from these examples at the following URLs. https://dlang.org/phobos/std_uni.html#InversionList https://dlang.org/phobos/std_uni.html#.InversionList.toString ``` $ dmd --version DMD64 D Compiler v2.107.0 Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved written by Walter Bright $ dmd cset2.d /usr/bin/ld: cset2.o: in function `_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv': cset2.d:(.text._D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv[_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv]+0x19): undefined reference to `_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv' collect2: error: ld returned 1 exit status Error: linker exited with status 1 ``` Use ``-allinst``, that is a template emission bug.