Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 14 July 2023 at 05:09:58 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:05:27 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

[...]


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller 
who calls my one public function does so by passing the type 
dchar or wchar ? And then we generate the strings from that. 
It might be rather more natural for the caller to pass one of 
the string types into the template. That’s where I get rather 
more confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


If I wrap the whole thing with a template declaration of the 
xchar type, then can I get away with no changes to the 
individual function definitions?


I tried it, wrapped the whole thing in a template definition and 
it compiled, but then my test file which calls Transform( 
someDString ) failed to compile with errors saying it couldn’t 
find the definition of Transform in the other module, which is or 
was public. It’s as if it is no longer public because it’s now 
inside the template.


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 14 July 2023 at 05:05:27 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

[...]


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller who 
calls my one public function does so by passing the type dchar 
or wchar ? And then we generate the strings from that. It 
might be rather more natural for the caller to pass one of the 
string types into the template. That’s where I get rather more 
confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


If I wrap the whole thing with a template declaration of the 
xchar type, then can I get away with no changes to the individual 
function definitions?


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

[...]


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller who 
calls my one public function does so by passing the type dchar 
or wchar ? And then we generate the strings from that. It might 
be rather more natural for the caller to pass one of the string 
types into the template. That’s where I get rather more 
confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

On 7/13/23 8:08 PM, Cecil Ward wrote:

What I really want to do though is provide one single 
templated function with the kind of characters / strings as a 
parameter. I want to have something like

T Transform( T )( T str)
called as
auto result = Transform!(dstring)( dstring str );


```d
T[] Transform(T)(T[] str)
```

Note that you don't have to specify the type when calling:

```d
Transform(someDstring); // infers dchar
```

I’m quite confused as to how to proceed. This is quite a large 
module ~ 2k loc, and I don’t really want to go through and 
change every private function into a templated one. Should I 
just make the whole thing into a giant template containing 
many functions?


If you have more questions, please ask. Some examples of how 
making a template would be painful would be helpful.


-Steve


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller who 
calls my one public function does so by passing the type dchar or 
wchar ? And then we generate the strings from that. It might be 
rather more natural for the caller to pass one of the string 
types into the template. That’s where I get rather more confused, 
say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Re: Giant template - changing types everywhere

2023-07-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/13/23 8:08 PM, Cecil Ward wrote:

What I really want to do though is provide one single templated function 
with the kind of characters / strings as a parameter. I want to have 
something like

T Transform( T )( T str)
called as
auto result = Transform!(dstring)( dstring str );


```d
T[] Transform(T)(T[] str)
```

Note that you don't have to specify the type when calling:

```d
Transform(someDstring); // infers dchar
```

I’m quite confused as to how to proceed. This is quite a large module ~ 
2k loc, and I don’t really want to go through and change every private 
function into a templated one. Should I just make the whole thing into a 
giant template containing many functions?


If you have more questions, please ask. Some examples of how making a 
template would be painful would be helpful.


-Steve


Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

Some advice on a couple of points.

I have been working on a module that works on either dchar / 
dstrings or wchar / wstrings with just two changes of alias 
definitions and a recompile.


What I really want to do though is provide one single templated 
function with the kind of characters / strings as a parameter. I 
want to have something like

T Transform( T )( T str)
called as
auto result = Transform!(dstring)( dstring str );

I only want to have one type as a parameter and derive other 
types from that: xstrings from xchars and I’ll need types of 
xchar arrays that are mutable and immutable.


I’m quite confused as to how to proceed. This is quite a large 
module ~ 2k loc, and I don’t really want to go through and change 
every private function into a templated one. Should I just make 
the whole thing into a giant template containing many functions?


Re: On assigning const to immutable

2023-07-13 Thread FeepingCreature via Digitalmars-d-learn

On Thursday, 13 July 2023 at 11:55:17 UTC, Ki Rill wrote:
Why does the first example `class A` work, but the second one 
with `class B` does not?

```D
class A {
immutable int a;
this(in int a) {
this.a = a;
}
}

class B {
immutable int[] b;
this(in int[] b) {
this.b = b;
}
}

void main()
{
auto a = new A(1);
auto b = new B([1, 2]);
}
```

It implicitly converts `const` to `immutable`, but fails to do 
the same with an array. Is it intentional? Why?


