On Mon, Apr 05, 2010 at 14:10:23 -0700, Adam Dingle wrote:
> I've noticed that Vala forces generic types to be non-nullable when
> instantiated with a primitive type.

Quite the opposite. Generic types in Vala can only contain reference types or
int, so all other struct types need to be boxed using '?'. Enums and boolean
should behave like int for this purpose, but I am not sure it's currently
handled.

> For example:
> 
> public class List<T> {
>  public T? abc() { return null; }
> 
>  public bool def(T? t) { return t == null; }
> }
> 
> void main() {
>  List<int> list = new List<int>();
>  int? i = list.abc();   // i receives the value 0, not null
>  bool b = list.def(null);   // compiler error: cannot convert from
> null to int
> }

What is going on here is that boxing of the type parameter is not
supported since it has to be boxed. 'int' is a special case, which would need
special-case code and there's none generated.

> Is this behavior by design?  I suspect that it is: this allows the
> compiler to generate only one copy of List<T> and use it for all
> instantiations including both reference and primitive types.  If
> this is a compromise by design, I think that it's a reasonable one,
> though it would be nice to know whether we can expect this behavior
> to remain the same in the future.  :)

There is indeed only one code for List<T>. That is so the generic code can be
placed in a library and used from separate code. In this it's similar to Java
generics and different from C++ templates that need to be fully defined in
headers.

> The above has a practical consequence when using generic collections:
> 
> HashMap<int, int> m = ...;
> int? i = m.get(5);
>
> Now i receives the value 0 (not null) if the element is absent.

It returns T, which is int, NOT int?, so you don't expect it to return null,
do you?

> On a related note, I've noticed that 'valac --vapi' makes generic
> types non-nullable.  If I generate a VAPI file for the List class
> above it looks like this:
> 
> public class List<T> {
>    public List ();
>    public T abc ();
>    public bool def (T t);
> }
> 
> Is this a bug?  Conceivably the nullable types are erased in the
> VAPI file as a warning to callers that they will not actually be
> nullable when the class is instantiated with a primitive type, given
> the behavior above.  But there doesn't seem to be much point to
> that, since callers must expect this same behavior when nullable
> types are present in a generic class anyway, even one which is not
> defined via a VAPI file.  Is there some other reason why the types
> should not be nullable in the VAPI file?

As explained above, T is always reference type, so T? makes no sense.

The generic is compiled with just void * and pointers to correct copy/ref and
destroy/unref functions are passed around. Since it is already pointer, it is
already nullable, so conversion to nullable does nothing. All types are boxed
to be representable by void *. Except int, which is simply cast to void *
(sizeof(int) <= sizeof(void *) on all platforms), but that makes it
non-nullable.

Note though, that you can substitute 'int?' as the template parameter and
than there will be difference between null and 0 (and a huge memory overhead
for allocating the storage).

-- 
                                                 Jan 'Bulb' Hudec <[email protected]>
_______________________________________________
Vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to