> 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