www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12931] New: Make const, immutable, and inout illegal as

https://issues.dlang.org/show_bug.cgi?id=12931

          Issue ID: 12931
           Summary: Make const, immutable, and inout illegal as funtion
                    attributes on the left-hand side of a function
           Product: D
           Version: unspecified
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: jmdavisProg gmx.com

Can we _please_, _please_ make it illegal to put any function attribute which
could also modify the return type on the left-hand side of the function? e.g.

const Bar foo() {...}

is currently legal and is equivalent to

Bar foo() const {...}

_Everyone_ makes the mistake of thinking that

const Bar foo() {...}

is equivalent to

const(Bar) foo() {...}

The result of this is not only confusion for newbies, but it also means that
it's bad pratice to put const, immutable, or inout on the left-hand side of a
function, because if you do

const Bar foo() {...}

then it immediately raises the question as to whether programmer who wrote it
intended for const to modify the function or the return type.

The reason that's usually given as to why const is legal on the left-hand side
is because all function attributes can go on either side of the function, and
it would be inconsistent to disallow const, immutable, or inout on the left.
But that's not even true! As issue# 12930 shows, static, private, public,
package, and protected are all illegal on the left. It's only  property,  safe,
 trusted,  nogc, pure, nothrow, const, immutable, and inout which can go on
both sides. So, we're allowing const, immutable, and inout to be on the
left-hand side in the name of consistency, when we're not even consistent! So,
we're allowing them on the left to no real benefit. It's already considered bad
practice to put them on the left-hand side, and it would reduce bugs and
confusion if we disallowed it. And the fact that

const Bar foo() {...}

doesn't return a const(Bar) is inconsistent with variable declarations (where
the parens are optional), so we're claiming to be consistent with function
attributes when we're not and are specifically being inconsistent with variable
declarations in a way that constantly confuses people. Heck, Robert Schadeck,
who spoke at dconf 2013 and who's working on std.log got this wrong in a stack
overflow question on this very topic!

http://stackoverflow.com/questions/24239156/const-member-fuction-vs-const-return-type/24239520#24239520

If our major contributors can't get this right, how do we expect normal D
programmers to get it right?

So, I propose that we disallow const, immutable, and inout on the left-hand
side of a function unless they use parens to explicitly modify the return type.
So,

const(Bar) foo() {...}

would continue to be legal, and

const Bar foo() {...}

would become illegal (after the proper deprecation cycle of course). The only
code that this would break would be code that's already breaking with what's
considered good practice, because it's always going to be questioned as to
whether the programmer who wrote it intended to modify the return type or the
function. It would be nice to make it so that

const Bar foo() {...}

were then the same as

const(Bar) foo() {...}

but we obviously can't do that immediately, as that would change the semantics
of the code (and potentially in a silent way, though usually, it would be quite
loud). Maybe we could do so in the future, but the most important thing IMHO is
to stop allowing it on the left as a function attribute, because that's too
confusing and bug-prone.

I know that Walter doesn't agree with this (or at least hasn't in the past),
but we really need to find a way to convince him to change this (or to allow
other compiler devs to change it). The current behavior is just causing us
problems.

--
Jun 16 2014