The changes have been announced for long time, and the new API has been
available if you #define GAUCHE_API_0_9 in your source.
Extension packages that are actively maintained are likely to have
switched using the new API. If a package is already using the new
API, it should be able to compile without problem with 0.9.

However, if an extension module hasn't been updated for some time,
you are likely to get compile errors.
An easy workaround is to #define GAUCHE_API_PRE_0_9 in the C sources
that don't compile. (If the C source is generated from
a stub file, you have to edit Makefile to give -DGAUCHE_API_PRE_0_9 flag
to the genstub command line.)

In other words, the visible API according to the preprocessor flag
has been changed as follows:

Before 0.9

If you define nothing, you see the old API.

If you define GAUCHE_API_0_9, you see the new API.

On or after 0.9

If you define nothing, you see the new API. (GAUCHE_API_0_9 is ignored)

If you define GAUCHE_API_PRE_0_9, you see the old API.

The compatibility feature using GAUCHE_API_PRE_0_9 will be removed
by 1.0 release, so the extension package maintainers are encouraged
to switch to the new API.

Eval-family functions

In older Gauche, Scm_Eval, Scm_EvalCString, and Scm_Apply didn't
catch errors. If an uncaught exception was thrown while execution, calls to these
functions never returned. The consequence was either one of the followings.

If the VM is "active" when the call is made, that is, the calling C code itself
is called from VM, then VM will catch the exception and invokes handlers
if any.

If the VM is "not active", for example, when you call Scm_Eval from C main()
function, the exception is handled by the default handler which prints
a message and just exits.

The first behavior is usually desirable, for it is the same way the Scheme
function behaves. The problem arises when the C code have something
to clean up; in which case you need to use SCM_UNWIND_PROTECT macro
in gauche/vm.h.

The second behavior is bad. You could use SCM_UNWIND_PROTECT to
prevent the program from exitting, but that's awkward, and it doesn't
give you what kind of exception was thrown.

There's another minor problem in the old API; the caller can only receive
single value, although the evaluated expression may yield multiple values.
The caller have to make extra calls to retrieve multiple values from the VM.

Thus, in 0.9, two sets of these functions are provided. The first set,
"fully featured" version, catches errors. They take an extra argument,
a pointer to ScmEvalPacket structure, to which the caught exception
is stored. The structure also stores multiple values, so the caller doesn't
need to make extra calls to retrieve them.

This first set is a kind of official way to call Scheme program from C code
at the beginning. So they got the original names: Scm_Eval, Scm_EvalCString,
and Scm_Apply.

The second set, "lightweight" version, behaves the same as the old
Scm_Eval etc. They are supposed to be called from the C code that
itself is called from the VM. They don't catch errors, for you know that
there's the VM waiting to catch it. They are named as
Scm_EvalRec, Scm_EvalCStringRec and Scm_ApplyRec,
where "Rec" indicates it is a recursive callback to the VM.

So, the easiest way to change old code to the new API is to rename
old Scm_Eval etc. to Scm_EvalRec etc. However, if the code is making
calls while the VM is not yet active, use of new Scm_Eval etc. is recommended.

Load-family functions

Likewise, Scm_Load, Scm_LoadFromPort and Scm_Require
are changed to capture errors during loading. They now take
an ScmLoadPacket structure, in which the captured exception
is stored. The ScmLoadPacket structure must be initialized
by the new Scm_LoadPacketInit function.
The return value of these functions are now consistent; 0 indicates
success, -1 indicates an error occurred during loading.

To get a behavior close to the old API, you have to rewrite
the call to the old API functions as shown below:

old: Scm_Load(file, flags)

new: Scm_Load(file, flags|SCM_LOAD_PROPAGATE_ERROR, NULL)

old: Scm_LoadFromPort(port, flags)

new: Scm_LoadFromPort(port, flags|SCM_LOAD_PROPAGATE_ERROR, NULL)

old: Scm_Require(feature)

new: Scm_Require(feature, SCM_LOAD_PROPAGATE_ERROR, NULL)

