4

我必须在 APL 中编码。由于代码将长期维护,我想知道是否有一些包含启发式/技巧/示例的论文/书籍来帮助设计干净易读的 APL 程序。

这是与使用其他编程语言进行编码不同的体验。例如,制作一个函数。小无助:这样的函数可以包含一行代码,完全看不懂。

4

3 回答 3

11

首先,欢迎来到 APL 的精彩世界。

编写可读和可维护的 APL 代码与用任何语言编写可读和可维护的代码没有太大区别。任何关于编写干净代码的好书都像任何其他语言一样适用于 APL,甚至可能更适用。我推荐Robert C. Martin 的Clean Code

考虑一下本书中的指导方针,即函数中的所有代码都应该处于相同的抽象级别。这适用于 APL 100 倍以上。例如,如果您有一个名为 DoThisBigTask 的函数,它应该只有很少的 APL 原始符号,而且肯定没有长的复杂单行代码。它应该只是对其他较低级别函数的一系列调用。如果这些更高级别的函数都具有良好的名称和良好的定义,那么即使不了解 APL 的人也应该很容易确定一般漂移。最低级别的函数将只是原语,并且对于非 APLer 来说是难以理解的。根据它们的编写方式,它们甚至可能最初对经验丰富的 APLer 来说是难以理解的。但是,这些低级函数应该很短,没有副作用,

一般来说,让你的函数保持简短、命名良好、定义明确且切中要害。并保持代码行更短。拥有定义良好且记录良好的函数比拥有编写良好或记录良好的代码行更重要。

于 2012-12-14T14:46:22.357 回答
3

由于您要求提供书籍和其他参考资料,我可以建议:

  • Norman D. Thomson 和 Raymond P. Polivka 深入了解 APL2 我与 Ray Polivka 共事多年,他是我认识的最好的 APL 老师之一。
  • Leonard Gilman 和 Allen J. Rose的经典APL: An Interactive Approach对核心语言很有用,但相当过时,并且没有包含太多与可读性真正相关的内容。
  • James A. Brown 和 Sandra Pakin 的APL 2 概览在某些方面是对 Gilman 和 Rose 的更新。它涵盖了对 APL 的嵌套操作和其他更新,但没有特别针对可读性。不过,如果您遵循此处的示例,您将编写可读的代码。
  • APL is Easy by STSC 和 Jerry R. Turner 是专门针对 APL*Plus 系列的介绍。同样,关于可读性的具体内容不多,但模型通常是精心设计的可读代码。
  • 精通 Dyalog APL: Bernard Legrand 的 Dyalog APL 完整介绍如果您专门从事 Dyalog APL 工作,则非常好,如果您正在使用其他版本之一,例如 APL*Plus(来自 APL2000),则不然

我认为 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.

于 2016-10-10T16:13:56.417 回答
1

(我将在这里使用“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 次。

于 2012-11-17T16:55:55.107 回答