Re: [Vala] non-null broken in vala 0.9.3



Hey!

On Fri, 2010-07-16 at 00:38 +0200, Aleksander Wabik wrote:
Hi all,

to my surprise, I've observed today a bug in vala 0.9.3 bindings:
compilation of anything fails when using
--enable-experimental-non-null. The error that I'm observing is:

glib-2.0.vapi:1134.15-1134.22: error: Access to instance member
`string.size' from nullable reference denied 
      str_size = str.size ();
glib-2.0.vapi:2698.5-2698.16: error: Access to instance member
`GLib.StringBuilder.append_c' from nullable reference denied
      ret.append_c ((char) c);
glib-2.0.vapi:2703.12-2703.18: error: Access to instance member
`GLib.StringBuilder.str' from nullable reference denied 
      return ret.str;

I posted a patch up for this, but no one seemed to notice...


I'd like to initiate some discussion about the future of this feature,
because I think that the change introduced in vala 0.9.3 - inability to
call methods and to access fields of possibly-null objects - is
disappointing to me...

PART ONE: my private disappointment.

To me using enable-experimental-non-null was a way to provide basic
compile-time sanity check of my code. Of course this check did not
cover every null-dereference crash bugs - only assignment of nullable
variable to non-null variable. But it was nice. What I get now is a
need to traverse all my sources and fix every of 157 errors (and it's
not a big project that I'm working on!) - what should I do?

1) go back to vala 0.9.2 and use it for builds in debug mode (where I
use experimental-non-null)?
2) quit using experimental-non-null?
3) fix all these errors by adding (!) everywhere, and keep using (!)
everywhere in the future just to suppress all these error messages
(and get feeling of being secure, but I'd not be secure if I add (!)
everywhere in furious attempt to make my code just compile again...)

I think going back to 0.9.2 is probably the best bet for now, until the
future of non-null is known.

Personally I think adding (!) everywhere is the worst idea possible.

PART TWO: rationale of reverting to old behaviour.

Why do I think that enforcing nullchecking by assignment 'non-null =
(!)nullable' is good, and enforcing checking when accessing members is
bad? Well: the first one is a contract programming technique, the
second is not.

I disagree.  I think one of the most basic contracts is that an object
is non-null when you access its members.  Its an implicit contract that
is very important.

When I'm passing nullable object to another function (which takes
non-null argument) or when I receive it from another function, it is a
situation when some foreign object is obtained. That is the place for
performing sanity checks on it, including nullchecking.

When I'm calling a method on an object, it's mostly a local
object / member variable, something that is, well, not foreign.
It's not passing data, but using data. Therefore I think that enforcing
such strict behaviour then is not desired. It would be also redundant
to what I've seen up till now: when in runtime you call methods with
null 'self', you get glib assertion.

I think the idea behind a language with non-null types is to use
algorithms that never need a null value except to handle inputs and
outputs.  IMO, if you have a nullable variable, you have a design
problem.

So. What can I do with a nullable object now? I cannot assign it to
non-null - good. I cannot access any of it's fields or properties. I
cannot call it's variables. It seems to me that I cannot do ANYTHING
beside checking it with (!) - any other manipulation is possible after
this. So probably the only reasonable code with nullables will look like
this:

      if(foo == null)
              throw ...
      else
              bar = (!)foo;
      // foo is not used below

Should this be the only nullables' purpose in vala?

Yes!

PART THREE: the ideal world.

To be honest, I'd welcome turning these errors into warnings,

If non-nullable types ever get out of experimental, then they should
only generate warnings (with an option to make them errors.)  One of my
biggest problems with Java is it forcing you to handle exceptions and I
don't want nullable types to be a repeat of that.

 or
creating another command-line switch
(--enable-super-strict-experimental-non-null). But there would be in
fact a lot better (and a lot more time-consuming) solution: let's
leave vala 0.9.3 behaviour, but extend it with algorithms which will
decide if there's a possibility of null dereference or assignment to
non-null object. For example this should produce no warning nor error:

      if(some_nullable == null)
              return 1;
      some_nullable.foo();
      Foo non_null = some_nullable;

It'd mean enabling very powerful static code analysis to vala, and
obviously I'd like to have non-null feature meaning powerful static
code checking than to have non-null being crappy, useless feature
that breaks glib vapis...

Bringing static code analysis would be amazing, but I have a feeling
that detecting when a variable is considered safe is an undecidable
problem (http://en.wikipedia.org/wiki/Undecidable_problem ).  Not sure
though.

PART FOUR: afterword

Well that's all. Please don't take this email as an offence - I know
that you're guys working really hard to make vala more and more
cool. I'm trying to help sometimes, reported a few bugs... :) And please
don't take this email as an "angry user change request", well, I'm
angry and I have my own vision of what should my favourite language be,
but I want to discuss this vision, not enforce it.

Same goes for me!  So far vala is the closest thing to what I want in a
language, and I think sharing the opinions of its users is a good idea.

Sam




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