Go to the previous, next section.

# Using ILU with Scheme (Guile)

## Introduction

This document is for the Scheme programmer who wishes to use ILU. The following sections will show how ILU is mapped into Scheme constructs and how both Scheme clients and servers are generated and built.

The Scheme support in ILU was kindly donated by
Siemens Corporate Research Inc., and written by Bill Nell.

## The ISL Mapping to Scheme

### Names

The mapping of ISL names to Scheme names for objects and methods are described in the following sections. For all other ISL types and exceptions the Scheme name will be module-name:name.

### Basic Types

This section describes the mapping of ISL types to Scheme types. Note that some mappings use extra precision where it is not necessary. This is because the Scheme types have no finer distinctions for these types. The basic ISL types have the following mapping to Scheme constructs:

- ISL `boolean` is mapped to Scheme `boolean`;
- ISL `short cardinal` is mapped to Scheme `unsigned long`;
- ISL `cardinal` is mapped to Scheme `unsigned long`;
- ISL `long cardinal` is mapped to Scheme `pair (unsigned long . unsigned long)`;
- ISL `short integer` is mapped to Scheme `long`;
- ISL `integer` is mapped to Scheme `long`;
- ISL `long int` is mapped to Scheme `pair (long . unsigned long)`;
- ISL `short real` is mapped to Scheme `double precision real`;
- ISL `real` is mapped to Scheme `double precision real`;
- ISL `short character` is mapped to Scheme `character`;
- ISL `character` is mapped to Scheme `long`;
- ISL `byte` is mapped to Scheme `character`.

#### Constant

### Strings

- ISL `string` is mapped to Scheme `string`.
- ISL `wstring` is mapped to Scheme `vector of unsigned longs`.

### Pickles and Typecodes

Not implemented yet.

### Constructed Types

#### Enumeration

Implemented with a set of symbols bound to the integer values of the enumeration type.

#### Array

Arrays are implemented as Scheme `vector`s. For arrays, a Scheme function will be generated that takes no arguments and returns a vector with dimensions corresponding to the ISL array type. The user is responsible for setting elements in the vector.

#### Sequence

Sequences are implemented as `list`s, except for sequences of characters, which are implemented as `string`s.

#### Record

Each record is mapped to an ILU-YASOS object. Each object has a constructor named (make-module-name:record-name) that takes no arguments. Each object also has methods to get and set all the fields of that record. These accessors follow the pattern of (get-field-name obj) and (set-field-name obj value). In the future record constructors will be able to take arguments to initialize their fields.

#### Union

Unions are implemented as a cons'ed value, with the cdr containing the union type discriminant, and the cdr containing the actual value. For union types, a constructor function taking two arguments is created. The first argument is the discriminator and the second is the union value. The discriminator of a union can be accessed or set using the `car` and `set-car!` functions, respectively. The value of a union can be accessed or set using the `cdr` and `set-cdr!` functions, respectively.

#### Optional

Either `#f` or the value. Note that this mapping is broken for optional boolean types.

### Object Types

Each object is mapped to an ILU-YASOS object.

Each object type has a constructor named (make-module-name:object-name) that takes no arguments. The user should not attempt to create objects using the constructor since these are surrogate objects and not true objects. All the method names should map exactly as they appear in the ISL definition.

#### Surrogate and True Object Types

Class: ilu:object

This is the root class of all objects in the Scheme LSR. It provides some basic functionality required by all ILU objects. The public methods are described below. Since ILU-YASOS has no notion of public or private there are additional methods which are not described here and should not ever be called by the user.

- `(string-binding-handle obj)` - return the string binding handle of obj
- `(publish obj)` - publish this object. Returns a boolean value for success or failure.
- `(withdraw obj)` - withdraw this object. Returns a boolean value for success or failure.
- `(class-name obj)` - return the class name for this object.
- `(class-id obj)` - return the class id for this object.
- `(get-server obj)` - get the kernel server that controls this object.
- `(get-instance-handle obj)` - get the instance handle for this object.
- `(get-kernel-server obj)` - get the true server for this object.
- `(get-instance-class-record obj)` - get the instance class record for this object.
- `(destroy obj)` - destroy this surrogate object. Unfortunately, ILU-YASOS objects are not hooked into the scheme garbage collector yet. So, the destroy method must be called when you are finished with a surrogate object to prevent memory leaks.

Surrogate objects present an interface to access a true objects which may or may not live in the same address space as the surrogate object. The user is not allowed to create their own surrogate objects. They must be looked up using a name binding service or through the use if a string binding handle.

