Discussion:
EX_USAGE?
felix
2001-06-13 19:29:24 UTC
Permalink
I have some trouble with the fact that an error in the invocation of
"main" is supposed to return EX_USAGE. Specifically
I have trouble thinking about a way to implement it in
a not too arcane way.
(If there is an obvious solution, then please feel free to
ignore this message)

1) Hooking into the error-mechanism isn't the problem,
but after entry into "main", when user code is running,
I can't think of a way to unhook the error handler again
(We want a "meaningful" usage-related error message
in the call to "main", but normal argc-error behaviour
in case another procedure is called with the wrong number
of arguments, right?)

2) Doing some fiddling with backtraces after the error
situation doesn't look that good either, especially in
the case of compiled scripts, which might not have
much debugging info.

3) Normally I wouldn't ask about implementation-specific things
like this. As I said: There might be a simple solution, and I'm just too
stupid too see it, but:
Is it really so helpful to have a distinct exit-code
in this case? Don't have many scripts a variable number of
arguments, anyway?


cheers,
felix
sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
2001-06-15 09:23:44 UTC
Permalink
felix> I have some trouble with the fact that an error in the invocation of
felix> "main" is supposed to return EX_USAGE. Specifically
felix> I have trouble thinking about a way to implement it in
felix> a not too arcane way.

You're summing up my original reservations about this issue. I do
believe yielding the correct exit code is important, but I also would
slightly prefer to leave that responsibility to the programmer of the
script.

Marc, how about you step in here?
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla
Marc Feeley
2001-06-15 12:01:21 UTC
Permalink
Post by sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
felix> I have some trouble with the fact that an error in the invocation of
felix> "main" is supposed to return EX_USAGE. Specifically
felix> I have trouble thinking about a way to implement it in
felix> a not too arcane way.
You're summing up my original reservations about this issue. I do
believe yielding the correct exit code is important, but I also would
slightly prefer to leave that responsibility to the programmer of the
script.
Marc, how about you step in here?
Well, I do find it odd that there is a different error code for the
case of a wrong number of arguments. But if it is the "Unix way" then
I can understand wanting to support it properly.

In terms of implementation, I don't see how to do it (at least in
Gambit) because the "main" procedure might tail call another procedure
(or even itself) with a wrong number of arguments, as in:

(define (main a1 a2)
(main a1))

and I can't see how to distinguish the first call (in the runtime)
from the second, and the SRFI requires each call to return a different
error code.

I thought it would be possible to use Gambit's continuation
introspection mechanism to extract the continuation's parent (the
procedure that created the continuation) or the error mechanism which
puts a reference to the procedure and list of arguments into the
exception object, but that is not sufficient for the simple example I
give above. Note that the "wrong number of arguments" error is
detected by Gambit on **entry** to the procedure (i.e. the procedure
call has already occured). In a system that detects this error in the
caller I guess it would be easier to satisfy the SRFI specs.

Note however that the error reporting process can't be completely
automatic (in an R5RS script). If a script accepts from 3 to 5
parameters then it is up to the main procedure to return EX_USAGE when
too many arguments are given as in:

(define (main a1 a2 a3 . others)
(if (> (length others) 2)
...EX_USAGE...
...keep going...))

If the script author does not put this test in (which is probably very
likely in quickly written scripts) then in practice the distinction
between EX_USAGE and EX_SOFTWARE will be lost anyway, so why bother.

So my position is that only EX_SOFTWARE should be required by the
SRFI. If the script author wants to support EX_USAGE, then she can
program it into the script explicitly (using a "main" with a rest
argument and appropriate logic).

Marc
sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
2001-06-15 12:05:50 UTC
Permalink
felix> I have some trouble with the fact that an error in the invocation of
felix> "main" is supposed to return EX_USAGE. Specifically
felix> I have trouble thinking about a way to implement it in
felix> a not too arcane way.
Post by sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
You're summing up my original reservations about this issue. I do
believe yielding the correct exit code is important, but I also would
slightly prefer to leave that responsibility to the programmer of the
script.
Marc, how about you step in here?
Marc> So my position is that only EX_SOFTWARE should be required by the
Marc> SRFI. If the script author wants to support EX_USAGE, then she can
Marc> program it into the script explicitly (using a "main" with a rest
Marc> argument and appropriate logic).

