Added copy constructors to "Programming in D"
    Ali Çehreli 
    acehreli at yahoo.com
       
    Thu Feb 10 02:39:11 UTC 2022
    
    
  
On 2/9/22 18:11, Meta wrote:
 > Why do we even bother with `in` when we can do:
 >
 > alias In(T) = const scope T;
 >
 > void test(In!int n) {
 >      pragma(msg, typeof(n));
 > }
 >
 > ?
 >
 > onlineapp.d(3): Deprecation: storage class `scope` has no effect in type
 > aliases
 > const(int)
 >
 > ...oh
I didn't know that but 'in' is underrated. There is heavy mental load on 
deciding parameter types:
// Silly const:
void foo(const(int));
// Too much information to the user (why
// do they need to know that I will mutate the parameter):
void foo(int);
// When I know that copying is expensive
// (which excludes rvalues; oops):
void foo(ref const(ExpensiveToCopy));
// When I know that the type is non-copyable,
// I have to use 'ref':
void foo(ref const(NonCopyable));
What if foo is a template? ref or const or by-value? Or inout? Always or 
sometimes?
Enough already! :)
All I want to say is "I want to use this parameter as input." I don't 
care if its rvalue or expensive to copy or impossible to copy. I will 
define it as 'ref' if that's what I want but I shouldn't be thinking 
about any of the above for function inputs.
I am happy to raise awareness of the new 'in':
   https://dlang.org/spec/function.html#in-params
'in' allows passing rvalues by ref! 'in' eliminates unwanted 
side-effects just because a function wants to use an object. 'in' passes 
non-copyable types by reference. Wow! That's engineering to my ears. :)
Having said that, there is one thing that bothers me with 'in' or 
'const'. Let's assume I want to mutate a copy of the parameter:
void foo(in int i) {
   ++i;    // ERROR
}
So I must make a copy:
   auto j = i;
   ++j;    // ERROR
Because 'auto' is too safe and takes 'const'. One more try:
   int j = i;
   ++j;
Or perhaps in some generic code:
   import std.traits : Unqual;
   Unqual!(typeof(i)) j = i;
   ++j;
Ok, fine.
One more thing remains: Although 'i' may be the most logical name for 
the parameter, I cannot name 'j' as 'i' so I can mangle the parameter 
name just to prevent using 'i' in the function by accident:
void foo(in int i_);
That's not good because it changes what my callers see of my function.
I can use 'i_' in the body (instead of 'j') but then I am open to the 
same mistake of using 'i' instead of 'i_' in the body. (Obviously not 
when mutating but when actually using.)
Yeah, that issue bugs me a little.
Ali
    
    
More information about the Digitalmars-d-announce
mailing list