Open In App

Input & Output in LISP

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Pre-requisites: Introduction to LISP

Lisp provides a huge set of facilities for performing input/output. All the input/output operations are performed on streams of several kinds. While reading and writing binary data is possible, the majority of Common Lisp input/output methods read or write characters. For reading and writing individual characters or lines of data, there are straightforward primitives. However, reading and writing written representations of any arbitrary Lisp objects is the most helpful input/output operation.

Lisp Objects:

Lisp objects are typically intricate data structures rather than text strings. They differ from text strings in terms of attributes because of how they are internally represented. However, Lisp offers a representation of the majority of objects in the form of written text, known as the printed representation, which is used for I/O facilities. This makes it possible to access and discuss Lisp objects.

The characters of a Lisp object’s printed representation are transmitted to a stream via functions like print. The (Lisp) printer is a group of functions that accomplishes this. The (Lisp) reader is a group of routines that performs the read function, which accepts characters from a stream, interprets them as a printed representation of a Lisp object, creates that object, and returns it.

Input Functions:

The input functions are split into two categories: those that work with character streams and those that work with binary streams.

Input from Character Streams:

There are many optional arguments in character input functions called input-stream, eof-error-p, and eof-value. The input-stream argument is the stream from which to collect input; if not specified or nil it defaults to the value of the special variable ‘standard-input’. The eof-error-p parameter controls what happens if the input is from a file and the end of the file is reached. If eof-error-p is true which is the default, an error will be signaled at end of the file. If it is false, then no error is encountered, and instead, the function returns eof-value.

read &optional input-stream eof-error-p eof-value recursive-p 

  • It constructs a corresponding Lisp object based on the written representation of a Lisp object read from the input stream and then returns the object.

read-line &optional input-stream eof-error-p eof-value recursive-p 

  • read-line inserts a line of text that has been separated by a newline. The line is given back as a character string (without the newline character). This function is typically used to obtain a line of user input. A flag that is true if the end-of-file terminated the (non-empty) line or false if the line was terminated properly is the second value that is returned.

read-char &optional input-stream eof-error-p eof-value recursive-p 

  • One character is taken from the input stream and returned as a character object by read-char.

unread-char character &optional input-stream 

  • The character is moved to the front of the input stream by unread-char. The character must match the one that was just read from the input stream. When a character is next read from the input stream, it will be the specified character followed by the previous contents of the input stream because the input stream “backs up” over this character. Unread-char returns back nil.

read-preserving-whitespace &optional in-stream eof-error-p eof-value recursive-p

  • When it is necessary to know precisely which character ended the extended token, the function read-preserving-whitespace is offered.

read-delimited-list char &optional input-stream recursive-p

  • This reads objects from the stream until the following character is a char (while disregarding whitespace and comments). It returns a list of the read items.

peek-char &optional peek-type input-stream eof-error-p eof-value recursive-p 

  • The peek-type, which has a default value of nil, determines what peek-char performs. Without actually deleting the character from the input stream, peek-char returns the next character to be read from the input stream when the peek-type is nil. The character will remain when input from the input stream is performed again later. It appears as though read-char and unread-char were called back-to-back.

listen &optional input-stream 

  • When a character is instantly available from the input stream, the predicate listen is true; otherwise, it is false. This is especially helpful when the stream gets its characters from a keyboard or other interactive device.

read-char-no-hang &optional input-stream eof-error-p eof-value recursive-p 

  • It is similar to read-char, but instead of waiting for a character if it doesn’t receive one, it returns nil right away.

clear-input &optional input-stream

  • By doing this, the input-related stream’s buffered input is cleared. When an asynchronous error has occurred, it is most useful for clearing type-ahead from keyboards. If the stream in question doesn’t make sense for this operation, clear-input has no effect. Clearing input yields nil.

read-from-string string &optional eof-error-p eof-value &key :start :end :preserve-whitespace

  • It generates a LISP object out of the string’s characters one at a time, then returns the object. Additionally, it returns the length of the string (or length + 1), or the index of the first character in the string that was not read.

parse-integer string &key :start :end :radix :junk-allowed 

  • It looks at the portion of the string that is start and end-delimited (default to the beginning and end of the string). Whitespace characters are skipped over before an attempt is made to parse an integer.

Example :

Lisp




