Ok, now I get why using Unqual to get tail const wouldn't work. My silly oversight:<br><br><span style="font-family: courier new,monospace;">// The following doesn'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"><<a href="mailto:schveiguy@yahoo.com">schveiguy@yahoo.com</a>></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's switch to "tail-const doesn't work".<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>
><br>
>From: David Simcha <<a href="mailto:dsimcha@gmail.com">dsimcha@gmail.com</a>><br>
>To: Discuss the phobos library for D <<a href="mailto:phobos@puremagic.com">phobos@puremagic.com</a>><br>
>Sent: Thu, August 12, 2010 11:28:24 AM<br>
>Subject: Re: [phobos] is*Range + Qualified Types<br>
<div><div></div><div class="h5">><br>
><br>
><br>
><br>
>On Thu, Aug 12, 2010 at 1:43 AM, Andrei Alexandrescu <<a href="mailto:andrei@erdani.com">andrei@erdani.com</a>> wrote:<br>
><br>
><br>
>><br>
I think the main argument is that currently most of std.algorithm doesn't work<br>
with const arrays, which have a simple "tail-const" version. const(T[]) is<br>
implicitly convertible to const(T)[].<br>
>><br>
>>That doesn't apply to most other ranges, which don't have an obvious<br>
>>"tail-const" version.<br>
>><br>
>>David, I think we need to think through a bit more before proceeding. The way I<br>
><br>
>>assume you want to proceed is to essentially add a special function signature<br>
>>for each algorithm and have it forward to the peeled version. Perhaps we could<br>
<br>
>>look at a simpler solution, e.g. one that would involve a language change.<br>
>><br>
<br>
Fair enough. If you think this might be better solved at the language level,<br>
that's a worthwhile discussion to have. I do believe, though, that most ranges<br>
besides T[] do have an obvious "tail-const" 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's const/immutable system to be utterly useless (and I'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'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'm the main author<br>
of, so I'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'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>