questions on nullability
Burak Emir writes:
The "Nullability" proposal reads developer.mozilla.org/es4/proposals/nullability.html
zzz Classes can be defined to be non-nullable by default via a special declaration syntax:
class C! { ... }
This annotation does not imply anything about subclasses of C; they are still nullable by default unless declared non-nullable. zzz
This triggers some questions. a) can I write
var c: C = new C // (1), or var c: C! = new C // (2) or are both equivalent (3)?
They are equivalent because the name C used in a type annotation context means the same as C!, ie, null is not included.
IMHO explicit is better than implicit.
The entire reason that the class definition can be annotated is to make it easier for the programmer not to have to worry about null when using classes for which a null value does not make sense. The canonical example is "Complex": this is usually viewed as a "value type", ie, it does not normally make sense to have Complex values that can be null. You'd want to write
var c : Complex
not
var c : Complex!
everywhere.
b) assuming only (3) is allowed (it doesn't really matter here), consider the subclass mess:
class D extends C! {} // subclass can still be nullable var c: C var d: D = null ... c = d
As I understand the proposal, this should not be allowed, because C does not include null, but D does?
I don't think the language on that has been written yet. In the standard language the assignment is unproblematic; there will be a run-time check that d is not null, and an error will be thrown if it is. In the strict language I might be inclined to require a cast but this has not been discussed, IIRC. The list of strict errors does not mention this case at this time.
c) (unrelated to above) how can one turn a value of type A into a value of type A! in order to guide the typechecker? a cast? a preceding if(a!=null)?
No control flow information should be used in the type checking, so it would have to be a cast, eg,
c = cast C(d)
(redacted) writes:
lth at opera.com writes:
The entire reason that the class definition can be annotated is to make it easier for the programmer not to have to worry about null when using classes for which a null value does not make sense. The canonical example is "Complex": this is usually viewed as a "value type", ie, it does not normally make sense to have Complex values that can be null.
Isn't there then an argument for adding a syntax to provide a default value in place of null, much as int or Number are defaulted to 0?
That would not prevent you from later assigning null to a variable of that type, though, or pass null to a function taking that type.
The intent of the non-nullability proposal is to be able to add annotations to the program that guarantee that that sort of thing will not happen, and that null-pointer exceptions won't be thrown. It goes beyond creating sensible non-null default values.
There has been rather a lot of discussion about whether default values could be provided for non-nullable variables; the discussion page for the proposal records some. In practice default values are fraught with issues, not the least because you'll want default values to have "value semantics": to be either read-only or copy-on-write.
--lars
(CC'ing the discussion list even though I received the reply privately; it's of general interest. Sender's name redacted.)
Just a stab at the syntax here but, to use your Complex example:
public class Complex extends Object = new Complex (0,0) { // }
public class Complex extends Object default new Complex(0,0) { // }
This would be far more useful than simply banning null. I would expect the statement defining the default value could be made up from any static methods or compile-time constants.
(redacted) writes:
lth at opera.com writes:
The entire reason that the class definition can be annotated is to make it easier for the programmer not to have to worry about null when using classes for which a null value does not make sense. The canonical example is "Complex": this is usually viewed as a "value type", ie, it does not normally make sense to have Complex values that can be null.
Isn't there then an argument for adding a syntax to provide a default value in place of null, much as int or Number are defaulted to 0?
That would not prevent you from later assigning null to a variable of that type, though, or pass null to a function taking that type.
It would if null was automatically converted to this default value, as happens with int.
The intent of the non-nullability proposal is to be able to add
annotations to the program that guarantee that that sort of thing will not happen, and that null-pointer exceptions won't be thrown. It goes beyond creating sensible non-null default values.
Yes, I wasn't suggesting default values as a direct replacement to non-nullable annotations. But, I think default values is much better solution to the specific Complex example. In fact, I think default values would tackle most of the reasons why you'd want to annotate a class declaration as non-nullable.
However, you introduce other problems when performing explicit coercions between types and the non-nullable version. In these situations, if you end up pushing the resolution to run-time, yielding coercion errors (and possibly null-pointer exceptions if "as" operator is used) non-nullability hasn't really achieved it's objective..
There has been rather a lot of discussion about whether default values
could be provided for non-nullable variables; the discussion page for the proposal records some. In practice default values are fraught with issues, not the least because you'll want default values to have "value semantics": to be either read-only or copy-on-write.
Ok. I missed that. I'll check out the discussion pages.
--lars
(CC'ing the discussion list even though I received the reply privately; it's of general interest. Sender's name redacted.)
oops. most of the lists I subscribe to have reply-to as the list itself.
From: Lars T Hansen <lth at opera.com> Date: 15 June 2006 05:26:57 EDT [...] The entire reason that the class definition can be annotated is to make it easier for the programmer not to have to worry about null when using classes for which a null value does not make sense.
Hi Lars,
Just curious why the default is to permit null. Seems to me that it
is more common for it not to make sense for a type to include the
null value. Is it just that that would be too great a departure from
Javascript 1?
[Just getting up to speed on this project, great to see you on it!]
On Thu, 15 Jun 2006 21:31:58 +0200, P T Withington <ptw at openlaszlo.org> wrote:
From: Lars T Hansen <lth at opera.com> Date: 15 June 2006 05:26:57 EDT [...] The entire reason that the class definition can be annotated is to make it easier for the programmer not to have to worry about null when using classes for which a null value does not make sense.
Hi Lars,
Just curious why the default is to permit null. Seems to me that it is more common for it not to make sense for a type to include the null value. Is it just that that would be too great a departure from Javascript 1?
[Just getting up to speed on this project, great to see you on it!]
Hi Tucker,
backwards compatibility is probably constraining us here, though classes are new in 4th Edition so it's possible that non-nullable could be the default for class instances. In practice I suspect it may be confusing, and I also suspect that most object structures are recursive in some way and will want nullable types. But I don't recall it being discussed.
Lars T Hansen wrote:
But I don't recall it being discussed.
It was discussed briefly. Two reasons mentioned were compatibility with existing implementations (e.g. AS3) and expectations of users familiar with mainstream object oriented languages.
But I don't recall it being discussed.
It was discussed briefly. Two reasons mentioned were compatibility with existing implementations (e.g. AS3) and expectations of users familiar with mainstream object oriented languages.
A synopsis of some of the discussion is in the wiki at:
http://developer.mozilla.org/es4/discussion/nullability.html
under "Defaults".
At the risk of being tangential, is there any value in generalising the nullability concept into a pseudo type, which may be defined as the union of some set of types, with a further set of types removed?
Re-using the + and - operators, it could be something like:
function add(a:(Number+Complex-Null), b:(Number+Complex-Null)):Complex{ if(a is Number){ a = new Complex(a, 0); } return a.add(b); }
or
const ComplexOrReal = (Number+Complex-Null); function add(a:ComplexOrReal, b:ComplexOrReal):Complex{ if(a is Number){ a = new Complex(a, 0); } return a.add(b); }
Most examples that I could think of could also be accomplished with method overloading. But it seems like a feature that might be simpler to implement than overloading. Method return types would probably have to be disallowed from using one of these types though.
Peter
At the risk of being tangential, is there any value in generalising the nullability concept into a pseudo type, which may be defined as the union of some set of types, with a further set of types removed?
Re-using the + and - operators, it could be something like:
function add(a:(Number+Complex-Null), b:(Number+Complex-Null)):Complex{ if(a is Number){ a = new Complex(a, 0); } return a.add(b); }
As far as I know, "null" is a value, not a type.
It is (see developer.mozilla.org/es4/spec/chapter_6_types.html), but I don't know if the type Null (as opposed to value null) is addressable. It isn't in AS3. Since the Null type has only one member, there are currently no occasions where you would need it.
Peter
It is (see developer.mozilla.org/es4/spec/chapter_6_types.html), but I don't know if the type Null (as opposed to value null) is addressable. It isn't in AS3. Since the Null type has only one member, there are currently no occasions where you would need it.
Peter
The docs say "A type is a set of values" so I guess they're talking about runtime types there. Types at compilation have a different meaning. In particular, nullity should be threated more like a constraint than a separate type since it can be toggled.
ML-style languages for instance encode nullity by using an "option type".
type option<T> = Null | Value : T
Null is option<*>
Value(0) is option<Int>
Value("") is option<String>
In order to extract the value from an option, you have to check it first, for example by using pattern matching :
var x = Value(0); match x { Null -> // handle null
Value(n) -> // n is the Number }
With this kind of technics, it's waranty that there will never be any kind of null pointer exception.
Traditionaly OO language are using "null" a lot more, in particular because they don't enforce variable initialization upon declaration. So it's more often that we see null or not-null contraints in OO.
There are more infos there : developer.mozilla.org/es4/proposals/nullability.html
The "Nullability" proposal reads developer.mozilla.org/es4/proposals/nullability.html
zzz Classes can be defined to be non-nullable by default via a special declaration syntax:
class C! { ... }
This annotation does not imply anything about subclasses of C; they are still nullable by default unless declared non-nullable. zzz
This triggers some questions. a) can I write
var c: C = new C // (1), or var c: C! = new C // (2)
or are both equivalent (3)? IMHO explicit is better than implicit.
b) assuming only (3) is allowed (it doesn't really matter here), consider the subclass mess:
class D extends C! {} // subclass can still be nullable var c: C var d: D = null ... c = d
As I understand the proposal, this should not be allowed, because C does not include null, but D does?
c) (unrelated to above) how can one turn a value of type A into a value of type A! in order to guide the typechecker? a cast? a preceding if(a!=null)?