在Erlang中是否有一种惯用的方法来命令函数参数?

时间:2009-11-24 04:04:57

标签: erlang

似乎它在列表模块中不一致。例如,split将数字作为第一个参数,列表作为第二个参数,但是子列表将列表作为第一个参数,将len作为第二个参数。

2 个答案:

答案 0 :(得分:19)

好吧,我记得它的历史和我的风格背后的一些原则。

正如克里斯蒂安所说的那样,图书馆已经发展并倾向于得到争论的顺序,并感受到我们刚才所获得的冲动。因此,例如元素/ setelement具有参数顺序的原因是因为它匹配Prolog中的arg / 3谓词;合乎逻辑但不是现在。通常我们会首先处理 thing ,但不幸的是并非总是这样。这通常是一个很好的选择,因为它允许“可选”参数方便地添加到最后;例如string:substr / 2/3。使用 thing 作为最后一个参数的函数通常受到currying的函数式语言的影响,例如Haskell,它很容易使用currying和部分求值来构建特定函数,然后可以应用于。这在列表中的高阶函数中非常明显。

我们没有的唯一影响来自OO世界。 : - )

通常我们至少在模块中保持一致,但并非总是如此。再次查看列表。我们确实尝试了一些一致性,因此dict / sets中高阶函数的参数顺序与列表中相应函数的参数顺序相匹配。

由于我们特别是我对图书馆有着相当傲慢的态度,这个问题也更加严重。我只是没有把它们视为语言的卖点,所以我并不担心它。 “如果你想要一个能做某事的图书馆那么你只需要写一下”就是我的座右铭。这意味着我的库是结构化的,并不总是具有相同的结构。 :-)这就是有多少初始库出现的。

当然,这会产生不必要的混淆并打破最不惊讶的法则,但我们无法对此采取任何行动。任何修改模块的建议总是遇到响亮的“不”。

我自己的个人风格通常是有条理的,但我不知道它是否符合任何书面指引或标准。

我通常将事物事物作为第一个参数,或者至少非常接近开头;顺序取决于最好的感觉。如果存在一个通过整个模块链接的全局状态(通常存在),则将其作为最后一个参数放置,并给出一个非常具有描述性的名称,如St0,St1,...(我属于短变量名称的教会) )。通过函数(输入和输出)链接的参数我尝试保持与返回顺序相同的参数顺序。这使得查看代码结构变得更加容易。除此之外,我尝试将属于一起的论点组合在一起。另外,在可能的情况下,我尝试在整个模块中保留相同的参数顺序。

这些都不是非常具有革命性的,但我发现如果你保持一致的风格,那么不用担心它会让你的代码感觉更好并且通常更具可读性。如果参数顺序错误,我实际上也会重写代码。

一个可能有用的小例子:

fubar({f,A0,B0}, Arg2, Ch0, Arg4, St0) ->
    {A1,Ch1,St1} = foo(A0, Arg2, Ch0, St0),
    {B1,Ch2,St2} = bar(B0, Arg4, Ch1, St1),
    Res = baz(A1, B1),
    {Res,Ch2,St2}.

此处Ch是本地链式变量,而St是更全局的状态。如果你想要一个更长的例子,请查看github上LFE的代码,特别是编译器。

这变得比应有的长得多,抱歉。

P.S。我使用 thing 这个词而不是 object 来避免混淆我正在谈论的内容。

答案 1 :(得分:4)

不,你的意思是没有一贯使用的习语。

但是,有一些有用的相关提示适用,特别是当您要进行深度递归调用时。例如,保持在参数列表中相同顺序/位置的尾调用期间保持不变的参数允许虚拟机进行一些非常好的优化。