Have-combinator.html 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <html lang="en">
  2. <head>
  3. <title>Have combinator - avram - a virtual machine code interpreter</title>
  4. <meta http-equiv="Content-Type" content="text/html">
  5. <meta name="description" content="avram - a virtual machine code interpreter">
  6. <meta name="generator" content="makeinfo 4.13">
  7. <link title="Top" rel="start" href="index.html#Top">
  8. <link rel="up" href="Interfaces-to-External-Code.html#Interfaces-to-External-Code" title="Interfaces to External Code">
  9. <link rel="prev" href="Library-combinator.html#Library-combinator" title="Library combinator">
  10. <link rel="next" href="Interaction-combinator.html#Interaction-combinator" title="Interaction combinator">
  11. <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
  12. <meta http-equiv="Content-Style-Type" content="text/css">
  13. <style type="text/css"><!--
  14. pre.display { font-family:inherit }
  15. pre.format { font-family:inherit }
  16. pre.smalldisplay { font-family:inherit; font-size:smaller }
  17. pre.smallformat { font-family:inherit; font-size:smaller }
  18. pre.smallexample { font-size:smaller }
  19. pre.smalllisp { font-size:smaller }
  20. span.sc { font-variant:small-caps }
  21. span.roman { font-family:serif; font-weight:normal; }
  22. span.sansserif { font-family:sans-serif; font-weight:normal; }
  23. --></style>
  24. </head>
  25. <body>
  26. <div class="node">
  27. <a name="Have-combinator"></a>
  28. <p>
  29. Next:&nbsp;<a rel="next" accesskey="n" href="Interaction-combinator.html#Interaction-combinator">Interaction combinator</a>,
  30. Previous:&nbsp;<a rel="previous" accesskey="p" href="Library-combinator.html#Library-combinator">Library combinator</a>,
  31. Up:&nbsp;<a rel="up" accesskey="u" href="Interfaces-to-External-Code.html#Interfaces-to-External-Code">Interfaces to External Code</a>
  32. <hr>
  33. </div>
  34. <h5 class="subsubsection">2.7.16.2 Have combinator</h5>
  35. <p>As virtual machine interfaces to external libraries accumulate faster
  36. than they can be documented and may vary from one installation to
  37. another, it is helpful to have a way of interrogating the virtual
  38. machine for an up to date list of the installed libraries and
  39. functions. A combinator called <code>have</code> can be used to test for the
  40. availability of a library function. It takes the form
  41. <dl>
  42. <dt><em>T34</em><dd>[[<code>have</code>]] (<var>x</var>,<var>y</var>) = <code>((nil,nil),((nil,</code><var>x</var><code>),(nil,</code><var>y</var><code>)))</code>
  43. </dl>
  44. <p class="noindent">where <var>x</var> is the name of a library and <var>y</var> is the name of a
  45. function within the library encoded as character strings. For example,
  46. if <var>x</var> is <code>'mtwist'</code> and <var>y</var> is <code>'u_disc'</code> (for the
  47. natural random number generator function in the Mersenne twistor
  48. library) then <code>have(</code><var>x</var><code>,</code><var>y</var><code>)</code> is a function that returns
  49. a non-empty value if an only if that library is installed and that
  50. function is available within it. The actual argument to the function
  51. is ignored as the result depends only on the installed virtual machine
  52. configuration. In this sense, it acts like a <code>constant</code> combinator.
  53. <p>One way for this combinator to be used is in code of the form
  54. <pre class="example"> portable_rng =
  55. conditional(
  56. have('mtwist','u_disc'),
  57. library('mtwist','u_disc'),
  58. some_replacement_function)
  59. </pre>
  60. <p class="noindent">which will use the library function if available but otherwise use a
  61. replacement function. Code in this form makes the decision at run
  62. time, but it is also possible to express the function such that the
  63. check for library presence is made at compile time, as the following
  64. example shows, which will imply a slight improvement in performance.
  65. <pre class="example"> non_portable_rng =
  66. apply(
  67. conditional(
  68. have('mtwist','u_disc'),
  69. constant library('mtwist','u_disc'),
  70. constant some_replacement_function),
  71. 0)
  72. </pre>
  73. <p class="noindent">This program would be non-portable in the sense that it would need to
  74. be recompiled for each installation if there were a chance that some
  75. of them might have the <code>mtwist</code> library and some might not,
  76. whereas the previous example would be binary compatible across all of
  77. them. <a rel="footnote" href="#fn-1" name="fnd-1"><sup>1</sup></a>
  78. <p>The actual value returned by a function <code>have(foo,bar)</code> is the
  79. list of pairs of strings <code>&lt;(foo,bar)&gt;</code> if the function is
  80. available, or the empty list otherwise. A non-empty list is
  81. represented as a pair <code>(head,tail)</code>, and an empty list as
  82. <code>nil</code>. The angle bracket notation <code>&lt;a,b,c...&gt;</code> used here is
  83. an abbreviation for <code>(a,(b,(c...nil)))</code>.
  84. <p>Either or both arguments to the <code>have</code> combinator can be a
  85. wildcard, which is the string containing a single asterisk,
  86. <a name="index-wild-cards-379"></a><code>'*'</code>. In that case, the list of all available matching library
  87. names and function names will be returned. This feature can be used to
  88. find out what library functions are available without already knowing
  89. their names.
  90. <p>If a library had a function named <code>'*'</code>, which clashes with
  91. the wild card string, the interpretation as a wild card would take
  92. precedence.
  93. <div class="footnote">
  94. <hr>
  95. <h4>Footnotes</h4><p class="footnote"><small>[<a name="fn-1" href="#fnd-1">1</a>]</small> In practice both examples are equally portable because
  96. the <code>mtwist</code> source is distributed with <code>avram</code> so all
  97. installations will have it. Most libraries are distributed
  98. separately.</p>
  99. <hr></div>
  100. </body></html>