klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

libraries.texi (8852B)


      1 @c -*-texinfo-*-
      2 @setfilename ../src/libraries
      3 
      4 @node Libraries, System, Errors, Top
      5 @comment  node-name,  next,  previous,  up
      6 
      7 @chapter Libraries
      8 @cindex libraries
      9 
     10 Libraries provide a way to organize klisp code with a clean & clear
     11 interface to the rest of the program.  They are first class objects
     12 (as all manipulable entities in Kernel, and according to the
     13 guidelines in the Kernel report). A library has list of exported
     14 symbols and values for those symbols (generally combiners but may be
     15 any object). The library type is encapsulated.
     16 
     17 In addition there's a mechanism to refer to library objects by name
     18 (where a name is actually a unique list of symbols and numbers), with
     19 the ability to register new libraries, get the library object from a
     20 name, unregister libraries, etc.  
     21 
     22 These two ways of working with libraries conform the low level API to
     23 libraries and are orthogonal to each other.  They are provided to
     24 allow klisp programs to construct their own interface to library
     25 definition and use, and to respect the guidelines and spirit of the
     26 Kernel Report.
     27 
     28 There's also a higher level API that is a combination of the lower level
     29 APIs and behaves more like traditional module systems.  This is
     30 probably what most klisp programs will use.  This API consist of the
     31 @code{$provide-library!} operative to define (and register) new
     32 libraries and the @code{$import-library!} operative to extract
     33 bindings out of existing libraries.  This allows various forms of
     34 controlling which bindings are extracted from the libraries and allows
     35 various forms of renaming. It can be used both in the body of
     36 libraries or in the top level.
     37 
     38 No association is made by klisp between source files and libraries.
     39 For a possible mechanism to handle this see @code{require} in the
     40 ports module. Also no special meaning is assigned to the library
     41 names.  This could be used by an even higher level API, for example to
     42 map to version numbers and/or to the underlying filesystem.
     43 
     44 SOURCE NOTE: This is mostly an adaptation from the r7rs draft of
     45 scheme.  There's no mention of libraries in the Kernel Report, but
     46 they were deemed important for klisp in order to share and distribute
     47 code with a common interface.  A number of adaptations were made to
     48 the scheme version to sit more comfortably with the Kernel way of
     49 doing things (first class status, exposing of the library register,
     50 etc).
     51 
     52 @deffn Applicative library? (library? . objects)
     53 The primitive type predicate for type library.
     54 @code{library?} returns true iff all the objects in @code{objects}
     55 are of type library.
     56 
     57 NOTE: This is part of the low level API to libraries. It won't be
     58 needed to writers or users of libraries that stick to the higher level
     59 API (i.e. @code{$provide-library!} & @code{$import-library!}).
     60 @end deffn
     61 
     62 @deffn Applicative make-library (make-library bindings)
     63 @code{bindings} should be an acyclic list of @code{(symbol . value)}
     64 pairs.  Each symbol may only occur once in the list.
     65 
     66 Constructs a new library object with the passed @code{bindings} as
     67 exported objects.  
     68 
     69 NOTE: This is part of the low level API to libraries, writers of
     70 libraries are encouraged to use @code{$provide-library!} to define
     71 their libraries.
     72 @end deffn
     73 
     74 @deffn Applicative get-library-export-list (get-library-export-list library)
     75 @deffnx Applicative get-library-environment (get-library-environment library)
     76 @code{get-library-export-list} returns the list of symbols exported
     77 from the passed library.  @code{get-library-environment} returns a
     78 fresh empty environment whose parent has all exported symbols of the
     79 library bound to the exported objects.
     80 
     81 NOTE: This is part of the low level API to libraries, users of
     82 libraries are encouraged to use @code{$import-library!} to get
     83 bindings out of libraries (and into the current environment).
     84 @end deffn
     85 
     86 @deffn Operative $registered-library? ($registered-library? name)
     87 @deffnx Operative $get-registered-library ($get-registered-library name)
     88 @deffnx Operative $register-library! ($register-library! name library)
     89 @deffnx Operative $unregister-library! ($unregister-library! name)
     90 @code{name} should a an acyclic list of symbols and exact non-negative
     91 integers.  Two registered libraries can't have the same name (in the
     92 sense of @code{equal?}).
     93 
     94 These operatives control the library registry that maps names to
     95 libraries.  
     96 
     97 Predicate @code{$registered-library?} returns true iff a
     98 library named @code{name} is already registered.
     99 @code{get-registered-library} returns the library object associated
    100 with @code{name} (or throws an error if no library named @code{name}
    101 is registered).  @code{$register-library!} registers @code{library}
    102 with name @code{name} (throws an error if @code{name} is already
    103 registered.  @code{$unregister-library!} removes the library
    104 registered as @code{name} from the library register (throws an error
    105 if no such library was registered).
    106 
    107 NOTE: This is part of the low level API to libraries, users & writers
    108 of libraries are encouraged to use @code{$provide-library!} to create
    109 & register new libraries.
    110 @end deffn
    111 
    112 @deffn Operative $provide-library! ($provide-library! name exports . body)
    113 @deffnx Operative $import-library! ($import-library! . imports)
    114 @code{name} should be as for @code{register-library!} and not already
    115 registered.  @code{exports} should be a list of @code{(#:export
    116 <export-spec> ...)}. Where @code{<export spec>} is either:
    117 @itemize @bullet
    118 @item @code{symbol}
    119 @item @code{(#:rename internal-symbol external-symbol)}
    120 @end itemize
    121 
    122 A lone symbol has the same semantics as the pair with that symbol in
    123 both internal and external positions.  No symbol can appear more than once as external.
    124 @code{body} should be an acyclic list of expressions.  @code{imports}
    125 should be a list like @code{(<import-spec> ...)} where
    126 @code{<import-spec>} is either
    127 @itemize @bullet
    128 @item @code{<name>}
    129 @item @code{(#:only <import-spec> symbol ...)}
    130 @item @code{(#:except <import-spec> symbol ...)}
    131 @item @code{(#:prefix <import-spec> symbol)}
    132 @item @code{(#:rename <import-spec> (orig-symbol new-symbol) ...)}
    133 @end itemize
    134 
    135 These two operatives conform the higher level API for klisp
    136 libraries.  They are what most users of klisp (both writers and users
    137 of libraries) will use.
    138 
    139 Operative @code{$provide-library!} creates and register a library with
    140 name @code{name} and exported symbols obtained from the @code{exports} list and
    141 values prepared by the @code{body}.  First a child of the dynamic
    142 environment is created.  Then, @code{body} is evaluated sequentially
    143 as if by @code{$sequence} in that environment.  Next a new library is
    144 created with a list of exported bindings that use the external symbols
    145 in @code{exports} as names and the values bound by the corresponding
    146 internal symbols in the created environment, as values.  If a lone
    147 symbol is used in @code{exports} it is used both as internal and
    148 external symbol for that binding.  Lastly, the new library object is
    149 registered as @code{name}.  This mechanism more or less follows the
    150 idea of operative @code{$provide!} from the Kernel Report, but it also
    151 allows for renaming.
    152 
    153 Operative @code{$import-library!} imports to the current environment
    154 any combination of bindings from any number of named libraries, while
    155 allowing renaming of said bindings.  It can be used in any context, as
    156 any other Kernel expression.  @code{$import-library!} looks for the
    157 named libraries and then extracts & renames the specified bindings
    158 according to each @code{<import-spec>} and defines them (in the sense
    159 of @code{$define!}  and @code{$set!}) in the current dynamic
    160 environment.  The set of bindings to import are generated in a
    161 recursive manner.  This allows a great deal of control of the imported
    162 bindings and their names.  The semantics for the set of bindings
    163 generated by the various @code{<import-spec>}s are as follows:
    164 @itemize @bullet
    165 @item 
    166 @code{<name>}: All bindings from library @code{name}.
    167 @item 
    168 @code{(#:only <import-spec> symbol ...)}: Only the named bindings from
    169 the set of bindings in @code{<import-spec>}.
    170 @item
    171 @code{(#:except <import-spec> symbol ...)}: All bindings from the set
    172 in @code{<import-spec>} except those named in the list.
    173 @item 
    174 @code{(#:prefix <import-spec> symbol)}: All bindings from the set in
    175 @code{<import-spec>} but renamed by prefixing each one with the
    176 specified prefix @code{symbol}.
    177 @item @code{(#:rename <import-spec> (orig-symbol new-symbol) ...)}:
    178 All bindings from the set in @code{<import-spec>} but renaming all
    179 @code{orig-symbol} to the corresponding @code{new-symbol}.
    180 @end itemize
    181 
    182 If two values are tried to be imported with the same name, they are
    183 checked for @code{eq?}-ness, if they are deemed @code{eq?} to each
    184 other they are imported, otherwise @code{$import-library!} throws an
    185 error.  This helps catch name collisions while allowing to reexport
    186 bindings from used libraries without conflict.
    187 @end deffn