Scheme 方案重写let*为嵌套的一元let

Scheme 方案重写let*为嵌套的一元let,scheme,racket,let,rewriting,Scheme,Racket,Let,Rewriting,我编写了一个函数match rewriter,它本质上是match lambda,但如果找不到匹配项,它将返回其参数: (define-syntax match-rewriter (syntax-rules () ((_ (patt body) ...) (λ (x) (match x (patt body) ... (_ x)))))) 现在我想使用match rewriter获取表示let*源代码的字符串,并将其重写为嵌套的一元数let: (define let*→

我编写了一个函数
match rewriter
,它本质上是
match lambda
,但如果找不到匹配项,它将返回其参数:

(define-syntax match-rewriter
  (syntax-rules ()
    ((_ (patt body) ...)
      (λ (x) (match x (patt body) ... (_ x))))))
现在我想使用
match rewriter
获取表示
let*
源代码的字符串,并将其重写为嵌套的一元数
let

(define let*→nested-unary-lets
  (match-rewriter (`(let*((,<var> ,<val>) ...) ,<expr1> ,<expr2> ...)
在我看来,这应该是:

(let* ((b (+ a 1)) (c (+ a b)))

另外,如果调用
让*→嵌套的一元let
将执行,而不只是作为文本打印。

以下是
语法规则中的
let*
的定义
-类似于可用于编写自己版本的伪代码:

(let* ((a b) (c d) ...) body ...) === (let ((a b)) (let* ((c d) ...) body ...))
(let* () body ...) === body

您应该能够使用
match
将其转换为函数,或者使用
语法规则将其转换为宏,这是
语法规则中的
let*
的定义,类似于可用于编写自己版本的伪代码:

(let* ((a b) (c d) ...) body ...) === (let ((a b)) (let* ((c d) ...) body ...))
(let* () body ...) === body

您应该能够使用
match
将其转换为函数,或者使用
语法规则将其转换为宏。是的,您可以这样做;这应该不会太难。具体来说,这里您需要的关键思想是不要试图同时处理整个列表。相反,您的模式应该将第一个绑定与其余绑定分开,然后将一个let封装在一个递归调用中,以let*->嵌套的一元let


如果您在制定此公式时遇到问题,请告诉我。

是的,您可以这样做;这应该不会太难。具体来说,这里您需要的关键思想是不要试图同时处理整个列表。相反,您的模式应该将第一个绑定与其余绑定分开,然后将一个let封装在一个递归调用中,以let*->嵌套的一元let


如果您在制定此方案时遇到困难,请告诉我。

这将涉及到很多问题。编译器可以做到这一点,但这并不简单。考虑< <代码> <代码>引用>代码> <代码>。你必须做不动点分解。但愿我有时间向您介绍更多详细信息。@luqui:let*
中不允许向前引用——您只能引用前面的变量。如果
var1
在任何地方使用变量
var2
,它将引用
let*
@Jeremiah之外的绑定,哦,那应该很容易
let*
递归的方法对吗?我假设在哈斯凯尔工作得像
let
。谢谢你的澄清。@luqui:是的,
let*
是递归的,我同意这应该很容易做到。不,是递归的。这将非常复杂。编译器可以做到这一点,但这并不简单。考虑< <代码> <代码>引用>代码> <代码>。你必须做不动点分解。但愿我有时间向您介绍更多详细信息。@luqui:let*中不允许向前引用——您只能引用前面的变量。如果
var1
在任何地方使用变量
var2
,它将引用
let*
@Jeremiah之外的绑定,哦,那应该很容易
let*
递归的方法对吗?我假设在哈斯凯尔工作得像let。谢谢你的澄清。@luqui:是的,
let*
是递归的,我同意这应该很容易做到。不,是递归的。谢谢。我考虑过这一点,但我不确定是否可以递归地进行模式匹配——我认为这需要某种letrec转换。您知道有没有一种方法可以使模式匹配的参数成为可选的吗?我试图将cond写为if语句,但我不知道如何使else子句在模式匹配中成为可选的。是的,我肯定在这方面遇到了问题。请看我对原始问题的编辑,以获得最佳猜测。好的。我已经找到了模式。我唯一剩下的问题是是否有可能对let进行递归调用*→嵌套一元让我们评估。嘿:你会考虑检查这个“检查”框旁边(或其他)的答案吗?这会给你一种温暖模糊的感觉,让我投票支持Eli的同义词提案。谢谢。我考虑过这一点,但我不确定是否可以递归地进行模式匹配——我认为这需要某种letrec转换。您知道有没有一种方法可以使模式匹配的参数成为可选的吗?我试图将cond写为if语句,但我不知道如何使else子句在模式匹配中成为可选的。是的,我肯定在这方面遇到了问题。请看我对原始问题的编辑,以获得最佳猜测。好的。我已经找到了模式。我唯一剩下的问题是是否有可能对let进行递归调用*→嵌套一元让我们评估。嘿:你会考虑检查这个“检查”框旁边(或其他)的答案吗?这会给你一种温暖模糊的感觉,让我投票支持Eli的同义词提案。
(let* ((b (+ a 1)) (c (+ a b)))
(let* ((a b) (c d) ...) body ...) === (let ((a b)) (let* ((c d) ...) body ...))
(let* () body ...) === body