Line Filters in Scheme

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 Scheme that writes a capitalized version of all input text. You can use this pattern to write your own Scheme line filters.

(import (scheme base)
        (scheme char)
        (scheme file)
        (scheme write))

(define (capitalize-line line)
  (string-map char-upcase line))

(define (process-lines)
  (let ((line (read-line)))
    (unless (eof-object? line)
      (display (capitalize-line line))
      (newline)
      (process-lines))))

(process-lines)

(when (port-error? (current-input-port))
  (display "error: " (current-error-port))
  (display (port-error-description (current-input-port)) (current-error-port))
  (newline (current-error-port))
  (exit 1))

This Scheme program does the following:

  1. We import necessary modules for basic operations, character manipulation, file I/O, and writing to output.

  2. We define a capitalize-line function that takes a line of text and returns its uppercase version using string-map and char-upcase.

  3. The process-lines function reads lines from standard input using read-line. For each line that isn’t an end-of-file object, it capitalizes the line, displays it, and then recursively calls itself to process the next line.

  4. We start the processing by calling process-lines.

  5. After processing all lines, we check if there was an error on the input port. If so, we display an error message on the error port and exit with a status code of 1.

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 | scheme line-filters.scm
HELLO
FILTER

This example demonstrates how to create a simple line filter in Scheme that reads from standard input, processes each line, and writes to standard output. It also shows basic error handling for I/O operations.