作为标准,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
的程序,if
对 cond
.
的程序
我猜唯一的其他方法是使用 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))
或者任何你想要的。
我发现 let
的括号太多了。例如,在编写以下代码块时,很容易错放 let
的许多右括号。
(define (adder n)
(let ((a 1))
(+ a n)))
所有这些括号对于巨大的 let
块来说显然是必需的,但对于较小的调用来说它们感觉多余。 Scheme 是否有语法糖来处理简单的 let 调用?例如,我只想在本地绑定一个变量的情况怎么办?我考虑过 define
,但显然是 dangerously dependent on your choice of implementation。是否有任何不存在该缺陷的内置解决方案?我宁愿不必编写宏。本质上,我正在寻找 let
的程序,if
对 cond
.
我猜唯一的其他方法是使用 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))
或者任何你想要的。