;LISP- Input 
(with-input-from-string (stream "Geeks for Geeks welcomes you!")
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (read-char stream))
   (print (peek-char nil stream nil 'the-end))
   (values)
)


Output :

 

Input from Binary Streams:

read-byte binary-input-stream &optional eof-error-p eof-value 

  • read-byte extracts one byte from the binary input stream and returns it as an integer.

Reading Input from Keyboard:

The read function in Common Lisp allows for keyboard input. It may not take any parameter. Characters are read from an input stream and parsed into representations of Lisp objects.

Syntax:

(setq varname (read))

This statement will take input from the keyboard and store it in the variable.

Example:

Lisp




; Lisp program to demonstrate 
; use of read function
; Program inputs value of radius from
; keyboard and calculates the perimeter of circle
  
(defun PerimOfCircle()
(terpri)
(princ "Enter Radius: ")
(setq radius (read))
(setq perimeter (* 2 3.1416 radius))
(princ "Perimeter: ")
(write perimeter))
(PerimOfCircle)


Output:

 

Output Functions:

The output functions are split into two categories: those that work with character streams and those that work with binary streams. Due to its extreme complexity, the function format—which operates on streams of characters—is discussed in a section separate from that of the other character-output functions.

Output to Character Streams:

Each of these routines accepts an optional argument called output-stream that specifies where the output should be sent. Output-stream defaults to the value of the variable “standard-output” if unspecified or nil. The value of the variable “terminal-io” is used if the value is t.

write object &key :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array

write object &key :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array :readably :right-margin :miser-width :lines :pprint-dispatch

  • The output stream designated by: stream, which by default has the value of “standard-output,” receives the printed version of the object.

prin1 object &optional output-stream
print object &optional output-stream
pprint object &optional output-stream
princ object &optional output-stream

  • prin1 sends an object’s printed representation to the output stream. When necessary, escape characters are utilized.
  • Print is identical to prin1, with the exception that a newline and a space is used to separate the printed representation of an item. print outputs the object.
  • In order to provide “beautiful” output, the object is printed with the “print-pretty” flag set to non-nil when using pprint rather than print. pprint gives no results.
  • Except for the absence of escape characters in the output, princ is identical to prin1. It gives the object back as the value.

write-to-string object &key :escape :radix :base :circle :pretty :level :length :case :gensym :array
prin1-to-string object
princ-to-string object

  • The object is effectively printed, and a string is created from the output characters and returned.

write-char character &optional output-stream

  • write-char writes the character to output-stream and returns the character.

write-string string & optional output-stream & key :start :end

  • The write-string command output streams the characters of the supplied string substring. A substring of a string is delimited by the: start and: end parameters in a typical way.

terpri &optional output-stream
fresh-line &optional output-stream

  • A newline is output to the output stream by the function terpri. However, terpri always returns nil, unlike (write-char #Newline output-stream), which is equivalent in effect.
  • Similar to terpri, fresh-line only outputs a newline if the stream is not already at the beginning of a line.

finish-output &optional output-stream
force-output &optional output-stream
clear-output &optional output-stream

  • The function finish-output tries to ensure that all output sent to the output-stream has reached its destination, and only then returns nil.
  • The function force-output initiates the clearing of any internal buffers but returns nil without waiting for completion or acknowledgment.
  • The function clear-output tries to abort any outstanding output operation in progress in order to allow as small output as possible to continue to the destination.

Example :

Lisp




; Lisp program to show output functions
; Program to double a number
  
  
(defun DoubledNumber()
   (terpri)
   (princ "Enter the Number : ")
   (setq n1 (read))
   (setq double (* 2.0 n1))
   (princ "The number is: ")
   (write n1)
   (terpri)
   (princ "The doubled number is: ")
   (write double)
)
(DoubledNumber)


Output :

 

Output to Binary Streams:

write-byte integer binary-output-stream

  • write-byte outputs an integer value of one byte. If the integer does not fit the description provided as the ‘element-type’ argument to open when the stream was established, it is an error. The result is an integer value.

Formatted Output:

The function format is highly helpful for creating well-formatted text, attractive messages, and other things. A stream or a string can be produced by format.

Syntax:

format destination control-string &rest arguments

The standard output is the syntax’s destination, while the control-string variable holds the characters that will be output along with the printing instruction.

With the exception of the tilde (~), which begins a directive, the format outputs the characters of the control string. It is specified by the character following the tilde, which may be followed by prefix parameters and modifiers. A tilde (~), optional prefix parameters separated by commas, an optional colon (:) and at-sign (@) modifiers, and a single character designating the type of directive this is make up a format directive.

Typically, the prefix parameters are integers with optionally signed decimal notation.

The following table tabulates some of the commonly used directives with their descriptions:

Directive Description
~A followed by ASCII arguments.
~S followed by S-expressions.
~B For binary arguments.
~C For character arguments.
~D For decimal arguments.
~E Exponential floating-point arguments.
~F For Fixed-format floating-point arguments.
~O For octal arguments.
~X For hexadecimal arguments.
~$ Dollar and floating point arguments.
~% A new line is printed.
~* The next argument is ignored.
~? Indirection. The next argument must be a string, and the one after it a list.
~T Tabulate. This spaces over to a given column.

Example :

Lisp




;Lisp program to show format function
  
(defun PerimOfCircle()
   (terpri)
   (princ "Enter Radius: ")
   (setq radius (read))
   (setq Perimeter (* 2 3.1416 radius))
   (format t "Radius: = ~F~% Perimeter = ~F" radius Perimeter)
)
(PerimOfCircle)


Output :

 



Last Updated : 15 Jul, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads