home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / PCLISP30.ZIP / PC-LISP.DOC < prev    next >
Encoding:
Text File  |  1990-02-01  |  144.7 KB  |  3,714 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.       
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.            A GUIDE TO THE PC-LISP INTERPRETER  (V3.00)  
  17.            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  18.  
  19.                  By Peter Ashwood-Smith  
  20.                  ~~~~~~~~~~~~~~~~~~~~~~ 
  21.  
  22.                 Ottawa, Canada.                
  23.                 ~~~~~~~~~~~~~~~
  24.          
  25.  
  26.  
  27.                 
  28.        Copyright (C) 1985,1986,1987,1989,1990 - Peter Ashwood-Smith
  29.  
  30.  
  31.  
  32.                   for my wife, Guylaine
  33.  
  34.  
  35.  
  36.                mail:  Peter Ashwood-Smith     
  37.                   #8, du Muguet,             
  38.                   Hull, Quebec,    
  39.                      Canada,
  40.                     J9A-2L8.
  41.  
  42.                  phone: (819) 595-9032.  
  43.             
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.                     1
  53.  
  54.  
  55.  
  56.          INTRODUCTION
  57.          ~~~~~~~~~~~~
  58.          PC-LISP is a small implementation of LISP for just about any 
  59.     machine with a good C compiler. This manual is biased towards the 
  60.     UNIX and MS-DOS versions.
  61.  
  62.          While small,  it is capable of running a pretty good  subset 
  63.     of Franz LISP.  The functions are supposed to perform in the same 
  64.     way  as  Franz with a few exceptions made for effeciencies  sake. 
  65.     Version 3.00 has the following features.
  66.          
  67.           - Types fixnum,flonum,list,port,symbol,string, hunk,
  68.             array. Forms lambda, nlambda, macro and lexpr.
  69.          
  70.           - Read Macros including splicing read macros.
  71.  
  72.           - Full garbage collection of ALL types.     
  73.  
  74.           - Compacting relocating heap management.     
  75.  
  76.           - Access to some MSDOS BIOS graphics routines.
  77.         
  78.           - Over 160 built in functions, sufficient to allow you 
  79.             to implement many other Franz functions in PC-LISP.
  80.  
  81.           - Stack overflow detection & full error checking
  82.             on all calls, tracing of user defined functions,
  83.             and dumping of stack via (showstack).
  84.  
  85.           - One level of break from which bindings at point
  86.             of error can be seen.
  87.  
  88.           - Reasonable size, requires minumum of 300K (machine 
  89.             RAM required may differ depending on OS size).
  90.  
  91.           - Access to as much (non extended) memory as you've 
  92.             got and control over how this memory is spread 
  93.             among the various data types.
  94.                
  95.          This  program is Shareware.  This means that it you are free 
  96.     to  distribute it or post it to any BBS that you want.  The  more 
  97.     the better. The idea is that if you feel you like the program and 
  98.     are  pleased with it then send us $15 to help  cover  development 
  99.     costs.  Source  code for this program is available upon  request. 
  100.     You  must  however send me 3 blank diskettes and about  $1.50  to 
  101.     cover  first class postage.  The program can be compiled with any 
  102.     good  C compiler that has a pretty complete libc.  In  particular 
  103.     the  program  will  compile with almost no changes on  most  UNIX 
  104.     systems.  A source code guide will probably be included with  the 
  105.     source  if  it  is  finished at the time I  receive  your  source 
  106.     request. If you send diskettes, SEND NEW, GOOD QUALITY DISKS as I 
  107.     have  had  problems writing IBM-PC readable data to old  or  poor 
  108.     quality diskettes with my Tandy 2000's 720K disk drives.
  109.  
  110.  
  111.  
  112.  
  113.                     2
  114.  
  115.  
  116.  
  117.          A WARNING
  118.          ~~~~~~~~~
  119.          PC-LISP  is  distributed as ShareWare.  The  executable  and 
  120.     source  code  may be freely distributed.  It is contrary  to  the 
  121.     purpose  of  ShareWare to charge more than media and  or  mailing 
  122.     costs for this program in any form source,disk,tape etc.  If  you 
  123.     use  PC-LISP  you  do so at your own risk.  I will  not  be  held 
  124.     responsible  for loss or dammage of any kind as a result  of  the 
  125.     correct  or  incorrect use of this program.  If  you  modify  the 
  126.     source and redistribute this source or its resulting executable I 
  127.     ask  that you add a "modified by x" or a "ported to z by y"  line 
  128.     to the initial banner and comment the code accordingly. Please do 
  129.     not remove my name from the banner.
  130.  
  131.          A NOTE
  132.          ~~~~~~
  133.          The  rest  of this manual assumes some  knowledge  of  LISP, 
  134.     MSDOS/UNIX and a little programming experience. If you are new to 
  135.     LISP or programming in general you should work your way through a 
  136.     book  on LISP such as LISPcraft by Robert Wilensky.  You can  use 
  137.     the  interpreter to run almost all of the examples in the earlier 
  138.     chapters.  I  obviously  cannot attempt to teach  you  LISP  here 
  139.     because  it  would require many hundreds of pages and  there  are 
  140.     much better books on the subject than I could write.  Also, there  
  141.     are other good books on Franz LISP besides LISPcraft.
  142.  
  143.          IF YOU WANT TO TRY PC-LISP RIGHT NOW
  144.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  145.          Make  sure  that PC-LISP.EXE and PC-LISP.L are in  the  same 
  146.     directory.  Then type PC-LISP from the DOS prompt. Wait until you 
  147.     get  the  "-->" prompt.  Here is what you should see starting  by 
  148.     typing pc-lisp at the prompt:
  149.  
  150.        PC-LISP V3.00 Copyright (C) 1990 by Peter Ashwood-Smith
  151.        NNN cell bytes, NNN alpha bytes, NNN heap bytes 
  152.        --- [pc-lisp.l] loaded ---
  153.        -->
  154.  
  155.        Be  patient,  it  takes  a few seconds  to  load  the  program 
  156.     especially  off  a floppy.  When you see the first line with  the 
  157.     version number it will take another second or two to produce  the 
  158.     status  line.  (The N's depend on how much memory you  have).  At 
  159.     this point PC-LISP is up and running and is reading LISP from the 
  160.     file PC-LISP.L. Again this takes a second or two. 
  161.  
  162.        If  your machine has some sort of graphics capability you  can 
  163.     try  the graphics demo as follows.  Type "(load 'turtle)" without 
  164.     the  "'s.  Wait until you see the "t" and the prompt "-->" again, 
  165.     then  type  "(GraphicsDemo)".  You  should  see  some  Logo  like 
  166.     squirals  etc.  If  you do not have any graphics  capability  try 
  167.     "(load 'queens)" or "(load 'hanoi)" and then (queens 5) or (hanoi 
  168.     5)  respectively.  For a more extensive example turn to the  last 
  169.     couple  of chapters in LISPcraft and look at the  deductive  data 
  170.     base  retriever.  Type  (load  'match) and look  at  the  match.l 
  171.     documentation. 
  172.  
  173.  
  174.                     3
  175.  
  176.  
  177.  
  178.          EXAMPLE LOAD FILES AND THE PC-LISP.L FILE
  179.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  180.          Included  with  PC-LISP  (V3.00) are a number of  .L  files. 
  181.     These include: PC-LISP.L, MATCH.L, TURTLE.L, DRAGON.L, DIFF.L and 
  182.     perhaps a few others. These are as follows.
  183.  
  184.          PC-LISP.L
  185.          ~~~~~~~~~
  186.          A  file  of extra functions to help fill the gap between  PC 
  187.     and Franz LISP. This file defines the pretty print function and a 
  188.     number  of macros etc.  It will be automatically loaded from  the 
  189.     current  directory  or from the directory whose path  is  set  in 
  190.     LISP_LIB when PC-LISP is executed. The functions in this file are 
  191.     NOT documented in this manual, look instead at a Franz manual.
  192.  
  193.          MATCH.L
  194.          ~~~~~~~
  195.          A  small programming example taken from the last 2  chapters 
  196.     of  LISPcraft.  It  is a deductive data base retriever.  This  is 
  197.     along the lines of PROLOG. Very few changes were necessary to get 
  198.     this to run under PC-LISP.
  199.  
  200.          TURTLE.L
  201.          ~~~~~~~~ 
  202.          Turtle   Graphics  primitives  and  a  small   demonstration 
  203.     program.  To  run the demo you call the  function  "GraphicsDemo" 
  204.     without  any  parameters.  This should run albeit slowly on  just 
  205.     about  every MS-DOS machine.  The graphics primitives look at the 
  206.     global  variable !Mode to decide what resolution to use.  If  you 
  207.     have  mode  8 (640X400) you should use it as the lines  are  much 
  208.     sharper.  Turtle graphic modes can be set by typing (setq !Mode -
  209.     number-). Have a look at TURTLE.L to see how they work.
  210.  
  211.          DRAGON.L
  212.          ~~~~~~~~
  213.          A  very  slow  example  of a  dragon  curve.  This  one  was 
  214.     translated from a FORTH example in the April/86 BYTE.  It takes a 
  215.     long  time on my 8Mhz 80186 machine so it will probably run for a 
  216.     few hours on a PC or AT.  I usually let it run for about 1/2 hour 
  217.     before  getting tired of waiting.  To run it you just type  (load 
  218.     'dragon)  then  type  (DragonCurve 16).  If  you  have  a  higher 
  219.     resolution  machine  like a Tandy 2000 then type (setq  !Mode  8) 
  220.     before  you  run  it and it will look sharper at  this  (640x400) 
  221.     resolution.
  222.  
  223.          DIFF.L
  224.          ~~~~~~
  225.          Is  an  example of symbolic computation.  It takes a  simple 
  226.     expression and computes it's first,  second,  third,  fourth  and 
  227.     fifth  symbolic  derivative.  Again this is just a small  example 
  228.     that should not be taken too seriously in itself. 
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.                     4
  236.  
  237.  
  238.  
  239.          USERS GUIDE
  240.          ~~~~~~~~~~~
  241.          The  PC-LISP program is self contained.  To run it just type 
  242.     the command PC-LISP or whatever you called it.  When it starts it 
  243.     will start grabbing memory in chunks of 16K each.  By default PC-
  244.     LISP  will grab 50 blocks but by setting the LISP_MEM environment 
  245.     variable this can be controlled.  Note,  there is a hard limit of 
  246.     75 blocks.  The LISP_MEM environment variable is set in MS-DOS or 
  247.     UNIX as follows:
  248.  
  249.          set LISP_MEM=(28B,4A,4H)
  250.  
  251.          Which  means allocate up to 28 blocks total,  of which 4 are 
  252.     for  alpha objects and 4 are for heap objects.  The remainder  go 
  253.     for cons cell,  file,  array base,  flonum and fixnum objects. By 
  254.     default  PC-LISP  will allocate up to 50 blocks.  1 of  which  is  
  255.     dedicated for alpha and 1 for heap. Note the environment variable 
  256.     MUST be formatted as above. No spaces are permitted, the brackets 
  257.     must  be  present as must the B,A and H (all capitals) after  the 
  258.     block counts.
  259.          
  260.           After allocating memory PC-LISP will then print the  banner 
  261.     message  followed  by the actual amount of memory  allocated  for 
  262.     each of the three basic object types. Next, before processing the 
  263.     command  line,  PC-LISP  will look for a file called  "pc-lisp.l" 
  264.     first in the current directory,  next in the library  directories 
  265.     specified  in the LISP_LIB environment variable as per the (load) 
  266.     function.  If  it  finds  pc-lisp.l  it will  read  and  evaluate 
  267.     commands from this file until the end of file is reached. Finally
  268.     PC-LISP will read the parameters on the command line. The command 
  269.     line may contain any number of files eg:
  270.  
  271.          PC-LISP file file .... file
  272.          
  273.          The files on the command line are processed one by one. This 
  274.     consists  of loading each file as per the (load)  function.  This 
  275.     means that PC-LISP will look in the current directory for 'file', 
  276.     then  in 'file'.l,  then in the directories given in the LISP_LIB 
  277.     environment variable,  when found the file is read and every list 
  278.     is evaluated.  The results are NOT echoed to the console. Finally 
  279.     when  all  the files have been processed you will  find  yourself 
  280.     with  the PC-LISP top level prompt '-->'.  Typing  control-Z  and 
  281.     ENTER  (MS-DOS end of file) or CONTROL-D (UNIX end of file)  when 
  282.     you  see the '-->' prompt will cause PC-LISP to exit to  whatever 
  283.     program  called it.   If an error occurs you will see the  prompt 
  284.     'er>'.  For more info see the 'TERMINATION OF EVALUATION' section 
  285.     of  this  manual  and  the  commands  (showstack),  (trace),  and 
  286.     (untrace).
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.                     5
  297.  
  298.  
  299.  
  300.          SYNTAX OR WHAT IS A LIST ANYWAY?
  301.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  302.  
  303.          You  will now be in the PC-LISP interpreter and can start to 
  304.     play  with  it.  Basically  it is expecting you  to  type  an  S-
  305.     expression whose value it will evaluate and return.   Formally an 
  306.     S-expression can be defined with a B.N.F Grammar where + means at 
  307.     least one occurence of and, * means any number of occurences of.
  308.  
  309.  
  310.          <S-expression> ::= <fixnum> | <flonum> | <string> | <symbol>
  311.                  |  '(' <elements> ')'
  312.  
  313.                          +
  314.          <elements>     ::=  (<S-expression>)  '.' <S-expression>
  315.                          *
  316.                  |   (<S-expression>)
  317.  
  318.  
  319.          Where characters whose ascii values are in 0..31 are ignored
  320.     and  have no effect other than delimiting other input items. Also
  321.     characters  between  ;  and the end of a line are ignored in  the 
  322.     same way as the white space characters just described,  these are 
  323.     used to introduce comments into your LISP programs.
  324.  
  325.          The the basic list elements <fixnum>, <flonum>, <string> and 
  326.     <symbol> are defined as follows.    
  327.  
  328.          A <fixnum> is a sign + , - or none followed by a sequence of 
  329.     digits 0..9. If the sequence of digits represents a fixnum larger 
  330.     than  can  be  stored in a 32 bit integer it is taken to  be  the 
  331.     nearest  <flonum>.  A <fixnum> can always be spotted when  it  is 
  332.     printed by the lack of a radix point.  Examples are:  2, +2,  -2, 
  333.     and -333333 .
  334.  
  335.          A  <flonum> is a sign + , - or none followed by digits  0..9 
  336.     which  may be followed by a radix point and more digits 0..9 this 
  337.     may  optionally be followed by an exponent specifier 'e'  or  'E' 
  338.     which  may  optionally  be followed by a  sign  +  ,  - or  none, 
  339.     optionally  followed by the exponent digits 0..9.  A <flonum> can 
  340.     always  be spotted when it is printed by the presence of either a 
  341.     radix point, or the exponent specifier 'e'.  Examples :  2.0,  
  342.     -2.0, +2.0, -2e10, -2e+20, -4.0E-13, 2E, -2E
  343.          
  344.          A <string> is a " followed by up to 254 characters  followed 
  345.     by  a  terminating " or |.  If the character \ is present in  the 
  346.     string and the following character is one of t,b,n,r or f the two 
  347.     characters are replaced by a tab,  backspace,  newline,  carriage 
  348.     return or form feed respectively. If the \ is not followed by one 
  349.     of  the previously mentioned special  characters,  the  following 
  350.     character  is  used to subtitute the \ and itself in the  string. 
  351.     The  \ is called the escape character and allows you to  put  non 
  352.     printing formatting characters into a string.  It also allows you 
  353.     to  put a " or | into a string which you could not otherwise  do. 
  354.     Examples: "abcd", "a\tb", "a\"b", "a\|b".
  355.  
  356.  
  357.                     6
  358.  
  359.  
  360.  
  361.          SYNTAX OR WHAT IS A LIST ANYWAY? CONT'D
  362.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  363.         A  <symbol> is either a string delimited with |'s instead  of 
  364.     the "'s,  or a sequence of characters none of which are spaces or 
  365.     non printing characters with ascii values < 32 or > 126.  A \ may 
  366.     be used to escape the following character just as in a string but 
  367.     is  also  legal  without the delimiters.  If  not  delimited  the 
  368.     character  after  the  escape  is  taken  literally  rather  than 
  369.     translated  to a newline etc.  If delimited any character may  be 
  370.     placed  between  the | delimiters with the exception of  "  or  | 
  371.     which must be preceeded by the escape character if they are to be 
  372.     literally included in the symbol.  If the symbol is not delimited 
  373.     by  |'s  and  does  not contain an escaped  character   then  the 
  374.     characters  must  be  in a sequence that  follows  the  following 
  375.     rules.  The  characters ( ) [ ] " | and ;  are reserved and  will 
  376.     cause termination of the symbol.  The set of characters that  are 
  377.     skipped  as  white  space (those with ascii values in  the  range 
  378.     0..31) are termed white space characters.  The set of  characters 
  379.     that  have  been defined as read macros are termed macro  trigger 
  380.     characters.  Only  the ' char is initially a read  macro  trigger 
  381.     character.   The  special  characters  are  all  of  these  above 
  382.     character classes.  Using these definitions, a symbol can  either 
  383.     start with a character in 0..9 or a character not in 0..9. If the 
  384.     character is not in 0..9 then the the following characters can be 
  385.     chosen  from among all but the special characters.  If the  first 
  386.     character  in the symbol is in 0..9 then the last character  must 
  387.     be  chosen from among the set of all characters that are  neither 
  388.     special  nor  in  0..9.  A symbol may be composed of  up  to  254 
  389.     characters  all  of  which  are  significant.   Here  are  a  few 
  390.     examples:  \(  a1 1a 1- 1234abc #hi# !hi% An_ATOM |ab\nc|  junk.l 
  391.     ThisIsOneRatherLargeAtomThatDemonstratesLength \1 2e1\0
  392.  
  393.          An  atomic  S-expression is just one of  a  fixnum,  flonum, 
  394.     string  and symbol.  The only other type of S-expression that can 
  395.     be input is a list S-expression. 
  396.  
  397.          In order to describe what a list S-expression is you need to 
  398.     know some lisp terminology for the parts of a list.  First a list 
  399.     consists  of two parts,  the first element of the list is  called 
  400.     the  car of the list and the rest of the elements in the list  is 
  401.     called the cdr of the list.  For example the list (a b c) has car 
  402.     a  and cdr (b c).  Now that we know the two parts of a  list,  we 
  403.     need to know how to build a list.  A list is built with a cons or 
  404.     constructor cell.  The constructor cell has two parts to it,  the 
  405.     first  is  the car of the list and the second is the cdr  of  the 
  406.     list.  Hence  one  cons  cell describes one list.  Its  car  part 
  407.     describes  the  first  element in the  list,  and  its  cdr  part 
  408.     describes  the list of the rest of the elements in the list.  For 
  409.     the  example  list  (a b c),  the  internal  structure  may  look 
  410.     something  like this:  (where a [ | ] represents a cons cell *--> 
  411.     is a pointer, / is a nil pointer)
  412.  
  413.           [*|*] ---> [*|*] ---> [*|/]
  414.            |          |          | 
  415.            a          b          c          
  416.  
  417.  
  418.                     7
  419.  
  420.  
  421.  
  422.          SYNTAX OR WHAT IS A LIST ANYWAY? CONT'D
  423.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  424.  
  425.          Here  is  an example of a simple nested list  which  can  be 
  426.     input as :  (a (b c) nil d) and which results in a structure like 
  427.     this:
  428.  
  429.           [*|*] ---> [*|*] ---> [/|*] ---> [*|/]
  430.            |          |                     |
  431.            v          v                     v
  432.            a         [*|*] ---> [*|/]       d
  433.                   |          |
  434.                   v          v
  435.                   b          c
  436.           
  437.          The  dot  '.' can be used to separate the last element in  a 
  438.     list  from  the  others  in  the  list.   When  this  occurs  the 
  439.     constructed  list will have a slightly different last  cons  cell 
  440.     second field. Rather than pointing to another cons cell whose car 
  441.     points to the last element, this field will point directly to the 
  442.     last element. For example inputting (a . b) creates the following 
  443.     list structure, which will also print as (a . b). 
  444.  
  445.           [*|*] 
  446.            | |
  447.            v v
  448.            a b 
  449.  
  450.          However  if the last element in the list is another list and 
  451.     we preceed it by a dot,  the list is spliced into the upper  list 
  452.     as  if the last element were not really a list.  For example if I 
  453.     were to input (a .  (b .  (c))) the following structure which  is 
  454.     identical to that constructed by (a b c) would be built.  It will 
  455.     also print as (a b c).
  456.  
  457.           [*|*] ---> [*|*] ---> [*|/]
  458.            |          |          | 
  459.            v          v          v          
  460.            a          b          c
  461.           
  462.  
  463.          The dotted pair is not normally used except when you wish to 
  464.     save  storage.  An  example  might be when you create a  list  of 
  465.     symbols  and  their associated values.  In this case  making  the 
  466.     symbol  and its associated value a dotted pair will save  1  cons 
  467.     cell or about 10 bytes per symbol value pair. 
  468.  
  469.          Finally, I have shown these structures with symbol elements. 
  470.     You  can  have  absolutly  any type as  an  element  of  a  list, 
  471.     including of course a list as shown in the second example  above. 
  472.     This  is a very quick look at list structure and you should  look 
  473.     at LISPcraft for more details.
  474.  
  475.  
  476.  
  477.  
  478.  
  479.                     8
  480.  
  481.  
  482.  
  483.          META SYNTAX
  484.          ~~~~~~~~~~~
  485.          Following  are  some syntactic properties  that  are  really 
  486.     above the level of the syntax of a simple S-expression. Thus they 
  487.     are  called  meta syntax conventions.  I consider Meta syntax  as 
  488.     anything  that does not conform to the B.N.F  grammar  previously 
  489.     given. These extensions to the syntax of S-expressions consist of 
  490.     any  extra  syntax intdoduced by built in or  user  defined  read 
  491.     macros  and the replacement of multiple parenthesis which  occurs 
  492.     when a single super parenthesis is used.
  493.  
  494.          PC-LISP supplies one built in read macro called 'quote'  and 
  495.     written  using  the little ' symbol.  This read macro is  just  a 
  496.     short hand way of writing the list (quote S).  Where S is the  S-
  497.     expression that follows the ' in the input stream.  Here are some 
  498.     examples of the simple conversion that the read macro performs on 
  499.     your input.
  500.  
  501.          'apples        -- goes to -->    (quote apples)
  502.          '|too late|                      (quote |too late|)
  503.          '(1 2 3)                         (quote (1 2 3))
  504.          ''a                              (quote (quote a))
  505.          '"hi"                            (quote "hi")
  506.          
  507.          If  you  are new to LISP you will soon see just  how  useful  
  508.     this little read macro is when you start typing  expressions.  It 
  509.     reduces  the amount of typing you must do,  reduces the amount of 
  510.     list  nesting you have to look at and draws attention to data  in 
  511.     your expressions.
  512.  
  513.          User  defined  read  macros  are  also  provided.   See  the 
  514.     (setsyntax)  function  in the next section  of  the  manual.  The 
  515.     backquote   macro  together  with  comma  (,)  and  at  (@)   are 
  516.     implemented  in the PC-LISP.L load file,  but are not  documented 
  517.     here. Again, see LISPcraft for a discussion of these read macros.
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.                     9
  541.  
  542.  
  543.  
  544.          META SYNTAX CONT'D
  545.          ~~~~~~~~~~~~~~~~~~
  546.  
  547.          PC-LISP  also  provides the meta or super parenthesis  [  ]. 
  548.     One of the problems with LISP is the often overwhelming number of 
  549.     parenthesis.  It  is very common to not supply enough closing )'s 
  550.     and therefore have syntactic/semantic errors in your program. The 
  551.     [ and ] characters when properly used allow you to force  certain 
  552.     structures  even  if  enough )'s have  not  been  provided.  They 
  553.     operate  as follows.  When the [ is encountered in the input,  it 
  554.     acts  like  a  (  except that a note is made  of  the  number  of 
  555.     unclosed  ('s so far.  Now when a ] is encountered in the  input, 
  556.     all lists up to and including the matching [ are closed. If there 
  557.     is  no  matching [,  ie none has been entered or  all  have  been 
  558.     closed with a ] then all open lists are closed. These parenthesis 
  559.     may  be nested up to 16 levels deep.  But,  deep nesting  reduces 
  560.     their  usefullness.   NOTE:  If you open a list with a [ you must 
  561.     close  it with a ].  If you close it with a ) you will cause  the 
  562.     next  [  ]  pair  to  function  incorrectly.  The  super  nesting 
  563.     information  is   reset  whenever a new  file  is  processed,  or 
  564.     whenever  the break level is entered.  That is,  meta parenthesis 
  565.     cannot  be used accross a load or read of another file.  Finally, 
  566.     here  are  a  few  example  legal  inputs  which  use  the   meta 
  567.     parenthesis and the list that results from their input.
  568.  
  569.       ((("hello world\n"] -- goes to --> ((("hello world\n")))
  570.       (([(((8 9] 10 ]                    ((((((8 9)))) 10))
  571.       [[[[[a]]]]]                        (((((a)))))
  572.  
  573.  
  574.         I  should just mention again the fact that  meta  parenthesis 
  575.     will not operate accross multiple reads.  For example suppose you 
  576.     were  using  (read) to get sublists from lists in one  file,  and 
  577.     then switched to reading lists from another file,  then  returned 
  578.     to the original file.  If the original input file made use of the 
  579.     super  parenthesis  and  the particular sublist  being  read  was 
  580.     between  a  pair of superparenthesis,  this information would  be 
  581.     lost when you resume reading the file.  Hence the next ] you  hit 
  582.     will  terminate all open lists rather than those opened after the 
  583.     lost  [.  The  moral  of this example is not  to  use  the  super 
  584.     parenthesis  in  a data file whose reading may be interrupted  by 
  585.     other I/O. This is not a particularly imposing limitation.
  586.  
  587.          A FRANZ DIFFERENCE 
  588.          ~~~~~~~~~~~~~~~~~~
  589.          PC-LISP V3.00 is different from Franz in how the \ character 
  590.     is  interpreted  when  followed by n,t,r etc.  in a string  or  | 
  591.     delimited symbol.  Franz does not convert them to  newline,  tab, 
  592.     carriage  return  etc.  Instead,   Franz  simply takes  the  next 
  593.     character  literally.  You can override the 'smart-backslash'  by 
  594.     using (sstatus) to set the option to nil.  The smart backslash is 
  595.     much more convenient though because you can say (patom "stuff\n")
  596.     instead of (patom "stuff") (terpri).  It is however non  portable 
  597.     so  don't use the smart-backslash unless you are only writing for 
  598.     PC-LISP.
  599.  
  600.  
  601.                        10
  602.  
  603.  
  604.  
  605.          SYNTAX ERRORS
  606.          ~~~~~~~~~~~~~
  607.          When  you  enter a list which is not  correct  syntactically 
  608.     the  interpreter will return the wonderfully informative  'syntax 
  609.     error'  message.  This message may be followed by a message as to 
  610.     the  cause  such  as 'atom too big' or it may be  followed  by  a 
  611.     pretty print of an expressopm which was close to where the  error 
  612.     was  detected.  You  will have to figure out where it is  in  the 
  613.     input  list.  Note that if you do not finish entering a list,  ie 
  614.     you put one too few closing )'s on the end,  the interpreter will 
  615.     wait  until you enter it before continuing.  If you are not  sure 
  616.     what has happened just type "]]" and all lists will be closed and 
  617.     the  interpreter will try to do something with the list.  If  you 
  618.     are running input from a file the interpreter will detect the end 
  619.     of  file  and  give you a 'syntax error'  because  the  list  was 
  620.     unclosed. Try also (showstack), it can help pinpoint the error in 
  621.     a  large  load  file.  V3.00's  syntax error  handling  could  be 
  622.     improved.
  623.  
  624.          EVALUATING S-EXPRESSIONS
  625.          ~~~~~~~~~~~~~~~~~~~~~~~~
  626.          The  interpreter expects an S-expression to be typed at  the 
  627.     prompt  '-->'.  The interpreter will evaluate the expression  and 
  628.     print  the resulting S-expression.  If the expression is either a 
  629.     fixnum  or a flonum,  the interpreter just returns it  because  a 
  630.     number  evaluates to itself.  If the expression is a string,  the 
  631.     interpreter also returns it because a string evaluates to itself.
  632.     If  however the expression is a symbol,  the interpreter  returns 
  633.     the  binding of the symbol.  It is an error to try to evaluate  a 
  634.     symbol  that  has  no  binding.   Certain  predefined  atoms  are 
  635.     prebound,  while  all other symbols are unbound until bound by  a 
  636.     function call or a set / setq.  If the expression is a list, then 
  637.     the  first element in the list is taken to be a function name  or 
  638.     description,  the rest of the elements are taken to be parameters 
  639.     to the function.  The interpreter will normally evaluate each  of 
  640.     the  arguments  and  then pass them to the  appropriate  function 
  641.     whose result is returned. For example: The list S-expression with 
  642.     a '+' as the first element and fixnums as elements will  evaluate 
  643.     as the sum of the fixnums. Eg.
  644.  
  645.          -->(+ 2 4 6 8)
  646.          20
  647.  
  648.          We  can  also  compose these function calls  by  using  list 
  649.     nesting.  Sublists are evaluated prior to upper levels. Eg:
  650.  
  651.          -->(- (+ 6 8) (+ 2 4))
  652.          8
  653.  
  654.          We  can  also  perform operations on other  objects  besides 
  655.     numbers.  Suppose that we wanted to reverse the list (time  flies 
  656.     like arrows).  Trying the built in function reverse we get: 
  657.          
  658.          -->(reverse (time flies like arrows))
  659.          --- error in built in function [apply] ---
  660.  
  661.  
  662.                        11
  663.  
  664.  
  665.  
  666.          EVALUATING S-EXPRESSIONS CONT'D
  667.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  668.          But the interpreter will be confused!  It does not know that 
  669.     'time'  is  data  and not a function  taking  arguments  'flies', 
  670.     'like'  and 'arrows'.  To indicate it is upset PC-LISP prints the 
  671.     error  message above and alters the prompt.  More on this  later. 
  672.     What  can  we do to fix this?  We must use the  function  'quote' 
  673.     which returns its arguments unevaluated, hence the name 
  674.     "quote".
  675.  
  676.          -->(reverse (quote (time flies like arrows)))
  677.          (arrows like flies time)
  678.            
  679.          Will give us the desired result (arrows like flies time). We 
  680.     can  do  the  same  thing  without  using  the  (quote)  function 
  681.     directly.  Remember the read macro ' above?  Well it will replace 
  682.     the  entry '(time flies like arrows) with (quote(time flies  like 
  683.     arrows)). So more concisely we can ask PC-LISP to evaluate: 
  684.                
  685.          -->(reverse '(time flies like arrows))
  686.          (arrows like flies time)
  687.  
  688.          This gives us the correct result without as much typing. You 
  689.     will  now  note that the subtraction of 2+4 from 6+8  could  also 
  690.     have been entered as:
  691.          
  692.          -->(- (+ '6 '8) (+ '2 '4))
  693.          8
  694.  
  695.          However,   the  extra  's  are  redundant  because  a fixnum 
  696.     evaluates to itself. In general a LISP expression is evaluated by 
  697.     first  evaluating each of its arguments,  and then  applying  the 
  698.     function to the arguments,  where the function is the first thing 
  699.     in the list.  Remember that evaluation of the function (quote s1) 
  700.     returns  s1 unevaluated.   LISP will also allow the function name 
  701.     to  be  replaced by a function body called a  lambda  expression. 
  702.     Which is just a function body without a name. Example:
  703.  
  704.          -->((lambda(x)(+ x 10)) 14)
  705.          24
  706.  
  707.          Which would be processed as follows. First the parameters to 
  708.     the  lambda expression are evaluated.  That's just 14.  Next  the 
  709.     body  of the lambda expression is evaluated but with the value 14 
  710.     bound to the formal parameter given in the lambda expression.  So 
  711.     the body evaluated is (+ x 10) where x is bound to 14. The result 
  712.     is  just  24.  Note  that lambda expressions  can  be  passed  as 
  713.     parameters  as can built in functions or user defined  functions. 
  714.     Hence  I  can  evaluate the following input.  Note I  use  the  ] 
  715.     character to close the three open lists rather than typing ))) at 
  716.     the end of the line.
  717.  
  718.          -->((lambda(f x)(f (car x))) '(lambda(l)(car l)) '((hi]   
  719.          hi                  
  720.  
  721.  
  722.  
  723.                        12
  724.  
  725.  
  726.  
  727.          EVALUATING S-EXPRESSIONS CONT'D
  728.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  729.          Which evaluates as follows. The parameters to the call which 
  730.     are   the   expressions  '(lambda(l)(cdr  l))  and  '((hi))   are 
  731.     evaluated. This results in the expressions being returned because 
  732.     they are quoted.  These are then bound to 'f and 'x  respectively 
  733.     and  the body of the first lambda expression is  evaluated.  This 
  734.     means  that  the  expression ((lambda(l)(car l))(car  ((hi)))) is 
  735.     evaluated. So again the parameters to the function are evaluated. 
  736.     Since  the  only  parameter  is  (car  ((hi)))  it  is  evaluated 
  737.     resulting  in  (hi).  This  is then bound to l  and  (car  l)  is 
  738.     evaluated giving hi.   
  739.  
  740.          PC-LISP is also capable of handling all other function  body 
  741.     kinds.  These are lambda, nlambda, lexpr  and macro kinds.  These 
  742.     expression kinds may all have multiple bodies which are evaluated 
  743.     in order,  the last one producing the value that is returned. See 
  744.     the  section on BUILT IN FUNCTIONS and MACROS for more details on 
  745.     these kinds and how they operate. Better yet read LISPcraft.
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.                        13
  785.  
  786.  
  787.  
  788.          TERMINATION OF EXPRESSION EVALUATION
  789.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  790.          There are three distinct ways that evaluation can terminate. 
  791.     First, evaluation can end naturally when there is no more work to 
  792.     do.  In  this  case the resulting S-expression is printed on  the 
  793.     console and you are presented with the prompt "-->".  Second, you 
  794.     can request premature termination by hitting the CONTROL-BREAK or 
  795.     CONTROL-C  keys  simultaneously (MS-DOS) or the INTR  key  (UNIX) 
  796.     (hereafter  referred  to as CONTROL-BREAK for both UNIX  and  MS-
  797.     DOS). Note that this will only interrupt list evaluation, it will 
  798.     NOT  interrupt garbage collection which continues to  completion. 
  799.     So, if you hit CONTROL-BREAK (ie INTR,CONTROL-C or CONTROL-BREAK) 
  800.     and  you don't get any response,  wait a second or two because it 
  801.     will respond after garbage collection  ends.  Finally,  execution 
  802.     can  terminate when PC-LISP detects a bad parameter to a built in 
  803.     function,  a stack overflows, a division by zero is attempted, or 
  804.     an atom is unbound etc. In all cases but a normal termination you 
  805.     will be returned to a break error level.  This is when the prompt 
  806.     looks  like 'er>'.  This means that variable bindings  are  being 
  807.     held  for  you to examine.  So if the evaluation aborts with  the 
  808.     message "error in built in function [car]",  you can examine  the 
  809.     atom  bindings  that were in effect when this error  occurred  by 
  810.     typing  the name of the atom desired.  This causes its binding to 
  811.     be displayed. When you are finished with the break level just hit 
  812.     CONTROL-Z plus ENTER (MS-DOS) or CONTROL-D (UNIX) and you will be 
  813.     placed  back in the normal top level and all bindings  that  were 
  814.     non  global will be gone.  Note you can do anything at the  break 
  815.     level  that you can do at the top level.  If further errors occur 
  816.     you will stay in the break level and any bindings at the time  of 
  817.     the  second error will be in effect as well as any bindings  that 
  818.     were in effect at the previous break level. If bindings effecting 
  819.     atoms  whose  values are being held in the first break level  are 
  820.     rebound  at the second break level these first bindings  will  be 
  821.     hidden by the secondary bindings.
  822.  
  823.          An  error  in built in functions 'eval' or 'apply' can  mean 
  824.     two  things.  First,  your expression could contain a bad  direct 
  825.     call  to eval or apply.  Or,  your code may be trying to apply  a 
  826.     function that does not exist to a list of parameters,  or  trying 
  827.     to apply a bad lambda form.  The interpreter does not distinguish 
  828.     an  error  made  in  a direct call by you  to  eval/apply  or  an 
  829.     indirect  call  to eval/apply,  made by the interpreter  on  your 
  830.     behalf to get the expression evaluated.
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.                        14
  846.  
  847.  
  848.  
  849.          TERMINATION OF EXPRESSION EVALUATION CONT'D
  850.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  851.  
  852.          There  are a variety of math errors that are detected  under 
  853.     certain  implementations  of PC-LISP.  The MS-DOS and  AT&T  UNIX 
  854.     versions will both trap domain,  argument singularity etc. errors 
  855.     as  per  the  MATH(3M) library.  These  errors  generate  similar 
  856.     messages as the "error evaluating built in function" errors.  The 
  857.     Berkeley  UNIX math library will not trap these in the same  way. 
  858.     Instead,  you  will  get a system error message  as  descrbed  by 
  859.     perror() in the UNIX programmers guide.  You will have to look at 
  860.     the  (showstack)  to  figure out which expression  generated  the 
  861.     error.  The  same is true for floating point exceptions  and  any 
  862.     other  detectable  system error such as (but not limited to)  I/O 
  863.     errors.  This  is because PC-LISP checks for system errors  after 
  864.     every  evaluation  so system errors such as "diskfull"  will  not 
  865.     pass unnoticed.
  866.  
  867.          It  is  also useful to know what the  circumstances  of  the 
  868.     failure  were.  You can display the last 20 evaluations with  the 
  869.     command  (showstack).  This will print the stack from the top  to 
  870.     the  20th  element  of the stack.  This gives  you  the  path  of 
  871.     evaluation  that lead to the error.  For more information on  the 
  872.     (showstack)  command  look  in the section  FUNCTIONS  WITH  SIDE 
  873.     EFFECTS OR THAT ARE EFFECTED BY SYSTEM.
  874.  
  875.          It  is  possible  but  hopefully pretty  unlikely  that  the 
  876.     interpreter  will stop on an internal error.  If this happens try 
  877.     to duplicate it and let me know so I can fix it.
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.  
  903.  
  904.  
  905.  
  906.                        15
  907.  
  908.  
  909.  
  910.          DATA TYPES IN PC-LISP
  911.          ~~~~~~~~~~~~~~~~~~~~~
  912.          PC-LISP  has  the  following data types,  32  bit  integers, 
  913.     double  precision floating point numbers,  lists,  ports for file 
  914.     I/O,  alpha atoms,  strings, hunks, and MacLisp style arrays. The 
  915.     (type) function returns these atoms:
  916.  
  917.           fixnum  - a 32 bit integer (possibly 64 on some UNIXes)
  918.  
  919.           flonum  - a double precision floating point number.
  920.  
  921.           list    - a list of cons cells.
  922.  
  923.           symbol  - an alpha atom, with print name up to 254 chars 
  924.             which  may  include spaces tabs  etc,  but  which 
  925.             should  not  include  an  (ascii  0)   character. 
  926.             Symbols may have property, bindings and functions
  927.             associated with them. Symbols with same print 
  928.             name are the same object.
  929.  
  930.           string  - A string of characters up to 254 in length. It 
  931.             has nothing else associated with it. Strings
  932.             with same print name are not necessarily the
  933.             same object.
  934.                
  935.           port    - A stream that is open for read or write. This 
  936.             type can only be created by (fileopen).
  937.  
  938.           hunk    - An array of 1 to 126 elements.  The elements may 
  939.             be  of  any other  type  including  hunks.  Franz 
  940.             allows 127, the missing element is due to a space
  941.             saving decision. This type can only be created 
  942.             by a call to (hunk) or (makhunk).
  943.  
  944.           array   - An array of any number of dimensions that can 
  945.             have any type of element. Size is restricted 
  946.             only by available memory. (no 64K limit)
  947.  
  948.          Fixnums and flonums are together known as numbers.  The read 
  949.     function will always read a number as a flonum and then see if it 
  950.     can represent it as a fixnum without loss of precision.  Hence if 
  951.     the  number 50000000000 is entered it will be  represented  as  a 
  952.     flonum because it exceeds the precision of a fixnum.  If a number 
  953.     has a decimal point or exponent specifier 'e' or 'E' in it, it is 
  954.     assumed  to  be  a flonum even if there are no  non  zero  digits 
  955.     following the radix point.
  956.  
  957.          Fixnums  and flonums will not appear the same when  printed. 
  958.     The  print function will output a flonum with a radix  point  and 
  959.     perhaps an exponent specifier if it will make the output smaller.
  960.     Naturally, a fixnum never has a radix point.
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.                        16
  968.  
  969.  
  970.  
  971.          DATA TYPES IN PC-LISP (CONT'D)
  972.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  973.  
  974.          Hunks when printed appear as { e0 e1 e2 ....  eN }. They are 
  975.     indexed  from zero.  They cannot be entered,  ie there is no read 
  976.     mechanism for creating them you must create them with a  function 
  977.     call.  Hunks  are  subject to compaction and relocation like  any 
  978.     other PC-LISP object.  The storage for the hunk itself comes from 
  979.     the heap,  storage for the cell that handles the hunk comes  from 
  980.     the cons, etc. space.
  981.  
  982.          Arrays  are implemented as 126-ary trees of hunks.  They are 
  983.     also  indexed from 0.  Because they are implemented in  terms  of 
  984.     hunks,  they  are  subject to compaction  and  reclaimation.  The 
  985.     storage for the array is thus not really contiguous.  However  it 
  986.     appears so to the caller. Although you do not need to know how an 
  987.     array is implemented to use them, here is how it works in PC-LISP 
  988.     for your interest. Formally, an array tree is defined recursively 
  989.     as follows:
  990.  
  991.       BASE : If the size of the array is < 126 the array tree is just 
  992.     a hunk the exact size as the array.
  993.  
  994.       INDUCTION:     If  the size of the array is >= 126,  the  array 
  995.     tree is a hunk of size exactly 126 or 125.  The entries 0 ..  124 
  996.     contain  array trees each of which has size equal to the parent's 
  997.     size divided by 125 (truncated division). If the remainder of the 
  998.     size of the array divided by 125 is zero, the hunk is of size 125 
  999.     and has no 125th entry. If the remainder of the size of the array 
  1000.     divided by 125 is non zero,  then the size of the hunk is 126 and 
  1001.     the 125th entry is used to either store the remainder  array,  or 
  1002.     the  remainder element as follows.  If the remainder array is  of 
  1003.     size exactly 1,  it is not stored,  the 125th entry of the parent 
  1004.     is  used to hold the entry instead.  If however the remainder  is 
  1005.     greater than 1,  the 125 entry of the parent holds a hunk of size 
  1006.     equal to the remainder.
  1007.  
  1008.          Arrays  when  printed will print as array[nnn] where nnn  is 
  1009.     the number of elements in the array.  Multidimensional arrays are 
  1010.     stored  in  exactly  the same way  as  linear  arrays.  The  only 
  1011.     difference  is in how the element number is computed  when  doing 
  1012.     array  accesses.  They will also print as array[nnn] where nnn is 
  1013.     the total number of elements in all dimensions of the  array.  It 
  1014.     is  possible  to  allocate  some pretty big  arrays  in  PC-LISP, 
  1015.     however you will need to adjust the LISP_MEM environment variable 
  1016.     H option to make sure there is enough heap space for them.
  1017.  
  1018.          Also note that the array hunk tree is allocated all at  once 
  1019.     so for large arrays it takes some time to initialize.  Also,  the 
  1020.     array  access functions (store) and (arraycall) are  provided  as 
  1021.     macros in pc-lisp.l.  Finally note that unlike Franz,  you cannot 
  1022.     specify a user written access function for the array or alter any 
  1023.     of the other array specific data besides the raw array tree.
  1024.  
  1025.  
  1026.  
  1027.  
  1028.                        17
  1029.  
  1030.  
  1031.  
  1032.          THE BUILT IN FUNCTIONS AND VARIABLES
  1033.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1034.  
  1035.          Following is a list of each built in function. I will denote
  1036.     the  allowed  arguments  as follows:  
  1037.  
  1038.        - a1...aN are alpha atom parameters, type symbol.
  1039.        
  1040.        - h1...hN are string or alpha atoms, type string or symbol.
  1041.  
  1042.        - x1...xN are integer atom parameters, type fixnum (32bits).
  1043.  
  1044.        - f1...fN are double precision reals, type flonum.    
  1045.  
  1046.        - n1...nN are number atom parameters, type flonum or fixnum.
  1047.  
  1048.        - z1...zN are numbers but all are of the same type. 
  1049.  
  1050.        - l1...lN are lists, must be nil or of type list.          
  1051.  
  1052.        - p1...pN are port atom parameters, type port.
  1053.  
  1054.        - s1...sN  are  S-expressions (any atom type or list)
  1055.  
  1056.        - H is a hunk.  
  1057.          
  1058.        - A is a symbol which is bound to an array.
  1059.  
  1060.        Additional Definitions:
  1061.        ~~~~~~~~~~~~~~~~~~~~~~~
  1062.        "{a|d}+"  means  any sequence of characters of length  greater      
  1063.     than  0  consisting  of a's and  d's  in  any  combination.  This      
  1064.     defines   the   car,cdr,cadr,caar,cadar...   function  class   as      
  1065.     follows: "c{a|d}+r".
  1066.  
  1067.         "[ -stuff- ]" indicates  that -stuff-  is/are optional and if 
  1068.     not provided a default will be provided for you.
  1069.          
  1070.         "*-stuff-*"  indicates  that  -stuff- is  not  evaluated.  An 
  1071.     example  of  this  is the function (quote *s1*) whose  single  S-
  1072.     expression parameter s1 is enclosed in *'s to indicate that quote 
  1073.     is passed the argument s1 unevaluated.
  1074.  
  1075.          For  the  simpler functions I will describe  the   functions 
  1076.     using  a sort of "if (condition) result1 else  result2"  notation 
  1077.     which should be pretty obvious to most people. For functions that 
  1078.     are a little more complex I will give a short English description 
  1079.     and  perhaps  an  example.  If the example code shows  the  '-->' 
  1080.     prompt  you  should  be able to type exactly  what  follows  each 
  1081.     prompt  and get the same responses from PC-LISP.  If the  example 
  1082.     does  not show a '-->' prompt the example is a code fragment  and 
  1083.     will not necessarily produce the results shown.
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.                        18
  1090.  
  1091.  
  1092.  
  1093.          PREDEFINED GLOBAL VARIABLES (ATOMS)
  1094.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1095.          
  1096.          A  number of atoms are globally prebound by  PC-LISP.  These 
  1097.     variables  are  testable and setable  by you but  in  some  cases 
  1098.     altering the bindings is highly inadvisable.  Note that a binding 
  1099.     can  be inadvertantly altered by defining one of these atoms as a 
  1100.     local or parameter atom to a function or a prog,  or directly  by 
  1101.     using 'set' or 'setq'.
  1102.  
  1103.          "displace-macros" - This atom when non nil will cause  macro 
  1104.     expansion to be follwed by code substitution if such substitution 
  1105.     is possible. The default value is nil meaning no substitution.
  1106.           
  1107.          "t"  - This  atom   means 'true',  it is  bound  to  itself. 
  1108.     Various predicates return this to indicate a true condition.  You 
  1109.     should  NOT change the binding of this atom,  to do so will cause 
  1110.     PC-LISP to produce incorrect answers.
  1111.  
  1112.          "nil" - This is not really an atom,  it represents the empty 
  1113.     list ().  It is not bound to () but is rather equivalent to () in 
  1114.     all  contexts.  Any  attempt to create a symbol with  print  name 
  1115.     "nil" will result in ().  
  1116.  
  1117.          "$ldprint" - Is initially  bound to "t".  When not bound  to 
  1118.     "nil"  this  atom  causes the printing of the -- [file loaded] -- 
  1119.     message  when  the function (load file) is executed.  When  "nil" 
  1120.     this  atom prevents the printing of the above  message.  This  is 
  1121.     useful  when  you  want  to load  files  silently  under  program 
  1122.     control. It will also inhibit the pc-lisp.l loaded message.
  1123.  
  1124.          "$gcprint"  - Is  initially bound to "nil".  When  bound  to 
  1125.     "nil"  garbage collection proceeds silently.  If bound non  "nil" 
  1126.     then  at  the  end of a garbage collection cycle  4  numbers  are 
  1127.     printed.  The first is the number of collection cycles that  have 
  1128.     occured  since PC-LISP was started,  the second is the percentage 
  1129.     of cons cells that are in use,  the third the percentage of alpha 
  1130.     cells, and the third the percentage of heap space that is in use. 
  1131.     These  last  three numbers are exactly what you get back  with  a 
  1132.     call to (memstat).
  1133.  
  1134.          "$gccount$  - Is initially bound to 0.  It increases by  one 
  1135.     every time garbage collection occurs. This number is the  same as 
  1136.     the  first  number printed when $gcprint is bound non  "nil"  and 
  1137.     garbage  collection  occurs.  While you can set $gccount$ to  any 
  1138.     value you want,  its global binding will be reset to the  correct 
  1139.     garbage collection cycle count whenever collection finishes.
  1140.  
  1141.          "piport",  "poport",  "errport" - Are bound to the  standard 
  1142.     input, standard output and standard error ports respectively. You 
  1143.     can  use these to force patom,  princ,  print and pp-form to send 
  1144.     their output to the standard output or error.  Or,  to force read 
  1145.     and  readc to get their input from the standard input.  They  are 
  1146.     initially bound to the keyboard and screen.  You can alter  their 
  1147.     bindings if you wish but this is not recommended.
  1148.  
  1149.  
  1150.                        19
  1151.  
  1152.  
  1153.  
  1154.          THE MATH FUNCTIONS
  1155.          ~~~~~~~~~~~~~~~~~~
  1156.          Functions that operate on numbers,  fixnums or flonums. Note 
  1157.     that the arrow --X--> may indicate what type is returned. If X is 
  1158.     's'  then the same type as the parameter(s) selected is returned. 
  1159.     If  X is 'f' then a flonum type is returned.  If X is 'x' then  a 
  1160.     fixnum is returned.  If X is 'b' then the best type is  returned, 
  1161.     this  means that a fixnum is returned if possible.  Note that you 
  1162.     should  use  fixnums  together  with  "1+,  1- zerop"  when  ever 
  1163.     possible because doing so gives nearly a 50% decrease in run time 
  1164.     for many expressions, especially counted loops or recursion.
  1165.  
  1166.          TRIG AND OTHER MATH FUNCTIONS
  1167.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1168.          (abs  n1)    --s-> absolute value of n1 is returned.
  1169.          (acos n1)    --f-> arc cosine of n1 is returned.
  1170.          (asin n1)    --f-> arc sine of n1 is returned.
  1171.          (atan n1 n2) --f-> arc tangent of (quotient n1 n2).      
  1172.          (cos n1)     --f-> cosine of n1, n1 is radians
  1173.          (exp n1)     --f-> returns e to the power n1.
  1174.          (expt n1 n2) - b-> n1^n2 via exp&log if n1 or n2 flonum. 
  1175.          (fact x1)    --x-> returns x1! ie x1*(x1-1)*(x1-2)*....1         
  1176.          (fix n1)     --x-> returns nearest fixnum to number n1.
  1177.          (float n1)   --f-> returns nearest flonum to number n1.
  1178.          (log n1)     --f-> natural logarithm of n1 (ie base e).
  1179.          (log10 n1)   --f-> log base 10 of n1 {not present in Franz}
  1180.          (lsh x1 x2)  --x-> x1 left shifted x2 bits (x2 may be < 0).
  1181.          (max n1..nN) --s-> largest of n1...nN or (0 if N = 0)
  1182.          (min n1..nN) --s-> smallest of n1..nN or (0 if N = 0)
  1183.          (mod x1 x2)  --x-> remainder of x1 divided by x2.
  1184.          (random [x1])--x-> random fixnum, or random in 0...x1-1.
  1185.          (sin n1)     --f-> sine of n1, n1 is radians.
  1186.          (sqrt n1)    --f-> square root of n1.
  1187.          (1+ x1)      --x-> x1+1. 
  1188.          (add1 n1)    --b-> n1+1 (done with fixnums if n1 is fixnum).
  1189.          (1- x1)      --x-> x1-1.
  1190.          (sub1 n1)    --b-> n1-1 (done with fixnums if n1 is fixnum).
  1191.  
  1192.          BASIC MATH FUNCTIONS 
  1193.          ~~~~~~~~~~~~~~~~~~~~
  1194.      (* x1 ...... ..xN) --x-> x1*x2*x3*.....nN (or 1 if N = 0)  
  1195.      (times n1 .. ..nN) --b-> n1*n2*n3......nN (or 1 if N = 0)
  1196.      (product n1....nN) --b-> Ditto                
  1197.      (+ x1....... ..xN) --x-> x1+x2+x3+.....xN (or 0 if N = 0)  
  1198.      (add n1 .......nN) --b-> n1+n2+n3+.....nN (or 0 if N = 0)
  1199.      (sum n1 .......nN) --b-> Ditto
  1200.      (plus n1.......nN) --b-> Ditto
  1201.      (- x1....... ..xN) --x-> x1-x2-x3-.....xN (or 0 if N = 0)  
  1202.      (diff n1.......nN) --b-> n1-n2-n3-.....nN (or 0 if N = 0)  
  1203.      (difference....nN) --b-> Ditto
  1204.      (/ x1....... ..xN) --x-> x1/x2/x3/.....xN (or 1 if N = 0)
  1205.      (quotient n1...nN) --b-> n1/n2/n3/.....xN (or 1 if N = 0)
  1206.  
  1207.          Note  that the Basic functions that operate on numbers  will 
  1208.     return a fixnum if the result can be stored in one.
  1209.  
  1210.  
  1211.                        20
  1212.  
  1213.  
  1214.  
  1215.          THE BOOLEAN FUNCTIONS
  1216.          ~~~~~~~~~~~~~~~~~~~~~
  1217.          These functions all return boolean values. The objects t and 
  1218.     nil represent true and false respectively. Note however that most 
  1219.     functions  treat a non nil value as being t.  t is  a  predefined 
  1220.     atom  whose binding is  t while nil is not a real atom but rather 
  1221.     a  lexical item that is EQUIVALENT to () in all  contexts.  Hence 
  1222.     nil and () are legal as both an atom and a list in all functions.
  1223.  
  1224.          Note when comparing flonums you cannot use (eq) because they 
  1225.     are  not identical objects.  (eq) however will work on fixnums as 
  1226.     in Franz.
  1227.           
  1228.          (alphalessp h1 h2) ---> if (h1 ASCII before h2) t else nil;
  1229.          (arrayp s1)        ---> if (s1 is type Array) t else nil;
  1230.          (atom s1)          ---> if (s1 not type list) t else nil;
  1231.          (and s1 s2 .. sN)  ---> if (a1...aN all != nil) t else nil;
  1232.          (boundp a1)        ---> if (a1 bound) (a1.eval(a1)) else nil;
  1233.          (eq s1 s2)         ---> if (s1,s2 same obj/fix) t else nil;
  1234.          (equal s1 s2)      ---> if (s1 has s2's structure) t else nil;
  1235.          (evenp n1)         ---> if (n1 mod 2 is zero) t else nil;
  1236.          (fixp s1)          ---> if (s1 of type fixnum) t else nil;
  1237.          (floatp s1)        ---> if (s1 of type flonum) t else nil;
  1238.          (greaterp n1...nN) ---> if (n1>n2>n3...>nN) t else nil;
  1239.          (hunkp s1)         ---> if (s1 of type hunk) t else nil;
  1240.          (lessp n1...nN)    ---> if (n1<n2<n3...<nN) t else nil;
  1241.          (listp s1)         ---> if (s1 of type list) t else nil;
  1242.          (minusp n1)        ---> if (n1 < 0 or 0.0) t else nil;
  1243.          (not s1)           ---> if (s1 != nil) nil else t;
  1244.          (null s1)          ---> Ditto                       
  1245.          (numberp s1)       ---> if (s1 is fix of float) t else nil;
  1246.          (numbp s1)         ---> Ditto. 
  1247.          (or s1 s2 .. sN)   ---> if (any si != nil) t else nil;
  1248.          (oddp n1)          ---> if (n1 mod2 is non zero) t else nil;
  1249.          (plusp n1)         ---> if (n1 > 0 or 0.0) t else nil; 
  1250.          (portp s1)         ---> if (s1 of type port) t else nil;
  1251.          (zerop n1)         ---> if (n1 = 0 or 0.0) t else nil;
  1252.          (< z1 z2)          ---> if (z1 < z2) t else nil;
  1253.          (= z1 z2)          ---> if (z1 = z2) t else nil;
  1254.          (> z1 z2)          ---> if (z1 > z2) t else nil;
  1255.  
  1256.          Note carefully the difference between (eq) and (equal).  One  
  1257.     checks  for  identical objects or fixnums,  ie the  same  object, 
  1258.     while  the  other  checks  for two objects  that  have  the  same 
  1259.     structure and identical leaves.                                      
  1260.  
  1261.          Note  that  the  (and) and  (or)  functions  evaluate  their 
  1262.     arguments one by one until the result is known. Ie, short circuit 
  1263.     evaluation is performed.
  1264.  
  1265.          Note  that proper choice of fixnums over flonums and  proper 
  1266.     choice   of   fixnum  functions  can  yield   large   performance 
  1267.     improvements.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.                        21
  1273.  
  1274.  
  1275.  
  1276.          LIST & ATOM CREATORS AND SELECTORS
  1277.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1278.  
  1279.          These functions will take lists and atoms as parameters  and 
  1280.     return  larger  or  smaller lists or atoms.  They  have  no  side 
  1281.     effects  on  the  LISP system nor are their results  affected  by 
  1282.     anything  other than the values of the parameters given to  them. 
  1283.     These functions are all nondestructive as they do not alter their 
  1284.     parameters in any way.
  1285.  
  1286.  
  1287.          (append l1..ln)    ---> list made by joining all of l1..ln.
  1288.                      If any of l1..ln is nil they are
  1289.                      ignored. 
  1290.  
  1291.          (ascii n1)         ---> atom with name 'char' where 'char' 
  1292.                      has ordinal value n1:(0 < n1 < 256).
  1293.           
  1294.          (assoc s1 s2)      ---> if s2 is a list of (key.value) pairs
  1295.                      then assoc --> (key.value) from s2,
  1296.                      where (equal key s1) is t else nil.
  1297.  
  1298.          (car l1)           ---> first element in l1. If l1 is nil
  1299.                      car returns nil.
  1300.  
  1301.          (cdr l1)           ---> Everything but the car of l1. If
  1302.                      l1 is nil cdr returns nil. 
  1303.  
  1304.          (c{a|d}+r l1)      ---> performs repeated car or cdr's on
  1305.                      l1 as given by reverse of {a|d}+.
  1306.                      Returns nil if it cars or cdrs off
  1307.                      the end of a list.
  1308.  
  1309.     (character-index h1 h2) -x-> Returns the index (from 1) of first
  1310.                      char in h2 in h1. h2 can be a fixnum
  1311.                      ascii value. Returns nil if none.
  1312.  
  1313.          (concat s1 .. sN)  ---> Forms a new atom by concatenating
  1314.                      all the strings,atoms,fixnums and
  1315.                      flonums print names.         
  1316.  
  1317.          (cons s1 s2)       ---> list with s1 as 1st elem s2 is rest. 
  1318.                      If  s2  is  nil  the  list  has  one 
  1319.                      element. If s2 is an atom the pair 
  1320.                      print with a dot. (cons 'a 'b) will
  1321.                      print as (a . b).
  1322.  
  1323.          (explode h1)       ---> list of chars in print name of h1. 
  1324.                      If h1 is nil returns (n i l)
  1325.  
  1326.          (exploden h1)      ---> list of ascii values of chars in h1.
  1327.                      If h1 is nil returns (110 105 108).
  1328.  
  1329.          (get_pname h1)     ---> String equal to print name of atom
  1330.                      h1 or same as string h1.
  1331.  
  1332.  
  1333.                        22
  1334.  
  1335.  
  1336.  
  1337.          LIST & ATOM CREATORS AND SELECTORS (CONT'D)
  1338.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1339.  
  1340.          (hunk-to-list H)   ---> Returns a list whose elements are
  1341.                      (eq) to those of hunk H and in the
  1342.                      same order. 
  1343.  
  1344.          (implode l1)       ---> atom with name formed by compressing
  1345.                      first char of each atoms print name  
  1346.                      in l1. Imploding (n i l) returns 
  1347.                      the empty list nil. Small fixnums in
  1348.                      0..255 are treated as ascii chars.
  1349.           
  1350.          (last  l1)         ---> returns the last element in l1.  If 
  1351.                      l1 is nil it returns nil.
  1352.  
  1353.          (length l1)        -x-> fixnum = to length of list l1.   
  1354.                      The length of nil is 0.
  1355.  
  1356.          (listarray A [n1]) ---> Returns all of A or just first n1
  1357.                      elements as a list.
  1358.  
  1359.          (list s1 s2...sN)  ---> a list with elements (s1 s2 ...sN)
  1360.                      If N = 0 list returns nil. 
  1361.  
  1362.          (member s1 l1)     ---> If (s1 (equal) to element of l1)  
  1363.                      returns l1 (from match) else nil.
  1364.  
  1365.          (memq  s1  l1)     ---> If (s1 (eq) to element of l1) 
  1366.                      returns l1 (from match) else nil.
  1367.  
  1368.          (nth n1 l1)        ---> n1'th element of l1 (indexed from 0)
  1369.                      like (cad...dr l1) with n1 d's.
  1370.                       
  1371.          (nthcdr n1 l1)     ---> returns result of cdr'ing down the
  1372.                      list n1 times. If n1 < 0 it returns
  1373.                      (nil l1).
  1374.          
  1375.          (nthchar h1 n1)    ---> n1'th char in the print name of h1
  1376.                      indexed from 1. 
  1377.          
  1378.          (pairlis l1 l2 l3) ---> l1 is list of atoms. l2 is a list 
  1379.                      of S-expressions. l3 is a list of
  1380.                      ((a1.s1)....) The result is the
  1381.                      pairing of atoms in l1 with values
  1382.                      in l2 with l3 appended (see assoc).
  1383.          
  1384.          (quote *s1*)       ---> s1, unevaluated!
  1385.  
  1386.          (reverse l1)       ---> copy of l1 reversed at top level.
  1387.          
  1388.          (type s1)          ---> list,flonum,port,symbol, fixnum, 
  1389.                      hunk or array as determined by the 
  1390.                      type of the parameter s1.
  1391.  
  1392.  
  1393.  
  1394.                        23
  1395.  
  1396.  
  1397.  
  1398.          LIST & ATOM CREATORS AND SELECTORS (CONT'D)
  1399.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1400.          
  1401.          (sizeof h1)
  1402.          ~~~~~~~~~~~
  1403.          Will return the number of bytes necessary to store an object 
  1404.     of  type  h1.  Legal  values for  h1  are  'list,'symbol,'flonum, 
  1405.     'fixnum,  'string , 'hunk, 'array and 'port. The size returned is 
  1406.     the  amount  of memory used to store the  cell,  incidental  heap 
  1407.     space, property list space, binding stack space and function body 
  1408.     space is not counted for types 'symbol, 'string, 'hunk or 'array.
  1409.  
  1410.          (stringp s1)
  1411.          ~~~~~~~~~~~~
  1412.          Will  return  t if the S-expression s1 is  of  type  string, 
  1413.     otherwise it returns nil.     
  1414.  
  1415.          (substring h1 n1 [n2])
  1416.          ~~~~~~~~~~~~~~~~~~~~~~
  1417.          If  n1  is positive substring will return the  substring  in 
  1418.     string  h1  starting  at  position n1 (indexed  from  1)  for  n2 
  1419.     characters  or until the end of the string if n2 is not  present. 
  1420.     If n1 is negative the substring starts at |n1| chars from the end 
  1421.     of  the string and continues for n2 characters or to the  end  of 
  1422.     the  string if n2 is not present.  If the range specified is  not 
  1423.     contained within the bounds of the string, nil is returned.
  1424.  
  1425.          (memusage s1)       { not in Franz }
  1426.          ~~~~~~~~~~~~~
  1427.          Will  return  the approximate amount of storage that the  S-
  1428.     expression s1 is occupying in bytes.  The printname heap space is 
  1429.     included  in this computation as are file true name  atoms.  This 
  1430.     function  is  not smart,  it will count an atom twice  if  it  is 
  1431.     found  more  than  once in the list.  The space  count  does  not 
  1432.     include  storage needed for binding stacks,  property  lists,  or 
  1433.     function bodies that are associated with a particular atom.  Hunk 
  1434.     and string space include the heap space owned by the cell.  If an 
  1435.     S-expression  is a list all the elements (memusage) will be added 
  1436.     to get the total (memusage) for the list. 
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.  
  1454.  
  1455.                        24
  1456.  
  1457.  
  1458.  
  1459.          NONINTERNING/INTERNING FUNCTIONS
  1460.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1461.          Unless  otherwise stated in this manual,  any function  that 
  1462.     returns  an atom will intern it (put it on the  oblist).  However 
  1463.     the following functions are not included in the above  statement. 
  1464.     Note  also  that the list returned by (oblist) is a copy  of  the 
  1465.     real  oblist.  Note carefully that the atoms created by read  are 
  1466.     interned.  See a really good LISP manual on this stuff because it 
  1467.     can be really confusing. 
  1468.  
  1469.          (copysymbol a1 s1)
  1470.          ~~~~~~~~~~~~~~~~~~
  1471.          Returns an UNINTERNED copy of atom a1. If the flag parameter 
  1472.     s1  is non nil then the returned atom has  property,  value,  and 
  1473.     function  definitions eq to a1 otherwise its property,  value and 
  1474.     function   definitions   are  nil,   undefined,   and   undefined 
  1475.     respectively.
  1476.  
  1477.          (gensym [a1])
  1478.          ~~~~~~~~~~~~~
  1479.          Returns  an UNINTERNED atom whose print name is of the  form 
  1480.     Xnnnnn  where  X is either 'g' or the print name of a1 (if a1  is 
  1481.     provided)  and  nnnnnn is some number such that  no  interned  or 
  1482.     uninterned atom in the system has the same print name.  Note that 
  1483.     the  the existence of a clashing interned or uninterned  atom  is 
  1484.     checked before selecting the value of nnnnn.
  1485.  
  1486.          (intern a1)
  1487.          ~~~~~~~~~~~
  1488.          Will INTERN a1 on the oblist. If an atom with the same print 
  1489.     name as a1 is already on the oblist the EXISTING interned atom is 
  1490.     returned. Otherwise,  a1 is physically added to the oblist and is 
  1491.     returned.
  1492.  
  1493.          (remob a1)
  1494.          ~~~~~~~~~~
  1495.          Will  return a1 after having physically removed a1 from  the 
  1496.     oblist. Future calls to read will create a new atom with the same 
  1497.     print  name  as a1.  This can be confusing if a1 had  a  function 
  1498.     definition, property, or value assocaited with it.
  1499.  
  1500.          (maknam l1)  
  1501.          ~~~~~~~~~~~
  1502.          Takes  a  list of symbols/strings/fixnums as  parameter  and 
  1503.     returns an UNINTERNED atom whose print name is the  concatenation 
  1504.     of the first characters in the print names of every symbol and/or 
  1505.     the ascii characters whose values are given as fixnums in l1.
  1506.                
  1507.          (uconcat a1 a2 ... aN)  
  1508.          ~~~~~~~~~~~~~~~~~~~~~~
  1509.          Returns   an  UNINTERNED  atom  whose  print  name  is   the 
  1510.     concatenation of each of the print names of a1...aN.  If N=0,  or 
  1511.     if N=1 and a1 is nil,  then the empty list nil is returned.  Note 
  1512.     that the empty list nil is neither interned or uninterned because 
  1513.     it is not really an atom. Like concat, it handles flo/fixnums.
  1514.  
  1515.  
  1516.                        25
  1517.  
  1518.  
  1519.  
  1520.          FILE I/O FUNCTIONS
  1521.          ~~~~~~~~~~~~~~~~~~
  1522.          These functions manipulate port atoms and allow character or 
  1523.     S-expression I/O.  A port atom is returned by (fileopen) and will 
  1524.     print as %file@nn% where 'file' is the name of the port and nn is 
  1525.     the  file number or -1 if the file is closed.  All I/O is checked 
  1526.     and an error closing, reading or writing a port will be trapped.
  1527.  
  1528.          (close p1)
  1529.          ~~~~~~~~~~
  1530.          Closes  the port p1 and returns t.  It will then  invalidate 
  1531.     the port p1.  Any further I/O to p1 is illegal. I/O errors may be 
  1532.     trapped when the close is issued. 
  1533.  
  1534.          (fileopen h1 h2)
  1535.          ~~~~~~~~~~~~~~~~
  1536.          Opens a file whose name is h1 for mode h2 access.  h1 should 
  1537.     be  a path or device name.  h2 should be one of 'r,'w,'a,'r+,'w+, 
  1538.     or  'a+  meaning respectively:  (r) Read only.  (w)  Truncate  or 
  1539.     create for writing. (a) Open for writing at end of file or create 
  1540.     for writing.  (r+) Open for update (read+write). (w+) Truncate or 
  1541.     create  for update.  And (a+) open or create for update at end of 
  1542.     file.  MS-DOS device names like 'con',  'lpt1' etc are  accepted.  
  1543.     Fileopen  will  not  search  for a file on the  PATH  or  in  the 
  1544.     LISP_LIBs.  The MICROSOFT C MS-DOS version allows the addition of 
  1545.     a mode 'b meaning binary (no newline translation). It is appended 
  1546.     to  the  above  modes eg 'rb or 'wb meaning  read  binary,  write 
  1547.     binary etc.  Depending on the compiler/operating system there may 
  1548.     be other modes allowed.  (See the LibC manual for fopen(3S)  mode 
  1549.     strings).  Fileopen  returns  an open port atom,  or nil  if  the 
  1550.     file/device could not be opened in the requested I/O mode.
  1551.          
  1552.          (filepos p1 [x1])
  1553.          ~~~~~~~~~~~~~~~~~ 
  1554.          If  fixnum parameter x1 is not provided filepos will  return 
  1555.     the  current  file position where the next  read/write  operation 
  1556.     will take place for port p1.  If x1 is provided it is interpreted 
  1557.     as  a new position where the next read/write should  take  place. 
  1558.     The  read/write pointer is seeked accordingly and the value x1 is 
  1559.     returned if the seek completes successfully. Otherwise nil.
  1560.      
  1561.          (load h1) 
  1562.          ~~~~~~~~~
  1563.          Will  try to find the file whose name is h1 and load it into 
  1564.     PC-LISP. Loading means reading every list, and evaluating it. The 
  1565.     results  of  the evaluation are NOT printed on  the  console.  In 
  1566.     trying  to  find the file h1, load uses the  following  strategy. 
  1567.     First  it  looks for file h1 in the current  directory,  then  it 
  1568.     looks  for h1.l in the current directory.  Then it gets the value 
  1569.     of  the  environment variable LISP_LIB which should  be  a  comma 
  1570.     separated  sequence  of MS-DOS paths (exactly the same syntax  as 
  1571.     for PATH). It then repeats the above searching strategy for every 
  1572.     directory  in the path list.  For example if I entered this  from 
  1573.     the COMMAND shell:
  1574.  
  1575.  
  1576.  
  1577.                        26
  1578.  
  1579.  
  1580.  
  1581.          FILE I/O FUNCTIONS (CONT'D)
  1582.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1583.  
  1584.          "set LISP_LIB=c:\usr\libs\lisp\bootup;c:\lisp\work\;"
  1585.  
  1586.     then  ran PC-LISP,  it would try to load the file PC-LISP.L first 
  1587.     from the current directory,  then from the two directories on the 
  1588.     C drive that are specified in the above assignment.  Future calls 
  1589.     to  (load h1) will also look for files in the same  way.  When  a 
  1590.     file  has been successfully loaded PC-LISP examines the value  of 
  1591.     atom  $ldprint.  If this value is non-nil (default is t)  PC-LISP 
  1592.     will   print   a  message  saying  that  the  file   was   loaded 
  1593.     successfully. If this value is nil then no message is printed. In 
  1594.     either  case  if the load is successful a value of t is  returned 
  1595.     and if the load fails a value of nil is returned.
  1596.  
  1597.          (patom s1 [p1]) & (princ s1 [p1])
  1598.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1599.          Both  cause  the  S-expression  s1  to  be  printed  without   
  1600.     delimiters  or escapes on the output port p1,  or on the standard 
  1601.     output if no p1 parameter is given. Without delimiters means that 
  1602.     if  an  atom has a print name that is not legal without the  |  | 
  1603.     delimiters  or  without an escape \,  neither will be added  when 
  1604.     printing  the  atom  with patom.  Patom returns  s1  while  princ 
  1605.     returns t. Strings will print without quotes or escapes.
  1606.  
  1607.          (print s1 [p1])
  1608.          ~~~~~~~~~~~~~~~
  1609.          Will cause the S-expression s1 to be printed with delimiters 
  1610.     and  escapes  if  necessary on the output  port  p1,  or  on  the 
  1611.     standard output if no p1 parameter is given. All atoms that would 
  1612.     require  | | delimiting,  strings that require " " delimiting and 
  1613.     characters  that would have to be preceeded by the escape  to  be 
  1614.     input,  will  be  printed with the delimiters and  any  necessary 
  1615.     escapes. If a character is one of the format characters tab, back 
  1616.     space,  carriage  return,  line feed or form feed,  it will print 
  1617.     preceeded by the escape as \t \b \r \n or \f respectively. If the 
  1618.     characters  ascii value is < 32 or > 126 and it is not  a  format 
  1619.     character, it will print as \?. Print returns the expression s1.
  1620.  
  1621.          (read [p1 [s1]]) 
  1622.          ~~~~~~~~~~~~~~~~
  1623.          Reads  the  next S-expression from p1 or from  the  standard 
  1624.     input if p1 is not given and returns it.  If s1 is given and  end 
  1625.     of  file is read the read function will return s1.  If s1 is  not 
  1626.     given and end of file is read the read function will return nil.
  1627.  
  1628.          (readc [p1 [s1]])
  1629.          ~~~~~~~~~~~~~~~~~
  1630.          Reads  the next character from p1 or from the standard input 
  1631.     if  p1  is  not given and returns it as an  atom  with  a  single 
  1632.     character name.  If s1 is given and end of file is read the readc 
  1633.     function  will return s1.  If s1 is not given and end of file  is 
  1634.     read the readc function will return nil.
  1635.  
  1636.  
  1637.  
  1638.                        27
  1639.  
  1640.  
  1641.  
  1642.          FILE I/O FUNCTIONS (CONT'D)
  1643.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1644.          (resetio)
  1645.          ~~~~~~~~~
  1646.          Will  close  all  open  files  except  the  standard  input, 
  1647.     standard  output and standard error ports.  It is useful when too 
  1648.     many  (load)s  are aborted due to errors in  the  load  file.  It 
  1649.     always returns true.
  1650.  
  1651.          (sys:unlink h1)
  1652.          ~~~~~~~~~~~~~~~
  1653.          Will erase the file whose name is the print name of atom h1. 
  1654.     If the erase is successful a value of 0 is returned. If the erase 
  1655.     is unsuccessful a value of -1 is returned.
  1656.  
  1657.          (truename p1)
  1658.          ~~~~~~~~~~~~~
  1659.          Will return an atom whose print name is the same as the name 
  1660.     of the file associated with port p1. This is just the same as the 
  1661.     value printed between the % and @ signs when a port is printed.
  1662.         
  1663.          (flatsize s1 [x1])
  1664.          ~~~~~~~~~~~~~~~~~~
  1665.          Returns the number of character positions necessary to print 
  1666.     s1 using the call (print s1). If x1 is present then flatsize will 
  1667.     stop  computing  the output size of s1 as soon as  it  determines 
  1668.     that  the size is larger than x1.  This feature is useful if  you 
  1669.     want  to see if something will fit in some small given amount  of 
  1670.     space but not knowing if the list is very big or not.
  1671.  
  1672.          (flatc s1 [x1])
  1673.          ~~~~~~~~~~~~~~~
  1674.          Returns the number of character positions necessary to print 
  1675.     s1 using the call (patom s1). x1 is the same as in flatsize.
  1676.  
  1677.          (pp-form s1 [ p1 [x1] ] )
  1678.          ~~~~~~~~~~~~~~~~~~~~~~~~~
  1679.          Causes  the  expression s1 to be pretty-printed on  port  p1 
  1680.     indented  by x1 spaces.  If p1 is absent  the standard output  is 
  1681.     assumed.  If  x1  is  absent  an indent of 0 is  assumed.  If  s1 
  1682.     contains  a list such as (prog ....  label1  ...  label2...)  the 
  1683.     normal  indenting will be ignored for label1 & label2  etc.  This 
  1684.     causes  the  labels to stand out.  For example IF  the  following 
  1685.     function were present in PC-LISP then I could run pp-form:
  1686.  
  1687.          -->(pp-form (getd 'character-index-written-in-lisp))   
  1688.          (lambda (a c)
  1689.              (prog (n)
  1690.                (setq n 1 a (explode a))
  1691.                (cond ((fixp c) (setq c (ascii c))))
  1692.                nxt:
  1693.                (cond ((null a) (return nil)))
  1694.                (cond ((eq (car a) c) (return n)))
  1695.                (setq n (1+ n) a (cdr a))
  1696.                (go nxt:))) 
  1697.  
  1698.  
  1699.                        28
  1700.  
  1701.  
  1702.  
  1703.          FILE I/O FUNCTIONS (CONT'D)
  1704.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1705.          (drain [p1])
  1706.          ~~~~~~~~~~~~ 
  1707.          Will cause p1 or the poport to be drained. If the port is an 
  1708.     input  port then all unread characters will be discarded.  If the 
  1709.     port  is  an output port then all unwritten  characters  will  be 
  1710.     flushed. 
  1711.  
  1712.          (zapline)
  1713.          ~~~~~~~~~
  1714.          Will  cause all characters up to and including the next  new 
  1715.     line  (ascii 10) to be read and discarded.  The port that is read 
  1716.     is the last one that was used for input.  This function is useful 
  1717.     for defining comment skipping macros. For example.
  1718.  
  1719.          -->(setsyntax '# 'vsplicing-macro 
  1720.                '(lambda()(zapline)))
  1721.  
  1722.          Will  define # as a comment starting character.  When it  is 
  1723.     encountered  by  (read) it will call (zapline)  which  skips  all 
  1724.     characters  up  to  an  including the  end  of  the  line.  Since 
  1725.     (zapline)  returns nil and the macro is 'vsplicing-macro,  nil is 
  1726.     spliced into the input list. In other words the nil has no effect 
  1727.     on the input list.  This is the reason for reading from the  last 
  1728.     file used for input.
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.                        29
  1761.  
  1762.  
  1763.  
  1764.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1765.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1766.          These  functions  will either have an effect on the way  the 
  1767.     system behaves in the future or will give you a result about  the 
  1768.     way  the  system has behaved in the past.  Future calls will  not 
  1769.     necessarily give the same results.
  1770.  
  1771.          (def *a1* *l1*)    
  1772.          ~~~~~~~~~~~~~~~    
  1773.          a1 is a function name and l1 is a lambda,  nlambda, lexpr or 
  1774.     macro body.  The body is associated with the atom a1 from now  on 
  1775.     and  can  be  used as a user defined function.  Def  returns  a1.            
  1776.     Note  that  a lambda expressions parameter list may  contain  the 
  1777.     &aux,&optional and &rest flags. See Defun for details.
  1778.  
  1779.            -->(def first  (lambda(x)(car x)))
  1780.            -->(def llast  (lexpr(n)(last (arg n))))
  1781.            -->(def myadd  (nlambda(l)(eval(cons '+ l))))
  1782.            -->(def firstm (macro(l)(cons 'car (cdr l))))
  1783.            -->(def X*2orY (lambda(x &optional(y 2))(* x y)))
  1784.  
  1785.          (defun *a1* [*a2*] *s0* *s1* *s2* ....*sN*)
  1786.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1787.          Defun  will  do the same job as "def" except  that  it  will 
  1788.     build  the  expression  body  for you.  a1 is  the  name  of  the 
  1789.     expression  that you are defining,  a2 is an optional  expression 
  1790.     kind  indicator  which  may be either expr,  fexpr or  macro. The 
  1791.     default  is  expr.  These kinds correspond  directly  to  lambda, 
  1792.     nlambda  and macro forms.  s0 specifies the formal parameters  to 
  1793.     the expression.  Usually this is just a list of symbols. If it is 
  1794.     a  single  symbol  it is assumed that the symbol  is  the  single 
  1795.     parameter  to an lexpr form and an lexpr form will be constructed 
  1796.     from the ensuing bodies s1....sn. If it is a list of symbols then 
  1797.     a  lambda,  nlambda  or macro body will be constructed  from  the 
  1798.     bodies  s1...sn according to the kind specified by parameter  a2. 
  1799.     For  example,  these calls to defun do the same job as the  above 
  1800.     calls  to  def. 
  1801.  
  1802.            -->(defun first(x)(car x))
  1803.            -->(defun llast n (last (arg n))) 
  1804.            -->(defun myadd fexpr(l)(eval(cons '+ l)))
  1805.            -->(defun firstm macro(l)(cons 'car (cdr l)))
  1806.            -->(defun X*2orY (x &optional(y 2)) (* x y)) 
  1807.  
  1808.          A  simple function definition (ie not an fexpr or macro) may 
  1809.     contain the flags &optional,&rest and &aux in its parameter list. 
  1810.     These  flags  must occur in the above order if all  are  present. 
  1811.     They have the following effects:  The function will be allowed to 
  1812.     take  a variable number of args (via an lexpr) and the parameters 
  1813.     up  to  the &optional flag must be present when the  function  is 
  1814.     called.  The  parameters  after the &optional do not have  to  be 
  1815.     present,  and if not present they will default to nil unless  the 
  1816.     formal parameter form (var default) ie (y 2) is used.  If this is 
  1817.     the case the parameter will be bound instead  to 'default'.
  1818.  
  1819.  
  1820.  
  1821.                        30
  1822.  
  1823.  
  1824.  
  1825.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1826.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1827.          CONT'D  (defun|def &optiona,&aux,&rest flags)
  1828.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1829.     If  &rest is present it may be followed by exactly one  parameter 
  1830.     name.  When  the  function is called any unaccounted for  'extra' 
  1831.     parameters  will  be  turned  into  a  list  and  bound  to  this 
  1832.     parameter.  If  &aux  is present then the symbols present in  the 
  1833.     following  forms will all be bound either to nil,  or if the form 
  1834.     is  (var  defualt) the symbol 'var' will be  bound  initially  to 
  1835.     'default'.  This  has the effect of introducting local  variables 
  1836.     with  either nil or predefined default values.  After this  nasty 
  1837.     English description, I think that an example is in order.
  1838.  
  1839.          -->(defun foo(a &optiona(b 2) c &rest d &aux (e 2) f)
  1840.               (list a b c d e f))
  1841.          foo
  1842.          -->(foo 1) 
  1843.          (1 2 nil nil 2 nil)      ; a=1 b=2 c=nil d=nil e=2 f=nil
  1844.          -->(foo "hi" "there")     
  1845.          ("hi" "there" nil nil 2 nil)    ; b="there" not the default.
  1846.          -->(foo 1 2 3 4) 
  1847.          (1 2 3 (4) 2 nil)               ; e = unaccounted for parms.
  1848.          -->(foo)
  1849.          --- error evaluating built in function[arg] ---
  1850.          er>(pp foo)
  1851.          (def foo (lexpr(_N_)  
  1852.               ((lambda(a b c d e f)(list a b c d e f))
  1853.                (arg 1)
  1854.                (arg? 2 2)
  1855.                (arg? 3 nil)
  1856.                (listify 4)
  1857.                2
  1858.                nil)))
  1859.  
  1860.          This  function  has  1 required  argument  'a',  2  optional 
  1861.     arguments  'b'  and  'c'  whose  default values  are  2  and  nil 
  1862.     respectively.  Any additional arguments are to be bound as a list 
  1863.     to  'e'.  The function has two local variables 'e' and 'f'  whose 
  1864.     default  values  are respectively 2 and nil.  The  function  when 
  1865.     called  simply makes a list of all it's arguments,  any left over 
  1866.     arguments,  and its local variables. Invoking the function with a 
  1867.     varying  number  of arguments shows the effect  in  the  returned 
  1868.     list.  The  (foo) invokation shows that at least one argument  is 
  1869.     required  otherwise the (arg 1) function fails.  Finally I dumped 
  1870.     the actual function definition. It is an lexpr expression with an 
  1871.     immediate invokation of a lambda expression with arguments  ((arg 
  1872.     1).....nil).  The special function (arg? nn exp) is like (arg nn) 
  1873.     except that if nn is not in the range of the actual parameters it 
  1874.     returns exp.  Franz does not do this but PC-LISP  does because it 
  1875.     is  much  more  effecient than using a (cond) to get the  arg  or 
  1876.     default  value.  Because  the (arg?) function is not  present  in 
  1877.     Franz,  I do not recommend you use it directly, instead use defun 
  1878.     to create the correct forms for you, this will be portable.
  1879.  
  1880.  
  1881.  
  1882.                        31
  1883.  
  1884.  
  1885.  
  1886.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1887.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1888.          CONT'D
  1889.          ~~~~~~
  1890.  
  1891.          (exec *s1* *s2* .... *sN*)
  1892.          ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1893.          Will execute the program s1+' '+s2+' '+....+' '+sN.  This is 
  1894.     done  by using the system() call.  For example if you are in  PC-
  1895.     LISP and you want to edit a file you could type.
  1896.  
  1897.          -->(exec zed "lisp.h")
  1898.  
  1899.          And the command "zed lisp.h" would be executed.  Note that I 
  1900.     put  quotes  around  the lisp.h file name because the  '.'  could 
  1901.     cause  syntax problems.  (exec) will return the return status  of 
  1902.     the  executed command as a fixnum.  Note that if you get -1  back 
  1903.     from (exec) either the command cannot be found,  or there is  not 
  1904.     enough memory to run it. If there is not enough memory to run the 
  1905.     command  you must set your LISP_MEM B setting a little smaller to 
  1906.     leave some memory for the commands you wish to execute. Note that 
  1907.     you can start up an MS-DOS shell as follows:
  1908.  
  1909.          -->(exec command)
  1910.  
  1911.          Which will execute command.com (assuming it is on your PATH) 
  1912.     and  put  you  in the shell.  You can  then  execute  normal  DOS 
  1913.     commands  and return to PC-LISP by typing exit at the DOS prompt. 
  1914.     The  pc-lisp.l file contains a definition of (shell)  which  does 
  1915.     exactly this. Note for UNIX you would have to do something like:
  1916.  
  1917.          -->(exec "/bin/sh") or (exec "/bin/csh") etc...
  1918.          
  1919.          (exit)
  1920.          ~~~~~~
  1921.          PC-LISP  will  exit to whatever program envoked it  this  is 
  1922.     usally  the  COMMAND.COM program.  Depending on how big  you  set 
  1923.     LISP_MEM  MSDOS may ask for a system disk to reload  COMMAND.COM. 
  1924.     Note that the video mode will be left alone if you call exit. But 
  1925.     if  you  leave  via  CONTROL-Z the video mode will  be  reset  to 
  1926.     80x25B&W if you have changed it via (#scrmde#)).
  1927.          
  1928.          (gc)
  1929.          ~~~~
  1930.          Starts garbage collection of alpha and cell space. Returns t 
  1931.     when  the cycle has ended.  Reducing the settings of the LISP_MEM  
  1932.     blocks(B) or alpha(A) and or increasing the value of heap(H) will 
  1933.     decrease  the time needed to complete garbage collection but will 
  1934.     reduce  the available cell memory thus increasing the  number  of 
  1935.     garbage collections that are required in a given period.  (gc) is 
  1936.     a  useful  way  to  spend idle time.  If  for  example  you  have 
  1937.     displayed  some  computation and are waiting for a response  from 
  1938.     the user,  you can invoke (gc) after prompting but before reading 
  1939.     the response.  Invoking (gc) yourself reduces the number of times 
  1940.     PC-LISP must do it for you.
  1941.  
  1942.  
  1943.                        32
  1944.  
  1945.  
  1946.  
  1947.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  1948.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1949.          CONT'D
  1950.          ~~~~~~
  1951.          (get a1 a2)
  1952.          ~~~~~~~~~~~
  1953.          Will  return  the value associated with property key a2   in 
  1954.     a1's property list.  This value will have been set by a  previous 
  1955.     call to (putprop a1 s1 a2). Example:
  1956.  
  1957.          -->(get 'frank 'lastname)
  1958.  
  1959.          (getd a1)
  1960.          ~~~~~~~~~
  1961.          Will  return the array,  lambda,  nlambda,  fexpr  or  macro 
  1962.     expression  that  is  associated  with  a1  or  nil  if  no  such 
  1963.     expression is associated with a1. 
  1964.  
  1965.          (getenv h1)
  1966.          ~~~~~~~~~~~
  1967.          Will  return  an atom whose print name is the string set  by 
  1968.     environment variable h1. For example we can get the PATH variable 
  1969.     setting by evaluating (getenv 'PATH).  Note that these must be in 
  1970.     upper case because MS-DOS converts the variable names to upper.
  1971.  
  1972.          (hashtabstat)
  1973.          ~~~~~~~~~~~~~
  1974.          Will  return a  list containing 503 fixnums.  Each  of these 
  1975.     represents  the  number of elements in the bucket for  that  hash 
  1976.     location  in  the heap hash table.  503 is the size of  the  hash 
  1977.     table.  This  is not especially useful for you but it gives me  a 
  1978.     way  of  checking  how the hashing function is  distributing  the 
  1979.     heap using cells.  Heap using cells are symbol,  string and hunk. 
  1980.     The  cell  itself  is allocated from the alpha  or  other  memory 
  1981.     blocks  while  its  variable length space is allocated  from  the 
  1982.     heap.  Hence  this  table contains the oblist  plus  strings  and 
  1983.     hunks and uninterned symbols.  This table should not be  confused 
  1984.     with the oblist which runs through this table.
  1985.  
  1986.          (memstat)      { not present in Franz }
  1987.          ~~~~~~~~~
  1988.          Returns  three fixnums. The first is the percentage of  cell 
  1989.     space that is in use.  The second is the percentage of alpha cell 
  1990.     space and the third is the percentage of heap space in use.  When 
  1991.     any of these reach 100%, garbage collection will occur. Alpha and 
  1992.     cell  space is collected together.  Heap space is only  collected 
  1993.     when  you run out.  After garbage collection you will  see  these 
  1994.     three  percentages  drop.  The alpha and cell percentages  should 
  1995.     drop  to  tell  you how much memory is actually in  use  at  that 
  1996.     moment.  The  heap  space when compacted and  gathered  will  not 
  1997.     necessarily drop to indicate how much you really have left.  This 
  1998.     is  because heap space is gathered in blocks of 16K,  not all  at 
  1999.     once as with atoms and cells.  So, there will almost certainly be 
  2000.     more  than 20% free heap space in other non compacted blocks even 
  2001.     if memstat reports 80% of the heap space is in use.                   
  2002.  
  2003.  
  2004.                        33
  2005.  
  2006.  
  2007.  
  2008.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  2009.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2010.          CONT'D
  2011.          ~~~~~~
  2012.          (oblist)
  2013.          ~~~~~~~~
  2014.          Returns  a  list of most known symbols in the system at  the 
  2015.     current  moment.  Note  that if you call oblist  and  assign  the 
  2016.     result  somewhere you will cause every one of those objects to be 
  2017.     kept  by the system.  If there are lots of large alpha atoms  the 
  2018.     heap  and alpha space will be tied up until you set the  assigned 
  2019.     variable to some other value.  Several special internal atoms are 
  2020.     not placed in the returned list to keep them out of user code.
  2021.  
  2022.          (plist a1)
  2023.          ~~~~~~~~~~
  2024.          Will return the property list for atom a1. The property list 
  2025.     is of the form ((ke1 . value1)(key2 . value2)...(keyn . valuen)). 
  2026.     Note  that  plist returns a top level copy of the  property  list 
  2027.     because remprop destroys this list's top level structure. 
  2028.  
  2029.          (putd a1 l1)
  2030.          ~~~~~~~~~~~~
  2031.          Identical  to "def" except that the parameters a1 and l1 are 
  2032.     evaluated.  This  allows  you  to  write  functions  that  create 
  2033.     other functions and then add them to the LISP interpreter.
  2034.          
  2035.          (putprop a1 s1 a2)
  2036.          ~~~~~~~~~~~~~~~~~~
  2037.          Adds to the property list of a1 the value s1 associated with 
  2038.     the  property  indicator a2.  It returns the  value  of  a1.  For 
  2039.     example: (putprop 'Peter 'AshwoodSmith 'LastName)
  2040.  
  2041.          (remprop a1 a2)
  2042.          ~~~~~~~~~~~~~~~
  2043.          Removes  the  property  associated  with  key  a2  from  the 
  2044.     property list of atom a1. The top level structure of the property 
  2045.     list  is  actually destroyed.  It returns the old  property  list 
  2046.     starting at the point where the deletion was made.
  2047.  
  2048.          (set a1 s1)
  2049.          ~~~~~~~~~~~  
  2050.          Will  bind a1 to s1 at current scope level or globally if no 
  2051.     scope yet exists for a1. (set) returns s1.
  2052.  
  2053.          (setplist a1 l1)
  2054.          ~~~~~~~~~~~~~~~~
  2055.          Will  set the property list of atom a1 to the list l1  where 
  2056.     the  list must be ((keyn.valn)..). It returns this new list l1.
  2057.  
  2058.  
  2059.  
  2060.  
  2061.  
  2062.  
  2063.  
  2064.  
  2065.                        34
  2066.  
  2067.  
  2068.  
  2069.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  2070.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2071.          CONT'D
  2072.          ~~~~~~
  2073.          (setq *a1* s1 *a2* s2 ..... *an* sn)
  2074.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2075.          Like set but takes any number of atoms "an" and values "sn". 
  2076.     (setq) evaluates only the values s1...sn,(not the atoms) and then 
  2077.     binds the values to the atom as per (set). If the atom is unbound 
  2078.     before  the call to setq it will be bound globally otherwise only 
  2079.     the  current binding is altered.  The expressions  are  evaluated 
  2080.     left  to  right  and the bind is made after  each  expression  is 
  2081.     evaluted.  Setq  will  return  the value of  the  last  evaluated 
  2082.     expression. If no parameters are given (setq) returns nil.
  2083.  
  2084.          -->(setq x '(a b c)
  2085.          (a b c)
  2086.          -->(setq x (cdr x) y (car x))
  2087.          b    
  2088.          -->x
  2089.          (b c)
  2090.          -->y
  2091.          b    
  2092.  
  2093.          (PAR-setq *a1* s1 *a2* s2 ..... *an* sn) {not in Franz}
  2094.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2095.          PAR-setq  does not exist in Franz Lisp.  It was added to PC-
  2096.     LISP  to help with the implementation of a (do)  macro.  PAR-setq 
  2097.     does  the  same thing as (setq) except that the  assignments  are 
  2098.     done in parallel.  Ie the bindings are only done after all of the 
  2099.     s1 to sn expressions have been evaluated.  PAR-setq should not be 
  2100.     used unless portability is not important. 
  2101.  
  2102.          -->(PAR-setq x '(a b c))
  2103.          (a b c)
  2104.          -->(PAR-setq x (cdr x) y (car x))
  2105.          a
  2106.          -->x
  2107.          (b c)
  2108.          -->y
  2109.          a
  2110.  
  2111.  
  2112.  
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122.  
  2123.  
  2124.  
  2125.  
  2126.                        35
  2127.  
  2128.  
  2129.  
  2130.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  2131.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2132.          CONT'D
  2133.          ~~~~~~
  2134.          (setsyntax a1 a2 l1)
  2135.          ~~~~~~~~~~~~~~~~~~~~
  2136.         Is  a  way of defining a read expression macro l1  to  be 
  2137.     associated with chracter a1 and invoked in 'vmacro or 'vsplicing-
  2138.     macro mode depending on a2. This function allows you to alter the 
  2139.     way  that  (read) works.  Basically after calling  setsyntax  the 
  2140.     expression  l1 will be invoked whenever the character a1 is found 
  2141.     in  the input stream and this character is not escaped or  hidden 
  2142.     in  a comment or delimiters of some kind.  For example a macro  : 
  2143.     that  pretty prints the following function name could be  defined 
  2144.     as follows:
  2145.  
  2146.          -->(setsyntax '|:| 'vmacro '(lambda()(list 'pp (read))))
  2147.          
  2148.          Then  if  I  typed :pp at the input prompt the  character  : 
  2149.     would  be  read causing the expression (list 'pp  (read))  to  be 
  2150.     invoked.  This would then read the pp atom and construct the list 
  2151.     (pp  pp)  which  would then be passed back to the  read  function 
  2152.     which would pass it back to the eval loop which will evaluate  it 
  2153.     and  pretty  print the function pp.  Read macro  expressions  are 
  2154.     lambda  expressions that take no parameters.  Any calls to (read) 
  2155.     must not have any arguments,  (read) will know where to read  the 
  2156.     next expression from because of a global binding performed by the 
  2157.     read macro driver on behalf of the read function. 
  2158.  
  2159.          Splicing macros are also available. Just replace the 'vmacro 
  2160.     parameter  with 'vsplicing-macro.  What will happen is  that  the 
  2161.     returned  list will be spliced into the input expression,  rather 
  2162.     than forming a sublist expression in the current input.  This  is 
  2163.     useful  if  you  want to define your own comment  delimiters  and 
  2164.     return nil.  For example let's define a new comment delimiter say 
  2165.     the < and > characters.
  2166.  
  2167.          -->(defun SkipToEnd()
  2168.                (cond ((eq (readc) '|>|) nil)
  2169.                  (t (SkipToEnd))))
  2170.          SkipToEnd
  2171.          -->(setsyntax '|<| 'vsplicing-macro '(lambda()(SkipToEnd)))
  2172.          t  
  2173.          -->(and t <junk junk junk> t)
  2174.          t
  2175.  
  2176.          What I have done is first write a comment skipping  function 
  2177.     that  just  reads  input character by character until  the  >  is 
  2178.     found.   I  then  associated the  character  '<'  with  a  lambda 
  2179.     expression that calls this skipper. The macro is a splicing macro 
  2180.     as (and t <junk...junk> t) demonstrates.  Think about what  would 
  2181.     have  happened if the macro were non splicing and I put a comment 
  2182.     in the (and ....) list.  Try it and see,  then you will know  why 
  2183.     splicing macros are needed. 
  2184.  
  2185.  
  2186.  
  2187.                        36
  2188.  
  2189.  
  2190.  
  2191.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  2192.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2193.          CONT'D
  2194.          ~~~~~~
  2195.          (sys:time) & (time-string [n1])
  2196.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2197.          sys:time  returns a fixnum representing the time in  seconds 
  2198.     since  UNIX/MS-DOS  creation.  Time-string takes a fixnum n1  and 
  2199.     returns to a human readable string representation of the time n1. 
  2200.     If n1 is not provided time-string uses the current sys:time.
  2201.          
  2202.          (trace [*a1* *a2* *a3* ..... *an*])
  2203.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2204.          Will  turn on tracing of the user defined functions a1...an. 
  2205.     Note that you cannot trace built in functions.  If you call trace 
  2206.     with  no  parameters it will return a list of  all  user  defined 
  2207.     functions  that  have been set for tracing by a previous call  to 
  2208.     trace,  otherwise  trace  returns exactly the list  (a1  a2...an) 
  2209.     after  enabling tracing of each of these user defined  functions. 
  2210.     If  any  of the atoms is not a user defined function trace  stops 
  2211.     and returns an error.  All atoms up to the point of error will be 
  2212.     traced.   
  2213.          
  2214.          (untrace [*a1* *a2* *a3* ..... *an*])
  2215.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2216.          Will  disable tracing of the listed functions which must all 
  2217.     be user defined.  If no parameters are given it disables  tracing 
  2218.     of  all functions.  Untrace returns a list of all functions whose 
  2219.     tracing has been disabled. Here is a demonstration of how you can 
  2220.     use them. This is the sort of sequence that you should see on the 
  2221.     console.  The comments ;...  were added to tell you what is going 
  2222.     on.
  2223.  
  2224.       -->(defun factorial(n)                ; define n! = n * (n-1)!
  2225.             (cond ((zerop n) 1)
  2226.               (t (* n (factorial (1- n]     
  2227.       factorial
  2228.       -->(trace factorial)                  ; ask LISP to trace n!
  2229.       (factorial)
  2230.       -->(factorial 5)                      ; ask LISP for 5!
  2231.       <enter> factorial( 5 )                ; entered with parm=5
  2232.        <enter> factorial( 4 )               ;    "      "    "  4
  2233.         <enter> factorial( 3 )              ;    "      "    "  3
  2234.          <enter> factorial( 2 )             ;    "      "    "  2
  2235.           <enter> factorial( 1 )            ;    "      "    "  1
  2236.            <enter> factorial( 0 )           ;    "      "    "  0
  2237.            <EXIT>  factorial 1              ; exit 0! = 1
  2238.           <EXIT>  factorial 1               ; exit 1! = 1
  2239.          <EXIT>  factorial 2                ; exit 2! = 1
  2240.         <EXIT>  factorial 6                 ; exit 3! = 6
  2241.        <EXIT>  factorial 24                 ; exit 4! = 24
  2242.       <EXIT>  factorial 120                 ; exit 5! = 120
  2243.       120
  2244.       -->(untrace factorial)                ; ask LISP to shut up
  2245.  
  2246.  
  2247.  
  2248.                        37
  2249.  
  2250.  
  2251.  
  2252.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  2253.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2254.          CONT'D
  2255.          ~~~~~~
  2256.  
  2257.          (showstack)
  2258.          ~~~~~~~~~~~
  2259.          When  called after an error causing entry to the break level 
  2260.     will  display  the last 20 evaluations including  the  one  which 
  2261.     caused  the  error.  The  top  of the internal  stack  is  copied 
  2262.     whenever  LISP is about to enter the break level (prompt  'er>').  
  2263.     This  means  that  if you execute some  function  and  it  aborts 
  2264.     prematurely  you can call showstack from the break level and  see 
  2265.     exactly  what lead to the error.  Whenever a new error occurs the 
  2266.     old copy of the top 20 elements on the internal stack is lost and 
  2267.     a new trace is copied for you to display via (showstack). This is 
  2268.     unlike  Franz  which allows lots of  break  levels.  For  example 
  2269.     consider this example session with PC-LISP which is similar to an 
  2270.     example in LISPcraft.
  2271.                
  2272.          -->(defun foobar(y)(prog(x)(setq x (cons (car 8) y]
  2273.          foobar
  2274.          -->(foobar '(a b c))
  2275.          --- error evaluating built in function [car] ---
  2276.          er>x
  2277.          ()
  2278.          er>y
  2279.          (a b c)
  2280.          er>(showstack)
  2281.  
  2282.          [] (car 8)
  2283.          [] (cons <**> y)
  2284.          [] (setq x <**>)
  2285.          [] (prog(x) <**>)
  2286.          [] (foobar '(a b c))
  2287.  
  2288.          t 
  2289.  
  2290.          In  this example I declared a function called 'foobar' which 
  2291.     runs a prog and does a single assignment to x.  When I execute it 
  2292.     with  parameter '(a b c).  PC-LISP correctly tells me that  there 
  2293.     was  an  error  evaluating the built in  function  'car'.  I  can 
  2294.     examine  the values of x and y and see that x is still set to the 
  2295.     empty  list () that the prog call set it to.  y is bound  to  the 
  2296.     parameter passed to foobar as expected. Next I called (showstack) 
  2297.     to see the trace of execution. I see that the top evaluation (car 
  2298.     8) is the culprit.  The <**> symbols in the show stack are just a 
  2299.     short hand way of saying look at the entry above to see what  the 
  2300.     <**> should be replaced with.  This greatly reduces the amount of 
  2301.     information  that you have to look at when you read a stack dump. 
  2302.     It also allows you to follow the stream of partial evaluations by 
  2303.     looking at each <**> in turn. Note that infinite recursion leaves 
  2304.     a telltale stream of <**>'s.
  2305.  
  2306.  
  2307.  
  2308.  
  2309.                        38
  2310.  
  2311.  
  2312.  
  2313.          FUNCTIONS WITH SIDE EFFECTS OR THAT ARE EFFECTED BY SYSTEM
  2314.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2315.          CONT'D
  2316.          ~~~~~~
  2317.          (sstatus *a1* *s1*)
  2318.          ~~~~~~~~~~~~~~~~~~~
  2319.          Returns  t but has the side effect of setting system  option 
  2320.     a1  to setting s1.  The legal values of a1 are symbols or strings 
  2321.     with   print  names  in  the  following   list:  smart-backslash, 
  2322.     ignoreeof,  chainatom,  and automatic-reset.  Any S-expression is 
  2323.     legal  for  s1  but it is only tested for nil  or  non  nil.  The 
  2324.     effects are as follows.
  2325.  
  2326.          (sstatus smart-backslash nil) will cause \n \t \r etc.  in a 
  2327.     string or delimited symbol to be interpreted as n,t,r etc. On the 
  2328.     other  hand (sstatus smart-backslash t) causes the \n \t \r  etc. 
  2329.     sequences to be interpreted as newline,  tab,  carriage return as 
  2330.     described in the section on SYNTAX (this is the default).
  2331.  
  2332.          (sstatus ignoreeof nil) will cause an exit to occur when the 
  2333.     EOF sequence is typed on the console from the top level.  This is 
  2334.     the default.  On the other hand (sstatus ignoreeof t) will  cause 
  2335.     an  EOF  sequence typed on the console from the top level  to  be 
  2336.     ignored. This is used to protect against accidental exit from the 
  2337.     top level (exit must be done by evaluating (exit) explicitly).
  2338.  
  2339.          (sstatus  chainatom nil) will cause an error to  occur  when 
  2340.     either  (car)  or  (cdr)  of  an object that is  not  a  list  is 
  2341.     evaluated.  This is the default. (sstatus chainatom t) will cause 
  2342.     nil to be returned by (car) and (cdr) if they are evaulated  with 
  2343.     a non list parameter.
  2344.  
  2345.          (sstatus automatic-reset nil) will cause entry to the  break 
  2346.     level to occur after an error is detected (this is the  default). 
  2347.     But, (sstatus automatic-reset t) will cause the break level to be 
  2348.     skipped  and no bindings will be held.  It is as if you typed the 
  2349.     EOF  sequence  from the break level after every  error.  This  is 
  2350.     useful in Franz where break levels can go N deep,  it has limited 
  2351.     use in PC-LISP.
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.                        39
  2371.  
  2372.  
  2373.  
  2374.          LIST EVALUATION CONTROL FUNCTIONS
  2375.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2376.          These functions are the control flow functions for LISP they 
  2377.     affect  which  lists are evaluated and how.  They operate on  the 
  2378.     basic LISP function types,  descriptions of which follow. 
  2379.  
  2380.          (lambda l1 s1....sn)
  2381.          ~~~~~~~~~~~~~~~~~~~~
  2382.          This  is  not a function but it is a  list  construct  which      
  2383.     can act as a function in any context where a function is legal. A 
  2384.     lambda  expression is a function body.  The S-expressions  s1..sn 
  2385.     are  expressions  that are evaluated in the  order  s1...sn.  The 
  2386.     result  is  the evaluation of sn.  The atoms in the list  l1  are 
  2387.     called  bound variables.  They will be bound to values that occur 
  2388.     on  the right of the lambda expression before  the  S-expressions 
  2389.     s1..sn  are  evaluated  and  unbound after the  value  of  sn  is 
  2390.     returned. 
  2391.  
  2392.          (nlambda l1 s1....sn)
  2393.          ~~~~~~~~~~~~~~~~~~~~~
  2394.          This is a function body construct similar to lambda but with 
  2395.     a few major differences.  The first is that the list l1 must only 
  2396.     specify  one formal parameter.  This will be set to a list of the 
  2397.     UNEVALUATED  parameters  that  fall on the right of  the  nlambda 
  2398.     expression when it is being evaluated.  This function allows  you 
  2399.     to  write  functions with a variable number of parameters and  to 
  2400.     control  the evaluation of these parameters.  For example we  can 
  2401.     write a function called 'ADDEM that behaves the same way as '+ in 
  2402.     nearly all contexts as follows:
  2403.  
  2404.          -->(def ADDEM (nlambda(l)(eval(cons '+ l))))  
  2405.     or   
  2406.          -->(defun ADDEM fexpr(l)(eval(cons '+ l)))
  2407.  
  2408.          Both  of  which create the  same  nlambda  expression.  This 
  2409.     function  will  behave as follows when spotted on the left  of  a 
  2410.     sequence  of parameters 1 2 3 4.  First it will not evaluate  the 
  2411.     sequence of parameters 1 2 3 4. Second it makes these into a list 
  2412.     (1  2  3  4).  It then binds 'l to this list  and  evaluates  the 
  2413.     expression (eval(cons( '+ l))).  This expression results in (eval 
  2414.     (+ 1 2 3 4)). Which is just the desired result 10.
  2415.  
  2416.          (label a1 (lambda|nlambda l1 s1..sn))     {not in Franz}
  2417.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2418.          This acts just like a lambda expression except that the body 
  2419.     is  temporarily  bound to the name a1 for evaluation of the  body 
  2420.     s1.  This allows recursive calls to the same body. The binding of 
  2421.     the  body  to  the  name a1 will be  forgotten  as  soon  as  the 
  2422.     expression s1 terminates the recursion. For example:   
  2423.  
  2424.          (label LastElement (lambda(List)
  2425.                 (cond ((null (cdr List))(car List))
  2426.                       (t (LastElement (cdr List))))))
  2427.  
  2428.  
  2429.  
  2430.  
  2431.                        40
  2432.  
  2433.  
  2434.  
  2435.          LIST EVALUATION CONTROL FUNCTIONS CONT'D
  2436.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2437.          (lexpr (a1) s1 s2 .... sN)
  2438.          ~~~~~~~~~~~~~~~~~~~~~~~~~~
  2439.          This  function  body  form is similar to  the  nlambda  form 
  2440.     except that all of its variable number of arguments are evaluated 
  2441.     and  the  args are accessed in a  different  manner.  The  second 
  2442.     element of the lexpr form must be a list of exactly one atom. The 
  2443.     remaining  elements  of the lexpr form represent bodies that  are 
  2444.     evaluated  one after the other.  The result of evaluating a  list 
  2445.     whose  first element is an lexpr is just the value  that  results 
  2446.     from  evaluating  s1....sN  in order in the context where  a1  is 
  2447.     bound to the number of actual parameters, and the (arg), (setarg) 
  2448.     and (listify) functions behave as follows:
  2449.  
  2450.          (arg [n1])  {see also (defun) for description of (arg?)}
  2451.          ~~~~~~~~~~
  2452.          When  in the context of an lexpr's evaluation,  will  return 
  2453.     either the number of arguments provided to the nearest  enclosing 
  2454.     lexpr,  or  the  nth argument indexed from 1 passed to the  lexpr 
  2455.     depending  on  whether or not n1 is provided as a  parameter.  An 
  2456.     error occurs if n1 is less than 1 or greater than (arg).
  2457.  
  2458.          (setarg n1 s1)
  2459.          ~~~~~~~~~~~~~~
  2460.          When  in the context of an lexpr's evaluation,  will  return 
  2461.     exactly s1.  It has the side effect that future calls to (arg n1) 
  2462.     will  return  the  value  s1  for the  duration  of  the  current 
  2463.     enclosing lexpr evaluation.  An error occurs if n1 is less than 1 
  2464.     or greater than (arg).
  2465.  
  2466.          (listify n1)
  2467.          ~~~~~~~~~~~~
  2468.          When in the context of an lexpr's evaluation,  will return a 
  2469.     tail  of  the list of arguments that were passed to  the  nearest 
  2470.     enclosing lexpr.  The head of this tail is either (arg n1) if  n1 
  2471.     is  positive,  or (arg (+ (arg) n1 1)) if n is negative.  If  the 
  2472.     value  of  n1 does not correctly index a head within  the  actual 
  2473.     argument list, nil is returned.
  2474.  
  2475.          Here  is  a small lexpr example which just sets some  global 
  2476.     variables  to  allow us to see what went  on  inside.  Again  see 
  2477.     LISPcraft for a much better description.
  2478.  
  2479.          -->((lexpr(n)
  2480.             (setq a0 n a1 (arg 1) an (arg(arg)))
  2481.             (listify -3)  
  2482.          ) 'A 'B 'C 'D 'E 'F 'G )  
  2483.          (E F G)
  2484.          -->a0
  2485.          7
  2486.          -->a1
  2487.          A
  2488.          -->an
  2489.          G
  2490.  
  2491.  
  2492.                        41
  2493.  
  2494.  
  2495.  
  2496.          LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2497.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2498.          (apply s1 l1)
  2499.          ~~~~~~~~~~~~~
  2500.          The  function s1 is evaluated in the context resulting  from 
  2501.     binding  its formal parameters to the values in l1. The result of 
  2502.     this evaluation is returned. Example:
  2503.  
  2504.          -->(apply '(lambda(x y z)(* (+ x y) z)) '(2 3 4))
  2505.          20
  2506.          
  2507.          (cond l1 l2 ... ln)
  2508.          ~~~~~~~~~~~~~~~~~~~
  2509.          The lists l1 ...  ln  are checked on by one. They are of the 
  2510.     form  (s1 s2 .. sn). Cond  evaluates the s1's one by one until it 
  2511.     finds one that does not eval to nil. It then evaluates the s2..sn 
  2512.     expressions  one by one and returns the result of evaluating  sn. 
  2513.     If  all of the s1's (called guards) evaluate to nil,  it  returns 
  2514.     'nil. For example:
  2515.           
  2516.           -->(cond ((equal '(a b c) (cdr '(x a b c))) 'yes)
  2517.                (t 'opps))         
  2518.          yes
  2519.  
  2520.          (eval s1) 
  2521.          ~~~~~~~~~
  2522.          Runs the LISP interpreter on the S-expression s1. It is like 
  2523.     removing a quote from the expression s1. For example:
  2524.          
  2525.          -->(eval '(+ 2 4))
  2526.          6
  2527.  
  2528.          (mapcar s1 l1 l2 l3 .... ln) and (mapc s1 l1 ... ln)
  2529.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2530.          These functions will map the function s1 onto the  parameter 
  2531.     list made by taking the car of each of l1...ln.  It forms a  list 
  2532.     of  the  results  of the repeated application of s1 to  the  next 
  2533.     elements in the lists l1...ln. It stops when the list l1 runs out 
  2534.     of  elements.  Note  that each of l1...ln should  have  the  same 
  2535.     number  of elements,  although this condition is not checked  for 
  2536.     and nil will be substituted if a list runs out of elements before 
  2537.     the others. Extra elements in any list are ignored. For example:
  2538.  
  2539.          -->(mapcar '< '(10 20 30) '(11 19 30))
  2540.          (t nil nil)
  2541.  
  2542.          Which  returns the results of (< 10 11) (< 20 19) and (<  30 
  2543.     30)  as  the  list (t nil nil). 
  2544.  
  2545.          The function mapc operates in exactly the same way as mapcar 
  2546.     except that the result is just l1.  No result  list is  returned. 
  2547.     Mapc  is meant to be used to save a little memory when  the  side 
  2548.     effect is of interest,  not the list of returned values from each 
  2549.     individual mapping.
  2550.  
  2551.  
  2552.  
  2553.                        42
  2554.  
  2555.  
  2556.  
  2557.          LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2558.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2559.  
  2560.          (maplist s1 l1 l2 ... ln) and (map s1 l1 l2 ... ln)
  2561.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2562.  
  2563.          These  functions are similar to mapc and mapcar except  that 
  2564.     rather than taking successive cars down the lists l1...ln to make 
  2565.     argument lists,  they take successive cdrs down the lists l1...ln 
  2566.     to make the arguement lists.  Map does the same thing as  maplist 
  2567.     but  it does not construct a list of the results of each mapping, 
  2568.     rather it just returns l1.  Like mapc,  this is usefull when  the 
  2569.     side effect is of greater interest than the result. For example:
  2570.  
  2571.          -->(maplist 'cons '(a b) '(x y))
  2572.          (((a b) x y) ((b)(y))
  2573.          -->(maplist 'car '(a b c))
  2574.          (a b c)
  2575.          -->(defun silly(a b)(list a b))
  2576.          -->(trace silly)
  2577.          (silly)
  2578.          -->(mapc silly '(a b) '(c d))
  2579.          <enter> silly((a b) (c d))
  2580.          <EXIT> silly ((a b) (c d))
  2581.          <enter> silly((b)(d))
  2582.          <EXIT> silly((b)(d))
  2583.          (a b)
  2584.          
  2585.          These examples operate as follows.  The first example simply 
  2586.     cons'es  the  list (a b) to the list (x y) and then  cons'es  the 
  2587.     list  (b)  to  the list (y).  It then makes a list of  these  two 
  2588.     results  and  returns it (((a b) x y) and  ((b)  y).  The  second 
  2589.     applies  car  to  successive  cdr's of the list (a  b  c)  ie  it 
  2590.     evaluates (car (a b c)) then (car (b c)) then (car (c)) and makes 
  2591.     a list of the results (a b c) which it returns.  The last example 
  2592.     demonstrates that mapc does the same thing as maplist except that 
  2593.     there  is no list of results returned.  Rather the first argument 
  2594.     list is returned.  To demonstrate this the function 'silly  which 
  2595.     makes  a  list of its two arguments was traced as it  was  mapped 
  2596.     accross  the  argument lists '(a b) and '(c d).  This results  in 
  2597.     silly  being called with two lists as parameters the first  time, 
  2598.     and the second time with the cdr's of the above two lists.
  2599.          
  2600.          Note the functions mapcon and mapcan are NOT built into  PC-
  2601.     LISP  but  are  available  in  PC-LISP.L  as  macros.  The  extra 
  2602.     functions  mapcon and mapcan apply (nconc).  Use them  carefully. 
  2603.     (See the notes on (nconc) in the DANGEROUS FUNCTIONS section).
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.                        43
  2615.  
  2616.  
  2617.  
  2618.          LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2619.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2620.          (defun a1 macro l1 s1 s2 ... sn)
  2621.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     
  2622.          Macro  is a special body,  similar to nlambda except that it 
  2623.     may causes code replacement when it is evaluated. When a macro is 
  2624.     encountered  the  list  (name  arg1  arg2...)  is  bound  to  the 
  2625.     macro parameter l1.  Name is the name of the macro and arg1..argn 
  2626.     are  the arguments that were provided to it.  Then the bodies  of 
  2627.     the macro s1..sn are evaluated and the expression returned by the 
  2628.     last body is returned.  Then depending on the value of  displace-
  2629.     macros and the type of the returned S-expression, the returned S-
  2630.     expression  may  destructively  replace the peice  of  code  that 
  2631.     called  it.  If the value of displace-macros is nil (its  default 
  2632.     value)   or the type of the returned S-expression is not one that 
  2633.     can  be replaced,  no destructive substitution will  occur.  Next 
  2634.     regardless  of whether the S-expression was substituted  or  not, 
  2635.     the  S-expression is evaluated and the value returned.  This  all 
  2636.     sounds pretty compex,  but in fact it is quite simple, here is an 
  2637.     example:
  2638.  
  2639.          -->(defun first-elemet macro(l)(cons 'car (cdr l)))
  2640.          first-element
  2641.          -->(setq x '(first-element '(a b c)))
  2642.          (first-element '(a b c)) 
  2643.          -->(eval x)
  2644.          a
  2645.          -->x
  2646.          (first-element '(a b c))
  2647.          -->(setq displace-macros t)
  2648.          t
  2649.          -->(eval x)
  2650.          a
  2651.          -->x
  2652.          (car '(a b c)) 
  2653.          -->(eval x)
  2654.          a
  2655.  
  2656.          In  the  example above I have first declared a macro  called 
  2657.     'first-element'  which  when run given a  list  parameter  should 
  2658.     return  the  first element in the list.  I could have  done  this 
  2659.     using  a  lambda  expression  but this  would  require  parameter 
  2660.     binding etc every time I execute 'first-element'.  Rather, what I 
  2661.     have chosen to do is to cause (first-element x) to be replaced by 
  2662.     the  code  (car  x) everywhere it  is  encountered.  Then  future 
  2663.     execution of (first-element x) is just as costly as an  execution 
  2664.     of (car x).  Let's examine what I did above.  First I declared  a 
  2665.     macro  which will take the parameter (first-element -stuff-)  and 
  2666.     construct  the  code  (car  -stuff-).  I  then set  x  to  be  an 
  2667.     expression  which when evaluated should give 'a.  I  then  verify 
  2668.     this  by evaluating x,  sure enough it is 'a.  I then look at the 
  2669.     code for x which has not changed.  Now, I set the global variable 
  2670.     displace-macros to be non nil.  What I should now expect is  that 
  2671.     (eval  x) will give the same answer,  but with the side effect of 
  2672.     doing  the  code  substitution  so  that  future  passes  of  the 
  2673.  
  2674.  
  2675.                        44
  2676.  
  2677.  
  2678.  
  2679.          LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2680.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2681.     expression  bound to x will run much faster.  This is  the  whole 
  2682.     reason  for  macros,  they are not much use if they are  expanded 
  2683.     every  time,  it is more work than a simple user  defined  lambda 
  2684.     expression  call.  Anyway  after  running x and  looking  at  its 
  2685.     definition  we can see that the code has indeed been substituted. 
  2686.     It is worth noting that unless you set displace-macros to be  non 
  2687.     nil  all  your  macros  will  be expanded  every  time  they  are 
  2688.     encountered.  This is probably not what you want.  You should set 
  2689.     displace-macros to be t to cause macros to behave  properly.  The 
  2690.     only  reason I did not set displace-macros to be t by default  is 
  2691.     that Franz does not. 
  2692.  
  2693.          Note,  macros  may  return any type expression however  some 
  2694.     expressions  may  not  result in  code  substitution  because  of 
  2695.     internal  problems with doing the substitution.  In particular  a 
  2696.     macro  that directly returns an atom,  hunk or string will  never 
  2697.     result  in code replacement,  while a macro that returns a  list, 
  2698.     fixnum, flonum or port can result in code replacement. Since code 
  2699.     replacement  is a physical copying of one cell over another  heap 
  2700.     space  owning functions cannot be physically substituted  because 
  2701.     their  cells  are  unique. You  should note  however  that  these 
  2702.     limitations  do not occur much in practice since usually a  macro 
  2703.     will  return a number or a list.  For exampe a quoted atom is  ok 
  2704.     because  it  is really the list (quote x).  In any  case  PC-LISP 
  2705.     macros  will  always  return  the correct  values  regardless  of 
  2706.     these substitution limitations.
  2707.  
  2708.          Macro   bodies can function in all contexts that an  nlambda 
  2709.     body can function, however expansion, if it is to occur will only 
  2710.     happen  when  a macro is referred to by its atom name  which  was 
  2711.     defined  by a defun,  def or putd call.  Using macro  expressions 
  2712.     disembodied from a name does not however seem terribly useful.
  2713.  
  2714.          (macroexpand s1)
  2715.          ~~~~~~~~~~~~~~~~     
  2716.          This  function lets you see  what the macro expansion of  s1 
  2717.     looks like prior to evaluation and substitution. This function is 
  2718.     useful  for debugging macro definitions and for controlling macro 
  2719.     evaluation when writing code that generates new code.
  2720.  
  2721.          -->(macroexpand '(a b (first-element '(a b c)) x y z))
  2722.          (a b (car '(a b c)) x y z) 
  2723.  
  2724.          Macroexpand  will  expand  all  macros in s1  but  will  not 
  2725.     expand lists that start with quote.  The workings of  macroexpand 
  2726.     are  probably a little different than Franz although the  results 
  2727.     should   be  pretty  much  the  same.   Note in particular   that 
  2728.     macroexpand creates a new structure,  it does not expand into the 
  2729.     existing structure as (eval) does during real macro expansion. 
  2730.  
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736.                        45
  2737.  
  2738.  
  2739.  
  2740.          LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2741.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2742.  
  2743.          (prog l1 s1.....sn)
  2744.          ~~~~~~~~~~~~~~~~~~~
  2745.          Prog  is  a  way  of  escaping  the  pure  LISP  applicative 
  2746.     programming environment.  It allows you to evaluate a sequence of 
  2747.     S-expressions  one after the other in true imperative  style.  It 
  2748.     allows you to use the functions (go..) and (return ..) to perform 
  2749.     the  goto and return functions that imperative languages  permit. 
  2750.     Prog  operates  as follows:  The list l1 which is a list of  atom 
  2751.     names  is  scanned and each atom is bound to nil  at  this  scope 
  2752.     level.  Next the S-expressions s1..sn are scanned once. If any of 
  2753.     s1..sn  are atoms they are bound to the S-expression that follows 
  2754.     them.  Next we start evaluating lists s1...sn ignoring  the atoms 
  2755.     which  are  assumed  to be labels.  If after  evaluation  an   S-
  2756.     expression  is  of the form ($[|return|]$  Z) we unbind  all  the 
  2757.     atoms  and  labels  and  return  the  S-expression  Z.  If  after 
  2758.     evaluation  a  list  is  of the form ($[|go|]$ Z)  we  alter  our 
  2759.     evaluation to start next at Z.  The functions (go)  and  (return) 
  2760.     will return the above mentioned special forms.  If at any time we 
  2761.     reach sn, and it is not a go or a return, we simply unbind all of 
  2762.     l1  and the labels in s1...sn and return the result of evaluating 
  2763.     sn.  Note  that prog labels must be alpha or literal alpha atoms. 
  2764.     You  are  advised to keep the calls to go and return  within  the 
  2765.     lexical  scope  of the prog body and to ensure that  the  special 
  2766.     form returned is not absorbed by some higher level function. 
  2767.          
  2768.            -->(prog (List SumOfAtoms)
  2769.             (setq List (hashtabstat))
  2770.             (setq SumOfAtoms 0)
  2771.            LOOP (cond ((null List) (return SumOfAtoms)))
  2772.             (setq SumOfAtoms (+ (car List) SumOfAtoms))
  2773.             (setq List (cdr List))
  2774.             (go   LOOP)
  2775.           )
  2776.            306  
  2777.  
  2778.          This peice of code operates as follows. First it creates two 
  2779.     local variables.  Next it binds the variable List to the list  of 
  2780.     hash bucket totals from the heap  hash table.  It then sets a sum 
  2781.     counter  to 0.  Next it checks the List variable to see if it  is 
  2782.     nil. If so it returns the Sum Of all the Atoms. Otherwise it adds 
  2783.     the  first  fixnum in the list List to  the  running  SumOfAtoms, 
  2784.     winds in the list List by one,  and jumps to LOOP. Note also that 
  2785.     we  can accomplish the same thing as the above prog with the much 
  2786.     simpler example which follows:
  2787.  
  2788.          -->(eval (cons '+ (hashtabstat)))
  2789.          306
  2790.  
  2791.          If   execution   reaches  the  end  of  the   prog   without 
  2792.     encountering  a  (return),   the  last  evaluated  expression  is 
  2793.     returned.
  2794.  
  2795.  
  2796.  
  2797.                        46
  2798.  
  2799.  
  2800.  
  2801.          LIST EVALUATION CONTROL FUNCTIONS  CONT'D
  2802.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2803.          
  2804.          (caseq exp *l1* *l2* ... *lN*)
  2805.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2806.          Where  l1..lN are of the form (key s1...sN) or  ((key1  key2  
  2807.      ..keyN)  s1...sN).  Will select one of a number of cases l1..lN. 
  2808.     The case will be selected if its key or one of the keys in a  key 
  2809.     list are eq to 'exp'. The key 't will match anything. When a case 
  2810.     is selected,  the expressions s1...sN are evaluated left to right 
  2811.     and the result of the last evaluation is returned. For example:
  2812.  
  2813.         -->(caseq 'apple 
  2814.             (orange "orange")
  2815.             (grape  "green")
  2816.             ((stawberry cherry apple) "red"))
  2817.         "red"
  2818.  
  2819.         -->(caseq '|\n|     
  2820.             ((a b c d e f g h i j k l m n o p q r s t u v w x y z)
  2821.                'lowercase)
  2822.             ((A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
  2823.                'uppercase)
  2824.             (t 'other))
  2825.         other
  2826.  
  2827.         -->(caseq (length '(a b c d))
  2828.               ( 0 nil)
  2829.               ( 1 nil)
  2830.               ( 2 (setq x 2) (patom "length is 2\n") t)
  2831.               ( 3 (patom "length is 3\n") t)
  2832.               ( (4 5 6 7 8 9 10)
  2833.               (patom "length is in 4..10\n") t))
  2834.         length is in 4..10
  2835.         t
  2836.         --> 
  2837.  
  2838.          Given the choice between caseq and cond,  pick caseq because 
  2839.     it is much faster than cond.  This is because most of the work of 
  2840.     testing conditions is done in the interpreter. 
  2841.  
  2842.          (funcall s1 .... sN)
  2843.          ~~~~~~~~~~~~~~~~~~~~
  2844.          Will  apply  the function s1 to arguments s2..sN and  return 
  2845.     the result.  This is equivalent to (apply s1 (list s2...sN)). The 
  2846.     function  s1  must  be present but the arguments  s2  ..  sN  are 
  2847.     optional and depend on the number of arguments/discipline of s1.
  2848.  
  2849.          -->(funcall 'car '(a b c))
  2850.          a
  2851.          -->(funcall 'cons 'a '(b c))
  2852.          (a b c)
  2853.  
  2854.  
  2855.  
  2856.  
  2857.  
  2858.                        47
  2859.  
  2860.  
  2861.  
  2862.          ERROR TRAPPING AND GENERATION
  2863.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2864.  
  2865.          PC-LISP V3.00 provides the user with the ability to trap any 
  2866.     error  with  the  exception of  stack  overflows  (for  technical 
  2867.     reasons).   This  is  accomplished  by  the  (errset)  and  (err) 
  2868.     functions.  Similar  control  flow  violations are  provided  for 
  2869.     general use via the (catch) and (throw) functions.
  2870.  
  2871.          (errset *s1* [*s2*])
  2872.          ~~~~~~~~~~~~~~~~~~~~
  2873.          Will evaluate its argument s2 THEN s1,  if s1 results in any 
  2874.     kind of error (with the exception of a stack ovflow), then errset 
  2875.     will return the value nil. If the value of s2 is non nil then the 
  2876.     normal  error message is printed at this time on the console.  If 
  2877.     no error occurs in evaluating s1 then the result of evaluating s1 
  2878.     is made into a list and returned (to distinguish nil from (nil)).
  2879.     If  the error was generated by a call to (err s1) then the  value 
  2880.     s1  is  returned  rather than nil.  Any bindings that  were  made 
  2881.     between  the time (errset) was called and the point of the  error 
  2882.     will  be undone.  However,  global bindings are not  undone.  The 
  2883.     number  of  (errset)s  that can be nested is  determined  by  the 
  2884.     amount of memory you have, there is no arbitrary fixed limit. For 
  2885.     example:
  2886.  
  2887.          -->(errset (car (cdr (car (car 8]
  2888.          --- error evaluating built in function [car] ---
  2889.          nil
  2890.          -->(errset (car 8) nil)       ; car err msg not printed.
  2891.          nil                                     
  2892.          -->(errset (atom 8))          ; no error
  2893.          (8)
  2894.          -->(errset (prog () l (go l)) nil)  ; trap CTRL-BREAK.
  2895.          nil 
  2896.  
  2897.          (err s1)
  2898.          ~~~~~~~~
  2899.          Will  'throw'  the  value of s1  to  the  nearest  enclosing 
  2900.     errset  which  will then return with the value s1.  If no  errset 
  2901.     encloses  the evaluation of err then the break level  is  entered 
  2902.     and the message "--- user err ---" is displayed. For example:
  2903.  
  2904.          -->(errset (+ 1 2 3 (err 'x)) nil) 
  2905.          x  
  2906.          -->(errset (+ 1 2 3 (err 'x)))
  2907.          --- user err ---
  2908.          x
  2909.          -->(err 'x)
  2910.          --- user err ---
  2911.          er>                 ; now do an end of file CONTROL-Z 
  2912.          -->(errset (errset (+ 1 2 3 (err 'x)) nil))
  2913.          (x)
  2914.          -->                 ; the 2nd errset trapped, 1st did not.
  2915.  
  2916.  
  2917.  
  2918.  
  2919.                        48
  2920.  
  2921.  
  2922.  
  2923.          NON STANDARD CONTROL FLOW FUNCTIONS
  2924.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  2925.          PC-LISP  V3.00  provides a means of skipping the returns  to 
  2926.     outer  evaluations and 'throwing' a value up to an outer  routine 
  2927.     to  be returned by that routine.  These two routines  are  called 
  2928.     (throw)  and  (catch)  respectively.  They operate  in  a  manner 
  2929.     similar  to  (err) and (errset) but allow selective  catching  by 
  2930.     means of a tag assocaited with a thrown value.
  2931.  
  2932.          (catch *s1* [*s2*])
  2933.          ~~~~~~~~~~~~~~~~~~~
  2934.          Will evaluate s2 first, then s1. If during the evaluation of 
  2935.     s1 a call is made to (throw s3) the catch will return immediately 
  2936.     with the value s3.  If s2 is provided it is interpreted as a tag, 
  2937.     or  a list of tags (where a tag is a symbol).  The catch is  then 
  2938.     selective in the throws that it will catch. It will not catch the 
  2939.     thrown expression  unless the tag argument provided to the  throw 
  2940.     matches either the symbol s2,  or one of the symbols  in the list 
  2941.     s2.  The  symbol  nil matches all tags.  If the tag of the thrown 
  2942.     expression does not match the symbol s2, or is not present in the 
  2943.     list  of symbols s2,  the expression and tag will be throw up  to 
  2944.     the next closest enclosing catch.  If a throw arrives at the  top 
  2945.     level having not been caught, the error handler will catch it and 
  2946.     display the message "--- no catch for this tag [xyz] ---".  Where 
  2947.     xyz was the tag assocaited with the thrown expression. This error 
  2948.     like  all other errors (with the exception of a  stack  overflow) 
  2949.     can be trapped by (errset).  As with errset and err, all bindings 
  2950.     other  than  global bindings that were made between the time  the 
  2951.     catch  was called and the throw was called will  be  undone.   As 
  2952.     with errset, there is no fixed limit to the depth of nesting.
  2953.  
  2954.          (throw s1 [s2])
  2955.          ~~~~~~~~~~~~~~~          
  2956.          Will never return,  it throws the expression s1 with tag  s2 
  2957.     or nil if s2 is not provided up to the nearest enclosing (catch). 
  2958.     The  catch will either catch the expression or throw it up to the 
  2959.     next  enclosing  (catch) depending on whether the tag s2  matches 
  2960.     the  catch's tag or list of tags.  A nil tag (the  default)  will 
  2961.     match  any other tag.  If the thrown expression is not caught  by 
  2962.     any  (catch)  the  error handler will catch it and  generate  the 
  2963.     error described for (catch) above. For example:
  2964.  
  2965.          -->(catch (patom "hi" (throw 'x))) 
  2966.          x    
  2967.          -->(catch (patom "hi" (throw 'x)) 'MyTag1)
  2968.          x
  2969.          -->(catch (patom "hi" (throw 'x)) 'MyTag1) 'MyTag1)
  2970.          x
  2971.          -->(catch (patom "hi" (throw 'x)) 'MyTag1) '(a b MyTag1))
  2972.          x
  2973.          -->(catch (catch "hi" (patom (throw 'x 't1)) 't2) 't1)
  2974.          x
  2975.          -->(catch (patom "hi" (throw 'x))) 'MyTag1)
  2976.          --- no catch for this tag [MyTag] ---
  2977.  
  2978.  
  2979.  
  2980.                        49
  2981.  
  2982.  
  2983.  
  2984.          HUNKS 
  2985.          ~~~~~
  2986.          A hunk is just an array of 1 to 126 elements.  The  elements 
  2987.     may be any other type including hunks.  With hunks it is possible 
  2988.     to create self referencial structures (see DANGEROUS  FUNCTIONS). 
  2989.     A  Hunks  element storage space comes from the heap.  Hunks  like 
  2990.     strings   and  alpha  print  names  are  subject  to   compaction 
  2991.     relocation and reclaimation.
  2992.  
  2993.          (hunk s1 s2 .... sN)
  2994.          ~~~~~~~~~~~~~~~~~~~~
  2995.          Returns  a  newly created hunk of size N whose elements  are 
  2996.     s1,  s2  ...  sN in that order.  N must be in the range 1 to  126 
  2997.     inclusive.   Note  that  a  hunk  is  printed  like  a  list  but 
  2998.     is delimited by { } not (). Ie {s1 s2 ...sN}. 
  2999.  
  3000.          (cxr n1 H)
  3001.          ~~~~~~~~~~
  3002.          Returns the n1'th element of hunk H indexed from 0. Hence n1 
  3003.     must be in the range 0 .. (hunksize H)-1.
  3004.  
  3005.          (hunkp s1)
  3006.          ~~~~~~~~~~
  3007.          Returns  true  if s1 is of type hunk,  otherwise it  returns 
  3008.     nil.  Note  this function has also been mentioned with the  other 
  3009.     predicates.
  3010.  
  3011.          (hunksize H)
  3012.          ~~~~~~~~~~~~
  3013.          Returns a fixnum whose value is the size of the  hunk.  This 
  3014.     value is one larger than the largest index allowed into the  hunk 
  3015.     by  both cxr and rplacx.  The size of a hunk is fixed at the time 
  3016.     of its creation and can never change throughout it's life.
  3017.  
  3018.          (makhunk n1) or (makhunk (s1 s2 ...sN))
  3019.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3020.          The  first form returns a nil filled hunk of   n1  elements. 
  3021.     Needless  to say,  n1 must be between 1 and  126  inclusive.  The 
  3022.     second form is just identical to (hunk s1.....sN).
  3023.  
  3024.          (rplacx n1 H s1)
  3025.          ~~~~~~~~~~~~~~~~
  3026.          Returns the hunk H, however as a side effect element n1 of H 
  3027.     has been made (eq) to s1.  In other words H[n1] = s1.  Note  that 
  3028.     this  function  like rplaca and rplacd allows you to create  self 
  3029.     referencial structures.
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037.  
  3038.  
  3039.  
  3040.  
  3041.                        50
  3042.  
  3043.  
  3044.  
  3045.          ARRAYS
  3046.          ~~~~~~ 
  3047.          (array *a1* *a2* n1 ... nN)
  3048.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3049.          Allocates  and  returns a nil filled array whose name is  a1 
  3050.     and whose dimensions are n1 x n2 x..nN.  Parameter a2 is  ignored 
  3051.     and is there for compatability with MacLisp arrays. There must be 
  3052.     at  least  one dimension.  The total size of the  array  is  only 
  3053.     limited  by  the  amount of memory available.   After a  call  to 
  3054.     (array  a1..)  the  symbol a1 will behave like  a  function  that 
  3055.     accesses  the  array using it's args as dimensions  and  optional 
  3056.     element to store in the array. (See next function).
  3057.          
  3058.          (A [exp] n2... nN )  { A is an array name not a function }
  3059.          ~~~~~~~~~~~~~~~~~~~
  3060.          If A is the name of an array created by (array a1 t n1...nN) 
  3061.     then  this  function  will return the  element  corresponding  to 
  3062.     indecies   n1...nN.   If   exp  is  provided  then  the   element 
  3063.     corresponding to indecies n1...nN will be set eq to exp. It is an 
  3064.     error  not to provide legal indecies to an array. 
  3065.  
  3066.          (arraydims A)   { A evaluates to an array name }
  3067.          ~~~~~~~~~~~~~
  3068.          Returns  a  list whose car is t,  and whose cdr is the  list 
  3069.     n1...nN  that  was  provided  to (array) when  the  array  A  was 
  3070.     created.  In other words returns a list whose car is the type  of 
  3071.     the  elements  of  the  array,  and whose cdr is a  list  of  the 
  3072.     dimensions of the array.
  3073.  
  3074.          (getlength A)   { A must evaluate to an array name  }
  3075.          ~~~~~~~~~~~~~
  3076.          Returns a fixnum whose value is the size of the array.  This 
  3077.     is  computed as n1xn2xn3...xnN where n1...nN are  the  dimensions 
  3078.     provided in the (array) call that created the array A.
  3079.  
  3080.          (getdata A)    { A must evaluate to an array name }
  3081.          ~~~~~~~~~~~
  3082.          Returns  a  hunk that is the root of the array tree used  to 
  3083.     store  the  raw  elements of A.  Its structure is  given  in  the 
  3084.     section on data types in this manual.
  3085.  
  3086.          (listarray A [n1])  { A must evaluate to an array name }
  3087.          ~~~~~~~~~~~~~~~~~~
  3088.          Returns a list of the elements in A.  If n1 is provided then 
  3089.     the first n1 elements of A are placed into the returned list.
  3090.  
  3091.          (fillarray A l1)    { A must evaluate to an array name }
  3092.          ~~~~~~~~~~~~~~~~
  3093.          Fills the array A with successive elements of l1.  If l1 has 
  3094.     less elements than A,  the last element in l1 is used to fill the 
  3095.     remainder of the elements in A.
  3096.  
  3097.  
  3098.  
  3099.  
  3100.  
  3101.  
  3102.                        51
  3103.  
  3104.  
  3105.  
  3106.          ARRAYS  (CONT'D)
  3107.          ~~~~~~~~~~~~~~~~ 
  3108.          Note  that  like  hunks  arrays  allow  us  to  create  self 
  3109.     referential  structures so watch out.  Here is a short example of 
  3110.     how the array access functions work together.  Note that  (store) 
  3111.     is  a  macro included in PC-LISP.L.  You should be able  to  type 
  3112.     these same statements and get the same results.
  3113.  
  3114.          -->(array A1 t 20 100)          ; A1 is a 20 x 100 array
  3115.          array[2000]                     ; ie it has 2000 elements
  3116.          -->(A1 0 0)                     ; get A1[0,0], it is nil
  3117.          nil                             ; to start with.
  3118.          -->(A1 "hello" 0 0)             ; A1[0,0] = "hello"
  3119.          "hello"
  3120.          -->(store (A1 19 99) "there")   ; macro A1[19,99]="there"
  3121.          "there"
  3122.          -->(A1 19 99)
  3123.          "there"
  3124.          -->(arraydims 'A1)              ; get the dimensions of A1
  3125.          (t 20 100)                      ; 20 x 100, any type elems
  3126.          -->(getlength 'A1)
  3127.          2000
  3128.          -->(listarray 'A1 5)            ; make list of first 5
  3129.          ("hello" nil nil nil nil)
  3130.          -->(getd 'A1)            
  3131.          array[2000]
  3132.          -->(type (getdata 'A1))         ; getdata give hunk tree.
  3133.          hunk
  3134.  
  3135.          Note  that  if you try to allocate an array that is too  big 
  3136.     for the available memory you will get either an out of  heap,  or 
  3137.     out  of  cons cell error message followed by entry to  the  break 
  3138.     level.   Try   making   your  LISP_HEAP  and/or  your   LISP_ALPH 
  3139.     environment variables smaller. (See also memory exhaustion).
  3140.  
  3141.  
  3142.  
  3143.  
  3144.  
  3145.  
  3146.  
  3147.  
  3148.  
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.  
  3158.  
  3159.  
  3160.  
  3161.  
  3162.  
  3163.                        52
  3164.  
  3165.  
  3166.  
  3167.          DANGEROUS FUNCTIONS
  3168.          ~~~~~~~~~~~~~~~~~~~ 
  3169.          The  following  two functions have  potentially  disasterous 
  3170.     results if used by unwary or inexperienced LISP programmers.  The 
  3171.     third function is provided to make their use less dangerous.
  3172.          
  3173.          (rplaca l1 s1)
  3174.          ~~~~~~~~~~~~~~
  3175.          The  cons  cell l1 is physically altered so that its car  is 
  3176.     (eq) to s1.  That is the car pointer of l1 is set to point to s1. 
  3177.     The list l1 is returned. (l1 must not be nil).
  3178.  
  3179.          (rplacd l1 s1)
  3180.          ~~~~~~~~~~~~~~
  3181.          The  cons cell l1 is physically altered so that its  cdr  is 
  3182.     (eq) to s1.  That is the cdr pointer of l1 is set to point to s1. 
  3183.     The list l1 is returned. (l1 must not be nil).
  3184.          
  3185.          (copy s1)
  3186.          ~~~~~~~~~
  3187.          Returns  a  structure (equal) to s1 but made with  new  cons 
  3188.     cells.  Note  that only cons cells are  copied,  strings,  atoms, 
  3189.     hunks etc are not copied.
  3190.  
  3191.          Warning  #1  - altering  a cons cell allows  you  to  create 
  3192.     structures that point (refer) to themselves.  While this does not 
  3193.     cause a problem for the LISP interpreter or garbage collector  it 
  3194.     does  mean  that many built in functions will either loop  around 
  3195.     the structure infinitely or recurse until a stack overflows. 
  3196.  
  3197.          -->(setq x '(a b c d))
  3198.          (a b c d)
  3199.          -->(rplaca x x)
  3200.          ((((((((((((((((((((((((((((((((((((((((...............
  3201.          -- stack overflow --
  3202.          er>
  3203.  
  3204.          Warning #2 - altering a cons cell can cause a million little 
  3205.     side  effects that you did not count on.  Consider carefully  the 
  3206.     following example.
  3207.          
  3208.          -->(defun FooBar(x) (cons x '(b c)))
  3209.          FooBar
  3210.          -->(setq z (FooBar 'a))
  3211.          (a b c)
  3212.          -->(rplaca (cdr z) 'GOTCHA!)
  3213.          (GOTCAH! c)
  3214.          -->(FooBar 'a)      
  3215.          (a GOTCHA! c)      
  3216.          
  3217.          What  happened?  The rplaca has modified the list that is  a 
  3218.     constant  in  FooBar.  Lists are not copied unless necessary  and 
  3219.     building the list (a b c) did not require a copy of the  constant 
  3220.     list (b c) to be made. Ie (cdr z) is eq to (b c) in FooBar.
  3221.  
  3222.  
  3223.  
  3224.                        53
  3225.  
  3226.  
  3227.  
  3228.          DANGEROUS FUNCTIONS (CONT'D)
  3229.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  3230.          
  3231.          (sort l1 s1)
  3232.          ~~~~~~~~~~~~
  3233.          Destructively sorts the list l1 and returns it. The function 
  3234.     s1  is  used to compare elements in the list.  If s1 is  nil  the 
  3235.     function  alphalessp  is used.  If s1 is non nil,  it must  be  a 
  3236.     lambda expression taking two parameters and return t or  nil.  It 
  3237.     may  also  be the name of a built in function such as '<  or  '>.    
  3238.     etc. For example:
  3239.  
  3240.          -->(sort '(john frank adam) nil)
  3241.          (adam frank john)
  3242.          
  3243.          -->(sort '(10 9 8 1 2 3) '<)
  3244.          (1 2 3 8 9 10)
  3245.  
  3246.          -->(sort '(10 9 8 1 2 3) '(lambda(x y)(not (< x y))))
  3247.          (10 9 8 3 1 2) ; reverse of last example would be faster.
  3248.          
  3249.          (sortcar l1 s1)
  3250.          ~~~~~~~~~~~~~~~
  3251.          Destructively  sorts the list l1 and returns it.  The car of 
  3252.     each  element  in l1 is used as the key rather then  the  element 
  3253.     itself  as in (sort) above.  The function s1 is used  to  compare 
  3254.     elements. s1 is as in (sort). For example.
  3255.  
  3256.          -->(sortcar '( (john smith) (frank jones) (adam west)) nil)
  3257.          ((adam west)(frank jones)(john smith))
  3258.  
  3259.          Note  that these functions are destructive,  they alter  the 
  3260.     actual list parameters passed to them.  Either make sure you know 
  3261.     what you are doing, or use (copy l1) before passing the list as a 
  3262.     parameter to (sort) or (sortcar). Both of these functions use the 
  3263.     quicksort algorithm.  Ie,  they run in O(n*lg(n)) time. Note that 
  3264.     there  is a limit to the length of list that you can sort imposed 
  3265.     by  the size of the system stack.  Sorting with s1=nil,  is  much 
  3266.     much faster than providing your own compare routine.  If you want 
  3267.     the reverse ordering,  sort using s1 = nil,  then call  (reverse) 
  3268.     don't  do (sort l1 '(lambda(k1 k2)(not(alphalessp(k1  k2)))),  it 
  3269.     will be much slower.  Sorting with s1=nil also does not cause any 
  3270.     garbage  collection  whereas  sorting with s1 not =  nil  may  be 
  3271.     interrupted  by  garbage  collection because of the  overhead  of 
  3272.     building a parameter list and calling the function. 
  3273.  
  3274.          (nconc l1 l2 ... ln)
  3275.          ~~~~~~~~~~~~~~~~~~~~
  3276.          Similar to append except that the lists are joined  together 
  3277.     destructively.  The  last cons cell in l1 is changed so that  its 
  3278.     cdr points to l2, the last cons cell in l2 is changed to point to 
  3279.     l3 etc.  Note that any nil parameters are ignored.  Nconc returns 
  3280.     the constructed list or nil if all parameters are nil.
  3281.          MSDOS BIOS CALLS FOR GRAPHICS OUTPUT
  3282.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3283.  
  3284.  
  3285.                        54
  3286.  
  3287.  
  3288.  
  3289.          These   functions   allow   you  to   perform   BIOS   level 
  3290.     graphics/character  oriented I/O.  They all result in an INT 10H. 
  3291.     This  means  that the graphics should be portable to  most  MSDOS 
  3292.     machines  and  should  run under any windowing  environment  like 
  3293.     Topview  or MSwindows.  This is why they are so slow.  Note  that 
  3294.     they all return 't.  They do not check to see if the INT call was 
  3295.     successful  or if you have a graphics capability.  You can  crash 
  3296.     your system if you abuse these functions.  
  3297.  
  3298.          (#scrline# n1 n2 n3 n4 n5)
  3299.          ~~~~~~~~~~~~~~~~~~~~~~~~~~
  3300.          Draws a line on the screen connecting (n1,n2) with the point 
  3301.     (n3,n4) using attribute n5. BIOS level I/O means this is slow but 
  3302.     does work on every MS-DOS machine I know of! 
  3303.          
  3304.          (#scrmde# n1)       {ah=0, al=n1, INT 10H}  
  3305.          ~~~~~~~~~~~~~
  3306.          Sets the video mode to n1. Modes are positive numbers 0..... 
  3307.     Where  (8  and  9) are high resolution for the  Tandy2000  and  I 
  3308.     suppose  are high resolution modes on other machines that support  
  3309.     the  (640 x 400) or greater graphics resolutions.  These are  all 
  3310.     listed in your hardware reference manual but basically they  are: 
  3311.     0 = 40x25B&W,  1=40x25COL, 2=80x25B&W 3=80x25COL,  4 =320x200COL,  
  3312.     5=320x200B&W,      6=640x200B&W,     7=reserved,    8=640x400COL, 
  3313.     9=640x400B&W etc...?   This is as of DOS 2.10. Also note that the 
  3314.     AT EGA Graphics Modes should also work with no problem. The value 
  3315.     of  n1  is not checked.  This allows for the  unpredictably  high 
  3316.     modes required by some machines.
  3317.  
  3318.          (#scrsap# n1)      {ah=5, al=n1, INT 10H}
  3319.          ~~~~~~~~~~~~~
  3320.          Sets the active video page to n1. n1 should be between 0 and 
  3321.     8.  This  is valid for text modes only.  Versions of MSDOS  other 
  3322.     than 2.10 may not support this call.
  3323.  
  3324.          (#scrspt# bh bl al)      {ah=11,bh=bh,bl=bl,al=al,INT 10H}
  3325.          ~~~~~~~~~~~~~~~~~~~
  3326.          Sets  the color palette according to the value  in  bh.  For 
  3327.     most  BIOS  compatable  machines  these  are:  If  bh=0  it  sets 
  3328.     background  color bl.  If bh=1 it sets the default palette to the 
  3329.     number 0 or 1 in BL. If bh=2 it sets a single palette entry where 
  3330.     bl  is the palette entry number and al is the  color  value.  See 
  3331.     your BIOS reference for the color values and additional info. 
  3332.  
  3333.  
  3334.  
  3335.  
  3336.  
  3337.  
  3338.  
  3339.  
  3340.  
  3341.  
  3342.  
  3343.  
  3344.  
  3345.  
  3346.                        55
  3347.  
  3348.  
  3349.  
  3350.          MSDOS BIOS CALLS FOR GRAPHICS OUTPUT  (CONT'D)
  3351.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3352.  
  3353.          (#scrscp# n1 n2 n3)      {ah=2,bh=n1,dh=n2,dl=n3,INT 10H}
  3354.          ~~~~~~~~~~~~~~~~~~~
  3355.          Sets  the cursor position to be in page n1 at row n2 and  in 
  3356.     column n3. Where 0 is the top row and 0 is leftmost col.
  3357.  
  3358.          (#scrsct# n1 n2)         {ah=1,ch=n1,cl=n2,INT 10H}
  3359.          ~~~~~~~~~~~~~~~~
  3360.          Sets  the  cursor  type to agree with the following:  n1 bit 
  3361.     5  (0 = blink 1 = steady),  bit 6 (0 = visible,  1 =  invisible), 
  3362.     bits  4-0 = start line for cursor within character cell.  n2 bits 
  3363.     4-0 = end line for cursor within character cell.
  3364.  
  3365.          (#scrwdot# n1 n2 n3)     {ah=12,cx=n1,dx=n2,al=n3,INT 10H}
  3366.          ~~~~~~~~~~~~~~~~~~~~
  3367.          Write a dot (pixel).  The pixel at row n1 and column n2  has 
  3368.     its  color  value XORed with the color attribute  n3.  Since  the 
  3369.     color  attributes  vary from machine to machine you will have  to 
  3370.     look up the correct values for this parameter in your BIOS guide.
  3371.  
  3372.  
  3373.  
  3374.  
  3375.  
  3376.  
  3377.  
  3378.  
  3379.  
  3380.  
  3381.  
  3382.  
  3383.  
  3384.  
  3385.  
  3386.  
  3387.  
  3388.  
  3389.  
  3390.  
  3391.  
  3392.  
  3393.  
  3394.  
  3395.  
  3396.  
  3397.  
  3398.  
  3399.  
  3400.  
  3401.  
  3402.  
  3403.  
  3404.  
  3405.  
  3406.  
  3407.                        56
  3408.  
  3409.  
  3410.  
  3411.          MEMORY EXHAUSTION   
  3412.          ~~~~~~~~~~~~~~~~~
  3413.          The  memory  is all used up when you get a message  such  as 
  3414.     "--- out  of  cons cells ---".  Usually when this happens  it  is 
  3415.     because  you are tying up memory somewhere but do not realize it. 
  3416.     The  most common way to tie up memory is to execute  an  infinite 
  3417.     recursion  such as (defun looper(n)(looper (+ n 1))).  The  stack 
  3418.     will  of course overflow and YOUR BINDINGS WILL BE HELD FOR YOU!! 
  3419.     This  means that ALL bindings are held.  If you execute the above 
  3420.     program  several  times  from  the break  level, 'er>', you  will 
  3421.     eventually run out of CONS cells. They are all in use to hold the 
  3422.     values  n,  n+1,  n+2,......  to  the point of  the  first  stack 
  3423.     overflow.  Then n,  n+1,....  to the point of the second overflow 
  3424.     and  so on and so on.  Eventually there is no more space left  to 
  3425.     evaluate  the function (looper).  The solution is simple:  If you 
  3426.     run an infinite recursion by mistake and are placed in the  break 
  3427.     level,  use  the showstack to figure out where you are.  Then use 
  3428.     the  break level to examine variables etc.  But  before  retrying 
  3429.     anything  return  to  the top level.  This will  cause  the  held 
  3430.     bindings  to  be  dropped and the cells will  become  reclaimable 
  3431.     ie  (garbage and thus free).  Consider the following session with 
  3432.     PC-LISP V3.00:
  3433.  
  3434.          -->(defun looper(n)(looper (+ n 1)))    ; infinite function
  3435.          looper
  3436.          -->(looper 0)                           ; run it from 0
  3437.          -- Stack Overflow --                    ; all n's saved!
  3438.          er>n                                    ; last value of n
  3439.          588
  3440.          er>(looper 0)                           ; another run will
  3441.          -- Stack Overflow --                    ; save more n's
  3442.          er>(looper 0)
  3443.          -- Stack Overflow --
  3444.          er>(looper 0)                           ; another run won't
  3445.          ---  out of cons cells ---              
  3446.          er>
  3447.  
  3448.          Note  that the last (looper 0) call we made from  the  break 
  3449.     level was unable to complete because we ran out of  memory.  When 
  3450.     any  of  the  three  types of memory is exhausted  a  message  is 
  3451.     printed  and  the break level is entered.  In most  cases  it  is 
  3452.     possible  to continue by typing CONTROL-Z and ENTER or  CONTROL-D 
  3453.     (if you are using UNIX) to return to the top level.
  3454.  
  3455.          If you find that you are running out of heap space it may be 
  3456.     because you are keeping too many unused strings,symbols or hunks.
  3457.     Or,  you  are trying to allocate an array that is too big for the 
  3458.     amount or configuration of your H and A LISP_MEM settings. In the 
  3459.     first  case  the  solution  is not to  do  things  like  (setq  x 
  3460.     (oblist)).  In  the  second  case the solution is to  adjust  the 
  3461.     H  option  up  and  the  A option down until  the  array  can  be 
  3462.     allocated.  There  is of course a practical limit to the size  of 
  3463.     array that can be allocated on a 640K IBM-PC.  A UNIX machine  or 
  3464.     MS-DOS  machine without the 640K limit will be restricted by  the 
  3465.     hard limit of 75 allocatable blocks.
  3466.  
  3467.  
  3468.                        57
  3469.  
  3470.  
  3471.  
  3472.          TECHNICAL INFORMATION
  3473.          ~~~~~~~~~~~~~~~~~~~~~
  3474.          The interpreter is written 99% in C.  The other 1 percent is 
  3475.     assember  needed  to trap things like stack overflows and  handle 
  3476.     BIOS  level  graphics on an MS-DOS  machines.  The  UNIX  version 
  3477.     requires  no  extra assembly language.  In total the  program  is 
  3478.     nearly 9000 lines of C and is easily ported to most UNIX machines 
  3479.     but  requires  a  little  assembler  for  most  MS-DOS  machines. 
  3480.  
  3481.          Memory is organized as follows.  Alpha cells have fields for 
  3482.     a  shallow  stack of bindings,  a pointer to heap space  for  the 
  3483.     print names, a pointer to any built in or user defined functions, 
  3484.     and a pointer to any property lists.  Alpha cells are the largest 
  3485.     of  all  the cells and have their own fixed  storage  area.  Heap 
  3486.     space  which  is just the space used for the print names  of  the 
  3487.     alpha cells and strings,  and the element array for hunks may  be 
  3488.     variable sized blocks of up to 254 bytes long. This is why a hunk 
  3489.     can have only 126 elements in PC-LISP. The rest of the cells used 
  3490.     by  PC-LISP  are  all considered as one.  This  consists  of  the 
  3491.     flonum,  fixnum,  list,  string,  hunk and port cells.  They have 
  3492.     their  own  contiguous  slice of memory.  This means  that  three 
  3493.     different contiguous types of memory are required.  It is managed 
  3494.     in the following way.  At start up time the percentages of memory 
  3495.     are  read from the default settings or the environment  variables 
  3496.     LISP_MEM. Next memory is allocated in 16K chunks up to either the 
  3497.     limit  given by the B setting in the LISP_MEM variable,  or until 
  3498.     either  no  memory  is left or the hard limit  of  75  blocks  is 
  3499.     reached. These blocks are then kept track of in a large vector of
  3500.     pointers.  Next  groups  of  these blocks are primed for  use  by 
  3501.     alpha,cell, or heap managers according to the A and H settings in 
  3502.     the LISP_MEM environment variable or the default of 1 each. These 
  3503.     managers  handle the distribution and reclamation  of  memory  in 
  3504.     their  own  block.  The heap manager will perform compaction  and 
  3505.     relocation  to get free space.  The alpha and cell managers  will 
  3506.     perform mark and gather garbage collection to get space. The heap 
  3507.     manager may request mark and gather collection if there is a real 
  3508.     shortage of heap space prior to performing compaction.
  3509.  
  3510.          Stack overflow detection is done by intercepting the call to 
  3511.     the MSC __chkstk() routine.  And performing its usual function of 
  3512.     local storage allocation but when an overflow occurs  temporarily 
  3513.     resets  the  stack,  and  them making a call to my  own  C  stack 
  3514.     overflow routine.  This then longjmps out of the error condition. 
  3515.     The  UNIX  version  does not require  this  checking  because  an 
  3516.     internal stack (not the C stack) will always overflow first.  The 
  3517.     opposite is always true of the MS-DOS version.
  3518.  
  3519.  
  3520.  
  3521.  
  3522.  
  3523.  
  3524.  
  3525.  
  3526.  
  3527.  
  3528.  
  3529.                        58
  3530.  
  3531.  
  3532.  
  3533.          TECHNICAL INFORMATION (CONT'D)
  3534.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3535.  
  3536.          Control-BREAK detection is done via periodic testing of  the 
  3537.     status in the evaluator main loop, and the read main loop. When a 
  3538.     break  is  detected control is transferred to the  break  handler 
  3539.     which  prints  a message and longjmps back to the mainline  code. 
  3540.     The  MS-DOS version must poll the break status because DOS is not 
  3541.     reentrant.  The UNIX version also polls the break status but only 
  3542.     because  it  is  forced to by the logic of the  MS-DOS   version. 
  3543.     CONTROL-C checking is done in the same way except that a CONTROL-
  3544.     C will only be spotted on I/O so a looping non printing  function 
  3545.     can  only be stopped with CONTROL-BREAK.  Note that CONTROL-BREAK 
  3546.     is INT 1BH and CONTROL-C is INT 23H on an MS-DOS machine.
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.  
  3560.  
  3561.  
  3562.  
  3563.  
  3564.  
  3565.  
  3566.  
  3567.  
  3568.  
  3569.  
  3570.  
  3571.  
  3572.  
  3573.  
  3574.  
  3575.  
  3576.  
  3577.  
  3578.  
  3579.  
  3580.  
  3581.  
  3582.  
  3583.  
  3584.  
  3585.  
  3586.  
  3587.  
  3588.  
  3589.  
  3590.                        59
  3591.  
  3592.  
  3593.  
  3594.          KNOWN BUGS OR LACKING FEATURES OF V2.16
  3595.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3596.  
  3597.         -It  is  possible (but pretty unlikely) to run out  of  stack 
  3598.     space  while  garbage collecting.  When this happens the  garbage 
  3599.     collection  is retried once but the error is  unrecoverable.  You 
  3600.     should  treat  this as a stack overflow CAUSED BY  YOUR  PROGRAM.   
  3601.     PC-LISP V3.00 uses a link inversion marking phase and thus uses a 
  3602.     small bounded amount of stack space for garbage collection.  Note 
  3603.     that  if  the stack overflows on the  second  garbage  collection 
  3604.     retry  PC-LISP  gives up.  Memory will be corrupt and you  should 
  3605.     quit  because  of the possibility of clobbering programs  in  RAM 
  3606.     other than PC-LISP,  ie DOS.  If you CTRL-Z out of the error,  no 
  3607.     corruption will occur,  but (exit) just could corrupt RAM if  you 
  3608.     were very unlucky.
  3609.  
  3610.         -Two  special atoms with rather obscure names should never be 
  3611.     directly   returned   or  manipulated  in  a  prog.   These   are 
  3612.     $[|return|]$ and $[|go|]$. If you attempt to say print these from 
  3613.     within a prog,  the print function will return them and this will 
  3614.     confuse  the  heck  out  of prog which  uses  them  for  internal 
  3615.     purposes. Because of this the (oblist) call does not return them. 
  3616.     Thus the only way they can get into your code is for you to enter 
  3617.     them  directly.  Since this is unlikely and I have warned you the 
  3618.     problem should not occur.
  3619.  
  3620.         -You are not prevented from altering the binding of t.   This 
  3621.     means  that  if  you  use t as a  parameter  or  set/setq  it  to 
  3622.     something  other  than  t you may cause some  strange  behaviour, 
  3623.     especially  if  you  bind t to nil by  accident.  To  limit  this 
  3624.     problem  (defun) and (def) will check their parameter list for  t 
  3625.     or nil parameters before putd'ing the expression.  (putd) however 
  3626.     does not check!
  3627.  
  3628.         -Macros  are slightly restricted in that only lists,  fixnums 
  3629.     , flonums or ports can be substituted. This is a small difference 
  3630.     from  Franz  but one that would require  significant  performance 
  3631.     penalties   to implement.  Since not substituting these types  is 
  3632.     less  expensive than implementing substitution would be,  I  will 
  3633.     not implement this feature of Franz in a PC environment.
  3634.  
  3635.         -Integer overflow/underflow is not trapped.  The answers will 
  3636.     silently  change sign leaving you to figure out why your  program 
  3637.     does  not work properly.  These could be trapped but I  have  not 
  3638.     figured out the best way to do it yet.
  3639.  
  3640.         -A  symbol  with  bindings  should not be  given  a  function 
  3641.     definition and vise versa. This is because the binding of an atom 
  3642.     is deemed to be its function body if it has no real binding. This 
  3643.     is  different from Franz and was done to simplify the  evaluator. 
  3644.     This  is  not really a problem because programmers  are  used  to 
  3645.     keeping function and variable names different.
  3646.  
  3647.  
  3648.  
  3649.  
  3650.  
  3651.                        60
  3652.  
  3653.  
  3654.  
  3655.          KNOWN BUGS OR LACKING FEATURES OF V3.00 (CONT'D)
  3656.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3657.  
  3658.         -The  interpreter  is slow.  I am planning on  introducing  a 
  3659.     compiler which should speed things up significantly.  The program 
  3660.     is  slower  than some of the commercially available  interpreters 
  3661.     for  3  reasons.  Mostly  because  it  is  a  large  model,  many 
  3662.     commercial interpreters are small models.  This makes it nearly 3 
  3663.     times slower, but gives it more usable memory. PC-LISP uses 32bit 
  3664.     integers which slow down many benchmarks. However, 32bit integers 
  3665.     are  what Franz  provides and compatability is more important  to 
  3666.     me.  Thirdly  PC-LISP uses very little assembler as it is  almost 
  3667.     entirely C.  A reasonable speed up could be achieved by rewriting 
  3668.     one or two key procedures in assembler.
  3669.  
  3670.         -Car  and cdr will not access the first and second element of 
  3671.     a hunk as they do in Franz.
  3672.  
  3673.         -You cannot create custom array accessing schemes.  I am  not 
  3674.     planning  on introducing these features as they are probably used 
  3675.     pretty  infrequently  and  would  make  the  already  slow  array 
  3676.     accessing even slower.
  3677.  
  3678.         -You  cannot set the syntax of a character to anything  other 
  3679.     than  a read or splicing read macro.  I may introduce this  stuff 
  3680.     later on.
  3681.  
  3682.         -Showstack   does   not  print  lists  in   compressed   form 
  3683.     horizontally.  The vertical compression <**> is however done.  
  3684.  
  3685.         -Circular structures may cause problems for certain built  in 
  3686.     functions  in  particular  you  may not  be  able  to  abort  the 
  3687.     evaluation  either.  They  do not however cause any  problem  for 
  3688.     garbage collection and can be manipulated if you are careful.
  3689.  
  3690.         -Depending on how much memory is free when PC-LISP is  loaded 
  3691.     it is possible that the (load) and (read) will become slowed down 
  3692.     due  to  lack  of  buffer  space  for  I/O.   This  happens  very 
  3693.     infrequently  but  if you notice the slowdown you can fix  it  by 
  3694.     setting the LISP-MEM blocks value so that not all the free blocks 
  3695.     are allocated.  See the (exec) command for instructions on how to 
  3696.     do this.
  3697.  
  3698.          RE BUGS OR DESIRED ENHANCMENTS
  3699.          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  3700.          Please  let  me  know if you find a bug or if you  have  any 
  3701.     suggestions.  I  am  always  interested  to  hear  other  peoples 
  3702.     ideas and/or criticism.
  3703.          
  3704.               Regards,
  3705.  
  3706.               Peter Ashwood-Smith.
  3707.  
  3708.  
  3709.  
  3710.  
  3711.  
  3712.                        61
  3713. 
  3714.