What is a Scheme interpreter to do when it is told to evaluate (car 2)? The interpreter is not required to report this error by current standard but all the implementations I have used do report the error and make some attempt to help the user find the error. I propose here a language extension that allows a debugger in Scheme to provide such guidance. I believe that this proposal does less violence to the language than the extension implemented in MzScheme. I think that the MzScheme breaks abstractions and that my proposal does not, but I will not try to defend this claim just yet except to say that these issues bear on the ideas that Jonathan Rees promulgates here.

Evaluation of both primitive and programmed procedures should be alike upon domain errors and similar mal-invocations. I consider the primitive procedures first. When a primitive procedure is to signal an error it invokes the procedure locally bound to the symbol 'error. (MzScheme already has a binding for 'error in the top scope. I will define my own 'error here but I would certainly choose a different symbol to avoid problems that might arise.) 'error is invoked with two arguments:

The invocation of 'error is with a continuation which is a procedure that ignores any continuation and prints “The procedure bound to 'error returned.”.
(let ((error (lambda (e c) (c (+ 1 (cadr e)))))) (car 3)) yields 4.
(let ((error (lambda (e c) (display e) (error "domain error")))) (car 3)) yields “(car 3) domain error” and resumes the REPL.
In the second case we rely on the MzScheme procedure called error

There are many names which a program can use without defining such as write and sin. We propose here a name which the program can define without using.

Now we try to make it so that a programmed procedure can report errors this way. The body of the reporting procedure does not have access to the procedure bound to 'error at the call site. The continuation produced there is available however. I propose a new primitive procedure re that takes such a continuation c and one other argument and invokes the procedure bound to 'error at the call site as if (error c x) had been evaluated in the context of the call site. x is the continuation for the expression whose failure this is a report of. Perhaps the file name string is passed as the first argument.

An alternative to re of the above paragraph would merely be a primitive procedure, called erx here, that takes one argument and invokes the procedure named error in the caller’s caller. This call to error would pass no continuation or merely a primitive error reporting continuation.

None of these proposals allow sending arbitrary messages to the procedure named error. I shall try to explain why I think that this a good idea. An insufficient reason is that it allows easier coding or such routines.

Other errors: Some variation is needed for the missing file error in the procedure open-input-file. Also to be distinguished:
storing into an immutable object
to reference an unbound variable

We must consider if procedure re can be abused. This proposal sneaks up on exception returns and should be coordinated with any such design. I am not anxious to design exception returns for Scheme.

It the purpose of the language designers was to avoid requiring implementations to check for pair-ness of the argument of car for reasons of performance then this proposal fails to address that issue.

Meta

Scheme has keywords, such as let, as part of its syntax. It has conventional symbols such as car to which are bound certain primitive procedures in the outer scope. This proposal adopts a ‘key-symbol’ error in a way that is like neither of the above language elements. If you want to use car for some other meaning but still need the primitive procedure, that is easy. My proposed use of error allows no such dodge.
This proposal goes beyond SRFI 23 yet still ignores some issues addressed there.
Unspecified in 1.3.2 should be narrower. It should not be data that is not in scope!