Jump to page: 1 2 3
Thread overview
Normalizing Const Syntax.
Apr 08, 2008
Scott S. McCoy
Apr 09, 2008
Georg Wrede
Apr 09, 2008
Graham St Jack
Apr 09, 2008
Scott S. McCoy
Apr 09, 2008
Janice Caron
Apr 09, 2008
Bill Baxter
Apr 09, 2008
Yigal Chripun
Apr 10, 2008
Janice Caron
Apr 10, 2008
Bill Baxter
Apr 10, 2008
Koroskin Denis
Apr 10, 2008
Bill Baxter
Apr 10, 2008
Georg Wrede
Apr 10, 2008
Bill Baxter
Apr 27, 2008
Bruno Medeiros
Apr 11, 2008
Scott S. McCoy
Apr 10, 2008
Simen Kjaeraas
Apr 11, 2008
Scott S. McCoy
Apr 11, 2008
Hans W. Uhlig
Apr 11, 2008
Georg Wrede
Apr 11, 2008
Hans W. Uhlig
Apr 14, 2008
Janice Caron
April 08, 2008
I've brought this up several times within threads, and not gotten any responses.  So I thought I would make it a thread of its own.  How about normalizing the syntax of const?

private const int foo;
public const const(int) bar () { return foo; }

In the above example, the behavior of the keyword "const" is relatively schizophrenic.  const is listed as a part of the storage class for foo, and then as an access qualifier for bar(), with the same syntax.  While it should be noted that this type of behavior is suitable with static, but that is because the nature of static is different.  static is both a storage class and an access qualifier, and it behaves fine as such.

However the "transitive const" definition makes const no longer a storage class.  const is now an attribute of the value type, which is what makes it transitive.  Granted, this type attribute does change the behavior of storage, but that doesn't magically make its behavior consistent with storage-class keywords such as static, or extern.  It's a different class of concept.

It would seem more consistent with the essence of our new const definition if const was always an attribute of the type, when associated with an identifier.  So the syntax should reflect this, as per the following example.

private const(int) _foo;
public const const(int) foo () { return _foo; }

This would also mean that:

private const int foo;

could retain it's previous definition, which is a part of what's
making people so frustrated about const.  Since const is listed in the
storage-class part of the declaration, const as a storage class could
be possible.  Alternatively, const as a storage class could be a syntax
error, if we really want to get rid of the concept entirely and not have
two consts floating around.  This would make porting D1 code to D2
easier, since it would either 1) Work as expected, or 2) Just not work
and the compiler could tell you about it.

Cheers,
	Scott S. McCoy



April 09, 2008
Scott S. McCoy wrote:
> I've brought this up several times within threads, and not gotten any
> responses.  So I thought I would make it a thread of its own.  How about
> normalizing the syntax of const?
> 
> private const int foo;
> public const const(int) bar () { return foo; }
> 
> In the above example, the behavior of the keyword "const" is relatively
> schizophrenic.  const is listed as a part of the storage class for foo,
> and then as an access qualifier for bar(), with the same syntax.  While
> it should be noted that this type of behavior is suitable with static,
> but that is because the nature of static is different.  static is both a
> storage class and an access qualifier, and it behaves fine as such.  

Suppose one has a new language to learn, and the syntax would be inconsistent between, say, storage class, access qualifier, and type attribute. How is one supposed to learn the difference?

While those who are familiar with a language may not "see" this, it is a severe stumbling block for those who really try to understand things. Ahd that's the kind of programmers we want to D.

> However the "transitive const" definition makes const no longer a
> storage class.  const is now an attribute of the value type, which is
> what makes it transitive.  Granted, this type attribute does change the
> behavior of storage, but that doesn't magically make its behavior
> consistent with storage-class keywords such as static, or extern.  It's
> a different class of concept.
> 
> It would seem more consistent with the essence of our new const
> definition if const was always an attribute of the type, when associated
> with an identifier.  So the syntax should reflect this, as per the
> following example.
> 
> private const(int) _foo;
> public const const(int) foo () { return _foo; }
> 
> This would also mean that:
> 
> private const int foo;
> 
> could retain it's previous definition, which is a part of what's
> making people so frustrated about const.  Since const is listed in the
> storage-class part of the declaration, const as a storage class could
> be possible.  Alternatively, const as a storage class could be a syntax
> error, if we really want to get rid of the concept entirely and not have
> two consts floating around.  This would make porting D1 code to D2
> easier, since it would either 1) Work as expected, or 2) Just not work
> and the compiler could tell you about it.
> 
> Cheers,
> 	Scott S. McCoy
> 
> 
> 
April 09, 2008
On Tue, 08 Apr 2008 15:51:22 -0700, Scott S. McCoy wrote:

