Ok, now I get why using Unqual to get tail const wouldn&#39;t work.  My silly oversight:<br><br><span style="font-family: courier new,monospace;">// The following doesn&#39;t work, though the natural tail <br>// const for const(Cycle!(int[]))</span><span style="font-family: courier new,monospace;"> is Cycle!(const(int)[]),<br>
// because Unqual!(const(Cycle!(int[]))) == Cycle!(int[]).<br></span><span style="font-family: courier new,monospace;">import std.range, std.traits;</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">void main() {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    const myRange = cycle([1,2,3,4]);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    pragma(msg, typeof(myRange));</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">    Unqual!(typeof(myRange)) myRangeMutable = myRange;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">    pragma(msg, typeof(myRange));</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">}</span><br><br><br><div class="gmail_quote">
On Thu, Aug 12, 2010 at 11:37 AM, Steve Schveighoffer <span dir="ltr">&lt;<a href="mailto:schveiguy@yahoo.com">schveiguy@yahoo.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Tail-const is doable, but does not enjoy the implicit conversion that T[] has.<br>
<br>
Without the implicit conversion, tail-const relies on unsafe casting, and that<br>
sucks.<br>
<br>
I agree with Andrei we need a language solution.  The question really is not<br>
what the solution should do, that much is clear -- apply const to a subset of<br>
the members (either all references or members designated by some identifier).<br>
The question is, what does the syntax look like.  That was the major stumbling<br>
block that flipped Walter&#39;s switch to &quot;tail-const doesn&#39;t work&quot;.<br>
<br>
I think we should concentrate on structs and not class references, since class<br>
references have no syntax that separates the reference from the data.  At least<br>
with structs, you can identify the parts to apply const to.  We have a somewhat<br>
clunky solution in Rebindable for classes, so it would be nice to include them,<br>
but past experience has shown that to be a big rat hole.<br>
<br>
-Steve<br>
<br>
&gt;<br>
&gt;From: David Simcha &lt;<a href="mailto:dsimcha@gmail.com">dsimcha@gmail.com</a>&gt;<br>
&gt;To: Discuss the phobos library for D &lt;<a href="mailto:phobos@puremagic.com">phobos@puremagic.com</a>&gt;<br>
&gt;Sent: Thu, August 12, 2010 11:28:24 AM<br>
&gt;Subject: Re: [phobos] is*Range + Qualified Types<br>
<div><div></div><div class="h5">&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;On Thu, Aug 12, 2010 at 1:43 AM, Andrei Alexandrescu &lt;<a href="mailto:andrei@erdani.com">andrei@erdani.com</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt;&gt;<br>
I think the main argument is that currently most of std.algorithm doesn&#39;t work<br>
with const arrays, which have a simple &quot;tail-const&quot; version. const(T[]) is<br>
implicitly convertible to const(T)[].<br>
&gt;&gt;<br>
&gt;&gt;That doesn&#39;t apply to most other ranges, which don&#39;t have an obvious<br>
&gt;&gt;&quot;tail-const&quot; version.<br>
&gt;&gt;<br>
&gt;&gt;David, I think we need to think through a bit more before proceeding. The way I<br>
&gt;<br>
&gt;&gt;assume you want to proceed is to essentially add a special function signature<br>
&gt;&gt;for each algorithm and have it forward to the peeled version. Perhaps we could<br>
<br>
&gt;&gt;look at a simpler solution, e.g. one that would involve a language change.<br>
&gt;&gt;<br>
<br>
Fair enough.  If you think this might be better solved at the language level,<br>
that&#39;s a worthwhile discussion to have.  I do believe, though, that most ranges<br>
besides T[] do have an obvious &quot;tail-const&quot; version, since in practice most<br>
ranges are structs that have the iteration state stored inline and only use<br>
indirection to store the payload, if anywhere.<br>
<br>
At any rate, I think this is a must-solve problem.  Despite its theoretical<br>
beauty, I find D&#39;s const/immutable system to be utterly useless (and I&#39;ve made a<br>
<br>
serious attempt to use it in a real multithreaded program) for all but the<br>
simplest cases in practice, for three reasons:<br>
<br>
1.   It&#39;s too hard to create non-trivial immutable data structures, especially<br>
without relying on unchecked casts during construction.<br>
<br>
2.  So many things in Phobos (even things as simple as std.math.pow() before I<br>
recently fixed it) behave incorrectly when given const/immutable data.  This<br>
also applies to other libraries I use, including ones that I&#39;m the main author<br>
of, so I&#39;m just as guilty of it as anyone.  Given that noone, including me,<br>
seems to be able to get this right in generic code, perhaps this does point to<br>
the need for a language-level solution.<br>
<br>
3.  inout is currently so bug-ridden it&#39;s not even funny.<br>
<br>
<br>
<br>
</div></div><div><div></div><div class="h5">_______________________________________________<br>
phobos mailing list<br>
<a href="mailto:phobos@puremagic.com">phobos@puremagic.com</a><br>
<a href="http://lists.puremagic.com/mailman/listinfo/phobos" target="_blank">http://lists.puremagic.com/mailman/listinfo/phobos</a><br>
</div></div></blockquote></div><br>