[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

#### 2.7.16.2 Have combinator

As virtual machine interfaces to external libraries accumulate faster than they can be documented and may vary from one installation to another, it is helpful to have a way of interrogating the virtual machine for an up to date list of the installed libraries and functions. A combinator called `have` can be used to test for the availability of a library function. It takes the form

T34

  [[`have`]] (`x`,`y`) = `((nil,nil),((nil,x),(nil,y)))`

where x is the name of a library and y is the name of a function within the library encoded as character strings. For example, if x is `'mtwist'` and y is `'u_disc'` (for the natural random number generator function in the Mersenne twistor library) then `have(x,y)` is a function that returns a non-empty value if an only if that library is installed and that function is available within it. The actual argument to the function is ignored as the result depends only on the installed virtual machine configuration. In this sense, it acts like a `constant` combinator.

One way for this combinator to be used is in code of the form

       portable_rng =

       conditional(
          have('mtwist','u_disc'),
          library('mtwist','u_disc'),
          some_replacement_function)

which will use the library function if available but otherwise use a replacement function. Code in this form makes the decision at run time, but it is also possible to express the function such that the check for library presence is made at compile time, as the following example shows, which will imply a slight improvement in performance.

       non_portable_rng =

       apply(
          conditional(
             have('mtwist','u_disc'),
             constant library('mtwist','u_disc'),
             constant some_replacement_function),
          0)

This program would be non-portable in the sense that it would need to be recompiled for each installation if there were a chance that some of them might have the `mtwist` library and some might not, whereas the previous example would be binary compatible across all of them. (2)

The actual value returned by a function `have(foo,bar)` is the list of pairs of strings `<(foo,bar)>` if the function is available, or the empty list otherwise. A non-empty list is represented as a pair `(head,tail)`, and an empty list as `nil`. The angle bracket notation `<a,b,c...>` used here is an abbreviation for `(a,(b,(c...nil)))`.

Either or both arguments to the `have` combinator can be a wildcard, which is the string containing a single asterisk, `'*'`. In that case, the list of all available matching library names and function names will be returned. This feature can be used to find out what library functions are available without already knowing their names.

If a library had a function named `'*'`, which clashes with the wild card string, the interpretation as a wild card would take precedence.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated on November 8, 2012 using texi2html 1.82.