Why can't we define re-assignable const reference variable?

Yigal Chripun yigal100 at gmail.com
Tue Feb 19 09:04:00 PST 2008


here's my random thought on the subject (just wanted to throw those in
the mix...):
[warning: long post ahead]

the current (and all previous) const designs fail due to too narrow a
view on the issue.
when introducing a const system to a language than the language as a
whole should be examined and related concepts should be tweaked
accordingly. So here's my list of those related issues:

references -
in a high level language like D you should be able to just use refs
everywhere and pointer usage should be discouraged.  D as a systems
programming language, should however provide pointers for those
/advanced/low-level/potentially unsafe uses when you do systems
programming. that means that refs should be enhanced in D and pointers
should be used _only_ when truly you need them (for example for pointer
arithmetic).
for example: you should be able to use (and it should be the preferred
way!):
ref S s1 = new S(); // S is a struct
instead of the equivalent:
S* s2 = new S();
so you can eliminate pointers from almost all user code.
how does this affect const?
i suggest the following:
const(T) t = new T(); // this would be a mutable ref to const T
const(ref T) t = new T(); // this would be a const ref to const T
and you can also define "const T" as a shortcut for "const(ref T)"
i know that this means const(T) isn't the same as "const T" but I think
that this is a reasonable compromise (if it's consistent for all types)
another issue with refs is that i want to be able to return the lvalue
by specifying the return type to be ([const] ref T).

another  issue is a function call -
there are really only two modes for passing a parameter to a function:
1. you allow the function to change the outside(actual) parameter
2.  you do not allow the function to do that.
value vs. ref semantics is an implementation detail that user level code
shouldn't care about at all, and a special syntax should be provided and
used to distinguish the two only for advanced use cases.
so for example you could define:
void func_name(in T t);
in the above example the in keyword would represent the fact that you
cannot change the outside parameter.
how do you implement it? the compiler should have a very simple
heuristic that says that if T is a primitive value or a small struct
than just pass it by value and if it's a class instance than pass it as
a const ref. that is an optimization the compiler should provide.
now, what if i want to explicitly choose the parameter passing
semantics? that is also possible (but discouraged for user level code)
with a bit more verbose code and language rules. for example primitives
should be passed by value be default and you can change that with a ref
keyword. class instances are passed by ref so you can pass them by value
if they implement a dup method, and the user must call that explicitly.
so, other_func(someClassInstance.dup()); passes someClassInstance by value.
the second mode above is simply pass T by ref. also a bigger change
could be done so that the default mode when passing parameters is 1. so
you won't need to specify in and it would be implied.

for generic programming to work it needs to use the above "in" and "ref"
(i.e. modes 1 and 2) and not rely on a specific parameter passing
semantics unless this is what needed.

one last thing: i really liked oskar's orthogonal const proposal and
wish for it to be further explored.

anyway, that is just my shnekel (2 NIS) that i wanted to add to the
discussion.

--Yigal



More information about the Digitalmars-d mailing list