On Wednesday, 29 May 2013 at 16:24:00 UTC, Timon Gehr wrote:
On 05/29/2013 06:21 PM, Timon Gehr wrote:
On 05/29/2013 07:35 AM, Walter Bright wrote:
On 5/28/2013 9:55 PM, Diggory wrote:
As a last resort there should be a runtime check available
such as
assertNotNull(T) which does the conversion.
The idea is to put the check on assignments to NotNull, not
on usage
of it.
This is like allowing assigning 'Object' references to
'Exception'
references and adding a runtime check that the dynamic type
actually
conforms to 'Exception'.
The current behaviour is like always allowing assigning
'Object' to
'Exception' but crashing when a method that is not present in
'Object'
is called on an 'Exception' reference pointing to an 'Object'.
Obviously both of those behaviours are not very sensible.
What he is suggesting is something like this:
// TODO: Add template constraints
struct AnActual(T){
private T payload;
public T _upcastToNullable(){ return payload; }
alias _upcastToNullable this;
@disable this();
private this(T t){ payload = t; }
}
// ...
// Obviously here should be:
auto match(alias therecase, alias nullcase,T)(T t){
if(t !is null) return therecase(AnActual!T(t));
return nullcase();
}
// ...
// the following suffers from the inability to use a private
// constructor to build a non-nullable object...
auto New(T,S...)(S args){ return AnActual!T(new T(args)); }
If you put these declarations in their own module, then the
guarantee
that AnActual!T does not contain null can be provided
_statically_
without any runtime checks. (modulo unsafe constructs, as
always.)
This still does not prevent dereferencing nullable pointers.
Yay, at least someone understood what I meant! It would be nice
if things like "new" had some way to express that it will never
return "null" so that there's no need to wrap it in "New" or use
"assumeNotNull".
Perhaps "new" could return a special internal type, similar to
"typeof(null)" which normally is immediately converted to a
normal pointer or class instance, but which "NotNull" could
provide an overload for. This could also be used to avoid the
necessity of "assumeUnique" on new objects, and I'm sure there
are a bunch of other use-cases too.