digitalmars.D.learn - Is Nullable supposed to provide Optional semantics?
- Chris Paulson-Ellis (29/29) Dec 29 2017 I've been bitten by trying to use Nullable(T) on class types.
- vit (6/9) Dec 29 2017 use:
- Chris Paulson-Ellis (3/7) Dec 29 2017 Only nullify() can make isNull return true again. I need that
- Dukc (4/6) Dec 29 2017 Quick idea without much afterthought: instead of Nullable, use
- vit (14/22) Dec 29 2017 import std.typecons : Nullable;
- Chris Paulson-Ellis (9/14) Dec 30 2017 Thanks.
- Jonathan M Davis (6/18) Dec 30 2017 destroy used to be called clear (e.g. that's what TDPL calls it), but it...
- Steven Schveighoffer (17/32) Dec 30 2017 clear was renamed to destroy because clear typically is used in
- Chris Paulson-Ellis (5/6) Jan 13 2018 Sorry for the delay - stuff happened.
I've been bitten by trying to use Nullable(T) on class types. Minimal example... import std.typecons : Nullable; void main() { auto o = new Object(); o.toString(); Nullable!Object n = o; o.toString(); n.nullify(); o.toString(); // SegV! } The SEGV is caused by nullify calling object.destroy() on o, invalidating it. This makes Nullable unsafe to use with class types when there may be other references to the optional values in the program. Perhaps I'm not using the correct abstraction. I'm looking for something equivalent to java.util.Optional, or Haskell's Maybe. If Nullable(T) *is* intended to be used like Java Optional, then calling .destroy when clearing the value seems to be going beyond its remit for class types. For those confused as to why you'd want to wrap a Nullable around something that already has nullable semantics, it's mostly about making APIs that explicitly declare their optional return values. See: http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html I also want to use it in template code that works with both value & reference types. Chris.
Dec 29 2017
On Friday, 29 December 2017 at 20:52:51 UTC, Chris Paulson-Ellis wrote:I've been bitten by trying to use Nullable(T) on class types. Minimal example... [...]use: n = Nullable!Object.init; //doesn't call destroy instead of: n.nullify();
Dec 29 2017
On Friday, 29 December 2017 at 21:34:27 UTC, vit wrote:use: n = Nullable!Object.init; //doesn't call destroy instead of: n.nullify();Only nullify() can make isNull return true again. I need that semantic.
Dec 29 2017
On Friday, 29 December 2017 at 21:43:25 UTC, Chris Paulson-Ellis wrote:Only nullify() can make isNull return true again. I need that semantic.Quick idea without much afterthought: instead of Nullable, use pointer to o?
Dec 29 2017
On Friday, 29 December 2017 at 21:43:25 UTC, Chris Paulson-Ellis wrote:On Friday, 29 December 2017 at 21:34:27 UTC, vit wrote:import std.typecons : Nullable; auto o = new Object(); Nullable!Object n; assert(n.isNull == true); n = o; assert(n.isNull == false); n = Nullable!Object.init; assert(n.isNull == true); o.toString(); //OK assert(Nullable!Object.init.isNull == true); more: https://forum.dlang.org/thread/jrdedmxnycbqzcprebjl forum.dlang.org?page=1use: n = Nullable!Object.init; //doesn't call destroy instead of: n.nullify();Only nullify() can make isNull return true again. I need that semantic.
Dec 29 2017
On Friday, 29 December 2017 at 22:08:59 UTC, vit wrote:n = Nullable!Object.init; assert(n.isNull == true); [...] more: https://forum.dlang.org/thread/jrdedmxnycbqzcprebjl forum.dlang.org?page=1Thanks. No-one in the linked thread seemed to know why .destroy is used in nullify. Looking at the commit history it used to be .clear, but maybe that did the same thing, I don't know. I still think nullify is going beyond the Nullable remit for reference types. Unless anyone disagrees, I'll submit a bug report. C.
Dec 30 2017
On Saturday, December 30, 2017 08:59:40 Chris Paulson-Ellis via Digitalmars- d-learn wrote:On Friday, 29 December 2017 at 22:08:59 UTC, vit wrote:destroy used to be called clear (e.g. that's what TDPL calls it), but it was renamed, because it was too easily confused with clearing a container and tended to be misused. - Jonathan M Davisn = Nullable!Object.init; assert(n.isNull == true); [...] more: https://forum.dlang.org/thread/jrdedmxnycbqzcprebjl forum.dlang.org?page =1Thanks. No-one in the linked thread seemed to know why .destroy is used in nullify. Looking at the commit history it used to be .clear, but maybe that did the same thing, I don't know.
Dec 30 2017
On 12/30/17 3:59 AM, Chris Paulson-Ellis wrote:On Friday, 29 December 2017 at 22:08:59 UTC, vit wrote:clear was renamed to destroy because clear typically is used in containers to remove all elements (but not destroy the container itself). Since clear was a UFCS function, it led to confusion: somestruct.clear; // equivalent to clear(somestruct), destroys it. container.clear; // remove all elements clear(container); // destroy the container So destroy was used instead, and it's a much better name.n = Nullable!Object.init; assert(n.isNull == true); [...] more: https://forum.dlang.org/thread/jrdedmxnycbqzcprebjl forum.dlang.org?page=1Thanks. No-one in the linked thread seemed to know why .destroy is used in nullify. Looking at the commit history it used to be .clear, but maybe that did the same thing, I don't know.I still think nullify is going beyond the Nullable remit for reference types. Unless anyone disagrees, I'll submit a bug report.I think you are correct. I believe it is calling destroy expecting it to work like calling destroy on a pointer (which does nothing I think, or just sets it to null). But it doesn't work that way. What may have been missed by the others is that the call to toString that caused the segfault was NOT on the nullable `n`, but on the original object `o`. So nullifying the nullable kills any other references to the same object. Please file a bug report. -Steve
Dec 30 2017
On Saturday, 30 December 2017 at 19:11:05 UTC, Steven Schveighoffer wrote:Please file a bug report.Sorry for the delay - stuff happened. I reopened an existing bug that I found: https://issues.dlang.org/show_bug.cgi?id=17440
Jan 13 2018