A simplification of the RvalueRef idiom

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Nov 22 11:16:56 PST 2016


On 11/22/2016 08:05 AM, Satoshi wrote:

 > Sorry, but D seems to be worse and worse day by day.

I don't have extensive experience with other languages. In fact, the 
only other languages that I can claim proficiency are C and C++. (I also 
know Python just enough to find it incredible how it's used in the 
industry. Let's not get in to that discussion but I really tried and 
failed... in industry... :) ) Given that experience, I still find D a 
very useful tool.

 > This should be resolved by language and not doing it by template 
function.

byRef() is not implicit due to a deliberae design decision. Walter talks 
about why the language lacks ref variables in his recent talk. No, I was 
not there and the audio is lost, so all we have at this point are the 
slides. It's the "Memory Safety and the D Programming Languge" presentation

   http://www.walterbright.com/

Slide 26 starts talking about ref and why it's only for parameters and 
returns.

 > Same thing should be applied for maybe monad and tuples.
 >
 > e.g. When I want to create simple function for drawing
 >
 > void lineTo(auto ref Point point...) {
 > //...
 > }
 >
 > It's easier to call it like:
 > Point p = Point(42, 42);
 >
 > lineTo(p);
 > lineTo(42, 42);

Agreed but it opens the door for bugs. Assuming

struct A { int a; }
struct B { int b; int c; }

void foo(int, int, int);

If foo(1, 2, 3) meant foo(A(1), B(2, 3)) today, it could silently mean 
foo(A(1, 2), B(3)) if one moved one member from one struct to the other.

Then there are other corner cases:

     writeln(1, 2, 3);

Should that print the integers or A(1) and B(2, 3)? It's always better 
to be explicit.

 > lineTo(Point(42, 42)); // this
 > lineTo(Point(42, 42).byRef); // and this is just overhead

I don't agree with those two examples but e.g. I find the following 
cumbersome:

     A[] arr = [ A(1), A(2) ];

 > Sorry, but I want to write fast and safe programs in the fastest
 > possible way

I think in these examples 'fast' and 'safe' don't work together.

 > and writing Point(...) or Point(...).byRef every time is
 > redundant overhead.
 >
 > Like http://pix.toile-libre.org/upload/original/1479816672.png
 >
 >
 > PS: sorry for sarcasm
 > - Satoshi
 >

Agreed but I find solutions like the following acceptable. Yes, function 
names must be different but it's usually fine.

import std.stdio;

struct Point {
     int x;
     int y;
}

struct GraphicsContext {
     static GraphicsContext current() {
         return GraphicsContext();
     }

     void moveTo(Point point) {
         writefln("Moving to %s", point);
     }

     void lineTo(Point point) {
         writefln("Drawing line to %s", point);
     }
}

void goTo(GraphicsContext gc, int x, int y) {
     gc.moveTo(Point(x, y));
}

void drawTo(GraphicsContext gc, int x, int y) {
     gc.lineTo(Point(x, y));
}

void main() {
     auto gc = GraphicsContext.current;
     gc.goTo(70, 70);    // <-- Clean syntax
     gc.drawTo(70, 170);
}

Ali



More information about the Digitalmars-d-learn mailing list