Chapter 2

Values and Types

A Scheme value is represented by a pointer-sized value. The low bit is a mark bit: a 1 in the low bit indicates an immediate integer, a 0 indicates a (word-aligned) pointer.

A pointer Scheme value references a structure that begins with a type tag. This type tag has the C type Scheme_Type. The rest of the structure, following the type tag, is type-dependent. Examples of Scheme_Type values include scheme_pair_type, scheme_symbol_type, and scheme_compiled_closure_type.

MzScheme's C interface gives Scheme values the type Scheme_Object *. (The ``object'' here does not refer to objects in the sense of MzLib's class library.) The struct type Scheme_Object is defined in scheme.h, but extension or embedding code should never access this structure directly. Instead, the code should use macros, such as SCHEME_CAR, that provide access to the data of common Scheme types. A Scheme_Object structure is actually only allocated for certain types (i.e., some of the built-in types that contain two words of data, in addition to the type tag), but Scheme_Object * is nevertheless used as the type of a generic Scheme value (for historical reasons).

For most Scheme types, a constructor is provided for creating values of the type. For example, scheme_make_pair takes two Scheme_Object * values and returns the cons of the values.

The macro SCHEME_TYPE takes a Scheme_Object * and returns the type of the object. This macro performs the tag-bit check, and returns scheme_integer_type when the value is an immediate integer; otherwise, SCHEME_TYPE follows the pointer to get the type tag. Macros are provided to test for common Scheme types; for example, SCHEME_PAIRP returns 1 if the value is a cons cell, 0 otherwise.

In addition to providing constructors, MzScheme defines six global constant Scheme values: scheme_true, scheme_false, scheme_null, scheme_eof, scheme_void, and scheme_undefined. Each of these has a type tag, but each is normally recognized via its constant address.

An extension or embedding application can create new a primitive data type by calling scheme_make_type, which returns a fresh Scheme_Type value. To create a collectable instance of this type, allocate memory for the instance with scheme_malloc. From MzScheme's perspective, the only constraint on the data format of such an instance is that the first sizeof(Scheme_Type) bytes must contain the value returned by scheme_make_type. Extensions with modest needs can use scheme_make_cptr, instead.

Scheme values should never be allocated on the stack, and they should never contain pointers to values on the stack. Besides the problem of restricting the value's lifetime to that of the stack frame, allocating values on the stack creates problems for continuations and threads, both of which copy into and out of the stack.

2.1  Standard Types

The following are the Scheme_Type values for the standard types:

The following are the procedure types:

The predicate SCHEME_PROCP returns 1 for all procedure types and 0 for anything else.

The following are additional number predicates:

2.2  Global Constants

There are six global constants:

2.3  Library Functions

¤ Scheme_Object * scheme_make_char(char ch)

Returns the character value.

¤ Scheme_Object * scheme_make_character(char ch)

Returns the character value. (This is a macro.)

¤ Scheme_Object * scheme_make_integer(long i)

Returns the integer value; i must fit in a fixnum. (This is a macro.)

¤ Scheme_Object * scheme_make_integer_value(long i)

Returns the integer value. If i does not fit in a fixnum, a bignum is returned.

¤ Scheme_Object * scheme_make_integer_value_from_unsigned(unsigned long i)

Like scheme_make_integer_value, but for unsigned integers.

¤ int scheme_get_int_val(Scheme_Object *o, long *i)

Extracts the integer value. Unlike the SCHEME_INT_VAL macro, this procedure will extract an integer that fits in a long from a Scheme bignum. If o fits in a long, the extracted integer is placed in *i and 1 is returned; otherwise, 0 is returned and *i is unmodified.

¤ int scheme_get_unsigned_int_val(Scheme_Object *o, unsigned long *i)

Like scheme_get_int_val, but for unsigned integers.

¤ Scheme_Object * scheme_make_double(double d)

Creates a new floating-point value.

¤ Scheme_Object * scheme_make_float(float d)

Creates a new single-precision floating-point value. The procedure is available only when MzScheme is compiled with single-precision numbers enabled.

¤ double scheme_real_to_double(Scheme_Object *o)

Converts a Scheme real number to a double-precision floating-point value.

¤ Scheme_Object * scheme_make_pair(Scheme_Object *carv, Scheme_Object *cdrv)

Makes a cons pair.

¤ Scheme_Object * scheme_make_string(char *chars)

Makes a Scheme string from a null-terminated C string. The chars string is copied.

¤ Scheme_Object * scheme_make_string_without_copying(char *chars)

Like scheme_make_string, but the string is not copied.

¤ Scheme_Object * scheme_make_sized_string(char *chars, long len, int copy)

Makes a string value with size len. A copy of chars is made if copy is not 0. The string chars should contain len characters; chars can contain the null character at any position, and need not be null-terminated. However, if len is negative, then the null-terminated length of chars is used for the length.

¤ Scheme_Object * scheme_make_sized_offset_string(char *chars, long d, long len, int copy)

Like scheme_make_sized_string, except the len characters start from position d in chars.

¤ Scheme_Object * scheme_alloc_string(int size, char fill)

Allocates a new Scheme string.

¤ Scheme_Object * scheme_append_string(Scheme_Object *a, Scheme_Object *b)

Creates a new string by appending the two given strings.

¤ Scheme_Object * scheme_intern_symbol(char *name)

Finds (or creates) the symbol matching the given null-terminated string. The case of name is (non-destructively) normalized before interning if scheme_case_sensitive is 0.

¤ Scheme_Object * scheme_intern_exact_symbol(char *name, int len)

Creates or finds a symbol given the symbol's length. The the case of name is not normalized.

¤ Scheme_Object * scheme_make_symbol(char *name)

Creates an uninterned symbol from a null-terminated string.

¤ Scheme_Object * scheme_make_exact_symbol(char *name, int len)

Creates an uninterned symbol given the symbol's length.

¤ Scheme_Object * scheme_make_vector(int size, Scheme_Object *fill)

Allocates a new vector.

¤ Scheme_Object * scheme_box(Scheme_Object *v)

Creates a new box containing the value v.

¤ Scheme_Object * scheme_make_weak_box(Scheme_Object *v)

Creates a new weak box containing the value v.

¤ Scheme_Type scheme_make_type(char *name)

Creates a new type (not a Scheme value).

¤ Scheme_Object * scheme_make_cptr(void *ptr, const char *name)

Creates a C-pointer object that encapuslates ptr and uses name to identify the type of the pointer. The SCHEME_CPTRP macro recognizes objects created by scheme_make_cptr. The SCHEME_CPTR_VAL macro extracts the original ptr from the Scheme object, and SCHEME_CPTR_TYPE extracts the type string.