Adding the ?. null verification

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 19 14:04:09 PDT 2014


On Thu, Jun 19, 2014 at 01:51:17PM -0700, H. S. Teoh via Digitalmars-d wrote:
> On Thu, Jun 19, 2014 at 04:29:12PM -0400, Etienne via Digitalmars-d wrote:
[...]
> > meh, this works:
> > 
> > 
> > writeln(currAssignment.safeDeref.typeInfo.ident.or("meh"));
> > 
> > ..
> > 	static struct SafeDeref {
> > 		T t;
> > 		
> > 		// Make the wrapper as transparent as possible.
> > 		alias t this;
> > 
> > 		// this overrides if null
> > 		T or(T defVal){
> > 			if (t is t.init)
> 
> This assumes that t.init is not a possible valid field value. But in
> that case, there's no need to remap it, you just check for t.init
> instead. For pointers, where .init is null, this isn't a problem, but
> for things like int, where 0 is possible valid value, you may be
> accidentally mapping 0 to the default value when the given field
> actually exists (and has value 0)!
[...]

Actually, on second thoughts, maybe it *is* possible after all. The key
is to differentiate between null-able types, and non-nullable types. For
the latter, we expand the SafeDeref struct to store a boolean flag to
indicate whether or not the value exists, then .or() can check that flag
to see if it should return the default value. Basically, something like
this:

	struct SafeDeref {
		T t;

		static if (!is(t = null))
			bool exists = true;

		...
		T or(T defVal) {
			return (exists) ? t : defVal;
		}
		...
		auto opDispatch(...) {
			...
			if (t is null)
				return safeDeref(Memb.init, false)
			else
				return safeDeref(__traits(getMember...), true);
		}
	}

I'll try this out to see if it works!

This also has the advantage of becoming even closer to a real monad: by
checking for .exists, we can also overload operators to return a wrapper
with exists=false whenever one of the operands also has exists=false.


T

-- 
Why can't you just be a nonconformist like everyone else? -- YHL


More information about the Digitalmars-d mailing list