                    (bs/biosequence-seq reader)))))
 
 (defn process-fasta-file
+  "Compute the statistics for a single input FASTA file from a file, given by its filename,
+  and pretty print the result to the standard output. It is a wrapper around
+  process-fasta-reader.
+
+  Arguments:
+    minlen: The minimum length sequence allowed (non-negative int). Sequences shorter than
+      this will be skipped by the program.
+    filename: The name of the FASTA file to process.
+
+  Result:
+    nil"
+
   [minlen filename]
   (timbre/info "Processing FASTA file from" filename)
   (with-open [reader (bs/bs-reader (bs/init-fasta-file filename :iupacAminoAcids))]
     (process-fasta-reader minlen filename reader)))
 
 (defn process-stdin
+  "Compute the statistics for a single input FASTA file from stdin, 
+  and pretty print the result to the standard output. It is a wrapper around
+  process-fasta-reader.
+
+  Arguments:
+    minlen: The minimum length sequence allowed (non-negative int). Sequences shorter than
+      this will be skipped by the program.
+
+  Result:
+    nil"
   [minlen]
   (timbre/info "Processing FASTA file from stdin")
   (with-open [reader (bs/init-fasta-reader (java.io.BufferedReader. *in*) :iupacAminoAcids)]
     (process-fasta-reader minlen "stdin" reader)))
 
-(def header "FILENAME\tTOTAL\tNUMSEQ\tMIN\tAVG\tMAX")
-
 (defn process-fasta-files
+  "Compute the statistics for each file in an array of filenames. If the array is
+  empty, compute statistics from stdin. Print an output header before any inputs 
+  are processed.
+
+  Arguments:
+    minlen: The minimum length sequence allowed (non-negative int). Sequences shorter than
+      this will be skipped by the program.
+
+    files: A possibly empty array of filenames (array of strings).
+
+  Result:
+    nil"
   [minlen files]
-  (println header)
-  (if (empty? files)
-    (process-stdin minlen)
-    (doseq [file files]
-      (process-fasta-file minlen file))))
-
-(defn usage [options-summary]
+  (let [header "FILENAME\tTOTAL\tNUMSEQ\tMIN\tAVG\tMAX"]
+    (println header)
+    (if (empty? files)
+      ;; If there are no filenames to process, then use stdin.
+      (process-stdin minlen)
+      ;; Otherwise process each file in sequence.
+      (doseq [file files]
+        (process-fasta-file minlen file)))))
+
+(defn usage
+  "Print usage information for the program
+
+  Arguments:
+    options-summary: A summary of the available program options (string).
+
+  Result:
+    nil"
+
+  [options-summary]
   (->> ["Print fasta stats"
         ""
         "Usage: program-name [options] FILES"

        options-summary]
       (string/join \newline)))

(defn error-msg [errors]
  (str "The following errors occurred while parsing your command:\n\n"
       (string/join \newline errors)))

(defn exit [status msg]
  (println msg)
  (System/exit status))

(def default-minlen 0)

(def cli-options
  [[nil "--minlen N" "Minimum length sequence to include in stats"
    :default default-minlen :parse-fn #(Integer/parseInt %)]
   [nil "--log LOG-FILE" "record program progress in LOG-FILE"]
   ["-v" "--version"]
   ["-h" "--help"]])

(defn config-logging
  [log-filename]
  (when log-filename
    (let [log-file-name log-filename]
      (timbre/merge-config! {:appenders {:println {:enabled? false}}})
      (timbre/merge-config! {:appenders {:spit (appenders/spit-appender {:fname log-filename})}})
      (timbre/set-level! :info))
    (timbre/info "Program started")))

(defn -main
  "Orchestrate the computation"


;;; The main parts of the program are:
;;; 1. Parse command line arguments. 
;;; 2. Process each FASTA file in sequence.
;;; 3. Pretty print output for each file. 
;;;
;;; If no FASTA filenames are specified on the command line then the program
