Proposal: forward compatibility

Denis Koroskin 2korden at gmail.com
Sat Sep 6 03:56:13 PDT 2008


On Fri, 05 Sep 2008 09:57:40 +0400, Jason House  
<jason.james.house at gmail.com> wrote:

> D is an evolving language that does not restrict itself by requiring  
> backwards compatibility. Instead I propose that D adopt forward  
> compatibility...
>
> Specifically, allow D1 code to accept D2 code without doing extra  
> functionality. In D1, his would allow defining constants to be declared  
> with either const or invariant, object invariants to allow parenthesis,   
> and ignoring transitive const elements of type declarations.
>
> The goal is to not change the behavior of existing D1 code, but to  
> accept previously invalid D1 code. This should make the job of  
> maintaining a dual code base much easier.

I came up with the following constness solution:

First, define a Const!(T) template as follows:

// dconst.d
version (D_Version2) {
     public import dconst2;
} else {
     public import dconst1;
}

//dconst1.d
template Const(T)
{
     alias const T Const;
}

//dconst2.d
template Const(T)
{
     alias const(T) Const;
}

Now you can import dconst.d and use the Const!(T) template in your code do  
define constant objects:

import dconst;

void foo(Const!(Bar) bar)
{
     // ...
}

D1 will ignore constness while D2 will preserve and respect it.

Next, you should add const methods into your classes:

class Node
{
     Node next() {
         return _next;
     }

version (D_Version2) {         // You have to duplicate the code
     const Const!(Node) next()  // when return a reference object in
     {                          // D2 anyway, so that's not a big deal.
         return _next;
     }
}

     void next(Node value) {
         _next = value;
     }

version (D_Version2) {        // However, you don't have to for void and
     const int value() {       // value types, and this is quite a pain now
         return _value;        // (especially for long function bodies).
     }
} else {
     int value() {
         return _value;
     }
}

     void value(int value) {
         _value = value;
     }

     private int _value;
     private Node _next;
}

// Test case:
void test(Const!(Node) node)
{
     Const!(Node) nextNode = node.next;
     if (nextNode !is null) {
         writefln(nextNode.value);
     } else {
         writefln(node.value);
     }
}

So here is my suggestion:
1) there should be something like Const template in Phobos/Tango for D1/D2  
compatibility. It is very simple yet clean and it is as easy to write  
Const!(T) as const(T).

2) D1 should swallow and ignore const modifier for member functions so  
that there would be no need for body duplication:

// Same for D1 *and* D2 (although meaning is slightly different)
// no need for version (D_Version2) { ... } else { ... } anymore

class Node {
     int value() const {
         return _value;
     }
}

This would allow much easier D1/D2 migration without massive language  
changes.

What do you think?



More information about the Digitalmars-d mailing list