(apply +) gives an uncatchable error

Create issue
Issue #262 on hold
Göran Weinholt created an issue

When apply is given too few arguments there is an error which guard can’t catch. The error seems to be raised even before the code is evaluated:

sash> (guard (exn (else #t)) (apply +))
Unhandled exception
  Condition components:
  1. &compile
    program: (guard (exn (else #t)) (apply +))
    source: #f
  2. &error
  3. &message wrong number of arguments: apply requires 2, but got 1
  4. &who apply
  5. &irritants ((#<identifier apply#user #f (0x55a66f8fdb80):0> #<identifier +#user #f (0x55a66f8fdb40):0>))
  6. &stack-trace

stack trace:
  [1] error
  [2] pass1
  [3] pass1/lambda
  [4] pass1/call
  [5] pass1/lambda
  [6] pass1/lambda
  [7] pass1/call
  [8] pass1
  [9] with-error-handler
  [10] dynamic-wind
  [11] eval
  [12] #f
    src: ((current-evaluator) form interactive-environment)
  [13] with-error-handler
  [14] read-eval-print-loop
    src: (call-with-current-continuation (lambda (continue)
  [15] eval

Comments (4)

  1. Takashi Kato repo owner

    Thank you for the report!

    This behaviour is deliberately, so that users don’t have to wait to find these minor mistake until the script is running.

    I’m a bit curious about in which situation this would be bother. Could you maybe describe when you don’t want to get this compilation time error?

  2. Göran Weinholt reporter

    I’m running an R7RS test suite from Alex Shinn in Akku and akku-r7rs, to test Akku’s support for converting from R7RS to R6RS. The test is also run on Sagittarius to see that it doesn’t get in the way of Sagittarius’ native R7RS support.

    The test suite has this code:

    (test 7 (apply + (list 3 4)))
    (test 7 (apply + 3 4 (list)))
    (test-error (apply +)) ;; not enough args
    (test-error (apply + 3)) ;; final arg not a list
    (test-error (apply + 3 4)) ;; final arg not a list
    (test-error (apply + '(2 3 . 4))) ;; final arg is improper

    Sagittarius is the only implementation that refuses to eval the code. I think it’s good to detect obvious errors like these, but generally in Scheme these things are errors at runtime, not compile time. Chez Scheme also finds things like this, but it emits warnings and generates code that raises the appropriate error at runtime. I guess R7RS is different from R6RS and allows the behavior seen in Sagittarius though, so I can put in a cond-expand in the test if you think Sagittarius is doing the right thing.

  3. Takashi Kato repo owner

    I’m not entirely sure if raising an error on compilation phase is a violation of RnRS. So at this moment, I wouldn’t make any change for this behaviour. (I’ll keep the ticket open for later reference and in case of change of my mind.)

    It would, indeed, be an idea to wrap with cond-expand or use eval for that particular test cases.

  4. Log in to comment