<?xml version="1.0" encoding="UTF-8"?>

<!-- ====================================================================== -->
<!-- = chapter-8.xml                                                      = -->
<!-- = afnix programmer's guide chapter 8                                 = -->
<!-- ====================================================================== -->
<!-- = This  program  is  free  software; you  can redistribute it and/or = -->
<!-- = modify it provided that this copyright notice is kept intact.      = -->
<!-- = This program is distributed in the hope that it will be useful but = -->
<!-- = without  any  warranty;  without  even  the  implied  warranty  of = -->
<!-- = merchantability or fitness for  a  particular purpose. In no event = -->
<!-- = shall  the  copyright  holder be liable for any  direct, indirect, = -->
<!-- = incidental  or special  damages arising  in any way out of the use = -->
<!-- = of this software.                                                  = -->
<!-- ====================================================================== -->
<!-- = copyright (c) 2005-2007 - amaury darsch                            = -->
<!-- ====================================================================== -->

<chapter volume="1" number="8">
  <title>Functional programming</title>

  <p>
  This chapter covers the interesting aspects of <afnix/> with respect
  to the <em>functional programming paradigm</em>. Functional
  programming is often described as the ability to <em>create 
  functions that creates functions</em>. As a matter of fact, it is a
  far bigger subject that finds its root in the <em>lambda
  calculus</em>. A language -- like <afnix/> -- that supports the
  functional programming paradigm is also sometimes called a
  <em>high order language</em>.
  </p>

  <!-- function expression -->
  <section>
    <title>Function expression</title>

    <p>
    A lambda expression or a gamma expression can be seen like a
    function object with no name. During the evaluation process, the
    expression object is evaluated as well as the arguments -- from
    left to right -- and a result is produced by applying those
    arguments to the function object. An expression can be built
    dynamically as part of the evaluation process.
    </p>

    <example>
    afnix&gt; println ((lambda (n) (+n 1)) 1)
    2
    </example>

    <p>
    The difference between a lambda expression and a gamma expression
    is only in the nameset binding during the evaluation process. The
    lambda expression nameset is linked with the calling one, while
    the gamma expression nameset is linked with the top level
    nameset. The use of gamma expression is particularly interesting
    with recursive functions as it can generate a significant
    execution speedup. The previous example will behaves the same with
    a gamma expression.
    </p>

    <example>
    afnix&gt; println ((gamma (n) (+n 1)) 1)
    2
    </example>

    <!-- self reference -->
    <subsect>
      <title>Self reference</title>

      <p>
      When combining a function expression with recursion, the need
      for the function to call itself is becoming a problem since that
      function expression does not have a name. For this reason,
      <afnix/> provides the reserved keyword <code>self</code> that is
      a reference to the function expression. We illustrate this
      capability with the well-known factorial expression written in
      pure functional style.
      </p>

      <example>
      afnix&gt; println ((gamma (n) 
              (if (&lt;= n 1) 1 (* n (self (- n 1))))) 5)
      120
      </example>

      <p>
      The use of a gamma expression versus a lambda expression is a
      matter of speed. Since the gamma expression does not have
      free variables, the symbol resolution is not a concern here.
      </p>
    </subsect>

    <!-- closed variables -->
    <subsect>
      <title>Closed variables</title>

      <p>
      One of the  <afnix/> characteristic is the treatment of
      <em>free variables</em>. A variable is said to be free if it is
      not bound in the expression environment or its children at the
      time of the symbol resolution. For example, the expression
      <code>((lambda (n) (+ n x)) 1)</code> computes the sum of the
      argument <code>n</code> with the free variable
      <code>x</code>. The evaluation will succeeds if <code>x</code>
      is defined in one of the parent environment. Actually this
      example can also illustrates the difference between a
      lambda expression and a gamma expression. Let's consider the
      following forms.
      </p>

      <example>
      trans x 1
      const do-print nil {
        trans x 2
	println ((lambda (n) (+ n x)) 1)
      }
      </example>

      <p>
      The gamma expression <code>do-print</code> will produce
      <code>3</code> since it sums the argument <code>n</code> bound
      to 1, with the free variable <code>x</code> which is defined in
      the calling environment as <code>2</code>. Now if we rewrite the
      previous example with a gamma expression the result will be one,
      since the expression parent will be the top level environment
      that defines <code>x</code> as 1.
      </p>

      <example>
      trans x 1
      const do-print nil {
        trans x 2
	println ((gamma (n) (+ n x)) 1)
      }
      </example>

      <p>
      With this example, it is easy to see that there is a need to be
      able to determine a particular symbol value during the
      expression construction. Doing so is called <em>closing a
      variable</em>. Closing a variable is a mechanism that binds into
      the expression a particular symbol with a value and such symbol
      is called a <em>closed variable</em>, since its value is closed
      under the current environment evaluation. For example, the
      previous example can be rewritten to close the symbol
      <code>x</code>.
      </p>
      
      <example>
      trans x 1
      const do-print nil {
        trans x 2
	println ((gamma (n) (x) (+ n x)) 1)
      }
      </example>

      <p>
      Note that the list of closed variable immediately follow the
      argument list. In this particular case, the function
      <code>do-print</code> will print <code>3</code> since
      <code>x</code> has been closed with the value <code>2</code> has
      defined in the function <code>do-print</code>.
      </p>
    </subsect>

    <!-- dynamic binding -->
    <subsect>
      <title>Dynamic binding</title>

      <p>
      Because <afnix/> has a dynamic binding symbol resolution, it is
      possible to have under some circumstances a free or closed
      variable. This kind of situation can happen when a particular
      symbol is defined under a condition.
      </p>

      <example>
      lambda (n) {
        if (&lt;= n 1) (trans x 1)
	println (+ n x)
      }
      </example>

      <p>
      With this example, the symbol <code>x</code> is a free variable
      if the argument <code>n</code> is greater than 1. While this
      mechanism can be powerful, extreme caution should be made when
      using such feature. Note also that many other language do not
      allow this kind of behavior. That kind of restriction is
      primarily driven by the need to have a language with
      <code>static binding</code>. The bad news is that it is
      impossible to write a compiler with dynamic symbol binding.
      </p>
    </subsect>
  </section>

  <!-- functional objects -->
  <section>
    <title>Functional objects</title>

    <p>
    Everything in <afnix/> is an object. As a consequence, an object
    can be manipulated, even if it is lexical element, a symbol or a
    closure.
    </p>

    <!-- lexical and qualified name -->
    <subsect>
      <title>Lexical and qualified names</title>

      <p>
      The basic forms elements are the lexical and qualified
      names. Lexical and qualified names are constructed by the
      <afnix/> reader. Although the evaluation process make that
      lexical object transparent, it is possible to manipulate them
      directly.
      </p>

      <example>
      afnix&gt; const sym (protect lex)
      afnix&gt; println   (sym:repr)
      Lexical
      </example>

      <p>
      In this example, the <code>protect</code> reserved keyword is
      used to avoid the evaluation of the lexical object named
      <code>lex</code>. Therefore the symbol <code>sym</code> refers
      to a lexical object. Since a lexical -- and a qualified --
      object is a also a literal object, the <code>println</code>
      reserved function will work and print the object name. In fact,
      a literal object provides the <code>to-string</code> method
      that returns the string representation of a literal object.
      </p>

      <example>
      afnix&gt; const sym (protect lex)
      afnix&gt; println   (sym:to-string)
      lex
      </example>
    </subsect>

    <!-- symbol and argument access -->
    <subsect>
      <title>Symbol and argument access</title>

      <p>
      Each nameset maintains a table of symbols. A symbol is a binding
      between a name and an object. Eventually, the symbol carries the
      <code>const</code> flag. During the lexical evaluation process,
      the lexical object tries to find an object in the nameset
      hierarchy. Such object can be either a symbol or an
      argument. Again, this process is transparent, but can be
      controlled manually. Both lexical and qualified named object
      have the <code>map</code> method that returns the first object
      associated in the nameset hierarchy.
      </p>

      <example>
      afnix&gt; const obj 0
      afnix&gt; const lex (protect obj)
      afnix&gt; const sym (lex:map)
      afnix&gt; println   (sym:repr)
      Symbol
      </example>

      <p>
      A symbol is also a literal object, so the <code>to-string</code>
      and <code>to-literal</code> methods will return the symbol
      name. Symbol methods are provided to access or modify the symbol
      values. It is also possible to change the <code>const</code>
      symbol flag with the <code>set-const</code> method.
      </p>

      <example>
      afnix&gt; println (sym:get-const)
      true
      afnix&gt; println (sym:get-object)
      0
      afnix&gt; sym:set-object true
      afnix&gt; println (sym:get-object)
      true
      </example>

      <p>
      A symbol name cannot be modified, since the name must be
      synchronized with the nameset association. On the other hand, a
      symbol can be explicitly constructed. As any object, the
      <code>=</code> operator can be used to assign a symbol
      value. The operator will behaves like the
      <code>set-object</code> method.
      </p>

      <example>
      afnix&gt; const sym (Symbol "symbol")
      afnix&gt; println sym
      symbol
      afnix&gt; sym:= 0
      afnix&gt; println (eval sym)
      0
      </example>
    </subsect>

    <!-- closure -->
    <subsect>
      <title>Closure</title>

      <p>
      As an object, the <code>Closure</code> can be manipulated
      outside the traditional declarative way. A closure is a special
      object that holds an argument list, a set of closed variables
      and a form to execute. The mechanic of a closure evaluation has
      been described earlier. What we are interested here is the
      ability to manipulate a closure as an object and eventually
      modify it. Note that by default a closure is constructed as a
      lambda expression. With a boolean argument set to true the same
      result is obtained. With false, a gamma expression is created.
      </p>

      <example>
      afnix&gt; const f (Closure)
      afnix&gt; println (closure-p f)
      true
      </example>

      <p>
      This example creates an empty closure. The default closure is
      equivalent to the <code>trans f nil nil</code>. The same can be
      obtained with <code>const f (Closure true)</code>. For a gamma
      expression, the following  forms are equivalent, <code>const f
      (Closure false)</code> and <code>const f nil
      nil</code>. Remember that it is <code>trans</code> and
      <code>const</code> that differentiate between a lambda and a
      gamma expression. Once the closure object is defined, the
      <code>set-form</code> method can be used to bind a form.
      </p>

      <example>
      # the simple way
      trans f nil (println "hello world")
      # the complex way
      const f    (Closure)
      f:set-form (protect (println "hello world"))
      </example>

      <p>
      There are numerous situations where it is desirable to mute
      dynamically a closure expression. The simplest one is the
      closure that mute itself based on some context. With the use of
      <code>self</code>, a new form can be set to the one that is
      executed. Another use is a mechanism call <em>advice</em>, where
      some new computation are inserted prior the closure
      execution. Note that appending to a closure can lead to some
      strange results if the existing closure expression uses
      <em>return</em> special forms. In a multi-threaded environment,
      the ability to change a closure expression is particularly
      handy. For example a special thread could be used to monitor
      some context. When a particular situation develops, that threads
      might trigger some closure expression changes. Note that
      changing a closure expression does not affect the one that is
      executed. If such change occurs during a recursive call, that
      change is seen only at the next call.
      </p>
    </subsect>
  </section>
</chapter>