> I've brought this up several times within threads, and not gotten any responses.  So I thought I would make it a thread of its own.  How about normalizing the syntax of const?
> 
> private const int foo;
> public const const(int) bar () { return foo; }
> 
> In the above example, the behavior of the keyword "const" is relatively schizophrenic.  const is listed as a part of the storage class for foo, and then as an access qualifier for bar(), with the same syntax.  While it should be noted that this type of behavior is suitable with static, but that is because the nature of static is different.  static is both a storage class and an access qualifier, and it behaves fine as such.
> 
> However the "transitive const" definition makes const no longer a storage class.  const is now an attribute of the value type, which is what makes it transitive.  Granted, this type attribute does change the behavior of storage, but that doesn't magically make its behavior consistent with storage-class keywords such as static, or extern.  It's a different class of concept.
> 
> It would seem more consistent with the essence of our new const definition if const was always an attribute of the type, when associated with an identifier.  So the syntax should reflect this, as per the following example.
> 
> private const(int) _foo;
> public const const(int) foo () { return _foo; }
> 
> This would also mean that:
> 
> private const int foo;
> 
> could retain it's previous definition, which is a part of what's making people so frustrated about const.  Since const is listed in the storage-class part of the declaration, const as a storage class could be possible.  Alternatively, const as a storage class could be a syntax error, if we really want to get rid of the concept entirely and not have two consts floating around.  This would make porting D1 code to D2 easier, since it would either 1) Work as expected, or 2) Just not work and the compiler could tell you about it.
> 
> Cheers,
> 	Scott S. McCoy

I agree that the present syntax is a problem, but I'm not sure how your suggestion fixes the problem.

The two alternatives that make sense to me are:

const ReturnType const method_name();

const ReturnType method_name() const;

where in each case the first const applies to the return type and the second to the method.
April 09, 2008
On Wed, 2008-04-09 at 01:08 +0000, Graham St Jack wrote:
> 
> 
> I agree that the present syntax is a problem, but I'm not sure how
> your
> suggestion fixes the problem.

By normalizing the syntax.  if const is transitive, then it needs to be differentiated from other types of storage classes such a static.  My solution simply takes the existing, currently defined syntax for differentiating between them and makes it mandatory for all const-typed identifiers.

const(int) foo how becomes the way of saying a const int.  Rather than trying to reshape the syntax (which I also tried to do, but found difficult in a number of ways) I thought maybe a quicker, and easier to get accepted route would just be to re-purpose the existing syntax.

In fact, this syntax already exists...I'm just suggesting removing the other, or removing it's newer definition.

> 
> The two alternatives that make sense to me are:
> 
> const ReturnType const method_name();
> 
> const ReturnType method_name() const;
> 

Right, and I've seen this suggestion.

Actually, I'm not sure any of this solves the problem.  The real issue here is that we just have too many damn things to say with the word const.

Maybe we should separate the concept of a const method and a const identifier.

After all, the difference between the const and invariant method definitions is...well...slim:

"""
Invariant member functions are guaranteed that the object and anything
referred to by the this reference is invariant.
"""

"""
Const member functions are functions that are not allowed to change any
part of the object through the member function's this reference.
"""

Isn't the goal here just that the member function doesn't modify anything?  And why do invariant member functions even need to exist? (Are we really going to use them?).

Maybe we could come up with a base-line that works for member functions between the two, and ditch the use of the keyword "const" for method declarations entirely.  Then we could have a special access class which defines that the function may be invoked from the context of a const *or* invariant instance.  Naturally, an invariant class means nothing can be modifiable, but I can't imagine why "doesn't modify anything in the this reference" doesn't suffice for functions in an invariant context.

Cheers,
	Scott S. McCoy


April 09, 2008
I think it would be enormously wrong for

    const int x;

and

    const(int) x;

to mean two entirely different things (which I think was part of what Scott was suggesting). But I do agree with all the rest of it.

So here's something to think about. Consider the following code:

    class C
    {
        const
        {
            T x;
            T f() { ... }
        }
    }

What would be the most intuitive meaning of f's const. Would it be:
(a) the function expects "this" to be const
(b) the function returns a const(T)
(c) both of the above simultaneously
(d) none of the above

I think (b).

In D2.012, the actual meaning is (a), but pretty much everyone agrees
that's not intuitive.
April 09, 2008
Janice Caron wrote:
> I think it would be enormously wrong for
> 
>     const int x;
> 
> and
> 
>     const(int) x;
> 
> to mean two entirely different things (which I think was part of what
> Scott was suggesting). But I do agree with all the rest of it.
> 
> So here's something to think about. Consider the following code:
> 
>     class C
>     {
>         const
>         {
>             T x;
>             T f() { ... }
>         }
>     }
> 
> What would be the most intuitive meaning of f's const. Would it be:
> (a) the function expects "this" to be const
> (b) the function returns a const(T)
> (c) both of the above simultaneously
> (d) none of the above
> 
> I think (b).

