Types in BBj

Types

In programming languages, the word "type" indicates a description of some data and a group of behaviors that use or affect that data. Business BASIC began as a language with only three atomic types and arrays of those types. The atomic types were numbers, integers, and strings. Declaring the type of a variable consisted of simply adding a single character suffix to the variable name.

BASIS has introduced objects, types, and typechecking into the Business BASIC language in BBj. While types indicate the description of data, objects hold data that conform to that description. BASIS introduced a new suffix to represent a variable that contains an object value. Typechecking allows the programmer to catch errors associated with types at compile time, such as assigning an expression that produces one type to a variable with a different, incompatible type. BASIS also introduced a compiler option to BBjCpl to perform type checking.

Object Types

BBj supports three different types of objects: Java objects, BBjAPI objects, and Custom objects. Java objects are instances of a Java type. A Java class provides the type description and must be in BBj's classpath, which is configurable through Enterprise Manager. BBjAPI objects are built-in objects created using the BBjAPI. These include such objects as BBjNamespace, BBjVector, and BBjButton. Custom objects are instantiated from Custom Classes, which the developer creates in BBj using the CLASS Verb.

Variables, Parameters, and Fields

Variables are names that hold values. Variable names are not case sensitive: A variable name of "apple" can be referred to as "Apple" or "aPPlE" at another place in the program. It is not recommended programming practice, however, to refer to the same variable names using different case or to create variable names where the case of each letter is difficult to remember. A variable's suffix partially indicates its type. A DECLARE statement further restricts a variable's type to the type specified.

Parameters are variables that hold values passed to functions, public programs and methods (collectively called "routines"). When invoking a routine, the runtime system implicitly assigns the values in the argument list of the routine to the corresponding parameter in the definition of the routine before executing its code. Function definitions, created using the DEF FN verb, may only specify an appropriate type for a parameter according to the parameter name's suffix. Functions have long been a part of BBx, and BBj remains backwards compatible with the original design that the function parameters have global scope and are no different than a variable of the same name. Assignment to the parameter, whether explicit by assignment or implicit by invoking the function, affects the value of the variable both inside and outside the code for the function. Like variables, function parameter names are not case sensitive.

Public programs specify their parameters with an ENTER statement. Like function definitions, the ENTER statement does not facilitate constraining the types of arguments being passed to the program, except by the suffixes used in the parameter names. The CALL Verb syntax allows the programmer to specify whether assignments to parameters in the called program will affect the calling program's variables. Consult the CALL Verb documentation for more details Public program parameters are not case-sensitive.

Method parameters require a type in the declaration in addition to the parameter name's suffix. This serves the same purpose as a DECLARE statement for a variable. Whenever the parameter is used, it may only contain values of its designated type, whether the values come from the arguments passed to the method, or the method body manipulates the parameter's value. Method parameters are only known within the method. BBj passes values of BBjInt, BBjString, and BBjNumberby value while passing objects by reference. Parameter names are not case sensitive.

Fields are similar to variables, but are only visible in the enclosing CLASS definition. They are strongly typed and case-sensitive. Fields are declared using the FIELD verb, which requires that a type for the field be specified. Fields are case-sensitive, unlike parameters to routines. See the BBj Custom Objects Tutorial for more information about the syntax and use of field values.

Variable, Parameter, and Field names must begin with a letter and may contain any combination of letters, numbers and underscores. The variable name must end in a suffix according to its declared type. Most suffixes indicate that the variable, parameter, or field has an atomic type – i.e., it stands for a literal value and does not provide any methods. The "!" suffix indicates the variable, parameter, or field is an object or a Java type.

Suffixes

Type

Suffix

Examples

BBjNumber

No suffix or "!"

Temperature, altitude!

BBjInt

"%" or "!"

counter%, quantity!

BBjString

"$" or "!"

name$, address!

Object

or Java type

"!"

customer!

Note: The "!" suffix, valid for all types, specifies an object or Java type and not an atomic BBj type.

Return Value

Functions and methods return values to the code that invoked them. The return type of a function is specified by the suffix on the function name. The return type of a method is specified in the METHOD statement. Often, these will be used in a larger expression or assignment. The return type of the function or method must be compatible with the value expected by the rest of the expression. Consider the BBx DATE() function, which returns the date as a human-readable string. BBj will only allow this value in an expression or assignment that expects a string; for example, assigning to a string variable or passing as an argument to a function that declares a string parameter.

CASTing and the concepts of Runtime Types and Static Types

Expressions in BBj have two types they may produce: the runtime type and the static type. The runtime type of an expression is the type of the value produced by the expression. The interpreter cannot generally determine the value of an expression until the program executes. The value's type, therefore, cannot be determined until runtime. Examining the expression's source code and its context, however, provides BBj with enough information to give a guarantee that a value's runtime type will share the "is-a" relationship with another type. This type is called the "static type." In the most trivial example, since all values are assignable to a java.lang.Object, BBj guarantees that every expression produces a value with a type that "is-a" java.lang.Object. The BBx DATE() function is guaranteed to return a BBjString, and so the static type and the runtime type of the DATE() function is BBjString. The BBjWindow.getControl(num) method declares that it returns a value of type BBjControl, which is the static type. However, the runtime type of BBjWindow.getControl(num) may be a BBjButton or a BBjListBox.

BBj allows assignments from an expression with static type typeA to a variable with declared type typeB if typeA "is-a" typeB. A programmer may explicitly request that an otherwise illegal assignment be attempted in two ways.

 

Consider the following example:

DECLARE BBjControl ctrl!
DECLARE BBjVector vec!
DECLARE BBjButton btn!
DECLARE AUTO BBjButton autoBtn!
DECLARE BBjSysGui sysgui!

REM ' Open the sysgui, create a window with button 101
...

ctrl! = window!.getControl(101)

REM ' Next line requires a CAST(), the following does not
btn! = CAST(BBjButton, ctrl!)

autoBtn! = ctrl!

In this code section, the variable ctrl! on the right-hand side of the assignment (RHS) has static type BBjControl. The runtime type of the assignment is unknown. It's possible another portion of the code may have called destroy() on the BBjButton and replaced it with a BBjListBox, for instance. However, a programmer who inspects this code might reasonably expect that no such code exists and that the value contained in the ctrl! variable will have a BBjButton. In this case, it's possible for the programmer to temporarily relax the constraints of static typing by using two different BBj elements as shown above.

The first line after the REM uses the CAST() function. The CAST() function takes a type and any value. It will attempt to ensure the runtime type of the value shares the "is-a" relationship with the cast type. If it does, BBj accepts that the static type of the CAST() function is the cast type. If the runtime type of the value does not share the "is-a" relationship with the cast type, the CAST() function causes a runtime error. The CAST() function serves to identify to another reader that a runtime error may occur at the given location.

There are cases where the code requires a CAST() because the static type of an expression is too broad, or the expression contains a general-purpose sub-expression that makes it impossible for BBj to determine a more specific static type. If it's obvious that the code will produce a specific type, programmers may wish to use the DECLARE AUTO syntax, as is done with the variable autoBtn! above. The use of the AUTO modifier relaxes the constraint that assignments to autoBtn! require a CAST(). The typechecker will issue a warning instead of an error in this case, and the code will run as though there is an CAST() function on assignment to such variables.

See Also

Type Checking

Why Use Custom Objects

Custom Object Tutorial

CLASS Verb

INTERFACE Verb

DECLARE Verb

FIELD Verb

CAST Function