10.15.1 Comparison

This is the trickiest part of the interface.

Mixing Scheme values with C comparison operators won’t produce any crash or warning when compiling but must be avoided:

scm_string_p (scm_value) == SCM_BOOL_T

As we can read in the reference, scm_string_p returns a Scheme value: either #t or #f which are written SCM_BOOL_T and SCM_BOOL_F in C. This will work, but it is not following to the API guidelines. For further information, read this discussion:

 
http://lists.gnu.org/archive/html/lilypond-devel/2011-08/msg00646.html

There are functions in the Guile reference that returns C values instead of Scheme values. In our example, a function called scm_is_string (described after string? and scm_string_p) returns the C value 0 or 1.

So the best solution was simply:

scm_is_string (scm_value)

There a simple solution for almost every common comparison. Another example: we want to know if a Scheme value is a non-empty list. Instead of:

(scm_is_true (scm_list_p (scm_value)) && scm_value != SCM_EOL)

one can usually use:

scm_is_pair (scm_value)

since a list of at least one member is a pair. This test is cheap; scm_list_p is actually quite more complex since it makes sure that its argument is neither a ‘dotted list’ where the last pair has a non-null cdr, nor a circular list. There are few situations where the complexity of those tests make sense.

Unfortunately, there is not a scm_is_[something] function for everything. That’s one of the reasons why LilyPond has its own Scheme interface. As a rule of thumb, tests that are cheap enough to be worth inlining tend to have such a C interface. So there is scm_is_pair but not scm_is_list, and scm_is_eq but not scm_is_equal.

General definitions

bool to_boolean (SCM b)

Return true if b is SCM_BOOL_T, else return false.

This should be used instead of scm_is_true and scm_is_false for properties since in LilyPond, unset properties are read as an empty list, and by convention unset Boolean properties default to false. Since both scm_is_true and scm_is_false only compare with ##f in line with what Scheme’s conditionals do, they are not really useful for checking the state of a Boolean property.

bool ly_is_[something] (args)

Behave the same as scm_is_[something] would do if it existed.

bool is_[type] (SCM s)

Test whether the type of s is [type]. [type] is a LilyPond-only set of values (direction, axis...). More often than not, the code checks LilyPond specific C++-implemented types using

[Type *] unsmob<Type> (SCM s)

This tries converting a Scheme object to a pointer of the desired kind. If the Scheme object is of the wrong type, a pointer value of 0 is returned, making this suitable for a Boolean test.


LilyPond — Contributor’s Guide v2.21.0 (development-branch).