The new flag SCM_LOAD_PROPAGATE_ERROR tells not to capture errors
during loading. If the flag is given and an error occurs during loading,
these functions never returns, and the error is caught by the VM (if one
is active.)

Although the above code works like the old API, you may actually
want not to pass SCM_LOAD_PROPAGATE_ERROR and let the function
catch errors, and then check the return value to find out if load is successful.

Hash table functions

Hash tables get a brand new set of APIs. Most functions of the new API
have different names. The old functions are kept for the backward compatibility,
but using them is deprecated. A couple of functions changed their signature
and the old code using them must be changed.

The main change is that now hash tables are implemented in two layers.
The base layer, called ScmHashCore, is a plain C structure (not a Scheme
object) and can be used as a general hash table (keys and values are
not necessarily Scheme objects). The upper layer, ScmHashTable,
is implemented using ScmHashCore---an instance of ScmHashTable is
a Scheme object, and its keys and values are also Scheme objects.

Another change is to decouple implementation of hash tables from
its interface. The old API returns a reference to the actual key-value pair
of the hash table; you modify the pair and it affects the actual hash table.
It has an advantage that an operation to "look up something, check the value,
and modify it necessary" can be written in a way that it only searches
the table once---the lookup operation returns the key-value pair, and the
caller can modify it if it needs to alter hash table, without re-searching the key.
Unfortunately though, this architecture requires the hashtable
to store a key and its value side-by-side, and restricts the future
option to have different hash table implementation.

The new API takes these changes into consideration. The higher-level
API that operates on ScmHashTable structure have the following API:

The constructor, Scm_MakeHashTableSimple, currently restricts you to
create eq?, eqv?, equal?, and string=? hash tables just like the Scheme API does.
In future we will add more general constructor that allows you to specify the
customized hash and comparison functions.
(The reason such a general constructor is not provided yet is that
we have to be careful to design what constraints should be applied
to the customized hash/comparison functions in order to keep
consistency with the Scheme world. You can give custom hash/comparison
function to the lower-layer ScmHashCore structure, at your own risk.)

Scm_HashTableRef is like the Scheme conterparts; you pass a key,
and gets a value. If the table doesn't have an entry for the key,
whatever value given to falback is returned. You may pass SCM_UNBOUND
to check if an entry actually exists, for it can't be a valid value of an entry.

Scm_HashTableSet is to modify the hashtable. It works in different modes
according to the flags value, which may be a bitwise or of
SCM_DICT_NO_CREATE and SCM_DICT_NO_OVERWRITE.

If SCM_DICT_NO_CREATE is given, the value is stored only if an entry
with key already exists.
The function returns SCM_UNBOUND if the entry doesn't exist.

If SCM_DICT_NO_OVERWRITE is given, the entry is created only if no entry
with key exists prior to this call.

So, the old Scm_HashTablePut behaivor is realized by flags=0, and
the old Scm_HashTableAdd behavior is realized by flags=SCM_DICT_NO_OVERWRITE.

Scm_HashTableDelete isn't changed.

The iterators are now defined on ScmHashCore instead of ScmHashTable.
We are planning to provide ScmHashTable-level iterator interface
in near future. For the time being, the old code should be changed in
the following way:

Scm_HashIterInit takes a pointer to ScmHashIter first, then a pointer to
ScmHashCore. You can get a pointer to the ScmHashCore in a ScmHashTable table
by SCM_HASH_TABLE_CORE(table).

Scm_HashIterNext returns a pointer to ScmDictEntry instead of ScmHashEntry.
ScmDictEntry should be treated as an opaque handle to access the key and
the value, and to modify the value. Use macros SCM_DICT_KEY,
SCM_DICT_VALUE, and SCM_DICT_SET_VALUE to operate on ScmDictEntry.

String port functions

Scm_GetOutputString, Scm_GetOutputStringUnsafe,
and Scm_GetRemainingInputString now take one additional argument,
flags. An acceptable flag is SCM_STRING_INCOMPLETE to force
the resulting string incomplete.

To get the old API behavior, you can just pass 0 to the flags argument.