Type inference in Buoy

So what is type inference ?

Compilers are pretty danged smart and they can be used to make the developers life easier

And they can correctly guess what you mean - or they can INFER what you mean from what they know

And determining what data type a variable should be is one of those things

For instance if I wrote

   dim key as string = "123"
    
   Print key

   var key2 = key + "456"

   print key2

The compiler can correctly determine that KEY2 MUST be a string as well because

  • KEY is a string
  • the literal we’re appending to KEY is also a string
    so the only sensible out come is that KEY2 is ALSO a string

And so that is precisely what happens

If we had done

    dim key as string = "123"
    
    Print key

    var key2 = key + 456

    print key2

we get an error
The compiler cannot correctly figure out if we want

  • KEY2 to be a string (since KEY is a string)
  • or if KEY2 should be numeric because were trying to add a number to KEY

and in this case you get an error since it cannot determine which you meant

I don’t know what Buoy does, but while type inference is straightforward for string.it could be dangerous for numeric types. I think I would rathe declare ties for everything because that way you are always intentional… But then again, since I became head of quality at my current employer, I get a lot of push back from the manufacturing people when trying to apply that principle in biotech manufacturing broadly!

Well it won’t do what you seem to be fearing

  var i as integer = 10

    print i

    var i2 = i + 1.98

    print i2

i2 will NOT be converted to a double or float

the compilation will fail on the line where the ambiguity exists because

  • i2 could be a float / double
  • i2 could be an integer by truncating the literal to 1

so you have to be explicit

On the other hand anyone reading the code (including the author, six months on) may not be clear on what was intended and would have slightly more cognitive burden in determining that since it’s not implicitly declared. Whoops is that a mistake in the code, or … doesn’t seem right … well the compiler allows it, okay, it’s a string. Too many cognitive hoops to jump through, especially as one’s brain ages.

Personally I prefer the compiler to require me to be unambiguous in some way and for the syntax to reinforce clear, unsloppy thinking. Obviously we could have a cordial disagreement about how far is too far to go here. In C#, var isn’t just a synonym for dim, it is literally asking the compiler to do type inference, yet I generally only use it when the type is explicit somewhere else in the line, e.g.

var foo = new Something(); // yes
var foo = bar              // no
Something foo = bar        // yes

In line 2, I don’t know what type bar is. I’d have to look at the preceding lines or maybe even do a find to figure that out. I want the line itself to be self evident and I want to read through code smoothly and sequentially.

The corollary to this principle is that at least if the compiler will accept the 2nd example line, it doesn’t insist on doing so, and I can still impose my own personal discipline as in line 3.

I just worry that a language becomes less universally clear when it doesn’t require something to identify all types on the line and allows looser styles of coding. It’s a small step on the slippery slope to things like macros in C where you can redefine the language to the extent that it requires occult knowledge or deep research to figure it out. Job security for the original author I suppose, lol.

inference is indeed optional

you are not required to use it and can always explicitly declare things however you like and do explicit conversions to make your code clear in whatever way you like

same as in C# :stuck_out_tongue:

Where in C# inference is indicated by the VAR keyword buoy makes no such distinction

FWIW I’m just writing this as I find it and am in no way the “designer” of the language

I make suggestions to Greg and he’s free to accept or reject them as he sees fit

This is the way Go does it. Even though they’re both numeric they are different numeric types and thus have to be converted explicitly. Yes, it can be a little annoying but it’s very safe.

Widening conversions are, as far as I understand, OK

so assigning an int16 to an int32 loses nothing

narrowing ones have to be explicit
so assigning as int32 to an int16 because you may lose precision