December 13
On 12/13/23 07:31, Max Samukha wrote:
> On Tuesday, 12 December 2023 at 21:48:59 UTC, Timon Gehr wrote:
> 
>> You can pass `Foo.bar` and `Foo.baz` as aliases, but I think currently there is no good way to access a field of an object based on an alias to the field symbol. (Other than `__traits(getMember, self, __traits(identifier, field))`, but that bypasses all the typechecking you might get anyway.)
> 
> `__traits(child, ...)` works sometimes.
> 
> 

Thanks!
December 13

On Wednesday, 13 December 2023 at 06:52:59 UTC, Walter Bright wrote:

>

On 12/12/2023 11:02 AM, Don Allen wrote:

>

Since ceasing my use of D out of concern for the direction and health of the project, I've nonetheless been following these forums and have seen what I consider to be sincere efforts to improve things.

Welcome back!
[snip]

>

But I'm failing to understand why the problem exists in the first place.

The misunderstanding appears to be the assumption that field is resolved inside the definition of bletch. It is not, it is resolved at the point of instantiation of the template bletch.

Not quite. I do understand the above, because it is evident from the behavior I am seeing. What I'm puzzled by is why template processing behaves this way, requiring that the symbol be defined at the point where it is passed (by symbol), rather than where it is used, which is the place where having a valid definition really matters.

More in my reply to your second message.

December 13
On Wednesday, 13 December 2023 at 07:05:10 UTC, Walter Bright wrote:
> On 12/12/2023 7:37 PM, Don Allen wrote:
>> ````
>> import std.stdio;
>> 
>> struct Foo {
>>      int bar;
>>      int baz;
>> }
>> 
>> void bletch(alias field)(Foo s, int n) {
>>      field = n;
>>      writeln("%d", field);
>> }
>> 
>> int main(string[] args)
>> {
>>      Foo s;
>>      bletch!(s.bar)(s, 5);
>>      bletch!(s.baz)(s, 6);
>>      return 0;
>> }
>> 
>> ````
>> 
>> Same complaints from the compiler:
>> ````
>> [nix-shell:~/Software/d_tests]$ dmd test.d
>> test.d(16): Error: calling non-static function `bletch` requires an instance of type `Foo`
>> test.d(17): Error: calling non-static function `bletch` requires an instance of type `Foo`
>> (dmd-2.106.0)
>> ````
>
> The trouble here is that `s` is a local variable of `main`. The `bletch!(s.bar)` is passing `s` not by reference, and not by value, but by symbol. Inside the body of `bletch`, there is no way that it can get at the runtime value of the symbol `main.s`. Hence, the complaint that `bletch` requires a way to get at the instance of `main.s`.

Note that in the message to which you are replying, I sent two attempts to resolve this. In the first, having seen the compilation errors I got, I came to the same conclusion you describe above. In the second, I added a 'Foo s' parameter and passed main.s to it in the two calls to bletch, which I thought would fix this problem, since now there is an s of type Foo defined in the scope of the field references. To my surprise, it didn't.

>
> D has 3 ways of passing arguments:
>
> 1. by value
> 2. by pointer (aka by reference)
> 3. by symbol (aka by alias)

