On 08/14/2015 06:17 AM, TheHamster wrote:
For class types, a special operator is defined to return the class
object for method calls rather than the return value from the call
itself. The use of the operator places the return types in special
variables to be accessed easily. The operator is simply a syntax helper
and is along the lines of UFCS.

e.g.,

class myClass
{
      Do(int x) { return x + 2; }

}

auto myObj = new myClass();
assert(@@myObj.Do(3).Do(4).Do(5) == 7);

Of course, such a silly example is not very helpful but demonstrates the
concept.

To make such a syntax work well, I believe one then needs a further
operator to access the last return value.

e.g.,

assert(@@myObj.Do(3).Do(@).Do(@2) == 9);

Where the same symbol is used for there return value placeholders and
indices are used to access nested calls return value with @ defaulting
to @1.

Essentially such syntax allows for easily doing nested calls.

The only down side is that the operator could only be used on one method
call at a type in the nesting. (or multiple or parameritized operators
would be required)

Obviously @ would not be the symbol of choice.



Close enough? :o)

import std.typecons; // (workaround for lack of seq return)

class MyClass{
  int do_(int x){ return x+2; }
}

void main(){
  auto myObj=new MyClass();
  assert(op(myObj).do_(3).do_(4).do_(5).val==7);
  assert(op(myObj).do_(3).do_[$[0]].do_[$[1]].val==9);
}

alias Seq(T...)=T;

struct Op(T,S...){
  T wrap;
  S vals;
  static if(vals.length) alias val=vals[$-1];

  template opDispatch(string s){
    auto opDispatch(A...)(A args){
      static struct Wrap{
        Op* outer; // (workaround)
        auto opCall(B...)(B args){
          static if(is(typeof(mixin(`outer.wrap.`~s)(args))==void)){
            mixin(`outer.wrap.`~s)(args);
            return Op!(T,S,void[0])(outer.wrap,outer.vals,[]);
          }else{
            auto cur=mixin(`outer.wrap.`~s)(args);
            return Op!(T,S,typeof(cur))(outer.wrap,outer.vals,cur);
          }
        }
        auto opIndex(T...)(T args){ return opCall(args); }
        @property opDollar(){ return tuple(outer.vals); }
      }
      Wrap w;
      w.outer=&this;
      static if(args.length) return w(args);
      else return w;
    }
  }
}

auto op(T)(T t){
  return Op!T(t);
}

Reply via email to