<div dir="auto">For the record, the "public" version of runRW# is called unsafeDupablePerformIO. It would be a good idea to find out if it can be used throughout bytestring without a significant penalty. If so, that would eliminate a bunch of scary stuff. If not, it would be nice to understand why.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mar 4, 2018 4:48 PM, "Ben Gamari" <<a href="mailto:ben@smart-cactus.org">ben@smart-cactus.org</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ben Franksen <<a href="mailto:ben.franksen@online.de">ben.franksen@online.de</a>> writes:<br>
<br>
> Am 04.03.2018 um 15:58 schrieb Ben Gamari:<br>
>> I'm afraid it's not possible to provide the interfaces exposed by<br>
>> bytestring without some form of unsafety. Lazy IO alone requires<br>
>> unsafeInterleaveIO and the bytestring indexing operations require at<br>
>> very least unsafePerformIO since GHC treats access to foreign memory<br>
>> as an effect.<br>
><br>
> I am well aware of that.<br>
><br>
>> accursedUnutterablePerformIO is an optimized form of unsafePerformIO<br>
>> which likely won't cause any issues that wouldn't otherwise manifest<br>
>> with plain unsafePerformIO. Consequently I am not sure it's worth<br>
>> providing a means to disable its usage.<br>
><br>
> I envy your confidence. The documentation mentions two bytestring<br>
> commits that fix bugs by reverting accursedUnutterablePerformIO to<br>
> unsafePerformIO. I guess this is plain evidence that there can in fact<br>
> be "issues that wouldn't otherwise manifest with plain unsafePerformIO".<br>
><br>
Ahh yes, I had forgotten that accursedUnutterablePerformIO is<br>
implemented directly in terms of realWorld#. This implementation is<br>
terribly bug-prone since floating can result in inappropriate sharing,<br>
as seen in the tickets referred to in the documentation.<br>
<br>
However, GHC 8.0 and later offer a much safer primitive, runRW#, which<br>
can be used to implement things like accursedUnutterablePerformIO<br>
without fear of over-zealous simplification. I believe the issues<br>
pointed out in documentation could not have happened with an<br>
implementation built on runRW#. Moreover, I highly doubt that the<br>
switching to runRW# would incur any measurable performance penalty.<br>
<br>
<br>
> Anyway. Would you perchance have any idea what could possibly make a<br>
> program work fine with the first version of linesPS and crash with the<br>
> second one? I find this pretty scary and would like to understand it.<br>
><br>
Indeed that is quite scary. The cause is not at all obvious. Do you have<br>
an isolated reproducer that you could share?<br>
<br>
Cheers,<br>
<br>
- Ben<br>
<br>______________________________<wbr>_________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/libraries</a><br>
<br></blockquote></div></div>