Yep: `immutable` is data that *cannot ever* change. If you could 
convert `int[]` to `immutable int[]`, you could do this:


```
int[] a = [2];
immutable(int)[] b = a;

auto first = b[0];
a[0] = 3;
auto second = b[0];

// Wait, this fails? I thought `b` was immutable.
assert(first == second);
```

Use `array.idup` (immutable dup) to turn `int[]` into `immutable 
int[]`.


And you can convert `int` to `immutable int` because it's a 
"value copy": you cannot mutate the immutable variable through an 
assignment to the original. Generally speaking, only the 
constness of referenced data matters for assignment.


That's why you can assign `string` to `immutable string`, because 
`string` is `immutable(char)[]`: the referenced data is immutable 
in both cases.


Re: On assigning const to immutable

2023-07-13 Thread Ki Rill via Digitalmars-d-learn

On Thursday, 13 July 2023 at 11:55:17 UTC, Ki Rill wrote:
Why does the first example `class A` work, but the second one 
with `class B` does not?

```D
class A {
immutable int a;
this(in int a) {
this.a = a;
}
}

class B {
immutable int[] b;
this(in int[] b) {
this.b = b;
}
}

void main()
{
auto a = new A(1);
auto b = new B([1, 2]);
}
```

It implicitly converts `const` to `immutable`, but fails to do 
the same with an array. Is it intentional? Why?


Oh, is it because the first one is passed by value, but the 
second one is a reference?


On assigning const to immutable

2023-07-13 Thread Ki Rill via Digitalmars-d-learn
Why does the first example `class A` work, but the second one 
with `class B` does not?

```D
class A {
immutable int a;
this(in int a) {
this.a = a;
}
}

class B {
immutable int[] b;
this(in int[] b) {
this.b = b;
}
}

void main()
{
auto a = new A(1);
auto b = new B([1, 2]);
}
```

It implicitly converts `const` to `immutable`, but fails to do 
the same with an array. Is it intentional? Why?


Re: getOverloads order

2023-07-13 Thread Dennis via Digitalmars-d-learn

On Thursday, 13 July 2023 at 11:04:40 UTC, IchorDev wrote:
However, the spec doesn't specify that this is how 
`getOverloads` **must** work; is this guaranteed behaviour but 
the spec simply omits it?


The order is not guaranteed. I don't know why you need a specific 
order, but perhaps you can sort based on `__traits(getLocation)`.


Re: getOverloads order

2023-07-13 Thread IchorDev via Digitalmars-d-learn

On Thursday, 13 July 2023 at 10:53:49 UTC, Dennis wrote:

On Thursday, 13 July 2023 at 08:03:02 UTC, IchorDev wrote:
I've noticed that `__traits(getOverloads)` always returns the 
overloads in lexical order across DMD, LDC, and GDC. Is this 
reliable at all?


No. It depends on the order the compiler analyzes the symbols, 
which is often lexical order, but it can vary based on static 
if, mixin, forward references etc. Here's a counter example:


```D
   void f(int  x);
mixin("void f(float y);");
   void f(char z);
```

Here you get overloads of `f` in the order (x, z, y) instead of 
(x, y, z).


Well that makes sense, but also wouldn't apply to the use-case 
that I was considering, since all the code would be in one mixin. 
However, the spec doesn't specify that this is how `getOverloads` 
**must** work; is this guaranteed behaviour but the spec simply 
omits it?


Re: getOverloads order

2023-07-13 Thread Dennis via Digitalmars-d-learn

On Thursday, 13 July 2023 at 08:03:02 UTC, IchorDev wrote:
I've noticed that `__traits(getOverloads)` always returns the 
overloads in lexical order across DMD, LDC, and GDC. Is this 
reliable at all?


No. It depends on the order the compiler analyzes the symbols, 
which is often lexical order, but it can vary based on static if, 
mixin, forward references etc. Here's a counter example:


```D
   void f(int  x);
mixin("void f(float y);");
   void f(char z);
```

Here you get overloads of `f` in the order (x, z, y) instead of 
(x, y, z).





getOverloads order

2023-07-13 Thread IchorDev via Digitalmars-d-learn
I've noticed that `__traits(getOverloads)` always returns the 
overloads in lexical order across DMD, LDC, and GDC. Is this 
reliable at all?