5

我经常看到它认为不应该使用重度嵌套的函数调用,因为它们不可读。然而,使用临时变量反而会产生很多不必要的冗长,并迫使读者在心理上将每个临时变量与其所代表的内容联系起来。在查看 Lisp 代码通常格式化的方式时,我突然想到,如果您格式化它们以反映嵌套,嵌套函数调用实际上可以变得非常可读。例如:

// Totally unreadable:
auto linesIter = filter!"a.length > 0"(map!strip(File(filename).byLine())))


// Perfectly readable.  The only difference is formatting.
auto linesIter = filter!"a.length > 0"(
    map!strip(
         File(filename).byLine()
    )
);

// Readable, but unnecessarily verbose:
auto rawLines = File(filename).byLine();
auto stripped = map!strip(rawLines);
auto filtered = filter!"a.length > 0"(stripped);

以嵌套函数形式编写类似于第一个示例的内容,恕我直言,相当于在更多过程式代码中执行以下操作:

for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) { if(x < 2) { z++; } else { y++; }}}

在这两种情况下,真正的问题是格式不正确,而不是过度嵌套。您如何评价格式良好的嵌套函数版本与临时变量版本的可读性/可理解性?你是否认为繁重的函数调用嵌套是不好的风格,即使它被格式化以获得最大的可读性?如果是这样,为什么?

4

5 回答 5

2

您说“使用临时变量反而会产生很多不必要的冗长,并迫使读者在心理上将每个临时变量与其所代表的内容联系起来”——但 IMO 这只是另一种说法,即您已将事物分解为步骤读者可以一次理解一个——换句话说,你让它更具可读性。

我很高兴添加一个额外的变量来将一长串分成单独的步骤(您的示例 3),但对我来说关键是您是否可以将事情干净地分解成真正的步骤。一个好的指标是你是否能找到一个好的变量名;如果你不能,也许这不是一个真正需要拆分的单独步骤。

您的示例 2 没有什么问题,但比这要长得多,我当然会分解它。当涉及到调试时,你会感谢自己...

于 2010-02-04T23:23:12.297 回答
2

我认为以使用格式的方式破坏大型嵌套函数调用没有任何问题。它是可读的,这是意图。

对于临时变量,我尽量避免使用它们。唯一的原因很简单,我完全没有能力给他们起好名字。我在绝对必要的时候尝试,最后浪费了 5 到 10 分钟的时间来思考“什么是做 cor blimey 的 blah blah 的好名字”?buffer如果它是一个数组,或者temp它是一个标量等 ,几乎总是最终放弃和使用。

也就是说,使用嵌套结构,函数代表动词,而不是动词动作的产物,这是使用临时变量得到的结果。使用临时变量,您确实有机会为该产品命名。但是,如果它是由动词和直接宾语本身( )更好地描述的事物,verb(directObject)那么这就是您应该采取的路线。

于 2011-03-07T05:27:37.077 回答
1

恕我直言,应仔细选择对象和名称,以便在您执行函数式编码(如第一个示例中那样将所有内容都放在一条线上)时,事情是可读的。如果它完全不可读,则有人选择了坏名字。您的目标是,如果某些东西看起来不对,通常意味着存在错误。

在现实世界中,当您必须处理那些选择不当的名称时,创建具有适当名称的临时常量(甚至例程)以稍微清理一下并没有什么问题。它胜过注释,因为它可以编译并且更容易修改。

于 2010-02-04T23:34:14.070 回答
0

我不喜欢使用太多变量 b/c 它们通常是错误的来源。如果我可以将某事表达为一个单一的表达方式,我更喜欢这种方式。我可能会选择你的第二个例子。

于 2010-02-04T08:58:21.383 回答
0

我个人认为,如果没有性能惩罚,可读性更重要。虽然我对 Lisp 语法一无所知,但看起来您的示例进行了相同数量的调用?如果是这样,请以可读的方式进行。但是如果你在一个循环中多次调用一个繁重的函数(比如打开一个文件并一次又一次地读取),你应该避免它。我希望这个答案是有用的。

于 2010-02-02T16:50:17.797 回答