rvalue types
Shachar Shemesh
shachar at weka.io
Mon Mar 12 14:19:17 UTC 2018
I'll just point out that the C++ name for this is "Proxy classes".
Maybe, for the sake of reducing confusion, it might be a good idea to
adopt that.
Shachar
On 12/03/18 15:59, Simen Kjærås 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.
>
> 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.
>
> The problem with such a set of types, of course, is that
> `typeof(functionThatReturnsRvalueType())` will be different from
> `typeof((){ auto t = functionThatReturnsRvalueType(); return t;}())`,
> and that bleeds into documentation. It may also be confusing that
> `return a ^^ b % c;` is much faster than `auto tmp = a ^^ b; return tmp
> % c;`.
>
> An example of how they would work:
>
> struct ModularExponentiationTemporary {
> BigInt lhs, rhs;
>
> @rvalue // Or however one would mark it as such.
> alias get this;
>
> BigInt get() {
> return pow(lhs, rhs);
> }
>
> BigInt opBinaryRight(string op : "%")(BigInt mod) {
> return modularPow(lhs, rhs, mod);
> }
> }
>
> unittest {
> BigInt b = 4;
> BigInt e = 13
> BigInt m = 497;
>
> // b ^^ e returns a ModularExponentiationTemporary,
> // and its opBinaryRight() is immediately invoked.
> auto fast = b ^^ e % m;
>
> assert(is(typeof(fast) == BigInt));
> assert(fast== 445);
>
> // b ^^ e returns a ModularExponentiationTemporary,
> // and its get() method is immediately invoked.
> auto slowTmp = b ^^ e;
> auto slow = slowTmp % m;
>
> assert(is(typeof(slowTmp == t) == BigInt));
> assert(is(typeof(slow) == BigInt));
> assert(slow == 445);
> }
>
> Is this an interesting concept? Are there other use cases I haven't
> covered? Can this be done with existing language features? Are there
> problems I haven't foreseen?
>
> --
> Simen
>
> [0]: https://forum.dlang.org/post/mqveusvzkmkshrzwsgjy@forum.dlang.org
More information about the Digitalmars-d
mailing list