| |
![Don Allen's Gravatar profile Gravatar of Don Allen](//www.gravatar.com/avatar/2befbcd3f1cf6eaa70b53e878baf1918?d=identicon&s=32) | Posted by Don Allen in reply to Walter Bright | Permalink Reply |
|
Don Allen ![Don Allen's Gravatar profile Gravatar of Don Allen](//www.gravatar.com/avatar/2befbcd3f1cf6eaa70b53e878baf1918?d=identicon&s=80)
Posted in reply to Walter Bright
| 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.
|