Don't Write Comments

CodeAesthetic
16 Jan 202305:55

Summary

TLDR这段视频脚本讨论了代码注释的价值和局限性。作者认为,在大多数情况下,应该避免编写注释,而是通过简化和重构代码来提高可读性。他强调,代码的复杂性应该通过变量命名和类型系统来解决,而不是依赖注释。注释可能会过时,而且没有工具来确保它们的准确性。相反,高质量的代码文档对于描述系统架构和公共API至关重要,应该与代码保持紧密联系。作者还提到,尽管有些情况下注释是必要的,但应该谨慎使用,并寻找其他方法来表达代码的意图。

Takeaways

  • 📝 代码注释大多数时候是不必要的,应该通过改进代码来提高可读性。
  • 🔍 如果代码复杂到需要注释解释,应该考虑重构或简化代码。
  • 📌 使用常量代替硬编码值,如将数字5替换为有描述性的常量。
  • 📋 通过变量命名来简化复杂的条件表达式,减少对注释的依赖。
  • 🔄 将复杂条件移动到单独的函数中,提高代码的可读性。
  • 🔧 类型系统可以减少注释的需要,如C++中的unique_ptr明确了资源所有权。
  • 🚫 注释可能会过时,而代码有工具可以检查错误,注释没有这样的系统。
  • 📖 阅读代码而不是注释来理解代码的功能。
  • 📚 重视代码文档,它描述了系统的高层架构和公共API。
  • 🔗 使用工具如Doxygen、pydoc和JavaDoc从代码文件生成文档。
  • 📝 在某些情况下,注释是必要的,如性能优化的非显而易见的原因。
  • 🔗 如果代码使用了特定的数学原理或算法,可以考虑添加源链接。

Q & A

  • 为什么作者认为大多数时候不应该在代码中写注释?

    -作者认为,如果代码需要注释来解释,那么更应该考虑简化或重构代码,使其更易于理解。

  • 在代码中使用常量有什么好处?

    -使用常量可以提高代码的可读性,使得代码中的数值更有意义,而不是仅仅作为一个数字存在。

  • 如何通过变量命名来简化复杂的条件表达式?

    -通过为表达式中的部分命名,可以使条件表达式更易于阅读,减少对注释的依赖。

  • 将复杂条件移动到单独的函数中有什么优势?

    -这样做可以使得代码更加模块化,易于理解和维护,同时减少对注释的需求。

  • 在C++中,unique_ptr类型如何减少对注释的依赖?

    -unique_ptr类型明确表示了对象的所有权,使得代码的意图更加清晰,减少了对注释的需要。

  • 为什么说注释可能会带来问题?

    -注释可能会随着代码的修改而变得过时,而且没有像代码那样的工具来检查注释的准确性。

  • 作者为什么更倾向于阅读代码而不是注释?

    -因为代码是精确的,而注释可能会出错或过时。作者认为代码本身就是最好的文档。

  • 代码文档与注释有何不同?

    -代码文档描述了系统的高层架构和公共API,而注释则描述了代码的内部工作方式。

  • 为什么说高质量的文档对于API的使用很重要?

    -高质量的文档可以帮助API的用户了解如何使用它,以及任何接口定义的期望,如线程安全、可能的状态或错误条件。

  • 在什么情况下应该考虑使用注释?

    -当代码为了性能原因做了一些不明显的操作,或者使用了特定的数学原理或算法时,可以考虑使用注释来解释。

  • 作者如何看待未来编程语言的发展?

    -作者认为代码是表达意图的更好方式,即使未来可能不需要编写代码,但目前来说,代码比注释更能准确表达开发者的意图。

Outlines

00:00

📝 代码注释的争议

本段落讨论了代码注释的使用,作者认为大多数情况下不应该在代码中添加注释。通过示例说明,如果代码复杂到需要注释来解释,那么应该考虑简化或重构代码。作者提倡使用常量、类型和函数来减少注释的需要,因为这些方法可以使代码更加清晰且易于维护。同时,作者强调了代码文档的重要性,它与注释不同,更侧重于描述系统的高层架构和公共API,有助于用户了解如何使用代码。

05:02

🤖 代码与注释的未来

这一段落通过一个关于未来可能不需要编码的幽默漫画,引出了代码比注释更能精确表达意图的观点。作者认为,尽管人工智能可能会影响到程序员的工作,但代码仍然是表达意图的最佳方式。最后,作者提出了一个问题,询问观众在哪些情况下认为注释是必要的,暗示了注释在某些特定情况下仍然有其价值。

