[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SRFI 22 finished?

This page is part of the web mail archives of SRFI 22 from before July 7th, 2015. The new archives for SRFI 22 contain all messages, not just those from before July 7th, 2015.



> 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