重复使用匿名函数Common Lisp vs. Scheme

时间:2017-04-11 23:30:57

标签: scheme common-lisp

我正在通过Little Schemer工作,我正在尝试将所有答案转换为Common Lisp。 在第8章中,讨论了匿名函数,以及返回匿名函数。 例如:

(define insertL-f
    (lambda (test?)
        (lambda (new old l)
            (cond
                ((null? l) (quote ()))
                ((test? (car l) old) (cons new l)))
                (else (cons (car l) ((insertL-f test?) new old (cdr l))))))))

我的代码:

(defun insertL-f (test)
    (lambda (new old l)
        (cond
            ((null l) '())
            ((funcall test (car l) old) (cons new l))
            (t (cons (car l) (insertL-f test) new old (cdr l))))))

问题是第二个代码块的最后一行。我得到错误“太多的缺点参数”但我不能添加额外的一对括号,如Scheme代码。这种递归方式在Common Lisp中是不可能的吗?

2 个答案:

答案 0 :(得分:2)

Registration.aggregate([
    {
        "$group": {
            "_id": { 
                "day": "$day", 
                "group": "$group",
                "division": "$division",
                "level": "$level"
            },
            "count": { "$sum": 1 }
        }
    },
    { $project: { count:1,  nets: { $ceil : { $divide: [ "$count" , 5 ] } } } },
    {
        "$group": {
            "_id": { 
                "day": "$_id.day", 
                "group": "$_id.group",
                "division": "$_id.division"                
            },
            "count": { "$sum": "$count" },
            "nets": { "$sum": "$nets" },
            "levels": {
                "$push": {
                    "level": "$_id.level",
                    "teams": "$count",
                    "nets" : "$nets"
                }
            }
        }
    },
    {
        "$group": {
            "_id": { 
                "day": "$_id.day", 
                "group": "$_id.group"             
            },
            "count": { "$sum": "$count" },
            "nets": { "$sum": "$nets" },
            "divisions": {
                "$push": {
                    "division": "$_id.division",
                    "count": "$count",
                    "nets:": "$nets",
                    "levels": "$levels"
                }
            }
        }
    }
])

答案 1 :(得分:2)

insertL-f返回一个函数,在你的Scheme版本中你应用它,而在CL中已经扁平化了列表,而不是用funcall应用它但是看起来要返回的函数等于它所提取的那个,所以你可以通过labels本地定义它来缓存它:

(defun insert-l-f (test)
  (labels ((func (new old l)
             (cond
               ((null l) '())
               ((funcall test (car l) old) (cons new l))
               (t (cons (car l) (func new old (cdr l)))))))
    #'func))

使用本地define(实际上是具有更平坦语法的letrec)的方案中的相同内容:

(define (insert-l-f test?)
  (define (func new old l)
    (cond
      ((null? l) (quote ()))
      ((test? (car l) old) (cons new l)))
      (else (cons (car l) (func new old (cdr l)))))
  func)