You could be right.  But either way, I object to the heavy use of non-local attribute modifiers that change the meaning of statements far from where they are written.  So even though it might be "cute" to put 'static' or 'const' in a big block around a big chunk of functions,  I think doing such things is bad style.  I'm not a big Java fan, but I think maybe Java might have had it right on this one.  When I look at a big class in D I'm forever trying to figure out whether some unlabeled method is public/private/protected.  And several times I've been bitten by not noticing an innocuous little  "extern(C):" stuck at the top of a file.

> In D2.012, the actual meaning is (a), but pretty much everyone agrees
> that's not intuitive.

Indeed.  I also don't like the idea that lots of extra parenthesis will be forced upon us just to allow something which I think is of dubious value to begin with.  I.e., this should return a const value, not have a const 'this':
    const Bar Foo()
But with the current regime that has to get some extra parens to express that.  Too many parens in a signature makes it hard to read, so I really don't want "const(Bar) Foo()" to be the norm.

--bb
April 09, 2008
Bill Baxter wrote:
> Indeed.  I also don't like the idea that lots of extra parenthesis
> will be forced upon us just to allow something which I think is of
> dubious value to begin with.  I.e., this should return a const value,
> not have a const 'this':
>     const Bar Foo()
> But with the current regime that has to get some extra parens to
> express that.  Too many parens in a signature makes it hard to read,
> so I really don't want "const(Bar) Foo()" to be the norm.
>
> --bb

the problem with the current syntax IMHO is that we want to specify
several different const meanings all at the same place in the code:
- constancy of the return type
- constancy of the this pointer (for methods)
- "constancy" of the code itself - i.e pure functions
to solve this we need to either,
a) have a different name for each of those (this is partly so with the
use of "pure")
// const_this & const_return are placeholders for 2 different keywords.
---> pure const_this const_return int func(int a, int b);
or b)  rearrange the syntax so each meaning has its own place.

in a perfect world that would be something like:
const func(const this, const int a,  int b) : const int; // first const
means pure, last const is for return type.
that even reduces the keyword count! (no need for pure)

but... that will not happen because it's too big a change in syntax for D. at least i hope the "const this" above could be considered as it also would be extensible for another use case promised for D2 - extensible classes.

basically, of all the other rearrangement of function declaration ideas
on the NG I liked the most the one Janice, i think, suggested of using
const(this).this makes very clear what is const, however it adds another
pair of parens which is confusing. so my personal conclusion is - why
have two pairs of parens? lets unite them to the following:
int a(const this, const int a);
which is very clear on its intent, IMO.

Questions? Suggestions?

--Yigal
April 10, 2008
On 09/04/2008, Yigal Chripun <yigal100@gmail.com> wrote:
>  so my personal conclusion is - why
>  have two pairs of parens? lets unite them to the following:
>  int a(const this, const int a);
>  which is very clear on its intent, IMO.
>
>  Questions? Suggestions?

I don't have any particular problem with that syntax, however, it's no better or worse than any other possiblity. The following all seem to be equally acceptable:

(1) ReturnType f(Params...) const
(2) ReturnType f(const this, Params...)
(3) ReturnType const f(Params...)

Of these, (1) is *already legal syntax*, so it's not like we need something to replace it. (Yours is option 2) Indeed, the simplest answer of all would be just to get rid of const-at-the-front, leaving const-at-the-back as the way to do things.

However, there is a reason why Walter has not made const-at-the-front illegal, which is that /he likes it/. And so far as I can gather, the reason that he likes it is because it means he is able to write

    const
    {
        /* lots of functions */
    }

So you see, part of the purpose of the const(this) proposal is to keep Walter happy. It means that he will still be able to do

    const(this)
    {
        /* lots of functions */
    }

Only something-at-the-front can do this. So, const(this) is an attempt
to simultaneously (a) remove the current unintuitive syntax, and (b)
keep Walter happy. It's also consistent with D-style in that D already
has attributes like extern(C) and version(Windows), so const(this)
would be right at home.

And of course - the bonus is that

    const R f(...)

can have its intuitive meaning of "f returns a const(R)".

(Of course, if const(this)-at-the-front ever replaces
const-at-the-front, then the question of whether to allow
const-at-the-back returns to haunt us! :-))
April 10, 2008
Janice Caron wrote:
> However, there is a reason why Walter has not made const-at-the-front
> illegal, which is that /he likes it/. And so far as I can gather, the
> reason that he likes it is because it means he is able to write
> 
>     const
>     {
>         /* lots of functions */
>     }

Which is a horrible syntax in my opinion.  Something to be avoided rather than something to bend over backwards trying to support.  Why should a big block-o-const only affect the 'this' arguments of functions inside of it?  Not to mention, the bigger the block-o-const, the more likely it is that someone reading the code will not see the const label.

It's a bad idea in my opinion.


--bb

April 10, 2008
On Thu, 10 Apr 2008 15:03:30 +0200, Janice Caron <caron800@googlemail.com> wrote:

>     const(this)
>     {
>         /* lots of functions */
>     }
>
> Only something-at-the-front can do this.

Could we not do like this:

{
    /* lots of functions */
} const;

:p
« First   ‹ Prev
1 2 3