Input and output

Input and output enter into dialogue

  Till now in the functions defined by us data entry and output were carried out in the course of dialogue with the interpreter. The interpreter read expression entered by the user, calculated its value and returned to its user. Forms and functions did not contain anything linked to input or output.
  If not to use the special command of input data it is possible to transfer functions only through parametres and unrestricted variables. Accordingly, without output usage, the result can be received only through finite value of expression. Often nevertheless there is a necessity to enter input data and to produce messages and by that to control and receive subproducts during calculations as it becomes and in other programming languages.

READ-LINE reads and returns expression

  Reading function read-line differs from input in other programming languages that it handles expression entirely, instead of single data items. Call of this function is carried out by the user in sort

  (cin read-line)

  As soon as the interpreter meets read-line command, calculations stop until the user will not enter any character or entirely expression:

>(cin read-line)
(entered expression)  ; expression of the user
"(entered expression)"  ; value of function read-line

  Pay attention, read-line in any way does not show, that he waits for expression input. The programmer should inform itself on it by means of considered after output functions. read-line only reads expression and returns as value this expression as string then calculations proceed.
  For brought above function call read-line there were no arguments, but this function has a value which coincides with the entered expression. On the operation read-line represents function, but it has the by-effect consisting in input of expression. Considering it, read-line is not pure function, and pseudo-function.
  If the read value is necessary for saving for further usage call read-line should be argument of any form, for example assignment which will link the received expression:

>(nil setq  input (cin  read-line))
(2 + 3) ; the entered expression
nil ; value
>input
"(2 + 3)" ; string

  The given function and the form calling the interpreter read together with other functions allow to read expressions external in relation to the program. It is possible to build new expressions or the whole programs of them. The constructed structures can be calculated, having transferred them to directly interpreter:

>(input read) ; the interpreter
(2  + 3)  ; the list
>(nil eval  (input  read))
5

The input program selects forms

  Function read is grounded on procedure of reading working at system level. She reads s-expression, from the signs arriving from a file or other source. Peripherals become accessible of Lisp-system through the objects named as streams. At logical level streams irrespective of character of the peripheral are list of readable or written signs or bits. For input and output, as well as for a double-sided exchange, there are types of streams and special operations.

Symbols are stored in a vector of objects

  Reading and interpreting signs, reading procedure tries to build atoms and of them lists. Having read a symbol name, the interpreter searches, whether met before such symbol or it is unknown. For the new symbol it is necessary to reserve memory for possible value, definition of function and other properties. Symbols are saved in memory in a vector of objects, in which they indexed on the basis of the name. The vector of objects contains both created by the user, and intrasystem characters (for example, first, cons, nil etc.). Depositing of the symbol in a vector of objects name as inclusion or internment.

Packages or spaces of names

  It is possible to use several various vectors of objects which name as spaces of names. Symbols from the various spaces, having identical names, can be used by various way. It is necessary at construction of the big systems, at programming of its various subsystems programmers quite often use identical names for the various purposes. All global variables of the interpreter are defined in space of names std. From other spaces of names it is possible to refer to variables, using a method namespace.

WRITELN prints value and passes to new line

  For output of expressions it is possible to use function writeln. This function at first calculates values of arguments, and then outputs their values. Function writeln after printing of arguments passes to new string.

>(cout  writeln (2  + 3))
5 ; printing (effect)
STREAM:Stdout ; value
>(cout  writeln (cin  read-line))
(2 + 3) ; input
(2 + 3) ; printing
STREAM:Stdout ; value

  As well as read-line, writeln is pseudo-function for which is both a side effect, and value. Value of function is the stream, and a side effect - the printing.
  Input\output statements, as well as assignment, are very floppy, as they can be used as arguments of other functions, that in other programming languages it is usually impossible:

>((cout writeln 2)  writeln 3)
2
3
STREAM:Stdout

PRINC and WRITE output without line feed

   write works the same as writeln, but does not pass to a new line:

