rvalue types

Steven Schveighoffer schveiguy at yahoo.com
Mon Mar 12 19:13:35 UTC 2018


On 3/12/18 2:56 PM, Simen Kjærås wrote:
>> I think this would solve the issue, and help with the property debate, 
>> but it would have to trim out all the intermediary stuff. I wonder 
>> instead of types which you don't want to exist anyway, you could find 
>> a better way to formulate this.
> 
> It's easy to imagine some patchwork solutions - going back to the 
> property discussion I mentioned that allowing alias this and operator 
> overloads on named mixins would enable properties to work as if they 
> were implemented with rvalue types. In the same vein, we could imagine a 
> solution for chaining operators:
> 
> struct BigInt {
>      BigInt opChain(string[] ops, T...)(T args)
>      if (allSatisfy!(isBigInt, T) && ops == ["^^", "%"])
>      {
>          return powMod(this, args);
>      }
> }

Yeah, what you need is some sort of access to the entire expression. I 
don't think it needs to be limited to operators.

What I don't like about your proposal is that you have to maintain 
(essentially) the AST yourself, in a type that never really should 
exist. Too bad the compiler can't just give you the AST and let you 
figure it out, but I think that's probably not ever going to happen.

Ideally, your call will lower to a single call to powMod, and all the 
cruft around it disappears. But it seems like every time stuff like this 
is tried, it leaves behind artifacts that suck.

> This would take care of those two cases, but don't offer a solution to 
> the WidgetBuilder example. It might be possible to find a similar 
> one-off solution there, but I'd rather have a more general solution that 
> might be useful in cases I haven't yet thought of.

A similar thing I did once in C++ for a logger is to use the destructor 
of an essentially rvalue type to actually log the information. It looked 
something like this:

log << value1 << " " << value2;

What log did is, based on the logging level, it would return either 
something that did nothing, or something that built up a single 
std::string, and then in the destructor, actually logged the data to 
something. This prevented partial messages from being logged (the 
destructor would lock a global mutex for this).

It's a similar thing to your widget builder in that the end of the 
statement is what triggers all the stuff to happen.

Unfortunately, we can't hook the destructor, but that would be the best 
place to do this. Hm... I wonder if we could make a return type for the 
destructor, and that would be the result of the expression?

-Steve


More information about the Digitalmars-d mailing list