Re: [Vala] Why do regular reference types leak null?



Why shouldn't they be null? IMO, it would just add much more trouble.
Checking nulls is responsibility of the programmer. That is consistent with
every other language I know, including dynamic ones, C#, Java, etc.

Perhaps I am misunderstanding the purpose of nullable types. The Vala
tutorial explains, "By default, Vala will make sure that all reference
point to actual objects." As I understand, the whole point of Foo? is
so that we can have nulls without infecting Foo with a null variant.

I don't think I understand what you mean. For reference types, there is no
technical difference between Foo and Foo?, except as the marking of
arguments and return values that must not be null (that's checked in the
method by simple assertions). You can't do any "cast" there.

By cast I mean that there must be some way to get a Foo out of a Foo?.
When I encounter a Foo? I should (ideally) not be allowed to
dereference it unless I have first ensured it is not null by
transforming it into a Foo. Vala is not dependently typed so the
preceding operation isn't generally supported but I believe that nulls
are important enough to warrant special handling. The Foo/Foo?
dichotomy is precisely that special case. The only thing we're missing
are the static checks to make it usable, IMHO.

Here's what I mean by dependently typed.

// f is Foo?
if (f != null) {
  // f is Foo
}

Of course the conditional would have to be statically verifiable. If
it is not then f would remain Foo? inside the consequent branch. But
disallowing dereference for Foo? is perhaps too draconian for Vala
since the constraint could be enforced elsewhere and making the
programmer put every use of Foo? in a dependently typed block is
insane.

But still, assignment ...

        Foo? fn = null;
        Foo f = fn;

breaks the guarantee of Foo pointing to an actual object. So the only
way Vala can keep the guarantee is to disallow assignment in the Foo
<- Foo? direction. Foo? <- Foo is safe because Foo is a varient of the
Foo? = (Foo | null) type.

Foo? fn;
Foo f;
...
f = fn; // unsafe
if (f != null) {
  f = fn; // safe
}

But Vala can't prove that the null-checked assignment is safe. This
means that the difference between Foo and Foo? is nonexistent from the
programmers point of view. I see a Foo and it might need a null check,
or it might not. If Vala could statically enforce that type Foo
references an object it would save lots of work. As it is, I treat Foo
essentially as I would Foo?. The tutorial also says "These checks are
performed at run time..." Well, An error message is better than a core
dump but that only changes debugging, not the way the language is
used. Essentially the ? just causes causes runtime null-checks to be
skipped. Why modify the type system for that?

Jürg already knows this stuff and more, and he can probably find
multiple errors in my reasoning. But the design of Vala is tantalizing
close to allowing a static checks. I can't see why the checks are
deferred to runtime.

You can use '?' to box simple types, though. There is a bug when casting
them. For example, when casting int? to int, you get a pointer, not the
value, so be careful with that. Simple assignment from nullable to normal
int works fine.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]