Diff of /ansi_data_flow.xml [a13b80] .. [7de359] Maximize Restore

  Switch to side-by-side view

--- a/ansi_data_flow.xml
+++ b/ansi_data_flow.xml
@@ -61,7 +61,7 @@
  </section>
 
  <section xml:id="ansi.functions">
-  <title>Functions</title>
+  <title>Function types</title>
 
   <para>Functions in &ECL; can be of two types: they are either compiled to
   bytecodes or they have been compiled to machine code using a lisp to C
@@ -72,11 +72,12 @@
   <function>compile-file</function>.</para>
 
   <para>The output of <code>(symbol-function
-  <replaceable>fun</replaceable>)</code> is a list, is either a function
-  object if <literal>'fun</literal> is has a function definition,
-  <literal>(macro . function-object)</literal> if <literal>'fun</literal> is
-  a macro, and <literal>'special</literal> if <literal>'fun</literal> is a
-  special form.</para>
+  <replaceable>fun</replaceable>)</code> is one of the following:
+  <itemizedlist>
+    <listitem><para>a function object denoting the definition of the function <literal>fun</literal>,</para></listitem>
+    <listitem><para>a list of the form <literal>(macro . function-object)</literal> when <literal>fun</literal> denotes a macro,</para></listitem>
+    <listitem><para>or simply <literal>'special</literal>, when <literal>fun</literal> denotes a special form, such as <symbol>block</symbol>, <symbol>if</symbol>, etc.</para></listitem>
+  </itemizedlist></para>
 
   <para>&ECL; usually drops the source code of a function unless the global
   variable <varname>si:*keep-definitions*</varname> was true when the
@@ -117,14 +118,43 @@
  <section xml:id="ansi.calling-conventions">
    <title>C Calling conventions</title>
 
-   <para>&ECL; is implemented using either a C or a C++ compiler. This is not a limiting factor, but imposes some constraints on how these languages are used to implement functions, multiple values, closures, etc. The first important constraint is that, while C functions can be called with a variable number of arguments, there is no facility to check how many values were actually passed. This forces us to have two types of functions in &ECL;
+   <para>&ECL; is implemented using either a C or a C++ compiler. This is not a limiting factor, but imposes some constraints on how these languages are used to implement functions, multiple values, closures, etc. In particular, while C functions can be called with a variable number of arguments, there is no facility to check how many values were actually passed. This forces us to have two types of functions in &ECL;
    <itemizedlist>
      <listitem><para>Functions that take a fixed number of arguments have a simple C signature, with all arguments being properly declared, as in <code>cl_object cl_not(cl_object arg1)</code>.</para></listitem>
      <listitem><para>Functions with a variable number of arguments, such as those acception <symbol>&optional;</symbol>, <symbol>&rest;</symbol> or <symbol>&key;</symbol> arguments, must take as first argument the number of remaining ones, as in <code>cl_object cl_list(cl_narg narg, ...)</code>. Here <replaceable>narg</replaceable> is the number of supplied arguments.</para></listitem>
    </itemizedlist>
    The previous conventions set some burden on the C programmer that calls &ECL;, for she must know the type of function that is being called and supply the right number of arguments. This burden disappears for Common Lisp programmers, though.</para>
 
-   <para>The second limitation of C and C++ is that functions can only take a limited number of arguments. In order to cope with this problem, &ECL; uses an internal stack to pass any argument above a hardcoded limit, <constant>ECL_C_CALL_ARGUMENTS_LIMIT</constant>, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as <symbol>apply</symbol>, <symbol>funcall</symbol> and their C equivalents, and also by a set of macros, <link linkend="ref.cl_va_arg"><function>cl_va_arg</function></link>, which can be used for coding functions that take an arbitrary name of arguments.</para>
+   <para>As an example let us assume that the user wants to invoke two functions which are part of the &ANSI; standard and thus are exported with a C name. The first example is <function>cl_cos</function>, which takes just one argument and has a signature <code>cl_object cl_cos(cl_object)</code>.</para>
+   <programlisting>
+#include &lt;math.h&gt;
+...
+cl_object angle = ecl_make_double_float(M_PI);
+cl_object c = cl_cos(angle);
+printf("\nThe cosine of PI is %g\n", ecl_double_float(c));
+</programlisting>
+
+   <para>The second example also involves some Mathematics, but now we are going to use the C function corresponding to <symbol>+</symbol>. As described in <link linkend="ansi.numbers.c-dict.ref">the C dictionary</link>, the C name for the plus operator is <function>cl_P</function> and has a signature <code>cl_object cl_P(cl_narg narg,...)</code>. Our example now reads as follows</para>
+   <programlisting>
+cl_object one = ecl_make_fixnum(1);
+cl_object two = cl_P(2, one, one);
+cl_object three = cl_P(2, one, one, one);
+printf("\n1 + 1 is %d\n", ecl_fixnum(two));
+printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
+</programlisting>
+
+   <para>Note that most Common Lisp functions will not have a C name. In this case one must use the symbol that names them to actually call the functions, using <function>cl_funcall</function> or <function>cl_apply</function>. The previous examples may thus be rewritten as follows</para>
+   <programlisting>
+/* Symbol + in package CL */
+cl_object plus = ecl_make_symbol("+","CL");
+cl_object one = ecl_make_fixnum(1);
+cl_object two = cl_funcall(3, plus, one, one);
+cl_object three = cl_funcall(4, plus, one, one, one);
+printf("\n1 + 1 is %d\n", ecl_fixnum(two));
+printf("\n1 + 1 + 1 is %d\n", ecl_fixnum(three));
+</programlisting>
+
+   <para>Another restriction of C and C++ is that functions can only take a limited number of arguments. In order to cope with this problem, &ECL; uses an internal stack to pass any argument above a hardcoded limit, <constant>ECL_C_CALL_ARGUMENTS_LIMIT</constant>, which is as of this writing 63. The use of this stack is transparently handled by the Common Lisp functions, such as <symbol>apply</symbol>, <symbol>funcall</symbol> and their C equivalents, and also by a set of macros, <link linkend="ref.cl_va_arg"><function>cl_va_arg</function></link>, which can be used for coding functions that take an arbitrary name of arguments.</para>
  </section>
 
  <xi:include href="ref_c_data_flow.xml" xpointer="ansi.data-and-control.c-dict" xmlns:xi="http://www.w3.org/2001/XInclude"/>