View mode: basic / threaded / horizontal-split · Log in · Help
September 10, 2007
Re: Const sucks
Derek Parnell wrote:
>> o  const and invariant now mean "fully const" and "fully invariant", 
>> where fully means "head and tail combined":
> 
> Remind me again what the difference between 'const' and 'invariant' is.

const: I promise not to change this, but acknowledge that somebody else 
might.

invariant: Neither I nor anyone else will change this.

const has a more limited use for optimization than invariant, since the 
value could be changed by other threads/programs-with-shm/whatever from 
under you.

 - Gregor Richards

PS: Or at least, this is my understanding :)
September 10, 2007
Re: Const sucks
Walter Bright escribió:
> Const, final, invariant, head const, tail const, it's grown into a 
> monster. It tries to cover all the bases, but in doing so is simply not 
> understandable.
> 
> Andrei and Bartosz have spent some time together going back to square 
> one with what are we trying to achieve with const, and came up with 
> another proposal.
> 
> What we are trying to achieve:
> 
> a) utility for functional programming
> b) better modularity by self-documenting interfaces better
> c) be able to treat reference types as if they were value types (i.e. 
> strings should behave to the user like value types, even though they are 
> references)
> 
> The insights they came up with were:
> 
> 1) final (i.e. 'head const') is not necessary for a, b or c. final is a 
> local thing, and not strictly necessary.
> 
> 2) tail const can be handled in other ways, read on
> 
> So, what we are left with is:
> 
> o  no more final
> 
> o  const and invariant now mean "fully const" and "fully invariant", 
> where fully means "head and tail combined":
> 
> const int x = 0;   // x is constant
> const int* p = &x;  // neither p nor *p can be changed
> const(int*) p = &x;  // neither p nor *p can be changed
> const(int)* p = &x;  // p can change, *p cannot be changed
> 
> o  const and invariant are transitive. There is no way to specify a 
> (pointer to)(const pointer to)(mutable int).
> 
> o  tail invariant for an array or pointer type can be done using the 
> existing syntax:
> 
>  invariant(char)[] s;   // string, i.e. an array of invariant chars
>  const(T)* p;  // pointer to tail const T
> 
> o  tail const of a struct would have to be done by making the struct a 
> template:
> 
>   struct S(T) { T member; }
>   S!(int)   // tail mutable
>   S!(const(int)) // tail const
> 
> o  one can construct a template to generically produce tail const or 
> tail invariant versions of a type.
> 
> o  it will be illegal to attempt to change the key value of a foreach 
> loop, but the compiler will not be able to diagnose all attempts to do so
> 
> o  static const/invariant means the initializer is evaluated at compile 
> time. non-static const/invariant means it is evaluated at run time.
> 
> o  no initializer means it is assigned in the corresponding constructor.
> 
> o  const/invariant declarations will always allocate memory (so their 
> addresses can be taken)
> 

I won't comment on all that since I'm still lost in all that const thing. But...

> o  So, we still need a method to declare a constant that will not 
> consume memory. We'll co-opt the future macro syntax for that:
> 
>     macro x = 3;
>     macro s = "hello";

Am I the only one who doesn't like this syntax? I guess it kinda makes sense, 
but I just don't like how it looks.

-- 
Carlos Santander Bernal
September 10, 2007
Re: Const sucks
You might want to allow

const(invariant(int)*)* p;

p is a mutable pointer to a const pointer to an invariant int.

Since invariant is "stronger" than const, you want to be able to do
const(invariant(...)), but not invariant(const(...))
September 10, 2007
Re: Const sucks
Carlos Santander wrote:
> Walter Bright escribió:
>> o  So, we still need a method to declare a constant that will not 
>> consume memory. We'll co-opt the future macro syntax for that:
>>
>>     macro x = 3;
>>     macro s = "hello";
> 
> Am I the only one who doesn't like this syntax? I guess it kinda makes 
> sense, but I just don't like how it looks.
> 

Seems to me like this unnecessarily departs from the macro syntax 
introduced at the conference:

macro foo(e) { e = 3; }

(On the other hand, in one of them the macro is for an expression while 
in the other one it's a sequence of declarations/statements.  So maybe 
it is reasonable to have the different syntax.)

Thanks,
Nathan Reed
September 10, 2007
Re: Const sucks
Walter Bright wrote:
> (snip)
> o  static const/invariant means the initializer is evaluated at compile 
> time. non-static const/invariant means it is evaluated at run time.

I'd like to suggest that we use some keyword other than "static."  Yeah, 
I know that "static" can imply "static analysis" (compile time), but the 
static modifier on a variable has a well-known meaning from C: it's not 
exported.  I think that that was a poor design choice in C, but now 
we're stuck with millions of programmers who expect it.

I think that this would just cause confusion, and perhaps we need a new 
keyword to express this new concept.  While I understand that we don't 
want to multiply keywords, multiplying concepts, and then overloading 
them all into a single keyword, is, IMHO, even worse.

> o  no initializer means it is assigned in the corresponding constructor.
> 
> o  const/invariant declarations will always allocate memory (so their 
> addresses can be taken)
> 
> o  So, we still need a method to declare a constant that will not 
> consume memory. We'll co-opt the future macro syntax for that:
> 
>     macro x = 3;
>     macro s = "hello";

