Common lisp lisp-sbcl中正确的函数式编程方法

Common lisp lisp-sbcl中正确的函数式编程方法,common-lisp,Common Lisp,我正在写一个粗糙的人工智能程序。我很高兴我的程序能够以一种允许逻辑操作的方式归档新单词。在我开始扩展程序的逻辑能力之前,我用我所理解的函数式编程重新编写了它。在我前进之前,我需要一个坚实的基础任何批评或见解都将不胜感激,因为我相信良好的编程。我已经改写了这一点,我是交叉的眼睛,但目前它的工作。 (很抱歉,我已多次转发,无法正确格式化代码) 在构造对象时,您可以使用语法糖或list*,并且大多数情况下不需要cons: (defun with-branch (word) `(,word ((un

我正在写一个粗糙的人工智能程序。我很高兴我的程序能够以一种允许逻辑操作的方式归档新单词。在我开始扩展程序的逻辑能力之前,我用我所理解的函数式编程重新编写了它。在我前进之前,我需要一个坚实的基础任何批评或见解都将不胜感激,因为我相信良好的编程。我已经改写了这一点,我是交叉的眼睛,但目前它的工作。 (很抱歉,我已多次转发,无法正确格式化代码)


在构造对象时,您可以使用语法糖或
list*
,并且大多数情况下不需要cons:

(defun with-branch (word)
  `(,word ((unk) ((unk)))))
这表明您可能应该在某个地方描述此数据结构的外观

ABCphrase
中,您可以使用
if
代替
cond
,或者至少使用
t
作为“否则”情况的测试。还请注意,默认情况下Lisp符号不区分大小写(严格来说,它们在读取时转换为大写)

您可能会将对
ABCphrase-x
的处理转换为三个嵌套循环,并生成一个函数
sure list
,该函数将
a
转换为
(a)
并将
(a)
转换为
(a)

这就是我现在要去的地方。至于功能性风格,尽管您似乎没有对汽车和CDR进行太多的更改,但您正在进行大量的全局状态变化
(setf符号值)
特别严重,可能会导致问题(例如,如果您试图让
pi
成为某事物的同义词,该怎么办?

一些指针:

  • 使用文件保存代码。有许多编程环境将编辑器与REPL连接相结合,这样您就可以直接向REPL发送顶级表单
  • 样式:整个文件的注释在每行开始处有四个半线(对于节或顶级表单3,所有其他注释在第2行,行结束注释1)
  • 样式:保留80列文本,这样就不必横向滚动
  • 错误:不使用
    setf
    引入全局变量。使用
    defvar
    defparameter
    (还有
    defcontain
    ,但现在让我们坚持基本原则)
    Setf
    用于修改位置,而不是创建位置

    (defvar *vobabulary* ())
    
  • 我看不出除了
    nil
    之外,您在哪里设置了
    sym

  • Lisp直接支持可选参数:

    (defun learn (a b c &optional (origin "none")
      …)
    
  • 样式:将实体缩进两个空格,对齐函数调用的参数

  • 样式:默认情况下,Lisp在读取名称时更新名称,因此
    ABCphrase
    变为
    ABCphrase
    ——驼峰大小写在这里没有意义。带连字符的组合符号结构:
    abc短语
  • abc短语
    中,您可以通过使用
    确保列表
    帮助器(制作您自己的,或使用
    alexandria
    库中的帮助器),使所有必需的参数更加明显:

  • 使用
    if
    可以更清楚地编写简单的双分支条件

  • 使用字符串作为单词。符号是程序员使用的,而不是用户数据。当有人输入
    *vocab*
    sym
    作为单词符号时会发生什么
  • 与此相关,使用
    :test#“equal
    哈希表(或alist)作为关联数据结构,而不是符号单元
  • 不要从用户输入中
    读取
    (或
    从字符串读取
    )。只要使用字符串
  • 只有在列表中尚未添加元素时,才可以使用
    pushnew
    将其添加到列表中
  • 努力消除代码中的所有拼写错误和拼写错误,以避免混淆(你是说“相互的”?)
  • 我强烈建议不要从处理逻辑回到用户交互。如果你需要得到倒数,首先在完全处理了原始短语之后再做。处理逻辑可能会返回一个指示符,表明这是必需的,可能是一个附加值
  • 至少要准确地记录
    with branch
    返回的数据结构是如何工作的。更好:使用
    defstruct
    defclass
    创建显式结构
  • 为函数使用文档字符串

我认为您的问题更适合于。代码中有几个括号错误。例如,RESOLVE-WORD,但还有其他的。谢谢大家,我将此移到code.review.stackexchange,正如Renzo所建议的那样。这些都是非常有用的建议。我很兴奋能重写这段代码。谢谢你,斯万特
(defun learn (a b c &optional (origin "none")
  …)
(let ((a (ensure-list a))
      (b (ensure-list b))
      (c (ensure-list c)))
  …)