I would hate to return something that we know to be wrong: Your
motivation, if I understood it correctly, for switching the
parameter-passing mode was to make doing the Right Thing for the
common case slightly easier. I don't see that being the case here.
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla
Marc Feeley
2001-06-15 12:58:09 UTC
Permalink
Post by sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
I would hate to return something that we know to be wrong: Your
motivation, if I understood it correctly, for switching the
parameter-passing mode was to make doing the Right Thing for the
common case slightly easier. I don't see that being the case here.
No, this is a secondary motivation. The prime motivation is that
you get to name parameters explicitly rather than using "list-ref", etc.

Marc
sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
2001-06-15 13:01:30 UTC
Permalink
Post by sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
I would hate to return something that we know to be wrong: Your
motivation, if I understood it correctly, for switching the
parameter-passing mode was to make doing the Right Thing for the
common case slightly easier. I don't see that being the case here.
Marc> No, this is a secondary motivation. The prime motivation is that
Marc> you get to name parameters explicitly rather than using "list-ref", etc.

Ah, but then it does seem as though putting in that additional APPLY
would not be so bad, or would it?
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla
Marc Feeley
2001-06-15 13:57:06 UTC
Permalink
Post by sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
Marc> No, this is a secondary motivation. The prime motivation is that
Marc> you get to name parameters explicitly rather than using "list-ref", etc.
Ah, but then it does seem as though putting in that additional APPLY
would not be so bad, or would it?
I see it the other way. If the script author wants greater control
she can use a rest parameter (and also possibly an APPLY) and return
EX_SOFTWARE when appropriate. If she doesn't mind that a wrong number
of arguments to the script is handled with an EX_SOFTWARE, which I
think is the more common case, then she specifies in main's parameter
list exactly the parameters expected, and APPLY is not needed.

While I'm on the subject, I can't say I'm very fond of having main
return a status code. I don't like it for C and I don't like it for
Scheme. Main should be a procedure. If main returns normally, then
the result is ignored and the EX_OK status code is returned from the
script. You can always call "error" to return an EX_SOFTWARE (this
will work even if "error" is not defined!...). The ability to return
some other status code should be left to an "exit" procedure (defined
in this SRFI or some other one), because it is common to want to bail
out of a program/script from a deeply nested computation. In the
absence of "exit" you have to use call/cc as in:

(define exit #f)

(define (main a1 a2)
(call-with-current-continuation
(lambda (cont)
(set! exit cont)
...body...
0)))

but this is needlessly ugly, and it still contains a reference to 0
for EX_OK, which will throw off beginners for sure. In fact, what
happens in your proposal if main does not return an exact integer, or
returns an integer outside the acceptable range?

Marc
sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
2001-06-15 16:43:12 UTC
Permalink
Marc> While I'm on the subject, I can't say I'm very fond of having main
Marc> return a status code. I don't like it for C and I don't like it for
Marc> Scheme. Main should be a procedure. If main returns normally, then
Marc> the result is ignored and the EX_OK status code is returned from the
Marc> script. You can always call "error" to return an EX_SOFTWARE (this
Marc> will work even if "error" is not defined!...).

We know. We though about this. We disagree. I'll confer with Martin
once he's out of the swamp, so we should have something by Monday or
Tuesday.

Marc> but this is needlessly ugly, and it still contains a reference to 0
Marc> for EX_OK, which will throw off beginners for sure. In fact, what
Marc> happens in your proposal if main does not return an exact integer, or
Marc> returns an integer outside the acceptable range?

That's a good point, but the issue is trivially resolved.
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla
David Rush
2001-06-15 17:23:37 UTC
Permalink
Post by sperber-jNDFPZUTrfQQDnmTUQnR1uqEdJ8o/ (Michael Sperber [Mr. Preprocessor])
Marc> While I'm on the subject, I can't say I'm very fond of having main
Marc> return a status code. I don't like it for C and I don't like it for
Marc> Scheme. Main should be a procedure. If main returns normally, then
Marc> the result is ignored and the EX_OK status code is returned from the
Marc> script. You can always call "error" to return an EX_SOFTWARE (this
Marc> will work even if "error" is not defined!...).
We know. We though about this. We disagree.
Just a bit of useless me-too-ism here, but I'm with Marc on this. It's
ridiculous that there is no (exit int) call in R5RS, especially since
there was supposed to be some kind of focus on compiled code. This
SRFI might not be a bad place to introduce the function, especially
since it is explicitly for addressing OS issues.

david rush
--
With guns, we are citizens. Without them, we are subjects.
-- YZGuy, IPL
Loading...