Mindmap

Keywords

💡代码注释

代码注释是程序员在源代码中添加的文本,用于解释代码的功能或目的。在视频中,作者认为大多数情况下不应该在代码中添加注释,因为注释可能会变得过时,而且没有工具可以确保注释与代码的同步更新。

💡代码可读性

代码可读性指的是代码的清晰度和易于理解的程度。视频强调,通过使用常量、类型和重构代码,可以提高代码的可读性,从而减少对注释的依赖。例如,通过将数字5替换为一个名为`MESSAGE_SENT`的常量,代码的意图变得更加明显。

💡代码重构

代码重构是指在不改变代码外在行为的前提下,对代码结构进行调整以提高其可读性和可维护性。视频中提到,如果代码复杂到需要注释来解释,那么应该考虑重构代码,使其更加简洁。

💡类型系统

类型系统是编程语言中用于定义数据类型及其操作的一套规则。在视频中,作者提到C++中的`unique_ptr`类型,它通过类型本身就能传达所有权信息,从而减少了对注释的需要。

💡文档

文档是用来描述软件系统架构、公共API和如何使用代码的文档。与注释不同,文档关注的是代码的高层次设计和使用方式。视频中强调,高质量的文档可以帮助用户更好地理解和使用API。

💡静态分析工具

静态分析工具是用于在不实际运行代码的情况下检查代码质量的工具。视频中提到,未来可能会有使用AI的静态分析工具来检查代码与注释的一致性,但目前还没有这样的系统。

💡代码意图

代码意图是指代码想要实现的功能或目标。视频中提到,代码是一种比注释更精确的表达意图的方式,因为它不会像注释那样可能变得不准确或过时。

💡性能优化

性能优化是指对代码进行调整以提高其运行效率。视频中提到,在某些情况下,如果代码为了性能而看起来不直观,注释可以帮助解释这种非显而易见的设计。

💡数学原理

数学原理是指在编程中应用的数学理论或算法。如果代码中使用了特定的数学原理,视频中建议可以考虑添加注释,并链接到相关资源,以帮助未来的维护者理解。

💡API

API(应用程序编程接口)是一组预定义的函数、协议和工具,用于构建软件和应用程序。视频中强调,编写更好的API可以使文档更加简洁,减少错误,并帮助用户了解如何使用代码。

💡社会政治动荡

社会政治动荡是指由于社会结构或政治体系的变化而导致的不稳定状态。视频中提到,随着人工智能的发展,我们可能会面临工作消失带来的社会政治动荡。

Highlights

大多数时候,你不应该在代码中写注释。

如果代码需要注释来解释,那么应该考虑简化或重构代码。

通过使用变量命名表达式的一部分,可以使条件语句更易读。

当条件足够复杂时,可以考虑将整个条件移动到自己的函数中。

类型可以消除注释的需要,例如C++中的unique_ptr类型。

注释可能会像代码一样出现错误,而且通常不会被更新。

代码文档与注释不同,它描述了系统的高层架构和公共API。

使用工具如Doxygen、pydoc和JavaDoc可以直接从代码文件生成文档。

文档应该描述类或API代表的内容以及接口定义的任何期望。

在某些情况下,例如为了性能原因,应该考虑使用注释。

如果代码利用了特定的数学原理或算法,可以考虑链接到源以帮助未来的维护者。

代码是一种比注释更精确的表达意图的方式。

如果你觉得需要用人类语言来描述你的代码,试着让你的代码更人性化。

注释可能会撒谎,但代码不会。

代码文档应该尽可能与代码保持同步。

在代码中使用注释的少数情况包括性能优化和特定算法的使用。

代码是更精确的规范表达方式。

Transcripts

00:00

It's time to get a bit controversial.

00:02

I don't think you should write comments in your code

00:04

pretty much most of the time.

00:11

Here,

00:11

we have some code where we expect the value to be 5

00:15

Looking at this code, it's not obvious what five signals.

00:19

We could add a comment explaining what five is,

00:21

but even better we can create a constant representing the variable instead.

00:26

The if statement now reads like a comment:

00:29

that we want status to be message sent.

00:32

If your code is complex enough that it warrants a comment, you should instead

00:35

see if you can simplify or refactor the code to make it better instead.

00:41

Right now, this condition is complex enough

00:43

that we add a comment explaining it, but we can simplify this

00:47

by using variables to name parts of the expression.

00:54

Now the condition reads like the comment does.

00:57

So the comment is basically redundant and can be removed.

