Возможно преждевременно «выйти» из рэкета

#scheme #lisp #racket

Вопрос:

Для короткого замыкания функции C (например, в целях тестирования) я могу поместить return туда раннее. Например:

 int main(void) {
    puts("Hello");
    return;

    ...bunch of other code...
}
 

Или сделайте sys.exit(0) это на python. Есть ли способ сделать это в DrRacket / схеме? Как часто, у меня будет рабочая книга с несколькими сотнями строк кода, и я хочу, чтобы перед выходом запускались только несколько верхних функций. Например:

 #lang sicp

(define (filtr function sequence)
  (if (null? sequence) nil
      (let ((this (car sequence))
            (rest (cdr sequence)))
        (if (function this) (cons this (filtr function rest))
            (filtr function rest)))))
              
(filtr  (lambda (x) (> x 5)) '(1 2 3 4 5 6 7 8 9))   
     
(exit)  ; ?? something like this I can drop in to terminate execution?

...200 more lines of code...
 

Есть ли способ сделать это здесь?

Ответ №1:

#lang racket это можно сделать с помощью функции с именем… exit . Попробуй:

 #lang racket

(display 1)
(exit 0)
(display 2)
 

#lang sicp не имеет exit , но вы можете потребовать это от Racket:

 #lang sicp

(#%require (only racket exit))

(display 1)
(exit 0)
(display 2)
 

Ранний возврат из функции может быть выполнен с помощью продолжения. Например, с let/cc оператором:

 #lang racket

(define (fact x)
  (let/cc return
    (if (= x 0)
        1
        (begin
          (display 123)
          (return -1)
          (display 456)
          (* x (fact (- x 1)))))))

(fact 10)
;; display 123
;; and return -1
 

Или, что эквивалентно , с call-with-current-continuation , который существует в обоих #lang racket и #lang sicp :

 (define (fact x)
  (call-with-current-continuation
   (lambda (return)
     (if (= x 0)
         1
         (begin
           (display 123)
           (return -1)
           (display 456)
           (* x (fact (- x 1))))))))