Scheme 如何计算单独代码文件中if语句的数量

Scheme 如何计算单独代码文件中if语句的数量,scheme,Scheme,我正试图编写一个scheme程序来计算包含代码的文件中if语句的数量。我知道如何读取文件,但我不知道如何计算if语句的数量。一种简单的方法可以是如下递归结构: (define (count-ifs exp) (+ (if-expression? exp 1 0))) (if (pair? exp) (+ (count-ifs (car exp)) (count-ifs (cdr exp)))) 0))) 但这可能算得太多了 更正确的方法是通过检

我正试图编写一个scheme程序来计算包含代码的文件中if语句的数量。我知道如何读取文件,但我不知道如何计算if语句的数量。

一种简单的方法可以是如下递归结构:

(define (count-ifs exp)
  (+ (if-expression? exp 1 0)))
     (if (pair? exp)
         (+ (count-ifs (car exp)) (count-ifs (cdr exp))))
         0)))
但这可能算得太多了


更正确的方法是通过检查您看到的每种类型的表达式来处理代码,当您输入lambda时,您需要添加绑定到阴影符号列表的变量。

一种简单的方法可以是如下递归结构:

(define (count-ifs exp)
  (+ (if-expression? exp 1 0)))
     (if (pair? exp)
         (+ (count-ifs (car exp)) (count-ifs (cdr exp))))
         0)))
但这可能算得太多了


一种更正确的方法是通过检查您看到的每种类型的表达式来处理代码——当您输入lambda时,您需要添加绑定到阴影符号列表的变量。

如果不实际实现将语言简化为更原始的形式,这是非常困难的。例如,想象一下:

<代码>(计算ifs'(let((if+)) (如果1 2 3))) ; ==> 0
0
是正确的数量,因为
if
是绑定阴影
if
并且Scheme支持阴影,因此该表达式的结果是
6
而不是
2
<代码>let可以重写,以便您可以改为检查:

(计算ifs'((lambda(if))
(如1、2、3)
+))
; ==> 0
这看起来可能不是一个改进,但在这里您可以实际修复它:

(定义(计数ifs expr)
(let helper((expr expr)(计数0))
(如果(或(不是)(列表?expr))
(和(eq?(汽车出口)λ)
(memq'if(cadr expr)))
计数
(foldl)助手
(如果(等式)(汽车出口)‘如果’
(添加1个计数)
计数)
expr)))
(计算ifs’((λ(if))
(如1、2、3)
(如果#t+(如果)))
; ==> 2.

挑战是扩展宏。实际上,您需要制作一个宏扩展器来重写代码,这样唯一的表单生成绑定就是
lambda
。这与制作80%的Scheme编译器的工作量是一样的,因为一旦你把它简化了,剩下的就很容易了

如果不真正实现将语言简化为更原始的形式,这是非常困难的。例如,想象一下:

<代码>(计算ifs'(let((if+)) (如果1 2 3))) ; ==> 0
0
是正确的数量,因为
if
是绑定阴影
if
并且Scheme支持阴影,因此该表达式的结果是
6
而不是
2
<代码>let可以重写,以便您可以改为检查:

(计算ifs'((lambda(if))
(如1、2、3)
+))
; ==> 0
这看起来可能不是一个改进,但在这里您可以实际修复它:

(定义(计数ifs expr)
(let helper((expr expr)(计数0))
(如果(或(不是)(列表?expr))
(和(eq?(汽车出口)λ)
(memq'if(cadr expr)))
计数
(foldl)助手
(如果(等式)(汽车出口)‘如果’
(添加1个计数)
计数)
expr)))
(计算ifs’((λ(if))
(如1、2、3)
(如果#t+(如果)))
; ==> 2.
挑战是扩展宏。实际上,您需要制作一个宏扩展器来重写代码,这样唯一的表单生成绑定就是
lambda
。这与制作80%的Scheme编译器的工作量是一样的,因为一旦你把它简化了,剩下的就很容易了