c++boost.gif (8819 bytes)HomeLibrariesPeopleFAQMore

10. Library

Table of Contents

10.1. Nuts and bolts
10.2. Constants
10.3. Data types
10.4. Basic list functions
10.5. Haskell standard prelude
10.6. Operators
10.7. Currying, thunks, and effect combinators
10.8. General combinators
10.9. Functoid promotion
10.10. Other
10.11. Note about lambda/monads

In this section, we briefly describe each of the components in the library's interface.

10.1. Nuts and bolts

To use the Boost FC++ library, just add the line

   #include "boost/fcpp/prelude.hpp"
to the top of your program. This file includes all of the other header files. All of the library interface is in namespace boost::fcpp.

Note that, by default, the "lambda" and "monad" portions of the library are not enabled. This is both because some compilers cannot handle the crazy templates there, and also because they slow down compilation a little, even if they're not being used. To enable these portions of the library, say

   #define BOOST_FCPP_ENABLE_LAMBDA
before #include-ing the library.

The library comes with dozens of example client files (the .cpp files in the FC++ directory). When in doubt about how to use something, check the client examples, which exhibit coverage of most of the library's features.

There are a few other #define flags worth mentioning. These flags are all disabled by default.

   BOOST_FCPP_DEBUG   
   Throws an exception if you try to take the head() or tail() of 
   an empty list.  By default, these operations just result in 
   undefined behavior.
   
   BOOST_FCPP_LAMBDA_DEBUG
   Turns on various extra compile-time checking and custom error
   messages in lambda code.  This is useful for debugging type errors
   with lambda, but slows down compilation, which is why it is disabled
   by default.

   BOOST_FCPP_SAFE_LIST
   Makes all list destructors iterative, rather than recursive.  If you
   have a really long list, you may blow the stack when the list goes
   out of scope.  Setting this flag ensures against this problem, but
   degrades the overall performance of lists, which is why it is
   disabled by default.  If you just need to safely destroy one
   specific instance of a list, just do
      while(l) l = tail(l);   // iteratively destroys l
   
   BOOST_FCPP_DEFER_DEFINITIONS
   Setting this flag makes all the functoids get declared as "extern"
   variables, but not defined.  You then need to link against a separate
   object file with the definitions.  Use this when you are using FC++
   in mutiple translation units, and you do not want each TU to have its
   own copy of all the functoids.
   
   BOOST_FCPP_ENABLE_LAMBDA
   Turns on the "lambda" and "monad" portions of the library, as
   described above.
   
   BOOST_FCPP_1_3_LIST_IMPL
   BOOST_FCPP_OOI_DEBUG
   Deprecated flags; the first one switches to the old (deprecated) list
   implementation, and the second one turns on various debugging code
   for that implementation.

10.2. Constants

FC++ defines the following constants:

   _          // placeholder for currying
   empty      // an empty struct (empty tuple)
   NIL        // the empty list (zero of the list_m monad)
   NOTHING    // an empty maybe (zero of the maybe_m monad)

10.3. Data types

FC++ defines these data types:

   // Useful data types
   list             // for lazy lists
   list_iterator   
   maybe            // represents 1 or 0 elements of some type
   odd_list         // (see Section 9 for details)
   strict_list      // eager (non-lazy) version of "list"
   
   // Utility (see Section 5 and Section 7)
   RT               // Return type computer (e.g.  RT<F,X,Y>::result_type)
   functoid_traits  // for seeing how many arguments a functoid accepts
   c_fun_type       // typedefs for monomorphic functoids
   fun_type         // typedefs for polymorphic functoids
   monomorphic_traits  // for reading argument types from monomorphic functoids
   
   // Miscellaneous
   fullN            // full functoid wrapper classes (Section 7)
   funN             // indirect functoid classes (Section 6)
   fcpp_exception   // used, e.g., when taking head() of an empty list
Note also that every functoid has a corresponding data type. For instance, the map() functoid is an instance of type map_type.

10.4. Basic list functions

Here are the basic functions that work on lists.

   head           // first element
   tail           // all but first element
   cons           // add element
   null           // test for empty
   cat            // concatenate
   ==             // compare for equality
   <              // lexicographical ordering
as well as some other miscellaneous list functions:
   list_with      // helper for creating small lists
   force          // odd_list-ify       (see Section 9)
   delay          // (even) list-ify    (see Section 9)
   
   list_until( pred, f, x )
      // create a list of [x, f(x), f(f(x)), ...] until pred is true
      // Example:   list_until( greater(_,20), plus(3), 1 )
      // yields     [1,4,7,10,13,16,19]

10.5. Haskell standard prelude

