Line Filters in Lisp

Here’s the translation of the Go line filter program to Lisp, along with explanations in Markdown format suitable for Hugo:

A line filter is a common type of program that reads input on stdin, processes it, and then prints some derived result to stdout. grep and sed are common line filters.

Here’s an example line filter in Lisp that writes a capitalized version of all input text. You can use this pattern to write your own Lisp line filters.

(defun main ()
  ;; We use the `with-open-file` macro to handle file operations
  ;; *standard-input* is the Lisp equivalent of stdin
  (with-open-file (input *standard-input* :direction :input)
    ;; Loop until we reach the end of the file
    (loop for line = (read-line input nil)
          while line
          do (process-line line))))

(defun process-line (line)
  ;; Convert the line to uppercase and print it
  (format t "~a~%" (string-upcase line)))

;; Call the main function
(main)

To try out our line filter, first make a file with a few lowercase lines.

$ echo 'hello'   > /tmp/lines
$ echo 'filter' >> /tmp/lines

Then use the line filter to get uppercase lines.

$ cat /tmp/lines | sbcl --script line-filters.lisp
HELLO
FILTER

This Lisp version of the line filter program does the following:

  1. We define a main function that opens the standard input stream.

  2. We use a loop to read lines from the input until we reach the end of the file.

  3. For each line, we call the process-line function.

  4. The process-line function converts the line to uppercase using string-upcase and prints it using format.

  5. Finally, we call the main function to start the program.

In Lisp, we don’t need to explicitly handle errors for end-of-file conditions as the read-line function returns nil when it reaches the end of the file, which naturally terminates our loop.

This example demonstrates how to create a simple line filter in Lisp, reading from standard input, processing each line, and writing to standard output. You can modify the process-line function to perform different operations on each line as needed.