Re: D style - member functions

2023-04-26 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 26 April 2023 at 18:24:08 UTC, DLearner wrote:

Consider:
```
struct S1 {
   int A;
   int B;
   int foo() {
  return(A+B);
   }
}

struct S2 {
   int A;
   int B;
}
int fnAddS2(S2 X) {
   return (X.A + X.B);
}

void main() {
   import std.stdio : writeln;

   S1 Var1 = S1(1, 2);
   writeln("Total Var1 = ", Var1.foo());

   S2 Var2 = S2(1, 2);
   writeln("Total Var2 = ", fnAddS2(Var2));

   return;
}
```

Of the two ways shown of producing the total from the same 
underlying structure, which is the better style?



To make both version really equivalent you should rather write

int fnAddS2(ref S2 X) {
return (X.A + X.B);
}

the `this` for the member functions is a reference as obviously 
you want to eventually mutate the members and not their copy. 
What happened in your `fnAddS2` is that the whole stuff was 
blitted and mutation of the members would have no effect on the 
argument used in the call.


Further, do we care about the situation where there are many 
variables of type 'S', which presumably means the function code 
generated from S1 gets duplicated many times, but not so with 
S2?


Your presumption is wrong. The code generated for a function is 
not regenerated per instance. One version is enough to handle all 
the instances as the instance is itself a parameter of the 
function. What is happening for `foo()`, i.e the member function, 
is that there is an hidden parameter. Depending on the language 
the way the hidden argument is read might be slightly different 
but you really should consider that


struct S1 {
int A;
int B;
int foo() {
   return(A+B);
}
}

is like

struct S1 {
int A;
int B;
static int foo(ref S1 that) {
   return(that.A+that.B);
}
}

or

struct S1 {
int A;
int B;
}

int foo(ref S1 that) {
   return(that.A+that.B);
}

One problem of the hidden parameter is that for example

int foo(const ref S1 that) {
   return(that.A+that.B);
}

cannot be expressed (at first glance)... how to qualify `const` 
something that is hidden ? It's actually possible using a member 
function attribute:


struct S1 {
int A;
int B;
int foo() const /*const is for the hidden parameter*/ {
   return(A+B);
}
}



Re: D style - member functions

2023-04-26 Thread Jacob Shtokolov via Digitalmars-d-learn

On Wednesday, 26 April 2023 at 18:24:08 UTC, DLearner wrote:

Consider:
```
struct S1 {
   int A;
   int B;
   int foo() {
  return(A+B);
   }
}

struct S2 {
   int A;
   int B;
}
int fnAddS2(S2 X) {
   return (X.A + X.B);
}


There are scenarios that won't let you use the second form, e.g. 
putting your struct under the `with()` statement:


```d
with (S1) {
auto sum = foo(); // Works correctly
}

with (S2) {
auto sum = foo(); // Error: function foo(S s) is not callable 
using argument types ()

}
```

In this case, the first option will be better. But there are no 
real "best practices" defined AFAIK.


However, the second form let you generalize the pattern by using 
template declaration:


```d
int fnAdd(T)(T v) {
return (v.A + v.B); // Doesn't matter what type is this if it 
has both members A and B

}

s1.fnAdd();
s2.fnAdd();
```


Re: D style - member functions

2023-04-26 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Apr 26, 2023 at 06:24:08PM +, DLearner via Digitalmars-d-learn 
wrote:
> Consider:
> ```
> struct S1 {
>int A;
>int B;
>int foo() {
>   return(A+B);
>}
> }
> 
> struct S2 {
>int A;
>int B;
> }
> int fnAddS2(S2 X) {
>return (X.A + X.B);
> }
> 
> void main() {
>import std.stdio : writeln;
> 
>S1 Var1 = S1(1, 2);
>writeln("Total Var1 = ", Var1.foo());
> 
>S2 Var2 = S2(1, 2);
>writeln("Total Var2 = ", fnAddS2(Var2));
> 
>return;
> }
> ```
> 
> Of the two ways shown of producing the total from the same underlying
> structure, which is the better style?

Either way works, it doesn't really matter.  The slight difference is
that the member function is preferred when resolving a symbol, so if
there's a module-level function called `foo` that takes S1 as a
parameter, the member function would be called instead.


> Further, do we care about the situation where there are many variables
> of type 'S', which presumably means the function code generated from
> S1 gets duplicated many times, but not so with S2?

This is false. Member functions are only instantiated once in the entire
program, not with every instance of S.

(Template functions may be instantiated more than once, but that's still
only once per combination of template arguments, not once per instance
of the enclosing type.)


T

-- 
MAS = Mana Ada Sistem?


D style - member functions

2023-04-26 Thread DLearner via Digitalmars-d-learn

Consider:
```
struct S1 {
   int A;
   int B;
   int foo() {
  return(A+B);
   }
}

struct S2 {
   int A;
   int B;
}
int fnAddS2(S2 X) {
   return (X.A + X.B);
}

void main() {
   import std.stdio : writeln;

   S1 Var1 = S1(1, 2);
   writeln("Total Var1 = ", Var1.foo());

   S2 Var2 = S2(1, 2);
   writeln("Total Var2 = ", fnAddS2(Var2));

   return;
}
```

Of the two ways shown of producing the total from the same 
underlying structure, which is the better style?


Further, do we care about the situation where there are many 
variables of type 'S', which presumably means the function code 
generated from S1 gets duplicated many times, but not so with S2?