rvalue types

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Mar 12 16:51:06 UTC 2018


On Mon, Mar 12, 2018 at 01:59:59PM +0000, Simen Kjærås via Digitalmars-d wrote:
> There's been a discussion[0] over in D.learn about a library-only
> implementation of properties. One of the ideas mentioned there is
> rvalue types - types that automatically decay into a different type
> when passed to a function or assigned to a variable. They are useful
> for property wrappers like this, and when you want to perform a series
> of operations on something before performing some final step.
> 
> An example of the latter is `a ^^ b % c` for BigInts, where the naïve
> way would be horribly inefficient, and there's a much better way of
> doing it, which requires more knowledge of the operations involved. If
> `a ^^ b` returned an rvalue type that either decays to a regular
> BigInt or acts as the LHS in `tmp % c`, it would have the necessary
> information and be able to do the right thing.

I suspect the current language already supports this, or is 90% of the
way there and just needs some small concessions on syntax.  For example,
today you can already make opBinary() return something other than the
parent type, and use alias this to make it decay to the parent type. Of
course, this requires the caller to write `BigInt x = a^^b % c` rather
than `auto x = a^^b % c`, but I think that's a minor inconvenience.


> Another use case is a chain of operations, e.g. fluent initialization:
> 
> Widget.create()
>     .width(35)
>     .height(960)
>     .data(readData())
>     .Done();
> 
> Where in current D the Done() step needs to be explicit, an rvalue
> type would automatically call Done when the result is assigned to a
> variable or passed to a function.
[...]

Not necessarily, if you make the concession that the caller has to
explicitly assign the result to a Widget, say:

	Widget w = Widget.create()	// returns WidgetBuilder, say
		.width(35)		// modifies WidgetBuilder
		.height(960)		// ditto
		.data(readData());	// implicitly converts to Widget

You could just have WidgetBuilder alias this itself to a widget:

	struct WidgetBuilder {
		... // stuff
		@property Widget done() { return new Widget(...); }
		alias done this;
	}

Then it will work the way you want.


T

-- 
You have to expect the unexpected. -- RL


More information about the Digitalmars-d mailing list