Behind every surrogate object there must be a true object. The user is in charge of defining true objects. Implementing a true object for a particular surrogate object is accomplished by subclassing the surrogate object class provided by the Scheme stubber. Each true object implementation must override every method of the surrogate "parent" object to work correctly. See the section on ILU-YASOS for implementing objects in Scheme. Also, see the examples of a Scheme client and server given in the examples/test1 directory.

IMPORTANT CAVEAT: When using multiple inheritance with ILU-YASOS objects to implement "true" objects it is important that the correct ILU class record be assigned to the true object. The class record of the last class listed in the superclass list of the object definition will be the one used for the object being defined. If this is not the desired class record, the implementor must set it by hand. (Hopefully, in the future this will be taken care of automatically). Usually, this is not a problem if you always place the most specific superclass of an object last in the list of superclasses.

#### Methods, Parameters, and Exceptions

All methods take at least two arguments in addition to any other arguments specified in the ISL definition. The first argument is the object the method is being called on and the second argument is the status object. The remaining arguments are the same as in the ISL definition.

Class: ilu:status

This is a status object type, used to record the success or failure of all method calls. Later this will be replaced with catch and throw. Also note that even though individual modules create their own status types, the ilu:status type can still be used in their place.

`ilu:status` objects support the following methods:

- `(get-return-code this)` - get the return code for this status object. If the value is ilu:success then the method call was successful. Any other value indicates an exception string, which can be printed.
- `(set-return-code this code)` - set the return code of this status object.
- `(get-status-value this)` - get the value associated with any exception raised in this status object. If the call was successful this field should be #f. Otherwise it will contain the contents of an exception record.
- `(set-status-value this value)` - set the status value of this status object. Used for setting additional information when an exception is raised.
- `(get-caller-passport this)` - get the passport for this method call.
- `(set-caller-passport this passport)` - set the passport for this method call.

Normal methods are called in the following manner:
`(method-name object status arguments)`
If any errors are encountered while executing the method, they will be stored in the status object parameter. Failed method calls always return `#f`.

Arguments defined as "out" must still be passed as placeholders even though their values are ignored. The return values of methods are as follows: If the method has no "inout" or "out" parameters, a single value is returned. When a method has "inout" or "out" parameters the method returns a list of values which contains any "inout" and "out" values (in the order they are specified in the ISL definition) followed by the "normal" return value as the last element of the list.

All exceptions are raised by setting the return code of a status value to something other than ilu:success. Depending on the type of the exception there may also be additional data associated with it that can be set using the "set-status-value" method on a status object.

Asynchronous methods are available in the Scheme LSR. They will return immediatedly with a return value of #t.

Functional methods are currently not supported in the Scheme LSR. At the moment they are treated as normal method calls.

#### Garbage Collection and COLLECTIBLE

At the moment garbage collection of surrogate and true objects is not supported.

## Access to standard ILU features

### Servers and Ports

#### Object Tables

See ``ilu:create-object-table``.

### Threading and Event Loops

At the moment the Scheme LSR does not support threading, so only the event loop mode of operation will work.

### Custom Records

### String Binding Handle Formation

### Simple Binding

### Principal Identities and Passports

## Building Scheme/ILU Applications

### Initialization order

All object and type definitions are initialized automatically when loading the Scheme code for a particular interface. The (ilu:init) function is used to initialize the GC server and callback object. If the user wishes to select their own main loop object, they must register it before calling (ilu:init).

### ILU-YASOS

The ILU version of YASOS is a slightly modified version of the standard YASOS with the following differences:

- All the standard YASOS functions are prepended with the prefix "ilu-", so regular YASOS and ILU-YASOS can operate together.
- All ILU-YASOS methods make take a variable number of arguments. This is so the same method may take different numbers of arguments depending on which object it is called with.
- An additional function called ilu-bind-arguments is provided to extract multiple arguments from a list and bind them to symbols (almost like a let block). It is provided only as a convienience and is not a required part of a method definition.

### Where to get Guile 1.2 and SLIB

Guile 1.2.

SLIB 2b1.

Guile snapshots -- Guile snapshots are daily updates of the Guile system, use them at your own risk. Also some snapshots may not be compatible with the current implementation of the stubber and runtime.

See also the Report on the Algorithmic Language Scheme -- revision 4 and the SLIB Reference Manual.

### Stub Generation

### Implementing an ILU module in Scheme

#### Implementation Inheritance

#### Exporting Objects

### Using an ILU module in Scheme

If you are using Guile Scheme, the value of the environment variable `LD_LIBRARY_PATH` should include the directory in which the `ilu` library for Guile has been installed; that's normally ``ILUHOME/lib'`. Additionally, the environment variable `SCHEME_LOAD_PATH` should contain ``ILUHOME/guile'`, so that the ILU Guile files can be found.

## Scheme/ILU API Reference

