作为标准,Scheme 是否有任何语法糖用于简单的 let 调用?

As standard, does Scheme have any syntactic sugar for trivial calls to let?

我发现 let 的括号太多了。例如,在编写以下代码块时,很容易错放 let 的许多右括号。

(define (adder n)
    (let ((a 1))
        (+ a n)))

所有这些括号对于巨大的 let 块来说显然是必需的,但对于较小的调用来说它们感觉多余。 Scheme 是否有语法糖来处理简单的 let 调用?例如,我只想在本地绑定一个变量的情况怎么办?我考虑过 define,但显然是 dangerously dependent on your choice of implementation。是否有任何不存在该缺陷的内置解决方案?我宁愿不必编写宏。本质上,我正在寻找 let 的程序,ifcond.

的程序

我猜唯一的其他方法是使用 lambda:

((lambda (a) (+ a n) 1)

但是:

I find that let has too many brackets.

您可能需要切换到另一种语言(这听起来可能很刺耳,但我的意思是友好的)。如果括号的数量太多,您可能会更喜欢总体上括号较少的语言,因为在 Scheme 中,再多的宏也无法消除括号是常见字符的事实。

[...] it was very easy to misplace lets many closing brakcets.

如果您在不突出显示匹配括号 不缩进嵌套形式的编辑器中编写代码,则可能会出现这种情况。因为在支持 Lisp 和 Scheme 的编辑器中(例如 Emacs),错放括号通常不会有风险(或者至少,如果(自动)缩进在左边或右边太多,那么很快就会出现错误) .

你有宏:你只需要发明你想要的语言。

例如,这个简单的 with 形式怎么样:

(define undefined #f)

(define-syntax with
  (syntax-rules ()
    ((_ (var val) form ...)
     (let ((var val)) form ...))
    ((_ (var) form ...)
     (let ((var undefined)) form ...))
    ((_ var form ...)
     (let ((var undefined)) form ...))))

现在

(with (a 2) ...)

(with (a)
  ;; a is undefined initially
  ...)

(with a
  ;; same as previous
  ...)

会好的

或者你可以得到更多的幻想(下面是用 Racket 的 R5RS 语言进行的最低限度测试,并且绝对没有捕捉到我认为的所有函数定义语法):

(define-syntax binding
  (syntax-rules (bind)
    ((_ (bind (f arg ...) body ...) form ...)
     (letrec ((f (lambda (arg ...) body ...))) (binding form ...)))
    ((_ (bind (f . arg) body ...) form ...)
     (letrec ((f (lambda arg body ...))) (binding form ...)))
    ((_ (bind var val) form ...)
     (letrec ((var val))
       (binding form ...)))
    ((_ form)
     form)
    ((_ form1 form ...)
     (begin form1 (binding form ...)))))

现在你可以说

(binding
 (display "here")
 (bind a 2)
 (display "there")
 (bind (f) (display a))
 (f)
 a)

例如。然后你可以添加

(define-syntax define/binding
  ;; Does not get all the possible fn definition syntaxes for sure
  (syntax-rules ()
    ((_ var val)
     (define var val))
    ((_ (f arg ...) body ...)
     (define (f arg ...)
       (binding body ...)))
    ((_ (f . arg) body ...)
     (define (f . arg)
       (binding body ...)))))

现在

(define/binding (ts x)
  (display x)
  (bind x^2 (* x x))
  (+ x x^2))

或者任何你想要的。