LISP中的函数式编程 [英] Functional programming in LISP

查看:121
本文介绍了LISP中的函数式编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习函数编程,这对我来说有点困惑,我现在有一个任务:从具有列表的行中删除所有重复项,因此:
输入行:

i just have started to learn function programming and it is a bit confusing for me, i have a task now: remove all duplicates from the row with lists, so: input row:

(SETQ X (LIST  2 -3 (LIST 4 3 0 2) (LIST 4 -4) (LIST 2 (LIST 2 0 2))-3)) 

我希望输出如下:(2 -3(4 3 0)(- 4)())
我想通过递归来实现。
我有一些概念性问题:如何从列表中删除一个元素,或者应该为输出添加一个新元素?在其他编程语言中,递归的每个步骤都有其自己的变量范围,在这里是否一样?拜托,您能描述一下您的方式吗?

I want output be like this : (2 -3 (4 3 0)(-4)()) I want to make it with recursion. I have some conceptual questions: how can i remove an element from list or i should make a new one for output? In other programming languages every step of recursion has it own scope for variables, is it same here? Please, can you describe the way, how would you do this?

顺便说一句,我正在尝试运行以下代码:

Btw, i am trying to run this code:

(SETQ X (LIST  2 -3 (LIST 4 3 0 2) (LIST 4 -4) (LIST 2 (LIST 2 0 2))-3))(DEFUN SEARCHDEEP (WHAT WHERE)
(COND
    ((NULL WHERE) NIL)
    (T (OR 
            (COND 
                ((ATOM (CAR WHERE)) (EQUAL WHAT (CAR WHERE)))
                (T (SEARCHDEEP WHAT  (CAR WHERE)))
            )
            (SEARCHDEEP WHAT (CDR WHERE))
        )
    )
))

(DEFUN REMDOUBLES (INPUT OUTPUT)(
(COND 
    ((NULL INPUT) NILL)
    (T 
        (REMDOUBLES (CDR INPUT) OUTPUT)
        (PRINT INPUT)
    )
)))


(REMDOUBLES X NIL)

但是我收到此错误,这是什么意思?

But i am getting this error, what does it mean?

SYSTEM ::%EXPAND-FORM:(COND((NULL INPUT)NILL)(T(REMDOUBLES(CDR INPUT)OUTPUT)(PRINT INPUT)))应该是lambda expres sion

推荐答案

在函数式编程中,您不会从参数中删除元素,因此您肯定会创建一个新列表,但是在许多情况下,您可以共享参数和结果相同的结构(尾部)。

In functional programming you don't remove elements from the arguments so you most definitely will make a new list, however in many cases you can share structure (tails) that are the same in the argument and the result.

Common Lisp在词法上是作用域上的。这意味着,除了绑定变量之外,还知道函数创建时存在的自由变量以及全局范围,绑定变量对于每次使用都是无约束的,就像您可能知道的其他语言一样。

Common Lisp is lexically scoped. That means that free variables that existed when the function was created plus the global scope is known in addition to bound variables, which would be bound unqiuely for each use just like the other languages you might know.

某些东西应该是lambda表达式是当您尝试使表达式位于运算符位置时的常见Lisp错误。例如。方案代码((如果(< x 10)+-)5 10)变为 15 -5 基于操作数位置表达式的计算结果。在Common lisp中,您可以使用一个符号,例如。例如(+ 1 2)中的 + 或lambda例如。 ((lambda(x)(* x x))10)。您尝试了((cond ...)),该方法在Scheme中有效,但在Common Lisp中不起作用。在Common Lisp中,您需要执行(funcall(如果(< x 10)#’+#’-)5 10)。由于括号在C#中几乎被当作curl放置,所以我想它们放错了位置,就像有人在语句 someFun(arg)() someFun 不返回函数时。

"something should be a lambda expression" is a Common Lisp error when you try to have an expression in operator position. eg. the Scheme code ((if (< x 10) + -) 5 10) becomes either 15 or -5 based on what function the expression in operand position evaluates to. In Common lisp you can either have a symbol, eg. like + in (+ 1 2) or a lambda eg. ((lambda (x) (* x x)) 10). You tried ((cond ...)) which would work in Scheme but not in Common Lisp. In Common Lisp you need to do (funcall (if (< x 10) #'+ #'-) 5 10). Since the parentheses are almost put as curlies in C# I guess they are misplaced just as if someone would add a esxtra set of () in the end of a statement someFun(arg)() when someFun doesn't return a function.

我会这样解决您的代码:

I would have solved your code like this:

;; setq is for mutating, defparameter is a good option to make a global variable 
(defparameter *test* '(2 -3 (4 3 0 2) (4 -4) (2 (2 0 2)) -3))

(defun unique-elements (lst)
  (let ((h (make-hash-table :test 'equal)))
    (labels ((aux (lst)
               (cond ((null lst) '())
                     ((consp (car lst))
                      (let ((a (aux (car lst))))
                        (if (null a)
                            (aux (cdr lst)) ; don't include empty elements
                            (cons a (aux (cdr lst))))))
                     ((gethash (car lst) h)
                      (aux (cdr lst)))
                     (t (setf (gethash (car lst) h) t)
                        (cons (car lst) (aux (cdr lst)))))))
      (aux lst))))

(unique-elements *test*) ; ==> (2 -3 (4 3 0) (-4))

这篇关于LISP中的函数式编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