突发奇想

看到D语言的opAssign即赋值操作符,突然想是不是能实现下面这个功能呢?以D语法写出:

auto x = new Variable;
auto y = new Variable;

// x = 10; y = 5;
x + 5 = y * 3;
x / y = 2;

简单的方程组,是否可以自动求出x和y值?

从我学习过的几种语言来考察,哪些语言可以支持这种语法呢?

1、C++

C++支持赋值操作符,不过如果我把x+5写成5+x,就必须用到全局运算符重载。要支持其它类型和Variable类型、Variable类型和其它类型、Variable和Variable的运算符重载,但不应该去支持其它类型之间的运算符。这个比较难办,理论上应该是这么写:
template <class T>
ResultType operator + (T v, Variable v1){
  return ResultType();
}

template <class T>
ResultType operator + (Variable v, T v1){
  return ResultType();
}

ResultType operator + (Variable v, Variable v1){
  return ResultType();
}

不过这如果是Variable和Variable运算,3种都可以匹配,所以会出现无法决议的错误。去掉最后一种形式,前2种还是无法决议,唯一能共存的是这2种:
template <class T, class U>
ResultType operator + (T v, U v1){
  return ResultType();
}

ResultType operator + (Variable v, Variable v1){
  return ResultType();
}

可以通过了,不过前一种根本没有约束,所以后面这个没多大意义,我们要的是对类型进行约束,这下又要扯远了。简单的做法是在函数体中加一个静态检查,检查2个参数中有一个类型必须是Variable,这个比较好做:
template <class T, class U>
class CheckMustHaveAVariableType{
  STATIC_ASSERT<false> muse_have_a_variable_type;
}

template <class T>
class CheckMustHaveAVariableType<Variable, T>{
}

template <class T>
class CheckMustHaveAVariableType<T, Variable>{
}

template <class T, class U>
ResultType operator + (T v, U v1){
  typedef CheckMustHaveAVariableType<T,U> SafeTypes;
  return ResultType();
}

可以检查并禁止不是variable类型的参数运算,不过这也是破坏性的,全局泛型实现,还让不让别人活。。。

考虑这么些因素,感觉用C++实现这个语法还是会遇到些困难,放弃。

C++实现也有些好处,比如上面的Variable以及运算结果类型只要实现了“=”运算符,那么完成这整个语句:
x + 5 = y * 3;
x / y = 2;


运算会产生临时变量,只要在它们构造或析构或赋值时运算的结果树存入某一变量即可。暂时没完整思考,感觉应该是可行的。

2、D语言

D语言没有全局运算符重载,不过它可以在类中重载,而且有left-side和right-side2种,也就满足了Variable类型在运算符左边和右边的语法实现。

class Variable{
  public:
  Combine opAdd(T)(T v){
    return null;
  }

  Combine opAdd_r(T)(T v){
    return null;
  }
}

打住!做点测试:
Variable x = new Variable;
Variable y = new Variable;
x + 5;
5 + x;
x + y;   // <=====

坏了,打标记的这一行无法编译,因为2个运算符重载都匹配。在python中,__add__和__radd__是可以同时存在的,匹配规则是如果有__add__,则调用__add__,否则调用__radd__。D语言没有实现它,而且强类型的爱好者可能更希望它这样。

另一个问题:
x + 5 = y * 3;

由于 x+5的结果是个右值,所以它连=运算符也不让调用了。错误提示如下:
Error: (x) + 5 is not an lvalue


放弃。

3、python

__add__和__radd__满足要求了,问题在于它也不让上面这个赋值通过:
SyntaxError: can't assign to operator


4、ruby

它没有left-side和right-side的运算符重载,不过ruby里面所有类型都是可以扩展的,所以实现上应该没有问题。不过在它里面写上面这个式子一样有问题:
a + b = 3
#被解释为:
a + (b = 3)

x + 5 = y * 3
#被解释为:
x + (5 = y * 3)
#语法错误


看来遇到麻烦了,唯一可以在语法上通过的是C++,有空再看看。。

你可能感兴趣的:(C++,c,python,Ruby,D语言)