Hi! I decided to take a look at how one can parse command line arguments in Guile and was looking for something like argparse in Python. It seems that (use-modules (ice-9 getopt-long)) does the job, except that I hit one problem and don't know what the mistake I am making is. It seems to be connected to the usage of `predicate` in my code.
The following is an example program, which I wrote to try the getopt-long facilities, adapted from the docs example at https://www.gnu.org/software/guile/manual/html_node/getopt_002dlong-Example.html#getopt_002dlong-Example: ;; ===== EXAMPLE START ===== (add-to-load-path (dirname (current-filename))) (use-modules (ice-9 getopt-long)) (define (string-exact-integer? str) (exact-integer? (string->number str))) (define option-spec '((version (single-char #\v) (value #f)) (help (single-char #\h) (value #f)) (user-name (value #t) (required? #f)) (times-hello (value #t) (single-char #\n) (required? #f) (predicate string-exact-integer?)))) (define options (getopt-long (command-line) option-spec)) (option-ref options 'help #f) (define (main) (let* ([help-wanted (option-ref options 'help #f)] [version-wanted (option-ref options 'version #f)] [user-name (option-ref options 'user-name #f)] [times-say-hello (option-ref options 'times-hello 1)]) (cond [(or version-wanted help-wanted) (when version-wanted (display "command-line-arguments.scm 1.0.0\n")) (when help-wanted (display (string-join '("" "getopt-long-example [options]" "-v, --version Display version" "-h, --help Display this help" "") "\n")))] [else (do ([i 0 (1+ i)]) ([>= i times-say-hello]) (display (simple-format #f "Hello, ~a!\n" (if user-name user-name "World"))))]))) (main) ;; ===== EXAMPLE END ===== This program I call as follows in Emacs' Eshell: ;; ===== COMMAND START ===== guile command-line-arguments.scm -n 3 --user-name test ;; ===== COMMAND END ===== Then I get the following error: ;; ===== ERROR START ===== Backtrace: 9 (apply-smob/1 #<catch-closure a98b80>) In ice-9/boot-9.scm: 705:2 8 (call-with-prompt ("prompt") #<procedure a9a0a0 at ice-9/eval.scm:330:13 ()> #<procedure…>) In ice-9/eval.scm: 619:8 7 (_ #(#(#<directory (guile-user) b2e140>))) In ice-9/boot-9.scm: 2312:4 6 (save-module-excursion #<procedure ad6330 at ice-9/boot-9.scm:3827:3 ()>) 3822:12 5 (_) In /home/xiaolong/development/Guile/examples-and-convenience-procedures/command-line-arguments/command-line-arguments.scm: 30:16 4 (_) In ice-9/getopt-long.scm: 350:6 3 (getopt-long _ _ #:stop-at-first-non-option _) In ice-9/boot-9.scm: 260:13 2 (for-each #<procedure acd1e0 at ice-9/getopt-long.scm:350:16 (spec)> _) In ice-9/getopt-long.scm: 209:28 1 (_ "times-hello" _) In unknown file: 0 (_ "3") ERROR: Wrong type to apply: string-exact-integer? ;; ===== ERROR END ===== Maybe I am doing something stupid, but as far as I can see, I am just doing what the docs say, I am providing a function that takes the option's value as string and returns #t or #f. Everything worked up to when I tried the predicate thing. What am I doing wrong?