一些重构我的Common Lisp代码的策略

时间:2018-07-13 22:45:06

标签: common-lisp clisp

我是Haruo。我的荣幸是解决Common Lisp(CLISP)中的SPOJ。今天我解决了古典/障碍!但在SBCL中不是CLISP。由于运行时错误(NZEC),我的CLISP提交失败。

我希望我的代码变得更加复杂。今天的问题只是一个机会。请遵循以下代码,并告诉我您的重构策略。我相信你。

https://github.com/haruo-wakakusa/SPOJ-ClispAnswers/blob/0978813be14b536bc3402f8238f9336a54a04346/20040508_adrian_b.lisp

春男

2 个答案:

答案 0 :(得分:4)

get-x-depth-for-yz-grid为例。

(defun get-x-depth-for-yz-grid (planes//yz-plane grid)
  (let ((planes (get-planes-including-yz-grid-in planes//yz-plane grid)))
    (unless (evenp (length planes))
      (error "error in get-x-depth-for-yz-grid"))
    (sort planes (lambda (p1 p2) (< (caar p1) (caar p2))))
    (do* ((rest planes (cddr rest)) (res 0))
         ((null rest) res)
      (incf res (- (caar (second rest)) (caar (first rest)))))))

样式-> ERROR可以用ASSERT代替。

可能的错误-> SORT可能具有破坏性->确保您拥有一份新鲜的清单!如果它已经由get-planes-including-yz-grid-in分配了,那么我们不需要。

错误-> SORT返回排序列表。排序的列表可能不是副作用。 ->使用返回的值

样式->用LOOP代替。

样式-> CAAR的含义不清楚。查找更好的命名或使用其他数据结构。

(defun get-x-depth-for-yz-grid (planes//yz-plane grid)
  (let ((planes (get-planes-including-yz-grid-in planes//yz-plane grid)))
    (assert (evenp (length planes)) (planes)
      "error in get-x-depth-for-yz-grid")
    (setf planes (sort (copy-list planes) #'< :key #'caar))
    (loop for (p1 p2) on planes by #'cddr
          sum (- (caar p2) (caar p1)))))

答案 1 :(得分:2)

  1. 某些文档比重构有更大的进步。
  2. 您的->宏会混淆sbcl的类型推断。您应该将(-> x)扩展为x,将(-> x y...)扩展为(let (($ x)) (-> y...))
  3. 您应该学习使用loop,并在更多地方使用它。发生额外突变的dolist不好
  4. 在许多地方,您应该使用destructuring-bind而不是(rest (rest ))。您也不一致,有时您会为此写(cddr...)
  5. 您的block*遇到许多问题:
    1. 它使用(let (foo) (setf foo...))来触发sbcl类型推断。
    2. 名称block*意味着各种绑定的范围都可以引用以前定义的东西,但实际上所有初始值都可以引用任何变量或函数名称,并且该变量尚未初始化。然后计算结果为零。
  6. 与Common Lisp相比,在另一个函数可以位于外部时在其中定义许多函数的样式更常见(它具有语法)的方案。
  7. get-x-y-and-z-ranges确实需要使用loop。我认为也是错的:列表的长度不同。
  8. 您需要定义一些访问器函数,而不是使用first等。甚至可能是struct(!)
  9. (sort foo)可能会破坏foo。您需要执行(setf foo (sort foo))
  10. 基本上没有理由使用do。使用loop
  11. 您可能应该在一些地方使用:key
  12. 您写了defvar,但我想您的意思是defparameter
  13. *t*是一个愚蠢的名字
  14. 大多数名字都是不好的,似乎并没有告诉我发生了什么事。
  15. 我可能是个白痴,但我根本无法说出您的程序在做什么。它可能可以完成很多工作