文学编程的直观动机?

发布于 2024-07-30 18:17:08 字数 477 浏览 11 评论 0原文

所以,我使用了scribble/lp< /em> 使用 plt-scheme 编写我的第一个读写程序的模块:

#lang scribble/lp
(require scribble/lp)

<<lp_scheme.ss>>

@chunk[<squarefunction>
        (define (f x)
         (* x x))]

当然,那里没什么用处。 现在我有点想知道为什么我不使用简单的注释,而不是文字编程结构。 欢迎任何意见。 如果有人可能有更多的接触/经验,那就太好了。 它可以更直观地解释有据可查的代码和使用 Literate 编程结构编写的代码之间的差异。

So, I used the scribble/lp module to write my first literate program using plt-scheme:

#lang scribble/lp
(require scribble/lp)

<<lp_scheme.ss>>

@chunk[<squarefunction>
        (define (f x)
         (* x x))]

Nothing useful there, of course. Now I am sort of wondering why would I just not use plain comments, instead of literate programming constructs. Any opinions welcome. It would be really great if some one who have probably had more exposure/exp. with it to possibly give a more intuitive explanation of the differences between well documented code and code written using Literate programming constructs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愿与i 2024-08-06 18:17:08

(我假设您正在使用 Donald Knuth 的读写编程定义。)

关键区别在于序列

在编写常规应用程序时,表达内容的顺序受到限制。

