Subject: Exported From Confluence
Content-Type: text/html; charset=UTF-8
Boo is a statically typed language.
Static typing is about the ability to type check a program for type corr=
Static typing is about being able to deliver better runtime performance.=
Static typing is not about putting the burden of declaring types on the =
programmer as most mainstream languages do.
The mechanism that frees the programmer from having to babysit the compi=
ler is called type inference.
Type inference means you don't have to worry about declaring types every=
where just to make the compiler happy. Type inference means you can be prod=
uctive without giving up the safety net of the type system nor sacrificing =
Boo's type inference kicks in for newly declared variables and fields, p=
roperties, arrays, for statement variables, overriden methods, method retur=
n types and generators.
Assignments can be used to introduce new variables in the current scope.=
The type for the new variable will be inferred from the expression on the =
s1 =3D "=
foo" # declare new variable s1
s2 =3D s1.Replace("f", "b") # s1 is a string so Replace is cool
Only the first assignment to a variable is taken into account by the typ=
e inference mechanism.
The following program is illegal:
s =3D "I=
'm a string" # s is bound with type string
s =3D 42 # and although 42 is a really cool number s can only hold strings<=
_name =3D ""
Declare the new field _name and initialize it with an empty string. The =
type of the field will be string.
When a property does not declare a type it is inferred from its getter.<=
=C2=A0 =C2=A0 =C2=A0Answer:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 get: return 42
In this case the type of the Answer property will be inferred as int.
The type of an array is inferred as the least generic type that could safely hold all of its enclosing eleme=
a =3D (1=
, 2) # a is of type (int)
b =3D (1L, 2) # b is of type (long)
c =3D ("foo", 2) # c is of type (object)
For statement variables
=3D (" John ",
for name in names:
# name is typed string since we are iterating a string array
print name.Trim() # Trim is cool, name is a string
This works even when with unpacking:
a =3D ( =
(1, 2), (3, 4) )
for i, j in a:
print i+j # + is cool since i and j are typed int
When overriding a method, it is not necessary to declare its return type=
since it can be safely inferred from its super method.
override def ToString():
Method return types
The return type of a method will the =
most generic type among the types of the expressions used in return sta=
# multiply operator is cool since spam() is inferred to return a string
# and strings can be multiplied by integer values
e(returnString as bool):
return "42" if returnString
# ltuae is inferred to return object
print ltuae(false)*3 # ERROR! don't know the meaning of the * operator
When a method does not declare a return type and includes no return stat=
ements it will be typed System.Void.
g =3D i*=
2 for i in range(3)
# g is inferred to generate ints
for i in g:
print i*2 # * operator is cool since i is inferred to be int
# works with arrays too
a =3D array(g) # a is inferred to be (int) since g delivers ints
print a + a[-1] # int sum
A Word of Cauti=
on About Interfaces
When implementing interfaces it's important to explicitliy declare the s=
ignature of a method, property or event. The compiler will look only for ex=
In the example below the class will be considered abstract since it does=
not provide an implementation with the correct signature:
=09def AllThroughTheNight(iMeMine, iMeMine2, iMeMine3 as int)
=09def AllThroughTheNight(iMeMine, iMeMine2, iMeMine3):
e =3D EvenThoseTears()
k. So where do I have to declare types then?
Let's say when.
- when the compiler as it exists today can't do it for you. Ex: parame=
ter types, recursive and mutually recursive method/property/field definitio=
ns, return for abstract and interface methods, for untyped containers, prop=
erties with a only set defined
def Method(param /* as object */, i as int) as string:
def fat([required(value >=3D 0)] value as int) as int:
return 1 if value < 2
for i as int in [1, 2, 3]: # list is not typed
- when you don't want to express what the compiler thinks you do:
) as object: # I want the return type to be object not string
# a common scenario is interface implementation
return "a string"
a =3D 3 # a will be typed int
a =3D "42" # uh, oh
- when you want to access a member not exposed by the type assigned to=
f as Sys=
tem.IDisposable =3D foo()
- when you want to use Duck Typin=
=C2=A0=C2=A0=C2=A0 type =3D System.Type.GetTypeFromProgID(progid)
=C2=A0=C2=A0=C2=A0 return type()
ie as du=
ck =3D CreateInstance("InternetExplorer.Application")
ie.Visible =3D true