Line Filters in Racket

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

#lang racket

(require racket/string)

(define (process-line line)
  (displayln (string-upcase line)))

(define (main)
  (let loop ()
    (define line (read-line))
    (unless (eof-object? line)
      (process-line line)
      (loop))))

(main)

Let’s break down the code:

  1. We start by requiring the racket/string module, which provides string manipulation functions like string-upcase.

  2. We define a process-line function that takes a line of input, converts it to uppercase using string-upcase, and prints it using displayln.

  3. The main function sets up a loop that reads lines from standard input using read-line. It continues reading until it encounters an end-of-file (EOF) condition.

  4. For each line read, we call process-line to process and print the uppercase version.

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

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 | racket line-filters.rkt
HELLO
FILTER

This Racket version achieves the same functionality as the original code. It reads lines from standard input, converts them to uppercase, and prints the results. The main differences are:

  • Racket uses read-line instead of a scanner object.
  • Error handling is implicit in Racket’s I/O operations.
  • The loop structure is different, using Racket’s recursive looping pattern.

This example demonstrates how to create a simple line filter in Racket, showcasing basic I/O operations and string manipulation.