【问题标题】:As standard, does Scheme have any syntactic sugar for trivial calls to let?作为标准,Scheme 是否有任何用于调用 let 的语法糖?
【发布时间】:2021-05-05 16:16:15
【问题描述】:

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

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

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

【问题讨论】:

  • 在 Common Lisp 中你可以这样做,例如,(let (a b c) ;; body)abc 都将绑定到 nil。或者你可以使用(let (a (b 2) c) ;; body) 来获得nil 绑定,但b 绑定到2。

标签: scheme let


【解决方案1】:

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

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

但是:

我发现 let 的括号太多了。

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

[...] 很多右括号很容易放错地方。

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

【讨论】:

【解决方案2】:

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

例如,这个简单的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))

或任何你想要的。

【讨论】:

    猜你喜欢
    • 2016-05-25
    • 1970-01-01
    • 2014-02-20
    • 2011-12-23
    • 2011-06-05
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多