Line Filters in Elixir

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

defmodule LineFilter do
  def main do
    IO.stream(:stdio, :line)
    |> Stream.map(&String.trim/1)
    |> Stream.map(&String.upcase/1)
    |> Enum.each(&IO.puts/1)
  end
end

LineFilter.main()

Let’s break down the code:

  1. We define a module LineFilter with a main function.

  2. IO.stream(:stdio, :line) creates a stream from the standard input, reading it line by line.

  3. We use Stream.map(&String.trim/1) to remove any trailing whitespace from each line.

  4. Stream.map(&String.upcase/1) converts each line to uppercase.

  5. Finally, Enum.each(&IO.puts/1) prints each processed line to the standard output.

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 | elixir line_filter.exs
HELLO
FILTER

In Elixir, we don’t need to explicitly handle errors for IO operations as we did in the original example. Elixir’s design philosophy is “let it crash”, and the runtime will handle most common IO errors gracefully.

This Elixir version provides the same functionality as the original, using idiomatic Elixir constructs like streams and the pipe operator to create a concise and efficient line filter.