Email list hosting service & mailing list manager

SRFI 22 finished? sperber@xxxxxx (17 May 2001 08:19 UTC)
Re: SRFI 22 finished? Marc Feeley (17 May 2001 15:31 UTC)
Re: SRFI 22 finished? sperber@xxxxxx (17 May 2001 15:40 UTC)
Re: SRFI 22 finished? Marc Feeley (17 May 2001 18:34 UTC)
Re: SRFI 22 finished? sperber@xxxxxx (17 May 2001 15:45 UTC)
Re: SRFI 22 finished? Marc Feeley (17 May 2001 18:06 UTC)

Re: SRFI 22 finished? Marc Feeley 17 May 2001 18:34 UTC

> Marc> Finally, I don't understand the sudden change in the way parameters
> Marc> are passed to "main".
>
> What change?  It was this way since day 1 of SRFI 22.

Sorry... I just assumed it from some of the messages I read.

> Marc> It seems much more elegant to define "main" as
> Marc> a procedure with as many arguments as are needed by the script, which
> Marc> allows the Scheme interpreter to very naturally catch wrong number of
> Marc> argument errors, and the code for scripts expecting a fixed number of
> Marc> arguments is more elegant (they don't have to extract the arguments
> Marc> from a list).
>
> But it would require the SRFI to specify what would happen in this
> place.  The vanilla reaction to this by the Scheme system is very
> probably not the one you want when someone calls the script with a
> wrong number of arguments.

Really?  I find that this gives the Scheme implementation a chance to
(automatically) give a message that is understandable to the user of
the script.  For example if "main" is

(define (main x y)
  (write (+ (string->number x)
            (string->number y)))
  0)

and you call the script with a single argument, Gambit will display

*** ERROR -- Wrong number of arguments passed to procedure
(main "123")

Surely other systems will give a similar error message.
However, if main receives all the arguments in a list, you would write

(define (main arguments)
  (write (+ (string->number (car arguments))
            (string->number (cadr arguments))))
  0)

and the error would me much more obscure:

*** ERROR IN "script.scm"@6.29 -- PAIR expected
(cadr '("123"))

Note that if you want to display a more friendly error message you still
can write:

(define (main . arguments)
  (if (= (length arguments) 2)
      (begin
       (write (+ (string->number (car arguments))
                 (string->number (cadr arguments))))
       0)
      (begin
       (display "usage: add first-number second-number\n")
       1)))

> Marc> Scripts that handle variable number of arguments (such
> Marc> as your example) can be written with a rest parameter:
>
> Marc> (define (main . arguments)
> Marc>   (for-each display-file arguments)
> Marc>   0)
>
> And vice versa:
>
> (define (main args)
>   (apply marc-feeley-main args))
>
> Why is this important?

Elegance.  The choice is between

(define (main arguments) ; fixed number of arguments
  (apply
   (lambda (x y) ; x and y would be meaningfull names in a realistic example...
     (write (+ (string->number x)
               (string->number y)))
     0)
   arguments))

(define (main arguments) ; variable number of arguments
  (for-each display arguments)
  0)

and in the approach I propose:

(define (main x y) ; fixed number of arguments
  (write (+ (string->number x)
            (string->number y)))
  0)

(define (main . arguments) ; variable number of arguments
  (for-each display arguments)
  0)

Using the approach I propose, the fixed number of arguments case is
concise and natural and the variable number of arguments case needs an
extra dot, which is a small price to pay.

Marc