April 02, 2008
"Steven Schveighoffer" <schveiguy@yahoo.com> wrote in message news:fsu80i$2pj1$1@digitalmars.com...
> "Craig Black" wrote
>> One idea that I had recently was that the const keyword could provide logical const (for developers) and the invariant keyword could provide transitive const (for the compiler).
>
> Making D not support logical invariant does not make it impossible to have logically invariant functions as I have already demonstrated.  If there is a way to legally implement logical invariant, then I think the language should not impose that restriction.  Imposing a restriction that you cannot have logical invariance is just going to be a nuisance for those who want to do it, and it does not provide any benefits for compiler optimization.

You are confident that Walter wrong about the benefits of transitivity. Honestly, I don't understand it deeply enough to agree or disagree.  I do think the const system should be easier for developers and having logical const will give us that.  If we get logical invariance too, then that's fine with me.  I was proposing a compromise since the D community and Walter each seem to have such strong opinions on the matter.

> The only place where it is important to ban logical const is for pure functions as far as I can tell, and that can be dealt with when pure functions are introduced.

I'd wager that Andrei/Walter have probably though about this quite a lot, and concluded that invariant transitivity was somehow the best solution to it.
Still, they could be wrong, and it's worth discussing, since even the smartest of us gets their wires crossed once in a while.

-Craig 

April 02, 2008
Craig Black wrote:
> Walter/Andrei are under the impression that transitive const is necessary for multiprogramming, but they have not presented a detailed explanation about why it is necessary.  It sounds like a more detailed explanation of the merits of transitive const from Walter/Andrei would help here.

That'll all come when we get the details worked out on how D will support multiprogramming. It's an ongoing effort, and current events are leading us to believe that this is getting extremely important.
April 02, 2008
Walter Bright wrote:
> Craig Black wrote:
>> Walter/Andrei are under the impression that transitive const is necessary for multiprogramming, but they have not presented a detailed explanation about why it is necessary.  It sounds like a more detailed explanation of the merits of transitive const from Walter/Andrei would help here.
> 
> That'll all come when we get the details worked out on how D will support multiprogramming. It's an ongoing effort, and current events are leading us to believe that this is getting extremely important.

If the ultimate goal is support for multiprogramming, then shouldn't the detailed design work should start *there*, with how to do great multiprogramming?  Rather than with const.

Not saying that you guys have done this, but I know from my own experience doing research that it's easy to get hung up trying to solve a tough but solvable problem that seems relevant for getting from A to B, only to realize in the end that it was not as relevant as I thought.

--bb
April 02, 2008
Bill Baxter wrote:
> If the ultimate goal is support for multiprogramming, then shouldn't the detailed design work should start *there*, with how to do great multiprogramming?  Rather than with const.
> 
> Not saying that you guys have done this, but I know from my own experience doing research that it's easy to get hung up trying to solve a tough but solvable problem that seems relevant for getting from A to B, only to realize in the end that it was not as relevant as I thought.

I think it is fairly obvious that transitive invariant (and const) is key to multiprogramming. The transitive closure of the state of everything reachable through an object is part of the state of that object, and all the troubles with multiprogramming stem from the state of an object changing asynchronously.
April 02, 2008
Walter Bright wrote:

> Bill Baxter wrote:
>> If the ultimate goal is support for multiprogramming, then shouldn't the detailed design work should start *there*, with how to do great multiprogramming?  Rather than with const.
>> 
>> Not saying that you guys have done this, but I know from my own experience doing research that it's easy to get hung up trying to solve a tough but solvable problem that seems relevant for getting from A to B, only to realize in the end that it was not as relevant as I thought.
> 
> I think it is fairly obvious that transitive invariant (and const) is key to multiprogramming. The transitive closure of the state of everything reachable through an object is part of the state of that object, and all the troubles with multiprogramming stem from the state of an object changing asynchronously.

And how do global variables fit into that?  Technically, they're always reachable and never inherit const.
April 02, 2008
Jason House wrote:
> Walter Bright wrote:
> And how do global variables fit into that?  Technically, they're always
> reachable and never inherit const.

If the global variables are not invariant, then you're going to have synchronization problems when accessing them from multiple threads. If they are invariant, you cannot have sync problems.
April 02, 2008
Bill Baxter wrote:
> So hmm, it does seem conceivable to me that the compiler could enforce "pure" without needing any explicit const notation.

Deducing purity doesn't help when one wants to specify an interface. It would only be useful in verifying conformance to the interface.
April 02, 2008
On 02/04/2008, Jason House <jason.james.house@gmail.com> wrote:
> And how do global variables fit into that?  Technically, they're always
>  reachable and never inherit const.

Global variables will /not/ be reachable from a pure function. Example:

    int g;

    pure int f()
    {
        return g; /*ERROR*/
    }

The above will not compile, because global variables won't be available to pure functions.

So the answer is, you will still be able to use global variables, but only in non-pure functions. I've always thought that using global variables is a very bad idea anyway, and they certainly can cause problems for multithreading.
April 02, 2008
On 02/04/2008, Janice Caron <caron800@googlemail.com> wrote:
> Global variables will /not/ be reachable from a pure function. Example:
>
>     int g;
>
>     pure int f()
>     {
>         return g; /*ERROR*/
>     }
>
>  The above will not compile, because global variables won't be
>  available to pure functions.

However, I suspect that the following will be OK.

    enum g = 42;

    pure int f()
    {
        return g;
    }

I'm only guessing here - I don't have any inside knowledge. But it seems reasonable to me that global compile-time constants declared outside the function ought to be available inside it. I guess we'll just have to wait and see.

But global variables - no.
April 02, 2008
On 01/04/2008, Craig Black <craigblack2@cox.net> wrote:
> Walter/Andrei are under the impression that transitive const is necessary
>  for multiprogramming, but they have not presented a detailed explanation
>  about why it is necessary.

It hardly needs a detailed explanation. In fact it's trivial to understand. Watch:

    // in C++
    void f(const C &c)
    {
        c.some.deeply.nested.but.reachable.var++;
    }

In a multithreaded program, a thread switch may occur between the read and the write of the read/write cycle that is ++. If that happens, you're screwed.

    // in D
    void f(const C c)
    {
        c.some.deeply.nested.but.reachable.var++; /*ERROR*/
    }

In D, such dodgy code just won't compile.


>  It sounds like a more detailed explanation of
>  the merits of transitive const from Walter/Andrei would help here.

Was that not detailed enough for you? It's not rocket science.


>  One idea that I had recently was that the const keyword could provide
>  logical const

Logical const is mutually incompatible with transitive const. If an object is transitively const, then it means "I promise not to modify anything reachable through this pointer", wheras if an object is logically const, it means that some bits exists which are reachable throgh the pointer, but which you are allowed to modify. The two promises:

(1) "I promise not to modify anything reachable through this pointer"
(transitive const)

(2) "I promise not to modify anything reachable through this pointer,
except - oh wait! I might modify these bits here" (logical const)

cannot both be simultaneously true. Multiprogramming needs transitive const. It's that simple.