有没有一个惯用的方式来命令函数参数在Erlang? [英] Is there an idiomatic way to order function arguments in Erlang?

查看:114
本文介绍了有没有一个惯用的方式来命令函数参数在Erlang?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎在列表模块中不一致。例如,split具有作为第一个参数的数字和列表作为第二个参数,但子列表的列表作为第一个参数,len作为第二个参数。

解决方案

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



正如Christian所说,图书馆发展和趋向从我们正在获得的冲动中获得理论秩序和感觉。因此,例如,元素/组件具有他们所做的参数顺序的原因是因为它与Prolog中的arg / 3谓词匹配;逻辑而不是现在。通常我们将首先使用事物,但不幸的是并不总是。这通常是一个很好的选择,因为它允许可选参数方便地添加到最后;例如string:substr / 2/3。作为最后一个参数的事物的功能常常受到功能语言的影响,例如Haskell,其中很容易使用currying和partial评估来构建特定的功能,然后可以将其应用于。这在列表中的高阶函数中是非常显着的。



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



通常我们至少设法在一个模块中保持一致,但并不总是。再次查看列表。我们确实有一些一致性,所以在dict / sets中的高阶函数中的参数顺序与列表中的相应函数的顺序相匹配。



问题也更加恶化事实上,我们,特别是我,对图书馆的态度更为恶劣。我只是没有看到他们是这个语言的卖点,所以我不是那么担心。 如果你想要一个做某事的图书馆,那么你只是写这是我的座右铭。这意味着我的图书馆是结构化的,并不总是具有相同的结构。 :-)这是有多少起始的图书馆。



这当然会造成不必要的混乱,打破了最不高兴的规律,但是我们还没有能够做任何事情。修改模块的任何建议一直都满足于一个响亮的否。



我自己的个人风格通常是结构化的,虽然我不知道是否符合任何书面准则或标准。



我一般都有的东西事情论据,至少非常接近开始;订单取决于什么感觉最好。如果存在通过整个模块链接的全局状态,通常它被放置为最后一个参数,并给出一个非常描述性的名称,如St0,St1,...(我属于短变量名称的教堂)。通过函数链接的参数(输入和输出)我尝试保留与返回顺序相同的参数顺序。这使得更容易看到代码的结构。除此之外,我试图将属于一起的论点集中在一起。另外,在可能的情况下,我尝试在整个模块中保留相同的参数顺序。



这些都不是革命性的,但是我发现如果你保持一致的风格这是一件少有的事情要担心,它使您的代码感觉更好,一般更可读。如果参数顺序感觉错误,我也会重写代码。



一个小例子可能有助于:

  fubar({f,A0,B0},Arg2,Ch0,Arg4,St0)→& (b0,Arg4,Ch1,St1),
Res = baz(A1,B1),
{Res,Ch2,St2}。

这里 Ch 是一个本地链接变量而 St 是一个更全球化的状态。查看github上的LFE代码,特别是编译器,如果你想要一个更长的例子。



这比现在的时间要长得多,对不起。 >

PS我使用这个词而不是对象来避免混淆我所说的话。


Seems like it's inconsistent in the lists module. For example, split has the number as the first argument and the list as the second, but sublists has the list as the first argument and the len as the second argument.

解决方案

OK, a little history as I remember it and some principles behind my style.

As Christian has said the libraries evolved and tended to get the argument order and feel from the impulses we were getting just then. So for example the reason why element/setelement have the argument order they do is because it matches the arg/3 predicate in Prolog; logical then but not now. Often we would have the thing being worked on first, but unfortunately not always. This is often a good choice as it allows "optional" arguments to be conveniently added to the end; for example string:substr/2/3. Functions with the thing as the last argument were often influenced by functional languages with currying, for example Haskell, where it is very easy to use currying and partial evaluation to build specific functions which can then be applied to the thing. This is very noticeable in the higher order functions in lists.

The only influence we didn't have was from the OO world. :-)

Usually we at least managed to be consistent within a module, but not always. See lists again. We did try to have some consistency, so the argument order in the higher order functions in dict/sets match those of the corresponding functions in lists.

The problem was also aggravated by the fact that we, especially me, had a rather cavalier attitude to libraries. I just did not see them as a selling point for the language, so I wasn't that worried about it. "If you want a library which does something then you just write it" was my motto. This meant that my libraries were structured, just not always with the same structure. :-) That was how many of the initial libraries came about.

This, of course, creates unnecessary confusion and breaks the law of least astonishment, but we have not been able to do anything about it. Any suggestions of revising the modules have always been met with a resounding "no".

My own personal style is a usually structured, though I don't know if it conforms to any written guidelines or standards.

I generally have the thing or things I am working on as the first arguments, or at least very close to the beginning; the order depends on what feels best. If there is a global state which is chained through the whole module, which there usually is, it is placed as the last argument and given a very descriptive name like St0, St1, ... (I belong to the church of short variable names). Arguments which are chained through functions (both input and output) I try to keep the same argument order as return order. This makes it much easier to see the structure of the code. Apart from that I try to group together arguments which belong together. Also, where possible, I try to preserve the same argument order throughout a whole module.

None of this is very revolutionary, but I find if you keep a consistent style then it is one less thing to worry about and it makes your code feel better and generally be more readable. Also I will actually rewrite code if the argument order feels wrong.

A small example which may help:

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}.

Here Ch is a local chained through variable while St is a more global state. Check out the code on github for LFE, especially the compiler, if you want a longer example.

This became much longer than it should have been, sorry.

P.S. I used the word thing instead of object to avoid confusion about what I was talking.

这篇关于有没有一个惯用的方式来命令函数参数在Erlang?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