30.04.2013 Views

BSV by Example - Computation Structures Group

BSV by Example - Computation Structures Group

BSV by Example - Computation Structures Group

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

type-checking environment. Type checking, which occurs before program elaboration or execution,<br />

ensures that object types are compatible and that conversion functions are valid for the context.<br />

Data types in <strong>BSV</strong> are case sensitive. The first character of a type is always uppercase (there are<br />

only two exceptions: the types int and bit, compatibility with Verilog). The first character of a<br />

variable name is always lowercase. A common source of errors for beginners in <strong>BSV</strong> is to use an<br />

uppercase name where <strong>BSV</strong> expects a lower case, and vice versa.<br />

3.2 Uppercase and lowercase in type and value identifiers<br />

In <strong>BSV</strong>, the case of the first letter of an identifier is significant, whether used to describe types<br />

or values. The general principle is that an uppercase first letter introduces a constant, whereas a<br />

lowercase first letter introduces a variable.<br />

A constant type is a particular type, such as Bool, Int, UInt, Server, Action, Module, Rule, and<br />

so on. A type variable is used to represent a polymorphic type, similar to “generic” or “template”<br />

types in other languages (see Section 9 for more on polymorphism).<br />

A constant value is a particular symbolic value, such as True, False, the symbolic labels declared<br />

in all enum types, the constructors associated with any struct or tagged union type, and so on. A<br />

type variable is the familiar identifier bound to some particular value, such as x, foo, mkTb, mkDut,<br />

and so on.<br />

3.3 Typeclasses and overloading<br />

[This section can be skimmed lightly on first reading. Overloading is used in a fairly lightweight<br />

manner in subsequent sections, for which this section provides some intuition and context.]<br />

<strong>BSV</strong> makes very effective use of systematic, user-extensible overloading. For example, instead of<br />

having ad hoc definitions of how various data types are represented in bits, in <strong>BSV</strong> each such data<br />

type has a pair of overloaded functions called pack and unpack that convert from the abstract view<br />

of the type into bits and vice versa. Further, because overloading is user-extensible, the user can<br />

specify the definitions of these functions precisely, and thus specify representations precisely.<br />

In <strong>BSV</strong>, we say that there is a“typeclass”called Bits#(t,n ), which can be regarded as a set of types.<br />

Any type t in this typeclass has definitions for bit representation in n bits, i.e., it has definitions for<br />

the overloaded functions:<br />

function Bit#(n) pack (t x);<br />

function t unpack (Bit#(n) b);<br />

Each member type t in a typeclass is called an instance of the typeclass. The functions pack and<br />

unpack are called overloaded because the same function names are used for different types, and the<br />

compiler figures out the appropriate ones to use based on the actual types of their arguments and<br />

results.<br />

In most cases in the examples below, we will use a shortcut to define bit representations. Instead of<br />

a full-blown instance declaration, you will often see the phrase “deriving (Bits)” appended to a<br />

type definition, indicating to the compiler to pick the obvious, canonical bit representation. Thus,<br />

we only write a full-blown instance declaration for Bits if we need a non-standard representation.<br />

Thus, a typeclass is a construct which implements overloading across related data types. Overloading<br />

is the ability to use a common function name or operator on a collection of types, with the specific<br />

function or operator being selected <strong>by</strong> the compiler based on the types on which it is actually used<br />

(this process is called “overloading resolution”). A typeclass may include multiple data types; all<br />

data types within the typeclass share functions and operators, hence the function names within a<br />

typeclass are overloaded across the various typeclass members.<br />

24

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!