如何使lambda中的函数在lambda体内使用的另一个函数中被调用
How to make the function in a lambda be called in another function used inside the body of lambda
我想用call/cc模拟异常处理语句:try...(throw)...exception。这是代码:
(define (month n) ; check if it's a month number (1-12)
(if (or (not (integer? n)) (< n 1) (> n 12))
(throw -1)
(display n)
)
)
(define error (call/cc
(lambda(throw)
(begin
(month 12)
(month -1)
(throw -1) ; won't be executed
(month 10)
(display "Hello world")
)
)
)
)
(if error
(display Error occured!")
)
但是,当我执行它时,它显示错误(在 biwascheme 中):
Error: execute: unbound symbol: "throw" [(anon), month]
我认为lambda中的throw与被调用函数中的throw不一样"month",但是如何解决呢?是否可以通过使用一些关键字制作 marco 来解决?例如:
(define-syntax exception-handling
(syntax-rules (throw raise error)
((_ body catch)
(define (error
(call/cc (lambda (throw) (begin body))))
)
(if error (begin catch)))
)
)
在 Scheme 中,continuations 是 first-class。捕获的延续只是另一个值。将它作为另一个参数传递给您的 month
函数:
(define (month n throw) ; check if it's a month number (1-12)
(if (or (not (integer? n)) (< n 1) (> n 12))
(throw -1)
(display n)))
并将其命名为
....
(month 12 throw)
....
(month 10 throw)
....
您的缩进风格不利于代码的可读性。
这里是如何使用 call-with-current-continuation
制作 "throw" 的示例。
#lang r5rs
(define (month n) ; check if it's a month number (1-12)
(call-with-current-continuation
(lambda (throw)
(define ok (and (integer? n) (<= 1 n 12)))
(if (not ok)
(throw "the month number must be between 1 and 12"))
(display n)
(newline))))
(month 12)
(month -1)
(month 10)
(display "Hello world\n")
我找到了模拟 try 和异常处理的方法:
(define-syntax try
(syntax-rules (catch)
((_ body catch handling)
(let ()
; evaluating body and save it as an exception.
(define except (begin body))
(if (and
(pair? except)
(eq? (car except) 'exception))
(handling except)
)
)
)
)
)
; returns an exception '(exception, "Error messenge")
(define (exception-content msg throw)
(throw (cons 'exception msg)))
; throw an exception if n = 0
(define (reciprocal n throw)
(if (= n 0)
(exception-content "Div 0 error" throw)
(/ 1 n)
)
)
; f1(n) = reciprocal(n) + 1
(define (f1 n throw)
(+ (reciprocal n throw) 1)
)
; main program
(try ; with call/cc and the continuation variable "throw"
(call-with-current-continuation
(lambda (throw)
(display (f1 2 throw))
(newline)
(display (f1 0 throw))
; the following won't be executed
(newline)
(display (f1 1 throw))
)
)
catch
; exception handling
(lambda (exception)
(display (cdr exception))
)
)
打印结果为:
3/2
Div 0 error
我想用call/cc模拟异常处理语句:try...(throw)...exception。这是代码:
(define (month n) ; check if it's a month number (1-12)
(if (or (not (integer? n)) (< n 1) (> n 12))
(throw -1)
(display n)
)
)
(define error (call/cc
(lambda(throw)
(begin
(month 12)
(month -1)
(throw -1) ; won't be executed
(month 10)
(display "Hello world")
)
)
)
)
(if error
(display Error occured!")
)
但是,当我执行它时,它显示错误(在 biwascheme 中):
Error: execute: unbound symbol: "throw" [(anon), month]
我认为lambda中的throw与被调用函数中的throw不一样"month",但是如何解决呢?是否可以通过使用一些关键字制作 marco 来解决?例如:
(define-syntax exception-handling
(syntax-rules (throw raise error)
((_ body catch)
(define (error
(call/cc (lambda (throw) (begin body))))
)
(if error (begin catch)))
)
)
在 Scheme 中,continuations 是 first-class。捕获的延续只是另一个值。将它作为另一个参数传递给您的 month
函数:
(define (month n throw) ; check if it's a month number (1-12)
(if (or (not (integer? n)) (< n 1) (> n 12))
(throw -1)
(display n)))
并将其命名为
....
(month 12 throw)
....
(month 10 throw)
....
您的缩进风格不利于代码的可读性。
这里是如何使用 call-with-current-continuation
制作 "throw" 的示例。
#lang r5rs
(define (month n) ; check if it's a month number (1-12)
(call-with-current-continuation
(lambda (throw)
(define ok (and (integer? n) (<= 1 n 12)))
(if (not ok)
(throw "the month number must be between 1 and 12"))
(display n)
(newline))))
(month 12)
(month -1)
(month 10)
(display "Hello world\n")
我找到了模拟 try 和异常处理的方法:
(define-syntax try
(syntax-rules (catch)
((_ body catch handling)
(let ()
; evaluating body and save it as an exception.
(define except (begin body))
(if (and
(pair? except)
(eq? (car except) 'exception))
(handling except)
)
)
)
)
)
; returns an exception '(exception, "Error messenge")
(define (exception-content msg throw)
(throw (cons 'exception msg)))
; throw an exception if n = 0
(define (reciprocal n throw)
(if (= n 0)
(exception-content "Div 0 error" throw)
(/ 1 n)
)
)
; f1(n) = reciprocal(n) + 1
(define (f1 n throw)
(+ (reciprocal n throw) 1)
)
; main program
(try ; with call/cc and the continuation variable "throw"
(call-with-current-continuation
(lambda (throw)
(display (f1 2 throw))
(newline)
(display (f1 0 throw))
; the following won't be executed
(newline)
(display (f1 1 throw))
)
)
catch
; exception handling
(lambda (exception)
(display (cdr exception))
)
)
打印结果为:
3/2
Div 0 error