Search code examples
chapel

Where do you put the type in Chapel variable declarations?


Where do you put the type in Chapel variable declarations?

More specifically, what’s the difference between var a = 42: int; and var a: int = 42;?


Solution

  • Three basic background facts for this question:

    1. Chapel's variable declaration syntax is: var ident: type = init;

    2. Chapel supports compile-time type inference

    3. In Chapel, : serves two roles:

      • as the type specifier or constraint when declaring new symbols
      • as the cast operator when applied to an expression

    Given that, the declaration:

    var a: int = 42;
    

    says "declare a variable named a, whose type is int and whose initial value is 42." Whereas,

    var a = 42: int;
    

    says "declare a variable named a, whose type (since it's not specified) will be inferred from its initializer, which is the value 42 cast to an int."

    Now, in Chapel, 42 is interpreted as an int by default, so this final declaration is really no different than:

    var a = 42;
    

    and all three of the declarations above have the same net effect.

    Things get slightly more interesting when you mix different types. For example:

    var b: int(8) = 42;
    

    says that b should be an 8-bit integer whose initial value is 42. In Chapel, even though the inferred type of 42 is int (which is a 64-bit int), since it is a literal value that can be represented in fewer than 8 bits, the compiler will automatically downcast it to fit into an int(8).

    Or, the downcast could be made explicit, using the following form:

    var b = 42: int(8);  // downcast to int(8) and infer the type
    

    But consider:

    var c: int(8) = a;
    

    this will be an error because a is a default int variable (64 bits) and Chapel doesn't support implicit downcasts from variables of wider int representations to narrower ones. So in this case, you'd need to write this declaration as one of the two forms:

    var c = a: int(8);          // explicitly downcast and infer the type
    var c: int(8) = a: int(8);  // give an explicit type and also explicitly downcast to make the initializer compatible
    

    Needless to say, since this second form is a bit pedantic, we tend to prefer the former of the two.