On 2/2/16 2:50 PM, Bambi wrote:
On Tuesday, 2 February 2016 at 15:48:02 UTC, anonymous wrote:
"immutable" is not a homonym here. It means the same thing ("cannot
ever change"). And it's not redundant either, as the two instances
apply to different targets. It's clear what the first "immutable" ties
to: It qualifies the return type. The second one is less clear: It
qualifies the type of the object, meaning the method can only be
called on an immutable object.

Leaving either of them out changes the meaning of the signature:
`int[] bar() immutable {}` - Return type is mutable now.
`immutable(int[]) bar() {}` - Object type is mutable now. I.e., this
method can be called on a mutable object, and it cannot be called on
an immutable object.

Making the return value immutable is a very different thing from making
every value of the object immutable to the method alone. These are
different meanings. It reads like a redundancy but has different
meanings. This isn't good in my eyes.

Technically, it doesn't *make* it immutable, it is just an overload that accepts an immutable object. I like to think of a method like this:

immutable(int)[] bar() immutable

as a function that looks like this:

immutable(int)[] bar(immutable(Object) this)

If you tried to call this method on a mutable object, and there wasn't a mutable overload (i.e. without an attribute), the call would fail.


Also it's not so much an issue of clarification - well, the extern one
is, I genuinely didn't understand what the documentation meant - but it
is an issue of the design choices not making much sense to me. These
just stand out to me as unnecessarily confusing and obscure in an
otherwise nice and clear language.

A lot of things in D come from C++. This is how C++ specifies const methods.

The purpose is to be familiar to C++ developers, and to make porting easier.

This means it can look confusing as not all C/C++ decisions were the best. However, this one I happen to like -- I can't think of a better way.

-Steve

Reply via email to