0

考虑这个示例函数:

第一个例子

;;; Lisp
(defun foo (x y z)
  (let ((tmp))
    (setf tmp (operation1 x y z))
    (setf tmp (operation2 tmp y z))
    (setf tmp (operation3 tmp y z))
    (setf tmp (operation4 tmp y z))
    ...
    (setf tmp (operationN tmp y z))
    tmp))

// PHP
function foo($x, $y, $z)
{
  $tmp = operation1($x, $y, $z);
  $tmp = operation2($tmp, $y, $z);
  $tmp = operation3($tmp, $y, $z);
  ...
  return operationN($tmp, $y, $z);  
}

我的老师告诉我,在函数式编程中,我不应该将返回值存储在 temp 变量中,而是立即将其传递给下一个函数。

第二个例子

;;; Lisp
(defun foo (x)
  (operationN
    (... 
      (operation3
        (operation2
          (operation1 x y z) 
        y z)
       y z)
    y z)
  y z)
)

// PHP
function foo($x, $y, $z)
{
  return operationN(
    ...(
     operation3(
      operation2(
        operation1($x, $y, $z),
        $y, $z),
      $y, $z),
     $y, $z),
    $y, $z);
}

将此视为一个非常简单的示例,并且可能有其他函数应用于其余参数。在我看来,第一个例子更具可读性。

  1. 以函数式编程方式格式化此代码的正确方法是什么?
  2. 编程时我应该更喜欢代码可读性还是正确的代码语法(应该取决于深度级别)?
4

1 回答 1

3

代码变得笨拙通常表明单个函数被赋予了过多的责任。
在我看来,两种语言的“正确”方式是重构为更小的函数。

当然,这种重构取决于实际问题,但您的示例的一个简单细分可能是

(defun operations1-2 (x y z)
  (operation2 (operation1 x y z) y z))

(defun operations1-3 (x y z)
  (operation3 (operations1-2 x y z) y z))

(defun operations1-4 (x y z)
  (operation4 (operations1-3 x y z) y z))

...

(defun foo (x y z)
  (operationN (operations1-N-1 x y z) y z))

当然你不能总是以一种有意义的方式来做,但是还有顺序的 let-binding,它比深度嵌套的函数应用程序更好:

(defun foo (x y z)
  (let* 
      ((tmp (operation1 x y z))
       (tmp2 (operation2 tmp y z))
       (tmp3 (operation3 tmp2 y z))
       (tmp4 (operation4 tmp3 y z))
       (...))
    (operationN tmpN-1 y z)))
于 2013-03-18T13:01:52.597 回答