I assume this is much like passing a quoted symbol in Lisp/Scheme, where the receiving function gets the symbol, not its value, e.g., (foo 'bar)? Your comment below about C macros and passing symbols by alias suggests that is true.

>
> Passing by symbol is strictly a compile time phenomenon, it cannot be a runtime one.

Understood.

>
> C++'s method of passing by alias is called a "template template parameter", and is limited to passing the names of template symbols. D generalized it so any symbol could be passed that way.
>
> C macros can have arguments, and they are always passed by name, which is roughly similar to by alias. They are also a compile-time phenomenon, not a runtime one.


December 13
On Wednesday, 13 December 2023 at 15:46:12 UTC, Don Allen wrote:
> On Wednesday, 13 December 2023 at 07:05:10 UTC, Walter Bright wrote:
>> On 12/12/2023 7:37 PM, Don Allen wrote:
>>> ````
>>> import std.stdio;
>>> 
>>> struct Foo {
>>>      int bar;
>>>      int baz;
>>> }
>>> 
>>> void bletch(alias field)(Foo s, int n) {
>>>      field = n;
>>>      writeln("%d", field);
>>> }
>>> 
>>> int main(string[] args)
>>> {
>>>      Foo s;
>>>      bletch!(s.bar)(s, 5);
>>>      bletch!(s.baz)(s, 6);
>>>      return 0;
>>> }
>>> 
>>> ````
>>> 
>>> Same complaints from the compiler:
>>> ````
>>> [nix-shell:~/Software/d_tests]$ dmd test.d
>>> test.d(16): Error: calling non-static function `bletch` requires an instance of type `Foo`
>>> test.d(17): Error: calling non-static function `bletch` requires an instance of type `Foo`
>>> (dmd-2.106.0)
>>> ````
>>
>> The trouble here is that `s` is a local variable of `main`. The `bletch!(s.bar)` is passing `s` not by reference, and not by value, but by symbol. Inside the body of `bletch`, there is no way that it can get at the runtime value of the symbol `main.s`. Hence, the complaint that `bletch` requires a way to get at the instance of `main.s`.
>
> Note that in the message to which you are replying, I sent two attempts to resolve this. In the first, having seen the compilation errors I got, I came to the same conclusion you describe above. In the second, I added a 'Foo s' parameter and passed main.s to it in the two calls to bletch, which I thought would fix this problem, since now there is an s of type Foo defined in the scope of the field references. To my surprise, it didn't.

I'm going to add a guess here: the field references passed by alias to bletch are to main.s.bar and main.s.baz, so passing 's' to bletch at runtime doesn't help, since the field references are not to bletch.s.bar, etc.
December 13
On 12/13/2023 7:46 AM, Don Allen wrote:
> Note that in the message to which you are replying, I sent two attempts to resolve this. In the first, having seen the compilation errors I got, I came to the same conclusion you describe above. In the second, I added a 'Foo s' parameter and passed main.s to it in the two calls to bletch, which I thought would fix this problem, since now there is an s of type Foo defined in the scope of the field references. To my surprise, it didn't.

Yes, but the compiler does not have a way to semantically connect the two.

December 13
On 12/13/2023 7:55 AM, Don Allen wrote:
> I'm going to add a guess here: the field references passed by alias to bletch are to main.s.bar and main.s.baz, so passing 's' to bletch at runtime doesn't help, since the field references are not to bletch.s.bar, etc.

Right.
December 13

On Tuesday, 12 December 2023 at 19:02:11 UTC, Don Allen wrote:

> >

__traits, __traits, __traits, __traits,

you should use a mixin instead of traits that use strings to store references.
The issue with either is that strings in different contexts may not keep referencing the same thing. The mixin will just be smaller.

void bletch(string field)(ref Foo s,int x){
    mixin("s."~field~"=x;");
}

if you want to be idiomatic you should figure out how to make an alias survive the compiler warnings for your use case and given I started an argument I suggest this is better and least prone to failure

void bletch(alias f, string s)(int x){
    mixin("f."~s)= x;
}
bletch!(s,"bar")(2);
December 13
On Wednesday, 13 December 2023 at 17:59:14 UTC, Walter Bright wrote:
> On 12/13/2023 7:55 AM, Don Allen wrote:
>> I'm going to add a guess here: the field references passed by alias to bletch are to main.s.bar and main.s.baz, so passing 's' to bletch at runtime doesn't help, since the field references are not to bletch.s.bar, etc.
>
> Right.

Walter -- I wanted to thank you for your responses. They have helped me to better understand what's happening. Perhaps I'm thinking of templates too much as a macro pre-processor; I clearly need to spend more time with template documentation.
December 14
On 12/13/2023 2:31 PM, Don Allen wrote:
> Walter -- I wanted to thank you for your responses. They have helped me to better understand what's happening. Perhaps I'm thinking of templates too much as a macro pre-processor; I clearly need to spend more time with template documentation.

You're welcome!
1 2
Next ›   Last »