>(nil progn (cout writeln 1)  (cout write 2)  (cout write 3))
1
23

  Function princ it is possible to output except atoms and lists and other data types, for example the strings represented by signs, quoted with both sides ("). Output in such form allows reading procedure (read) again to read the output expression in the sort logically identical to the initial. Thus, the string is output together with delimiters:

>(cout  princ "a b c")
"a b c"

  More pleasant sort from the point of view of the user can be received by means of function write. It outputs objects in the same sort as well as princ, but will transform some data types to more simple form. Such output expressions cannot be read (read) and to receive the expressions logically identical to the output. Function write we can print out string without inverted commas limiting it and special signs without their selection:

>(cout  write "a b c")
a b c ; printing without inverted commas

  By means of function write it is possible, naturally to print out and brackets:

>(nil progn (cout write "(((")
  (cout princ 'bulb)
  (cout write ")))"))
(((bulb)))
STREAM:Stdout

  Output function returns value of a stream.

TERPRI transfers line

  Output of expressions and signs is often desirable for dividing into some lines. Line carrying over can be carried out function writeln which automatically transfers line after output, or directly for this purpose intended function terpri (terminate printing). Function terpri does not have arguments and as value it returns a stream:

>(nil progn (cout princ 'a)
  (cout terpri)
  (cout writeln 'b)
  (cout princ 'c))
a
b
c
STREAM:Stdout ; value

  The method writeln can be defined with the help terpri and write as follows:

>('stream defmethod writeln (x)
  (this write x)
  (this terpri))
(lambda (x) (this write x)  (this terpri))

Usage of files

  Input and output in an operating time with a Lisp basically is carried out through the display and the keyboard. Files are used, as a rule, only for storage of programs in an interval between sessions. However sometimes there is a necessity of operation with files from the program.
  Input and output are carried out irrespective of a configuration of peripherals through streams. Streams represent special tanks of data from which it is possible to read (input stream) or to which it is possible to write (an output stream) signs or binary information. The system has some standard streams which are values of global variables. Most important of them

  cin and
  cout

  These environment variables define for input functions (read-line, etc.) and accordingly for output functions (prinx, terpri, etc.) files by default which in the session beginning the display or the customer provided terminal are. In this case there is no necessity for the initial declaration of an input stream for function read-line or a stream of output for output functions.
  If we wish to exchange data with any new file at first it needs to be opened depending on its usage for reading or for record. open directive can have many parametres.

  (file-name open {parameter})

  Following keys can be value of parametre:

parametervalue
inTo open a stream for input
outTo open a stream for an output

  For example, the following call opens a stream for output in a file test.lisp2d:

("test.lisp2d" open 'out)

  The stream object received as a result of call open , it is possible to assign for following usage of any variable:

(nil  setq  stream
  ("test.lisp2d"  open  'in 'out  'trunc))

  This call assigns a variable stream the double-sided stream linked to a new file "test.lisp2d".
  All earlier examined functions of input and output can be used and with file instructions, setting a stream corresponding to a file. For example, the following call princ writes expression in a new file "test.lisp2d", and call read reads this expression:

>(stream  princ '(in  a file  "test.lisp2d"))
STREAM:IO
>(stream  seekr 0)
STREAM:IO
>(nil setq  x (stream read))
nil
>x
(in a file  test.lisp2d)

  That the data written in a file were saved, it is necessary not to forget to close a file close directive:

  (stream close)

LOAD loads definitions

  In practice the writing of programs is carried out by filing of definitions of the functions given and other objects by means of the editor available in a program environment. After that for check of definitions call the interpreter of a Lisp which can read the expressions written in a file by load directive:

  (file-name load)

  Readable expressions are calculated as if they would be entered by the user. After loading it is possible to use functions, values of variables, values of properties and other definitions.
  For operation with files the considerable quantity of possibilities, including renaming and deleting of files contains except described above resources.