On Feb 25, 2007, at 11:19 AM, William D Clinger wrote:
> Mike Sperber asked:
>> Why is it not enough for the compiler to just issue a warning, and to
>> then abort at run time? (Scheme 48 also does some degree of arity
>> checking at compile time, and offers a special mode to make warnings
>> abort the compiler.)
>
> According to the current draft R6RS, implementations
> are not allowed to "abort at run time"; they would
> have to raise a &violation exception, from which the
> program might conceivably recover in a portable way.
I believe that's correct. I also believe the rationale
for that is to allow people to write robust code without
performing their own error checking. Example: I have a
file that contains a pair whose car I'm interested in.
I can open the file, read from it, and take the car of
that, all under one exception handler. I assume you're
not proposing allowing implementations to abort at runtime
in this example, correct?
> By legitimizing violations in that way, the draft
> R6RS requires compilers to generate R6RS-compatible
> code (whatever that means; see below) for programs
> that violate the requirements of the draft. That
> means compilers must be written in such a way as
> to continue to operate correctly when even the most
> basic requirements of the R6RS are not met by the
> program being compiled.
Here you talk about programs that violate the
requirements of the draft. I am having a hard time
finding these requirements in the current draft.
> That means compiler writers will have to write extra
> code for the sole purpose of undoing optimizations
> whose correctness temporarily assumes the program
> being compiled contains no fundamental violations
> of a kind that is easily detected after the program
> has been transformed according to the optimization,
> and is not so easily detected before the program
> transformation.
I sympathize with that (as a compiler writer but not
as a user). Let me give a simple example for the
readers who may not know the issue since they don't
deal with it directly.
It is well known that
(let ([lhs* rhs*] ...) body)
is equivalent to
((lambda (lhs* ...) body) rhs* ...)
My compiler expands the former to the latter during
macro expansion and transforms the latter to the former
in an early pass. So, we can easily transform
((lambda (x) x) 12) to (let ([x 12]) x)
A small nuisance happens when the compiler attempts to
perform this optimization, only to discover that the
actual arguments do not match the formal arguments, and
therefore, the procedure call is invalid. So, in these
circumstances, the compiler must be prepared to handle
such situation (cannot crash the compiler). For a simple
example, ((lambda () 12) E) where E is an arbitrary
expression may be transformed to (other, more creative,
possibilities exist):
1. ((lambda () 12) E) and detect the error at runtime.
2. (begin E (error ---)) (my favorite)
So, what's being proposed is to permit implementors to
reject compiling some programs upon encountering such
situations instead of forcing the implementors to handle
this case in a more "graceful" way.
> Requiring compiler writers to write
> this extra code, instead of allowing them to reject
> programs that violate the basic requirements of the
> language, is a silly waste of implementors' time.
As I said, I sympathize, somewhat. However, since I
actually fixed my compiler some time ago, I don't care
that much now (this may be due to Endowment Effect[*]).
Compare:
=== Native-code incremental compilers #1 & #2 ==================
> (call-with-current-continuation
(lambda (k) ((lambda () 12) (k 17))))
17
>
=== Native-code incremental compiler #3 ========================
> (call-with-current-continuation
(lambda (k) ((lambda () 12) (k 17))))
Error: Wrong number of arguments to known procedure (let () 12)
Entering debugger; type "?" for help.
debug>
================================================================
This is just one example to illustrate the point for the
non-implementors.
> For some compiler writers, the most likely response
> to a standard of silliness approaching that of the
> current draft is to ignore the sillier parts of the
> standard in their compilers, and to provide strict
> R6RS conformance (whatever that means; see below)
> only in their interpreters. If at all.
No doubt :-)
> Recognition of R6RS-compatible implementations might
> go a long way toward convincing some compiler writers
> that the R6RS language is worth implementing.
This statement is true (the higher the bar, the fewer
the conforming implementations). Is it enough to permit
a low-bar R6RS-compatibility in the standard? I don't
know.
> Most
> of those who would insist upon an R6RS-conforming
> implementation would be happy using an interpreter.
Maybe. But wouldn't you say that those same users may
be happier using an R6RS-conforming compiler? I don't
see why you seem to imply that the two are mutually
exclusive.
Aziz,,,
[*]
http://en.wikipedia.org/wiki/Endowment_effect
Received on Sun Feb 25 2007 - 14:31:14 UTC