Re: How to unpack a tuple into multiple variables?

2024-02-07 Thread Menjanahary R. R. via Digitalmars-d-learn

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.

2024-02-07 Thread mw via Digitalmars-d-learn

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.

2024-02-07 Thread Kevin Bailey via Digitalmars-d-learn

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

2024-02-07 Thread Mengu via Digitalmars-d-learn
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

2024-02-07 Thread Alexander Zhirov via Digitalmars-d-learn
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.

2024-02-07 Thread Gary Chike via Digitalmars-d-learn

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.

2024-02-07 Thread Gary Chike via Digitalmars-d-learn

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.

2024-02-07 Thread Gary Chike via Digitalmars-d-learn

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.

2024-02-07 Thread Gary Chike via Digitalmars-d-learn

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?

2024-02-07 Thread Gary Chike via Digitalmars-d-learn

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

2024-02-07 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

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

2024-02-07 Thread H. S. Teoh via Digitalmars-d-learn
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

2024-02-07 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

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

2024-02-07 Thread Carl Sturtivant via Digitalmars-d-learn
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?

2024-02-07 Thread ryuukk_ via Digitalmars-d-learn

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

2024-02-07 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

https://issues.dlang.org/show_bug.cgi?id=20802


Re: std.uni CodepointSet toString

2024-02-07 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

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.