Struggling with trivial command line program

Both versions work. Which would you use? It's surprising how hard this is and how inconsistent across schemes (and, of course, common lisp). Which would you use?

#lang cli

(program (square n)
    (let ((num (string->number n)))
      (displayln (* num num))))

(run square)

After a bit of messing around with code from Gambit the following also works. Needed to add '(require cli)' , '(run main)' and deref arg, which comes into racket as a vector of strings. In Gambit 'arg' comes in as a single string value on the command line.

#!/usr/bin/env racket 
#lang racket

(require cli)

(define (main arg)
   (displayln (expt (string->number (vector-ref arg 0)) 2)))

(run main)

Is there a reasonable way to do this in racket without using the 'cli' package? There ought to be some way to reference the command line passed by the OS to the executable, whether as a string, a vector of strings or as discrete values. Is there?

The alarming thing is that the first executable is over 50mb and the second is over 60mb, while with Gambit the executable ends up as 6mb and even with sbcl, I can create a 9.6mb executable. In all cases, a large run-time is bundled with the otherwise trivial code.

As I mentioned in another post, you do not need to use cli. Here’s the simplest variant:

#lang racket/base

(displayln (expt (string->number (vector-ref (current-command-line-arguments) 0)) 2))

;; $ racket file.rkt 8
;; 64

If you want to handle command-line parsing in a more principled way, you can use racket/cmdline.

#lang racket/base

(require racket/cmdline)

(define n
  (command-line
   #:args (number)
   (string->number number)))

(displayln (expt n 2))

;; $ racket file.rkt 8
;; 64
;; $ racket file.rkt
;; file.rkt: expects 1 <number> on the command line, given 0 arguments

1 Like

perfect. I saw that in the manual and wasn’t sure if it is a function or a vector (no diff if the function returns a vector).

  • Lewis