a more consistent const syntax

Daniel919 Daniel919 at web.de
Mon Aug 6 08:56:01 PDT 2007


Chris Nicholson-Sauls schrieb:
> Daniel919 wrote:
>> I've got some ideas about how to make the const syntax more
>> consistent.
>> First I will show you the current situation.
>> Then I will list the confusions and possible solutions.
>>
>> Some days ago I already mentioned my first idea on IRC, but got no 
>> replies.
>> Also I know that you, Walter, hardly don't change features, which
>> already have been implemented.
>> And my suggestions would require this of course.
>>
>> The "define proposal" is not such a big change in the language,
>> in opposite to the much more important idea about
>> "putting the return type in a bracket at the end".
>> Because this is what the last idea requires, it's written after "WAIT:".
>>
>> Nevertheless I will give it a try, because 2.0 is still alpha and it 
>> will break code compatibility anyway.
>>
>>
>>
>> currently the keyword const(/invariant) has three meanings:
>> -----------------------------------------------------------
>> 1. alone: const x = 1; compile-time variable (not an lvalue)
> 
> Well technically if that was what I wanted, I'd use one of 'invariant x 
> = 1;' or a more explicit 'final invariant(int) x = 1;'.
> 
>> 2. with(): const(P) p = new Point(1,2); run-time object, which is 
>> protected from changes
> 
> Well, protected from changes via this reference... but yeah.  I'd say 
> the 'const(type)' case would/should be used most often anyhow.
> 
>> 3. alone: const P func(P p) { writefln(p.x, " ", p.y); }; attribute 
>> for a member function: the function can't change any class fields
> 
> #3 is an issue, in my book.  Not a massive one, but its there.  We'll 
> get into that one below.
> 
>>
>> confusions and solutions:
>> -------------------------
>> #1
>> 1. const x = 1;
>> 2. const(P) p = new Point(1,2);
>> you see const first and later recognize the brackets
>> one would not expect brackets to lead to a completely different 
>> meaning of the forrun keyword
> 
> My eyes are trained to spot them... still yes, a sudden shift in meaning 
> can be counter-intuitive.  Although its not entirely a shift...  you 
> could probably think of 'const x = 1;' as shorthand for 'final 
> const(int) x = 1;'.

But they are not the same:

const x = 1;
doesn't take up space

final const(int) x = 1;
does take up space

Example:
struct A { const constx = 1; }
struct B { final const(int) x = 1; }

A.sizeof == 1
B.sizeof == 4


>> 1. define x = 1;
>> 2. const(P) p = new Point(1,2);
>> can't be confused anymore, different keywords
>> define defines a compile-time variable
>> const / invariant has nothing to do with compile-time anymore. it only 
>> means protection
> 
> Adding new keywords is usually the absolute last option around here. 
> (There was talk ages past of replacing 'auto x = 1' with 'let x = 1'.)

You might think about spoken languages: You learn more vocabularies to 
be able to differentiate better, so you are more capable to express what 
you mean, instead of relying on an absolutely small subset of vocabularies.
PS: "auto" also was a new keyword some time ago ;)

"define" is also known from C/C++ world to define something you can't 
change, equivalent to what const x = 1; acutally means: not an lvalue.
In my opinion it's better to have a different keyword for something 
different, and "define" makes much sense for me.