A great many FC++ functions are borrowed from Haskell. See [Haskell] for their definitions.

   until
   last
   init
   length    // Note: also used to force evaluation of an entire list
   at
   filter
   concat
   foldr
   foldr1
   foldl
   foldl1
   scanr
   scanr1
   scanl
   scanl1
   iterate
   repeat
   map
   take
   drop
   take_while
   drop_while
   replicate
   cycle
   split_at
   span
   break
   flip
   reverse
   all
   any
   elem
   not_elem
   sum
   product
   minimum
   maximum
   zip_with
   zip
   fst
   snd
   unzip
   gcd
   odd
   even
   enum_from
   enum_from_to
   just
   // These approximate the corresponding Haskell functions
   and
   or
   h_curry
   h_uncurry

10.6. Operators

The following named functoids mimic C++ operators:

   // (T,T) -> T
   plus
   minus
   multiplies
   divides
   modulus
   
   // (T) -> T
   negate
   
   // (T,T) -> bool
   equal
   not_equal
   greater
   less
   greater_equal
   less_equal
   
   // (T,T) -> bool    (where T is convertible to bool)
   logical_and
   logical_or
   logical_not
   
   dereference    // T -> U   (where U has typeof(*T) )
   address_of     // T -> T*
   delete_        // T* -> void

The following operators require extra explanation:

   out_stream
   in_stream
      // These are like operator<<() and operator>>(), but they take a
      // pointer to a stream as the left-hand side.  Examples:
      //    &cout ^out_stream^ x
      //    &cin ^in_stream^ y
      // The indirection is necessary to encapsulate the effects within
      // the library (see Section 8)
   
   dynamic_cast_
      // This is a family of functoids, templatized by the destination
      // type.  Example use:
      //    dynamic_cast_<dog*>()( an_animal_ptr )
      // Note that the functoid
      //    dynamic_cast_<T>()
      // has type
      //    dynamic_cast_x_type<T>::type
   
   constructN
   newN
      // These call constructors.  Like dynamic_cast_ above, they define
      // a family of functoids.  Examples:
      //    construct2<std::pair<int,char> >()( 3, 'c' )
      //    new1<int>()( 3 )
      // Note that, e.g.,
      //    new3<T>()
      // has type
      //    new3_type<T>::type

10.7. Currying, thunks, and effect combinators

   const_   // Turns a value into a thunk
      // Ex:   const_(3)  yields a new function "f":  f()=3
   
   konst    // Turns a value into a constant unary function
      // Ex:   konst(3)  yields a new function "f":  f(anything)=3
   
   thunkN   // binds all N arguments of a function into a thunk
      // Ex:   thunk2(plus,1,2) yields a new function: f()=1+2
   
   no_op    // do-nothing thunk
   
   before   // before(f,g)(args) = { f(); return g(args); }
   after    // after(f,g)(args)  = { r = f(args); g(); return r; }
   
   emptify  // throws away a functions result, returning "empty" instead
      // Example use:
      //    length( map( emptify(effectFunctoid), someList ) )
      // applies effectFunctoid to each element of someList, even if
      // effectFunctoid returns void
   
   split_args  // split_args(f)(x,y,z)  means  f(x)(y)(z)
      // This is rarely useful, but occasionally necessary

10.8. General combinators

These are some generally applicable combinators.

   compose     // compose(f,g)(args)  means  f( g(args) )
   
   of          // same as compose, but also works on function pointers
               // Good for infix:   f ^of^ g
   
   thunk_func_to_func
      // thunk_func_to_func(f)(args)  means  f()(args)
      // f is a thunk that returns a functoid; this combinator hides
      // the thunk.  This can be useful to break what would otherwise 
      // be infinite recursion in "letrec" expressions.
   
   duplicate   // duplicate(f)(x)     means  f(x)(x)
   
   ignore      // ignore(f)(x)(args)  means  f(args)

10.9. Functoid promotion

These functions promote non-functoids into functoids.

   make_fullN  // promotes an instance of a basic functoid into a full functoid
   
   stl_to_fun1 // promotes a std:: unary adaptable into a functoid
   stl_to_fun2 // promotes a std:: binary adaptable into a functoid
   
   ptr_to_fun  // converts C++ function/method pointers into functoids
   
   funify      // Converts function pointers into functoids, but is
               // the identity function on functoids.  Use this when
               // you're not sure exactly what "f" is, but you want it
               // to be a functoid.

10.10. Other

There are a few other miscellaneous functoids:

   make_pair      // creates a std::pair
   min            // lesser of two args
   max            // greater of two args
   inc            // returns ++x
   dec            // returns --x
   id             // identity function
   
   make_manip     // make_manip(aStream)(aManip) returns the manipulator 
                  // for that stream.  Necessary because names like
                  // "std::endl" are not C++ objects.  Ugh.
                  // Example: make_manip(cout)(endl)

10.11. Note about lambda/monads

We do not describe the interface to the FC++'s lambda and monad constructs here. See Section 12 and Section 13 for that info.

Last revised: October 03, 2003 at 23:27:22 GMTCopyright © 2000-2003 Brian McNamara and Yannis Smaragdakis