01:01

When conditions are complex enough like this,

01:03

you could also consider moving the whole condition to its own function.

01:07

Now you don't need to decipher at all.

01:09

Types can also make comments redundant.

01:12

In C++, there's no built in memory management.

01:15

You often have a function like this where you get back a thing,

01:19

but we need to make clear who will take ownership of the thing.

01:22

Ownership, meaning the responsibility

01:24

to release the memory after everyone is done with it.

01:27

In older C++, you pretty much had to rely on comments to do this.

01:31

If you were given ownership of an object, you'd find out by reading

01:35

the comments of the function.

01:37

But C++ added a new type called unique_ptr.

01:41

The type represents a unique reference to the object.

01:45

So if you get one, congratulations!

01:48

It's now your responsibility.

01:51

The type tells you explicitly

01:52

that you now own it without the need for a comment.

01:56

And even better, the type makes it so you get a compile error

02:00

if you do bad things with it.

02:02

A comment doesn't do that.

02:05

Likewise, if we have a function that returns an int,

02:08

but that int is optional.

02:10

We could add a comment saying that -1 means we're not actually

02:14

returning a value.

02:16

But even better, we could use a type.

02:18

If we return an optional int instead, it's

02:21

now obvious that we might not give a value.

02:24

We can't miss the comment and not realize that we might get

02:27

an invalid timestamp back.

02:29

The user needs to handle a missing value or they'll get a compiler error.

02:33

You might

02:33

wonder why don't we just make our code high quality and add comments anyways?

02:37

Isn't more comments just better?

02:40

That ignores the problems with comments.

02:42

Comments get bugs like code.

02:44

When people make changes to code,

02:45

they often don't update the comments to match.

02:48

But unlike comments, we have tools to stop bugs from entering code.

02:52

We have tests, compiler checks and limiting.

02:54

We don't have any system like that for comments.

02:57

Maybe one day we can have some static analysis tool that uses AI to determine

03:01

if the code matches the comments and flags any discrepancies -

03:04

there's a start up idea - but because of this I don't trust the comments

03:08

even when they exist.

03:10

Comments can lie, but code cannot.

03:12

So when trying to understand what a piece of code does, I read the code.

03:15

I never read the comments.

03:17

Maybe it's just me.

03:18

Do you guys find yourself reading comments to understand code?

03:22

What I do read is code documentation.

03:26

Code documentation describes the high level

03:28

architecture and public APIs of a system.

03:31

Code documentation differs from comments

03:33

where comments describe the internals of how your code works.

03:37

Documentation describes how you use the code.

03:42

The world needs more high quality documentation,

03:45

and while we could write the documentation for our code

03:48

completely separated from our code, it makes sense to keep our documentation

03:52

as close to the code as possible in order to try to help them stay in sync.

03:56

Tools like Doxygen, pydoc and JavaDoc generate documents

04:00

directly from code files and therefore change alongside our code.

04:05

It's useful to document what a class or API represents

04:08

and any expectations for interface definitions

04:11

like thread safety, possible states or error conditions.

04:15

This helps the consumers of the API know how to use it and also helps

04:18

any new implementers of the interface

04:21

know how they're supposed to operate and behave.

04:24

The guidance I've given about comments still applies for documentation.

04:27

If we write better APIs, our documentation will be more concise

04:31

and less prone to errors.

04:32

But I concede that you'll never be able to make all of the parts

04:35

of the system obvious with pure code.

04:38

I do think there's a few cases where you should consider comments:

04:41

if the code does something non-obvious for performance reasons,

04:45

a comment can help explain why the code looks weird.

04:49

If the code is utilizing a specific

04:51

mathematical principle or an algorithm from a particular source

04:54

you might consider linking to the source to help future maintainers.

04:59

There's this comic called comic strip,

05:01

and one of the comics is about a guy

05:05

telling a developer that one day we won't need code in the future

05:08

because you'll be able to

05:09

simply write a spec and the program will just write itself.

05:13

The developers are casting retorts that code is just a more precise way

05:17

of writing a spec.

05:18

I mean, I think it's wrong. And A.I.

05:21

is coming for all our jobs, and we should be afraid

05:23

of the impending sociopolitical turmoil that comes when our best tool

05:25

for distributing wealth, the job disappears.

05:28

But alas, it still helps my point.

05:31

Code is a much better way to express intent than comments about code.

05:36

So in general, if you feel like you need human language to describe your code,

05:40

see if you could make your code more human.

05:45

What other cases do you think comments are needed?