Thread overview
[Issue 24688] Parameter by-value keeps const (only in templates)
Aug 19
RazvanN
July 30
https://issues.dlang.org/show_bug.cgi?id=24688

Nick Treleaven <nick@geany.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nick@geany.org

--- Comment #1 from Nick Treleaven <nick@geany.org> ---
To do that, the compiler would have to analyse the body of the template function. Because T may be used to declare something that needs to be const in order for the function to compile, e.g. T*, T[].

--
July 30
https://issues.dlang.org/show_bug.cgi?id=24688

--- Comment #2 from Dominikus Dittes Scherkl <dominikus@scherkl.de> ---
(In reply to Nick Treleaven from comment #1)
> To do that, the compiler would have to analyse the body of the template function.
No. The strategy is
- create a mutable copy (as it is done for normal functions)
- only if this is not possible, create a const copy
- if a const copy is neccessary, declare the template to take a const T (or,
what I would recommend, take it by const ref T)

--
August 19
https://issues.dlang.org/show_bug.cgi?id=24688

RazvanN <razvan.nitu1305@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |razvan.nitu1305@gmail.com
         Resolution|---                         |WONTFIX

--- Comment #3 from RazvanN <razvan.nitu1305@gmail.com> ---
What you are asking for is not a reasonable strategy. The type deduction
mechanism works by looking at the parameter type and binding T to 'const int'.
It's an elegant and simple to understand strategy. If you want tpl to be
instantiated with a mutable parameter you can just specify that at the call
site:
`z = tpl!int(i);`.

Having the compiler deduce constraints from the template body (or worse: just guess) is something that will complicate the implementation of the compiler and it's gonna be a behavior that is hard to understand (it's not intuitive). There will be a lot of gotcha moments for users when they have to guess what was the type with which the compiler instantiated the template.

--
August 24
https://issues.dlang.org/show_bug.cgi?id=24688

--- Comment #4 from Dominikus Dittes Scherkl <dominikus@scherkl.de> ---
So, instead of
```d
T fun(T)(T x) { ... }
```

I have to write

```d
T fun(T)(const T x) { return fun(cast(T)n); }
T fun(T)(T x) if(!is(T==const)) { ... }
```

For all functions that used to get a mutable copy of x, just to allow the
compiler to create a const copy of x where this is never useful.
And I thought D wants the developer to write *less* boilerplate.
sigh.

This is really only a tiny bit better than to write multiple copies of fun() for each type it can take and renders templates much less useful for me :-(

--
August 24
https://issues.dlang.org/show_bug.cgi?id=24688

--- Comment #5 from Dominikus Dittes Scherkl <dominikus@scherkl.de> ---
of course I meant 'cast(T)x', as there is no parameter 'n'.
This is not only boilerplate, you also have to be careful with the parameter
names, as this now occurs three times instead of one time.
Really, I hate this.

--
August 24
https://issues.dlang.org/show_bug.cgi?id=24688

--- Comment #6 from Dominikus Dittes Scherkl <dominikus@scherkl.de> ---
Ok, it's possible to optimize it to one extra line:

T tpl(T)(T x)
{
   ...
}

becomes

T tpl(T)(T x)
{
   static if(is(T==const)) return tpl(cast(T)x);
   ...
}

But I have to add this to pretty much *every* template in my code, as this is a pattern that I use almost always. And I can only hope, the compiler is smart enough to optimize this extra call and additional copy of x away.

--