snippetMinor
A Simple Unix Filter in Racket - Learning the Racket Way
Viewed 0 times
simpleunixthewaylearningfilterracket
Problem
I've written the following simple filter in Racket as my first Racket program and am wondering if I am writing it in an "idiomatic Racket style".
`#! /usr/bin/env racket
#lang racket
(require racket/cmdline)
(define a-prolog-mode? (make-parameter #f))
;; parses the options passed on the command-line
(command-line
#:program "patoms"
#:once-any
[("-a" "--aprolog") "output as A-Prolog code"
(a-prolog-mode? #t)])
;; dlv-input? : string -> boolean
;; Returns True if the given text corresponds to the output of DLV
;; and False otherwise. DLV's output is prefixed by one of the following
;; strings: "DLV", "{", or "Best model".
(define (dlv-input? text)
(regexp-match? #rx"^DLV|^{|^Best model" text))
;; text->answer-sets : string -> list of strings
;; Returns a list comprised of all of the answer sets in the given text.
(define (text->answer-sets text)
(cond
[(dlv-input? text) (regexp-match #rx"{(.?)}" text #:match-select cadr)]
[else null]))
;; write-as-code : string
;; Writes the given answer set in plain text form to standard output.
(define (write-as-text answer-set)
(let ([literals (map string-trim (string-split answer-set ","))])
(cond
[(empty? literals) (printf "~a~n" "{}")]
[else (for-each (λ (literal) (printf "~a~n" literal)) literals)])
(printf "~a~n" "::endmodel")))
;; write-as-code : string
;; Writes the given answer set as A-Prolog code to standard output.
(define (write-as-code answer-set)
(let ([literals (map string-trim (string-split answer-set ","))])
(for-each (λ (literal) (printf "~a.~n" literal)) literals)
(printf "~a~n" "%%endmodel")))
;; main
;; Serves as the main function of the program. If a-prolog-mode is specified
;; by the user via the command-line, all of the answer sets that may be parsed
;; from standard input are written to standard output as A-Prolog. Otherwise
;; the answer sets are written in a plain text format.
(define (main)
(let* ([text (port->string (curren
`#! /usr/bin/env racket
#lang racket
(require racket/cmdline)
(define a-prolog-mode? (make-parameter #f))
;; parses the options passed on the command-line
(command-line
#:program "patoms"
#:once-any
[("-a" "--aprolog") "output as A-Prolog code"
(a-prolog-mode? #t)])
;; dlv-input? : string -> boolean
;; Returns True if the given text corresponds to the output of DLV
;; and False otherwise. DLV's output is prefixed by one of the following
;; strings: "DLV", "{", or "Best model".
(define (dlv-input? text)
(regexp-match? #rx"^DLV|^{|^Best model" text))
;; text->answer-sets : string -> list of strings
;; Returns a list comprised of all of the answer sets in the given text.
(define (text->answer-sets text)
(cond
[(dlv-input? text) (regexp-match #rx"{(.?)}" text #:match-select cadr)]
[else null]))
;; write-as-code : string
;; Writes the given answer set in plain text form to standard output.
(define (write-as-text answer-set)
(let ([literals (map string-trim (string-split answer-set ","))])
(cond
[(empty? literals) (printf "~a~n" "{}")]
[else (for-each (λ (literal) (printf "~a~n" literal)) literals)])
(printf "~a~n" "::endmodel")))
;; write-as-code : string
;; Writes the given answer set as A-Prolog code to standard output.
(define (write-as-code answer-set)
(let ([literals (map string-trim (string-split answer-set ","))])
(for-each (λ (literal) (printf "~a.~n" literal)) literals)
(printf "~a~n" "%%endmodel")))
;; main
;; Serves as the main function of the program. If a-prolog-mode is specified
;; by the user via the command-line, all of the answer sets that may be parsed
;; from standard input are written to standard output as A-Prolog. Otherwise
;; the answer sets are written in a plain text format.
(define (main)
(let* ([text (port->string (curren
Solution
Overall, this is very pleasant code to review. Especially given you're new to the language. Your function names are follow convention such as the use of ending predicates with
? and indicating conversions with ->. The comments make this code easy to understand. So bravo, keep at it! That being said, here are some pretty minor suggestions.- "Favor define when feasible". Your
let's andlet*'s could be changed to internaldefine's to decrease nesting.
- Change
(define (main) ...)to(module+ main ...). Submodule support added in June's 5.3 release make having main's and test's easier than ever.
- Within
main, should one of thecondbranches be usingwrite-as-textinstead ofwrite-as-code? right now, both branches do the same thing. Along the same vein, the comment abovewrite-as-textwas copied but not changed from;; write-as-code.
- In racket, we have 3 ways of doing output, display, write, and print. Since your
write-as-text/codefunctions use printing, I would change the names of those functions to be calledprint-as-text/code
Context
StackExchange Code Review Q#19123, answer score: 2
Revisions (0)
No revisions yet.