鸡计划;在函数内部使用let时出错

时间:2017-11-24 19:28:15

标签: scheme chicken-scheme

这段代码有什么问题?

(define (make-node key data )
        (list key data 'null 'null ) )

(define (right)(2) )
(define (left) (3) )          
;;inserts a key to the tree
;; string x string ->  list 
(define (insert lst key data )
          (if (null? lst )
               (make-node key data )
               (cond ( [(string>? key (car lst))  (list-set lst 2 (insert lst key data))  ]
                       [(string<? key (car lst))  (list-set lst 3 (insert lst key data))   ]
                       [(string=? key (car lst))  (list-set lst 1 data )   ]
                      ))))

 (define (list-set lst ix data )   
          (if (eqv? ix 0 ) ( cons data (cdr lst )  ) ( cons (car lst)  (list-set ( cdr lst) ( - ix 1 )  data ))))         


( define (newdiction) [   
                        let ( ( [ tree '() ]) [ (msg  key data  )[ cond ( (eqv? msg 'insert ) [ set! tree (insert tree key data )    ]   ) ] ] )
                         ] )

鸡计划翻译吐:

CHICKEN
(c) 2008-2014, The Chicken Team
(c) 2000-2007, Felix L. Winkelmann
Version 4.9.0.1 (stability/4.9.0) (rev 8b3189b)
linux-unix-gnu-x86-64 [ 64bit manyargs dload ptables ]
bootstrapped 2014-06-07
; loading dict.scm ...
Error: during expansion of (let ...) - in `let' - symbol expected: (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg (quote insert)) (set! tree (insert tree key data)))))))
    Call history:
    <syntax>      (define (list-set lst ix data) (if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst...
    <syntax>      (##core#set! list-set (##core#lambda (lst ix data) (if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst...
    <syntax>      (##core#lambda (lst ix data) (if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst...
    <syntax>      [list-set] (##core#begin (##core#if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst) (- ix...
    <syntax>      [list-set] (##core#if (eqv? ix 0) (cons data (cdr lst)) (cons (car lst) (list-set (cdr lst) (- ix 1) data)))
    <syntax>      [list-set] (eqv? ix 0)
    <syntax>      [list-set] (cons data (cdr lst))
    <syntax>      [list-set] (cdr lst)
    <syntax>      [list-set] (cons (car lst) (list-set (cdr lst) (- ix 1) data))
    <syntax>      [list-set] (car lst)
    <syntax>      [list-set] (list-set (cdr lst) (- ix 1) data)
    <syntax>      [list-set] (cdr lst)
    <syntax>      [list-set] (- ix 1)
    <syntax>      (define (newdiction) (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg (quote insert)) (set......
    <syntax>      (##core#set! newdiction (##core#lambda () (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg...
    <syntax>      (##core#lambda () (let (((tree (quote ()))) ((msg key data) (cond ((eqv? msg (quote insert)) (set! t......    <--

1 个答案:

答案 0 :(得分:2)

此代码含有太多括号。因此Scheme非常灵活,因此您可以使用以下代码:

((som-func som-arg) some-other-arg)

那里发生了什么?好。由于(some-func som-arg)不是特殊形式或宏,因此它必须是一个导致函数的表达式,因此它会被评估。由于some-func不是特殊形式或宏,因此它必须是一个导致函数的表达式,因此它会将其和some-arg进行转换并应用它。结果将是以some-other-arg的评估作为参数调用的函数。

我看到您使用[ ... ]以及( ... )。要知道它们之间的区别只是它们的外观和对它们的解释是相同的。因此,如果您将(+ 1 2)更改为[+ 1 2],则两次都会获得3。没有不同。您可以使用它们来表示某些类型的分组,例如let,但它对实现没有任何影响。

如果你看看let

(let ([(tree '())] ...)
  body ...)

所以第一个变量是(tree '())没有值 ..但(tree '())不是符号而是列表。

(let ([tree '()] ...)
  body ...)

此处tree绑定到'()。看到? 现在先查看cond你有一个一词。通常cond有两个以上,否则简单的if就足够了。一个术语中的谓词是:

[(string>? key (car lst)) (list-set lst 2 (insert lst key data))]

现在没有额外的( ... )整个事情,上面的整个代码将成为一个术语,而不是只是播放一个谓词。

但请坚持..为什么你有cond ifcondif-elseif-else。有没有办法让整件事cond?是!这与cond

相同
(define (insert lst key data)
  (cond
    [(null? lst) (make-node key data)]
    [(string>? key (car lst)) (list-set lst 2 (insert lst key data))]
    [(string<? key (car lst)) (list-set lst 3 (insert lst key data))]
    [else (list-set lst 1 data)]))

我还注意到你检查它是否小于,大于等于,但没有else(替代)所以我假设它不小于或大于它必须相等,因此一切因为你现在有一个完整的维恩图,所以在最后一个学期。