- `(ilu:init)` - called to initialize the scheme interface to ILU. If the user wants to set their own main loop (see (ilu:set-main-loop)), they must do so before calling (ilu:init). Multiple calls to (ilu:init) will have no effect.

- `(ilu:time-now)` - get the current time in seconds as a floating point value.

- `(ilu:find-class-from-type-name name)` - get the class record given the type name of an object.

- `(ilu:find-class-from-id id)` - get the class record given the type id of an object.

- `(ilu-class:name class)` - given a class record object, get the name of the class.

- `(ilu:create-object-table object-of-ih-func free-self-func)` - create an object table given a function that converts instance handles to objects and a function that cleans up an object table. object-of-ih-func must take at least two arguments the first being the object table and the second the instance handle of the object being requested. The free-self-func must take at least one argument which is the object table being freed.

- `(ilu:set-default-server server)` - set the default server in the process to be "server".

- `(ilu:get-default-server)` - return the default server object.

- `(ilu:create-port server protocol-type transport-type)` - create a port on the given server. protocol-type is a string containing the protocol type and transport-type is a vector containing the transport layers to use on the given port. protocol-type and transport-type may have the value of #f in which case the default protocol and transport types are used.

- `(ilu:set-server-default-port server port)` - set the default port for a given server.

- `(ilu-server:create server-name object-table)` - create a server given a name and an object-table.

- `(ilu-server:id server)` - return the id of a server.

- `(ilu-server:add-port server protocol-type transport-type make-default)` - add a port to the given server. Basically, the same as "ilu:create-port", except it takes one additional argument "make-default" which indicates whether the new port should be made the default one for the given server.

- `(ilu:make-main-loop-id)` - make an "id" that can be used to start and stop a main loop execution.

- `(ilu:free-main-loop-id id)` - free a main-loop-id created by the function (ilu:make-main-loop-id). This should only be used when the id is no longer needed. Note: the same main loop id can be reused for different main loops if desired, but may not be used by multiple main loops at the same time.

- `(ilu:run-main-loop id)` - run the ILU main loop. id must be 0 or an id created by (ilu:make-main-loop-id). If the id is 0 the scheme runtime will assign a default id to use. Note: that the 0 id can be only used for one main loop at a time.

- `(ilu:exit-main-loop id)` - stop execution of a main loop with the given id.

- `(ilu:set-main-loop main-loop)` - set the main loop to a user defined main loop object. See (make-ilu:main-loop) for more information.

- `(ilu:register-input-handler port handler)` - register in input handler for the given input port. handler may be any lambda expression.

- `(ilu:unregister-input-handler port)` - unregister an input handler for the given port.

- `(ilu:register-output-handler port handler)` - register in output handler for the given output port. handler may be any lambda expression.

- `(ilu:unregister-output-handler port)` - unregister an output handler for the given port.

- `(ilu:create-alarm)` - create an alarm object.

- `(ilu:set-alarm alarm time proc)` - set an alarm object. The time is given as a floating point value in seconds. proc is an arbitrary lambda expression.

- `(ilu:clear-alarm alarm)` - clear the given alarm so it will not be called.

- `(make-ilu:main-loop)` - this is an ILU-YASOS object is an abstract base class for main loop objects. If the user desires to make their own main loop object, the must subclass from this one and redefine all of the following methods.

  Public Methods:

  - `(run this stop)` - run this main loop. stop is a main-loop-id as described in (ilu:make-main-loop-id);
  - `(exit this stop)` - stop this main loop. stop is a main-loop-id as described in (ilu:make-main-loop-id);
  - `(register-input-handler this port handler)` - register an input handler for the given port. handler can be an arbitrary lambda expression;
  - `(register-output-handler this port handler)` - register an output handler for the given port. handler can be an arbitrary lambda expression;
  - `(unregister-input-handler this port)` - unregister an input handler for the given port;
  - `(unregister-output-handler this port)` - unregister an input handler for the given port;
  - `(create-alarm this)` - create an alarm object;
  - `(set-alarm this alarm time proc)` - set an alarm object (see ilu:set-alarm for more details);
  - `(clear-alarm this alarm)` - clear the given alarm so it won't trigger.

- `(ilu:sbh-to-object sbh class)` - takes a string binding handle and a class record and returns the object associated with that string binding handle. It also checks to make sure the correct class is set.

- `(ilu:parse-sbh sbh)` - parse the given string binding handle. A list is returned which has the following form: (instance-handle server-id mstid contact-info length-of-contact-info-substring).

- `(ilu-object:lookup server-id instance-handle class)` - attempt to lookup an object given a server-id, instance-handle and class record. If the lookup fails, #f is returned.

Go to the previous, next section.