举例来说:

  • 特定类的所有代码都必须在一个地方表达
    (或者在极少数地方,例如 C# 部分类)
  • 必须一次性给出一个方法的所有代码,并按照正确的执行顺序
  • 必须在依赖于它们的事物之前声明依赖关系
    (在大多数语言中,变量在使用前声明;在 Pascal 中,过程/函数在使用前声明;在 .NET 中,库程序集在其他程序之前编译)

通过文学编程,您可以摆脱这种限制,并可以自由地表达您的概念在向其他开发人员解释程序时,请使用对您有意义的顺序。

这还有另一个结果 - 在某些形式中,您可以一次表达一个概念(例如,“所有属性在更改时都会触发 PropertyChanged 事件”),然后将其以无数其他方式编织到整个应用程序中。地方。

对于非常简单的程序,一个有文字的程序和一个注释良好的程序可能看起来是一样的 - 但随着系统复杂性的增加,两者将开始显得非常不同。

(I'm assuming you're using Donald Knuth's definition of literate programming.)

The key difference is one of sequence.

In writing a regular application, there are restrictions on the order in which you express things.

To illustrate:

  • All code for a particular class has to be expressed in one place
    (or in a very small number of places, e.g. C# partial classes)
  • All the code for one method has to be given in one go, in the correct order for execution
  • Dependencies must be declared before the things dependent upon them
    (variables declared before use in most languages; procedures/functions declared before use in Pascal; library assemblies compiled before others in .NET)

With literate programming you are freed from this restriction and freed up to express your concepts in whichever order makes sense for you to use when explaining the program to another developer.

This has another consequence - in some forms, you can express a concept once (say, "All properties will fire the PropertyChanged event when changed"), and have that woven throughout your application in a myriad of other places.

For very simple programs, a literate program and a well commented one might look the same - but as the complexity of the system grows, the two will start to appear very different.

枕花眠 2024-08-06 18:17:08

对我来说,主要动机是每个程序员都使用纸张/笔记本来“设计”架构、开发想法,在那里他写方案、图表、尝试一些数学等等。 程序完成后,所有这些笔记本/纸张都会丢失,因此程序的可支持性下降。
我在 LP 工具 NanoLP 的 WiKi 中写到了这一点: http://code.google .com/p/nano-lp/wiki/AboutLP

第二个动机(不那么明确)是减少错误。 但这不是“理论”的事情,它是经验事实(对我来说)——当你在纸上“思考”、画图表、算法方案时——你的程序会有更少的错误。 LP就是这样的“纸”,仅此而已。

有很多开发人员,他们从不画东西,甚至没有评论(!),他们只写程序......太糟糕了!

LP 可以帮助您创建良好的文档(不是以正式的方式 - 函数的描述,它的参数,以及它返回的内容,并且确保这是众所周知的函数签名,那么为什么需要这样的文档??),但它有助于用语义、图片和真实动作的描述来编写真正的实际文档...

很多动机:) 当然有时只使用反向 LP(例如 Doxygen)更好,有时 - 真正的 LP 取决于许多因素。

Main motivation, as for me, is that every programmer use paper sheets/notebook to 'design' architecture, develop ideas, there he writes schemes, diagrams, try some math and so on. After finishing of the program, all of these notebooks/paper sheets are lost, so supportability of the program is getting down.
I wrote about this in WiKi of my LP tool NanoLP: http://code.google.com/p/nano-lp/wiki/AboutLP.

Second motivation, not so explicitly, is lesser bugs. But this is not 'theoretical' thing, it's experience fact (for me) - when you're 'thinking' on the paper, drawing diagrams, algorithms schemes - your program will have lesser bugs. LP is such 'paper', nothing else.

There are many developers, who never draws something, no comments even (!), they write program only... Terrible!

And LP helps you to create good documentation (not in formal way - description on functions, it's args, and what it returns, and sure this is good known with function signature, so why such documentation is needed??), but it helps to write REAL ACTUAL documentation with semantic, with pictures, with describing of real actions...

Many motivations :) And sure sometimes is better to use only reverse LP (Doxygen, for example), sometimes - real LP, depends on many factors.

傲鸠 2024-08-06 18:17:08

文学编程基于三个简单的陈述:

  1. 程序员必须编写计算机可以理解的代码
  2. 程序员应该编写人们可以理解的文档
  3. 如果这些是单独的文档,那么它们将不可避免地不同步

事实上,根据我的经验, #2 通常会受到冷遇。 我已经记不清有多少次 QA 告诉我“文档是这样说的,但代码是那样的;是代码不正确还是文档已经过时了?” 在这方面,我并不认为我的工作场所与众不同。 此外,在我的一个早期项目中,我试图使文档保持最新状态,因为与利益相关者的反复交流导致了需求的变化。 这非常耗时,管理层告诉我不要再搞乱文档,让项目正常运行。 从那时起,我们就采用了不那么繁琐的文档流程(谢天谢地!)。

我们有代码审查工具,当我们对代码进行更改时,多个人可以看到更改,清楚地描述,并且可以发表评论,提出问题,解释内容,提供改进。 如果代码是使用文学编程技术编写的,那么这个问题/答案的大部分内容将是多余的,因为将包含解释。

现代编程的大部分思维方式是你的代码应该是它自己的文档。 许多专家认为,如果您发现自己需要在注释中解释代码,您可能应该重新格式化代码(更改变量/函数名称等),以便不需要注释。 我发现这在理论上很棒,但在现实中不太实用。 我的意思是,当我使用其他人创建/维护的库时,他们对方法/函数名称的选择对我来说并不总是直观的。 例如:

Set<String> statesWeCareABout = new HashSet<String>(Arrays.asList(new String[] { "one", "two", "three" }));
Set<String> statesWeFound = <some function>;
statesWeFound.retainAll(statesWeCareAbout);

如果您不熟悉 Set<> 或者 HashSet<>,你可能不知道 .retainAll() 意味着给我两者的交集,结果在修改后的 Set<> 中。

最后,文学编程通常让您分解事物,以便您可以单独解释这段代码,然后将其内联到另一段代码中。 这更符合人类的理解方式。 向我解释这是如何工作的,然后在此基础上解释更大的情况。 计算机并不真正关心; 你可以用 1,000 行代码编写一个函数,并且理解整个过程没有问题。 如果您作为开发人员必须维护这一点,那么上帝会帮助您。

这确实是文学编程背后的原因。 代码需要维护,无论是修复错误还是添加功能。 如果其他人无法理解它,那么稍后就会以有效的方式被替换。 这个世界上有很多“只写”代码。 文学编程使它更容易阅读和理解,这使得它更有可能被长期保留和使用。

我们真的有时间继续重新发明轮子吗?

Literate Programming is based on three simple statements:

  1. Programmers must write code, which the computer can understand
  2. Programmers should write documentation, which people can understand
  3. If these are separate documents it is inevitable that they will be out-of-sync

Indeed, in my experience, #2 usually gets short shrift. I've lost count of how many times QA has told me "the doc says this, but the code does THAT; is the code incorrect or is the doc out-of-date?" I don't expect my workplace is out of the ordinary, in that respect. Additionally, in one of my early projects, I was trying to keep the docs up-to-date as the back-and-forth with the stakeholders resulted in changing requirements. This was sufficiently time-consuming that I was told, by management, to stop messing with the docs and just get the project working. We've gone to less-tedious documentation processes, since then (thank heavens!).

We have code review tools where, when we make a change to the code, multiple people can see the changes, clearly delineated, and comments can be made, asking questions, explaining stuff, offering improvements. If the code was written with Literate Programming techniques, much of this question/answer would be superflous because the explanation would be included.

Much of the mindset of modern programming is that your code should be its own documentation. Many pundits argue that, if you find yourself needing to explain your code in comments, you should probably reformat the code (changing variable/function names, etc.) such that the comments are unneeded. I find this to be great in theory, less practical in reality. I mean, when I'm using libraries created/maintained by someone else, their choice of method/function names isn't always intuitive to me. For example:

Set<String> statesWeCareABout = new HashSet<String>(Arrays.asList(new String[] { "one", "two", "three" }));
Set<String> statesWeFound = <some function>;
statesWeFound.retainAll(statesWeCareAbout);

If you aren't familiar with Set<> or HashSet<>, you may not know that .retainAll() means give me the intersection of the two, with the result in the modified Set<>.

Finally, Literate Programming usually lets you break things down so that you can explain this piece of code in isolation, then in-line it into this other piece of code. This is more in-line with how human comprehension works. Explain to me how this works, then build on that understanding to explain the larger picture. Computers don't really care; you can write a single function with 1,000 lines of code and it has no problem comprehending the whole thing. God help you if you, as a developer, have to maintain that.

And that, really, is the reasoning behind Literate Programming. Code will need to be maintained, whether it's bugs being fixed or features being added. And if it can't be comprehended by someone else, later on, in an efficient fashion, it will be replaced. There is way to much "write only" code in this world. Literate Programming makes it easier to read and comprehend, which makes it more likely to be kept and used, long-term.

And do we really have time to keep re-inventing the wheel?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文