我必须在 APL 中编码。由于代码将长期维护,我想知道是否有一些包含启发式/技巧/示例的论文/书籍来帮助设计干净易读的 APL 程序。
这是与使用其他编程语言进行编码不同的体验。例如,制作一个函数。小无助:这样的函数可以包含一行代码,完全看不懂。
我必须在 APL 中编码。由于代码将长期维护,我想知道是否有一些包含启发式/技巧/示例的论文/书籍来帮助设计干净易读的 APL 程序。
这是与使用其他编程语言进行编码不同的体验。例如,制作一个函数。小无助:这样的函数可以包含一行代码,完全看不懂。
首先,欢迎来到 APL 的精彩世界。
编写可读和可维护的 APL 代码与用任何语言编写可读和可维护的代码没有太大区别。任何关于编写干净代码的好书都像任何其他语言一样适用于 APL,甚至可能更适用。我推荐Robert C. Martin 的Clean Code。
考虑一下本书中的指导方针,即函数中的所有代码都应该处于相同的抽象级别。这适用于 APL 100 倍以上。例如,如果您有一个名为 DoThisBigTask 的函数,它应该只有很少的 APL 原始符号,而且肯定没有长的复杂单行代码。它应该只是对其他较低级别函数的一系列调用。如果这些更高级别的函数都具有良好的名称和良好的定义,那么即使不了解 APL 的人也应该很容易确定一般漂移。最低级别的函数将只是原语,并且对于非 APLer 来说是难以理解的。根据它们的编写方式,它们甚至可能最初对经验丰富的 APLer 来说是难以理解的。但是,这些低级函数应该很短,没有副作用,
一般来说,让你的函数保持简短、命名良好、定义明确且切中要害。并保持代码行更短。拥有定义良好且记录良好的函数比拥有编写良好或记录良好的代码行更重要。
由于您要求提供书籍和其他参考资料,我可以建议:
我认为 APL 作为“只写语言”的声誉被夸大了。确实需要习惯于原语和用于表示它们的符号。但随后需要习惯许多其他语言环境中的语法和各种库函数。我已经看到 C、C++ 和 Java 中的复杂代码与任何 APL 一样难以遵循。当然,它不是好的 C、C++ 或 Java,即使它很聪明。
一些忠告:
You can use an OOP-like style if you wish. But there is no need to do so. If you do, it should IMO be used fairly pervasively through an application, except perhaps for low-level utilities. But OOP-style code can be at least as convoluted as non-OOP code, and APL doesn't have built-in inheritance or other OOP-supporting syntax.
(我将在这里使用“A”而不是注释,“'”而不是符号。)
嗯,我开发 APL 一年了,我只用过Aplusdev.org。
你甚至不需要更多。诀窍是尝试像 OOP 一样思考。你应该有——如果我没记错的话——用作类数据的结构化字段obj.attribute1
,比如 {'attribute1 'attribute2, {value,value2}},这样你就可以像在 c++中一样轻松地将它们挑选出来。(这里是'属性 Pick 对象,仅在类函数中使用 :))
此外,使用命名空间函数:
namespace_classname.method(this, arg1)
namespace_classname._private_method(this, arg1, arg2)
和许多简单的工具功能,而不是漂亮的长线。性能下降并不显着,您可以稍后优化说阵列,一旦您发现某些东西可能会更快。
在任何事情之前:想想没有 for 循环的matlab 和 mathematica !:) 它有很大帮助。
使用广泛的实用函数集而不是使用那些不可读的符号来使您的代码始终切中要害。
try-catch 块有一个内置的异常处理,可以在这里使用,
尝试开始();
一个尝试过的代码,可能在额外的括号中不要忘记最后的 try_end() 。
try_end();
捕捉(某事,function_here);
可以很好地实现。(你会看到,捕捉错误非常重要)
粗略的类型检查:实现一个标准并用于不那么多次调用的函数......(你可以在函数定义之后放置一个具有灵活参数的函数)
语法:
函数(point2i,ch):{类型
检查({{'int,[1 2]},'char});A do some assertions in typecheck...
// 你的函数放在这里
}
lambda 函数可以非常有效,你可以做一些反射来实现 lambdas。
总是用“return”声明退货!
基于 try-catch测试您编写的每个函数的单元测试。
我还使用了很多来自mathematica的' apply '和' map ',实现了我自己的版本,它们在这里非常非常有效。
我写了 matlab 思维,因为你可以在这里有一个变量中的结构化字段列表(=类数据)。如果你想保持 for-loop-less(你想,相信我),你会写很多这样的东西。为此,您需要有一个标准的命名约定,比如用复数表示:
namespace_class.method(对象,arg1,arg2)
最后:另外,我编写的 inputBox 和 messageBox 就像 Javascript 或 VisualBasic 中的一样,它们可以很容易地组合简单的工具或检查状态。messageBox 的唯一问题,它不能暂停功能流,所以你需要
AA documentation of f1
f1():
{
A do sth
msgbox.call("Hi there",{'Ok, {'f2}});
}
f2():
{
A continue doing stuff
}
您可以使用 gawk/sed 组合在 bash 中编写自动文档,以将其放入网页中。创建 HTML 格式的代码也有助于打印。;)
我希望这是一个很好的大纲,可以进行适当的构建。在编写自己的工具之前,请尝试从遗留代码库中挖掘可用的工具......由于当时的混乱,函数通常甚至用不同的名称实现 4 次。