函数式编程语法优化

时间:2013-03-18 11:40:27

标签: syntax functional-programming

考虑这个示例函数:

第一个示例

;;; 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. 编程时我是否更喜欢代码可读性或正确的代码语法(是否取决于深度级别)?

1 个答案:

答案 0 :(得分: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)))