>>
>> #2
>> 3. const P func(P p) { ... }
>> reads like: func returns a const(P)
> 
> Which is, indeed, a problem -- in that I agree.
> 
>> const / invariant alone (without brackets) is an attribute and has no 
>> other meaning
>> further proposal: returned types in a bracket at the end:
>> 3. const func (P p) (P) { ... }
>> //templated syntax: const func!(T) (T p) (T) { ... }
> 
> Uhm.  Ew.  No, seriously, I just could not possibly handle that; I would 
> keep thinking I saw templates where there aren't any.  Worse yet, for a 
> long time I'll see the '!(' and keep wondering how I could be 
> instantiating a template in that position, when its really a template 
> declaration.  T'is a naughty naughty thing to mix the two -- would give 
> both the compiler and the user headaches.  IMHO, its the 

You are right, it really looks like a template instatiation.
So lets try without the ! on declaration:

func(T) (T var) (T)  //IFTI  take T  return T
func(T) (T var)      //IFTI  take T
func(T) () (T)       //IFTI          return T
func(T)              //IFTI
func(T var) (T)      //      take T  return T
func(T var)          //      take T
func() (T)           //              return T
func()               //

At least one () should remain, to make clear that it's a function

Before the return brackets there must always be the take brackets.
So 4. can only mean IFTI.

This looks good in my opinion.



To compare with the current syntax:
T func(T) (T var)    //IFTI  take T  return T
void func(T) (T var) //IFTI  take T
T func(T) ()         //IFTI          return T
void func(T) ()      //IFTI
T func(T var)        //      take T  return T
void func(T var)     //      take T
T func()             //              return T
void func()          //

> 'const'/'invariant' keyword on methods that needs to move -- not sure 
> where it should go, though.  What looks best down here?  ;)  (First 
> listing is the current state, for reference.)
> 
> const P       vunc       (P p)       { ... }
>       P const func       (P p)       { ... }
>       P const:func       (P p)       { ... }
>       P const(func)      (P p)       { ... }
>       P       func const (P p)       { ... }
>       P       func:const (P p)       { ... }
>       P       func       (P p) const { ... }
> 

I would suggest
const: P func (P p) { ... }

Not allowed:
const:
  ... func1 ...
  ... func2 ...

You always have to explicitly mention the "const:" for each function.

This way the "attribute feeling" is retained.


>>
>> #3
>> 1. same meaning: invariant x = 1; const x = 1;
> 
> For basic types, there often isn't much difference anyhow.  Except that 
> invariant members of structures allocate no memory in the structure, for 
> example.
> 
>> not allowed anymore: const(/invariant) alone is an attribute, instead 
>> use:
>> 1. define x = 1;
>>
>> #4
>> //this is ok: final int x = 1; const(int)* xptr = &x; // but:
>> 2. const(int) x = 1;
>> this is nonsense and also atm it could be confused with:
>> 1. const int x = 1;
>>
>> the compiler should issue at least a warning, and instead you should use:
>> 1. define x = 1;
>>
>>
>> #5
>> void func(const P p) { typeof(p) == const(P) }
>> bad, because one could expect this to be also valid then:
>> const P p = new P(1,2); //but fails of course
>> correctly is has to be:
>> void func(const(P) p) { ... }
>> void func(ref const(P) p) { p = new P(3,4); } //OK
>> //void func(const(int) i) { ... } //const(int) nonsense (see #4)
>> //void func(ref const(int) i) { ... } //const(int) nonsense (see #4)
>>
>> compiler should issue an error
>> const(/invariant) alone is an attribute
>>
>>
>> WAIT:
>> -----
>> because we have another syntax for compile-time variables now,
>> we could say that:
>> const P** ptr2ptr2P means:
>> const(P**) ptr2ptr2P
>> in this case, #5 would be allowed
>> but this would also require #2 further proposal to be implemented, 
>> because if it wasn't:
>> const P** func() { ... }
>> would not only be confused with, but it would be THE SAME as:
>> const(P**) func() { ... }
>> then the correct form would have to be:
>> const func() (const P**) { ...}
>>
>> note that #4 would be true for: const int x = 1; then
>> this would be nonsense, because it would be the same as: const(int) x 
>> = 1;
>> so the compiler should issue at least a warning
>>
>>
>>
>> PS: Having the return types in a bracket at the end, would make it
>> possible to implement multiple return values / return tuples
>> in a consistent way, too.
>> It would also allow more tricks, like returning local values of a 
>> function, avoiding ref, etc etc ...
>>
>>
>>
>> I would really enjoy to get some replies (especially yours, Walter),
>> even if it's just a: "No that's totally stupid" ;)
>>
>> Best regards,
>> Daniel
> 
> No that's totally stupid.
> 
> 
> 
> Ahh I'm just kidding.  At least you're thinking about the situation and 
> offering suggestions.  (And welcome to the tiny militia of 'const R 
> func()' syntax detractors. ;))  The final/const/invariant system needs 
> some good hammering yet -- although its off to a lovely start, danke 
> Walter.
> 
> -- Chris Nicholson-Sauls

Yes, there seem to be a lot of people not being very happy with the 
current const syntax.
But I have not seen much concrete suggestion how to make it better.


Best regards,
Daniel



More information about the Digitalmars-d mailing list