This is just about removing the constness for whatever the part of a type that is passed by value. This is not really a special rule and make sense.

Le 10/12/2011 23:31, kenji hara a écrit :
Treating whole constant arrays as ranges by automatically shedding the
top-level const is good.
But realizing it by language semantic change is definitely bad.It
breaks IFTI rule, and adding special case will make difficult to learn
language.

Instead of language change, we can add specializations that receive
non-ranges and convert them to ranges by removing top-level const.
I believe that it is Phobos issue and is never the issue of language.

Kenji

2011/12/11 Andrei Alexandrescu<seewebsiteforem...@erdani.org>:
Walter and I discussed today and decided to fix this long-standing issue:

import std.algorithm;
void main() {
  const arr = [1, 2, 3];
  reduce!"a*b"(arr);
}

The problem here is that D's built-in arrays are at the same time containers
and their own ranges. When the array is constant the matter becomes
confusing because the range itself must be non-constant such that it can
iterate the constant array.

Put simply, the type of the array in this case should be const(int[]) and
the type of its range should be const(int)[].

This problem does not commonly occur with ranges because people do expect
that a constant range can't be used for iteration, and an elaborate
container will emit the proper type of range even when the container itself
is constant.

We decided to fix this issue by automatically shedding the top-level const
when passing an array or a pointer by value into a function.

The rule is simple and does not complicate lookup rules, type deduction, or
template specialization. It is a semantic rewrite as follows.

Consider x an array of type qualifier(T[]). In any function call in which it
is established that x is passed by value (i.e. no "ref" with the parameter),
the call:

fun(..., x, ...)

is lowered into:

fun(..., cast(qualifier(T)[]) x, ...)

after which the usual language rules apply. Similarly, if x has type
qualifier(T*), AND if x is passed by value into a function, the call:

fun(..., x, ...)

is lowered into:

fun(..., cast(qualifier(T)*) x, ...)

after which, again, the usual rules apply. Note that fun does not need to be
a template and generally must meet no special conditions aside from taking x
by value. If fun takes specifically a const(T[]), the call will go through
no problem because const(T)[] is implicitly convertible to const(T[]).

This allows template functions to accept arrays by value yet modify their
own private copy of the array's bounds, which is reasonable and expected.

This rule solves a host of issues related to applying range algorithms to
arrays. I hope we will have this rule in action in dmd 2.057.


Andrei

Reply via email to