How about "inline"?  That seems to clearly express what we want to 
express (there is a clear parallel between inline functions and inline 
constants).

I don't recall: is inline a keyword in D or not?
September 10, 2007
Re: Const sucks
Derek Parnell wrote:
> On Mon, 10 Sep 2007 12:15:09 -0700, Walter Bright wrote:

>> o  tail const of a struct would have to be done by making the struct a 
>> template:
>>
>>    struct S(T) { T member; }
>>    S!(int)   // tail mutable
>>    S!(const(int)) // tail const

So then it would be ok to completely overrwrite an S, but not to set 
it's only member directly?
alias S!(const(int)) T;
T a;
T b;
a = b;  // ok??
a.member = b.member; // not ok??

It seems a little odd since they do exactly the same thing.
Hopefully copying a struct will be treated the same as elementwise 
copying of the members (so both should be illegal above).

> But most structs contain multiple members, and usually of different types.

Probably someone clever will create a type-constructor template that 
generates constified version of a given struct type using __traits or 
something.  Then you'll just do

   alias MakeConst!(MyStruct) MyConstStruct;

If not, we'll just keep pestering Walter until it is possible to write 
such a template. :=)

Probably more realistic is a case where you want to switch between
struct T { int* x; int y; }
and
struct T { const(int)*; int y; }

So the const doesn't start on the member level, but 
stuff-pointed-to-by-members level

--bb
September 10, 2007
Re: Const sucks
On 9/10/07, Russell Lewis <webmaster@villagersonline.com> wrote:

> the
> static modifier on a variable has a well-known meaning from C: it's not
> exported.

We use private for that purpose in D, so static is free to be retooled
to mean "compile-time".
September 10, 2007
Re: Const sucks
Walter Bright wrote:
> Const, final, invariant, head const, tail const, it's grown into a 
> monster. It tries to cover all the bases, but in doing so is simply not 
> understandable.
> 
> Andrei and Bartosz have spent some time together going back to square 
> one with what are we trying to achieve with const, and came up with 
> another proposal.
> 
> What we are trying to achieve:
> 
> a) utility for functional programming
> b) better modularity by self-documenting interfaces better
> c) be able to treat reference types as if they were value types (i.e. 
> strings should behave to the user like value types, even though they are 
> references)

Does c) include being able to pass literal arguments to functions 
expecting const-references?  I.e. sort of the opposite: being able to 
treat value types as const-references, even though they are const values.

> o  const and invariant now mean "fully const" and "fully invariant", 
> where fully means "head and tail combined":
> 
> const int x = 0;   // x is constant
> const int* p = &x;  // neither p nor *p can be changed
> const(int*) p = &x;  // neither p nor *p can be changed
> const(int)* p = &x;  // p can change, *p cannot be changed

I'm very happy that 'const int' will mean something other than 'just 
plain int'.  The always-off-by-one part of the current design is hard to 
get enthusiastic about.  But this one makes more sense.

Maybe you might consider Janice's suggestion for the structs, though:

const(S)* // Pointer to S nonconst, S is const
const(S)  // S const
const*(S)  // S nonconst, but stuff accessed via S is const
const**(S)  // S and S.member nonconst, but stuff accessed via S.member
is const

--bb
September 10, 2007
Re: Const sucks
Walter Bright wrote:
> What we are trying to achieve:
> 
> a) utility for functional programming
> b) better modularity by self-documenting interfaces better
> c) be able to treat reference types as if they were value types (i.e. 
> strings should behave to the user like value types, even though they are 
> references)

Is there a way to express (for a pointer passed as a function parameter) 
"the callee is allowed to modify this object through the pointer, but 
the caller ensures that no other code will be modifying it at the same 
time"?   Sort of a "you have exclusive write access" modifier?  Is that 
a common enough case to even support?

Russ
September 10, 2007
Re: Const sucks
Nathan Reed wrote:
> Carlos Santander wrote:
>> Walter Bright escribió:
>>> o  So, we still need a method to declare a constant that will not 
>>> consume memory. We'll co-opt the future macro syntax for that:
>>>
>>>     macro x = 3;
>>>     macro s = "hello";
>>
>> Am I the only one who doesn't like this syntax? I guess it kinda makes 
>> sense, but I just don't like how it looks.
>>
> 
> Seems to me like this unnecessarily departs from the macro syntax 
> introduced at the conference:
> 
> macro foo(e) { e = 3; }
> 
> (On the other hand, in one of them the macro is for an expression while 
> in the other one it's a sequence of declarations/statements.  So maybe 
> it is reasonable to have the different syntax.)

It's not far off from things used in some functional programming 
languages, so it doesn't look to bad to me.  The word 'macro' typically 
implies a direct, maybe even textual, substitution.  It's also a lot 
like #define, just with an '=' there which I think is an improvement 
over #define.  '=' for the no-arg macros, '{ }' for the arg-ful macros. 
 Seems ok to me.

--bb
1 2 3 4 5 6
Top | Discussion index | About this forum | D home