为什么 Pascal 控制结构看起来不一致?

发布于 2024-10-10 10:22:28 字数 571 浏览 6 评论 0原文

大多数 Pascal 控制结构对我来说都是有意义的,例如:

for ... do {statement};

if (condition) then {statement};

while (condition) do {statement};

其中 {statement} 要么是单个语句,要么是 begin ... end 块。我有一个问题:

repeat {statement-list} until (expression);

try {statement-list} except {statement-list} end;

repeattry 具有相同的一般结构,仅接受单个语句或 begin 不是更好吗> ... end 块,而不是使用一个未用 beginend 正式阻止的语句列表?

Most Pascal control structures make sense to me, like:

for ... do {statement};

if (condition) then {statement};

while (condition) do {statement};

where the {statement} is either a single statement, or a begin ... end block. I have a problem with:

repeat {statement-list} until (expression);

try {statement-list} except {statement-list} end;

Wouldn't it be better that repeat and try have the same general structure, accepting only a single statement or a begin ... end block, instead of having a statement-list that's not formally blocked with a begin and an end?

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

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

发布评论

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

评论(7

雪若未夕 2024-10-17 10:22:28

需要开始/结束的形式都存在于一行中——编译器没有其他方法可以知道块在哪里结束。不需要开始/结束的形式有一个结束结构,告诉编译器它在哪里结束,因此开始/结束只是多余的。不过,如果您愿意,可以在这种情况下自由使用它。

The forms that require a begin/end all exist on a single line--the compiler has no other way to know where the block ends. The forms that don't require a begin/end have a closing structure that tells the compiler where it ends and thus the begin/end would simply be redundant. You're free to use it in this case if you want, though.

荒路情人 2024-10-17 10:22:28

Niklaus Wirth(Pascal 的设计者)在他的下一种语言 Modula-2 中纠正了这些不一致之处。在 Modula-2 中,像 IF 这样的复合语句没有 BEGIN 和强制的 END

IF {condition} THEN
    {statement-list}
END;

其他控制结构,例如 WHILE > 与REPEAT 相似且一致。

Niklaus Wirth (the designer of Pascal) corrected these inconsistences in his next language, Modula-2. In Modula-2, compound statements like IF have no BEGIN and a mandatory END:

IF {condition} THEN
    {statement-list}
END;

Other control structures such as WHILE are similar and consistent with REPEAT.

没企图 2024-10-17 10:22:28

问题是:这样不是更好吗?

答案是:这要看情况,因为这种事情完全是主观的。除非你是一台机器,或者像一台机器一样思考。

是的,强制所有复合语句的开始/结束会满足一些一致性的需求,但是如果周围的语言元素已经提供了自然的封闭,那么要求这一点是完全多余的。

考虑 CASE 语句:

// "Sensible" syntax

  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
    DoForAllOtherValues;
    DoMore;
  end;

与不太明智但更一致和“逻辑”的语句相比:

  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
    begin
      DoForAllOtherValues;
      DoMore;
    end;
  end;

请注意,最终的“结束”是“案例”的一部分。你不能没有它。

我相当确定,在 Chrome 的早期版本(后来成为 Oxygene 和后来的 Prism)中,这实际上是 case 语句所需的语法。如果是这样,那就不再是这样了。常识大概占了上风。

在我个人看来,满足 OGoSC(句法一致性的客观诸神)会激怒也许次要但实际上与你我更相关的 SGoHRaC(人类可读性和理解性的主观诸神)。

尽管在许多情况下可能看起来并非如此,但我们人类实际上并不是机器。我们不需要将规则简化和减少到最小一致集,以便能够解析文本并理解它。我们需要一些规则,但我们可以处理更多,因为我们相对于机器的巨大优势是思想自由,它将我们从严格的语法和结构规则中解放出来,特别是在这种语法和结构与冗余无关的情况下。

就像这个例子一样。

如果你犯了一个编译器无法解释的错误,它会在你每次编译时告诉你。但是编译器不会感谢您使代码“更容易”“阅读”(编译器只是遵循给定的规则 - 它不会使编译器通过更改它已经可以完美地遵循的规则)。

如果您强加任意规则,使其难以阅读(不是因为规则或多或少是不变/一致的,而是因为您强加了一致的结构,该结构本身包含更多必须过滤的噪音和冗余信息),那么您将付出人类生产力的代价。

事实上,这些“更简单”更“一致”的规则,实际上可能会让事情变得更难......再次考虑 CASE 语句。

为了使复合开始/结束有意义,我们必须使“case”成为一个独立的语句,而不是 case/end 对的一部分,因此所有这些都应该是有效的语法:

  case VALUE of
    1: DoSomething;
    2: DoSomethingElse;


  case VALUE of
    1: DoSomething;
    2: DoSomethingElse;
  else
    DoOther;


  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
    DoOther;


  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
  begin
    DoOther;
    DoMoreOther;
  end;


  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;

你可能不同意,但在我看来,突然这个更一致的语法实际上会导致实际代码的一致性较差,尽管编写代码要遵循的规则具有更高的一致性。

The question is: Wouldn't it be better ?

The answer is: That depends, as this sort of thing is entirely subjective. Unless you are, or think like, a machine.

Yes, it would satisfy some ache for consistency to enforce begin/end for ALL compound statements, but where the surrounding language elements already provide a natural enclosure, it is utterly redundant to require this.

Consider the CASE statement:

// "Sensible" syntax

  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
    DoForAllOtherValues;
    DoMore;
  end;

Versus a less sensible but more consistent and "logical":

  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
    begin
      DoForAllOtherValues;
      DoMore;
    end;
  end;

Notice that the final "end" is part of the "case". You cannot do without it.

I am fairly sure that in an early version of Chrome (that became Oxygene and subsequently Prism) this was actually required syntax for the case statement. If so, it is no longer the case. Common sense presumably prevailed.

In my personal opinion, satisfying the OGoSC (Objective Gods of Syntactic Consistency) angers the perhaps lesser, but actually more relevant to you and me, SGoHRaC (Subjective Gods of Human Readability and Comprehension).

Though in many cases it might appear otherwise, we humans are not in fact machines. We do not need to simplify and reduce rules to a minimum consistent set to make it possible to parse text and make sense of it. We need some rules, but we can handle more, since our great advantage over machines is a freedom of thought that liberates us from a strict regimen of syntax and structure, especially where such syntax and structure is extraneous to the point of redundancy.

As in this case.

If you make a mistake that the compiler cannot interpret, it will tell you, every time you compile. But the compiler won't thank you for making the code "easier" to "read" (the compiler simply follows the rules it is given - it does not make it "easier" for the compiler to "read" the code by changing the rules that it can already follow perfectly happily).

If you impose arbitrary rules that make it harder to read (not because the rules are more or less invariant/consistent, but because you impose a consistent structure that itself contains more noise and redundant information that has to be filtered) then you will pay the price in human productivity.

In fact, these "easier" more "consistent" rules, may actually may make it harder all around ... consider again the CASE statement.

To make that compound begin/end make sense, we must make "case" a standalone statement, not part of a case/end pair, thus ALL of these should be valid syntax:

  case VALUE of
    1: DoSomething;
    2: DoSomethingElse;


  case VALUE of
    1: DoSomething;
    2: DoSomethingElse;
  else
    DoOther;


  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
    DoOther;


  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;
  else
  begin
    DoOther;
    DoMoreOther;
  end;


  case VALUE of
    1: DoSomething;
    2: begin
         DoSomethingElse;
         DoMore;
       end;

You may disagree, but it seems to me that suddenly this more consistent syntax results actually in LESS consistency in the actual code, even though there is greater consistency in the rules that the code is being written to conform to.

心碎无痕… 2024-10-17 10:22:28

大概。但语言设计,尤其是具有一定历史的语言,很少是直接或理想的。

你可以在其他语言中看到类似的东西。例如,Java需要try之后有一个块,并且不允许使用单个语句,尽管如果您只查看其他控制结构,单个语句也可能有效。

为什么 C 及其派生语言中的 switch 是单个块,而个别情况不是?

Probably. But language design, especially languages with a bit of history, is rarely straightforward or ideal.

You can see similar things in other languages. Java, for example, requires a block after try and won't allow a single statement, although a single statement might also work if you just look at other control structures.

Why is switch in C and derived languages a single block and the individual cases not?

白馒头 2024-10-17 10:22:28

我猜你问错了问题。我的意思是,您可能没有看到 if/while/for 组和重复/尝试组之间的区别。

第一组需要一些东西(条件或参数)来开始一些东西。相反,第二个意味着开始某事。只需阅读以下文字:重复(以下)并尝试(以下)。

Pascal 干净、简单、优雅,因为它是为普通人类读者设计的,Wirth 教授在设计它时就考虑到了学习编程的人。

I guess you are asking the wrong question. I mean, may be you are not seeing the difference between the if/while/for group and the repeat/try group.

The first group needs something (condition or arguments) to BEGIN something. The second, instead, implies to BEGIN something. Just read the words: repeat (the following) and try (the following).

Pascal is clean, simple and elegant because it's designed for regular human readers, Professor Wirth had in mind people learning programming when he designed it.

早乙女 2024-10-17 10:22:28

它与解析器的工作方式有关。 Begin/end、try/ except和repeat/until都包含语句块。对于开始块(伪代码),解析器的代码看起来像这样:

procedure ReadBlock;
begin
  Match('begin');
  while CurrentToken <> 'end' do
    ReadStatement;
  Match('end');
end;

对于该类型的块来说,它工作得很好。但是,当您需要块结束行中的附加信息(重复/直到的条件,以及 try 的异常处理块)时,您不希望它运行到结束,该语言的语法期望其后没有任何内容。您可以修改语法,但这会给解析器增加很多复杂性。因此,您只需选择不同的关键字即可。

It has to do with the way the parser works. Begin/end, try/except and repeat/until all contain blocks of statements. The parser's code looks something like this, for a begin block (pseudocode):

procedure ReadBlock;
begin
  Match('begin');
  while CurrentToken <> 'end' do
    ReadStatement;
  Match('end');
end;

And that works fine for that type of block. But when you need additional information in the block ending line (a conditional for the repeat/until, and an exception-handling block for the try,) then you don't want it to run until end, which the language's grammar expects to not have anything after it. You could modify the grammar, but that would add a lot of complexity to the parser. So instead you just pick a different keyword.

久夏青 2024-10-17 10:22:28

您是部分正确的 - 在repeat;直到语句。

您不需要 BEGIN-END 来实现复合语句的一致性,这感觉有点作弊,但这是为了避免过度的痛苦。因为您在所有其他情况下都会看到,您需要开始结束包围效果来显示 thenelse 或循环 do 适用于。 REPEAT-UNTIL 是我能想到的唯一一个 Pascal 语句,它需要一个遥远的第二部分 - 因为它有意义循环退出的条件在文本上将被检查 - 循环体之后。另一种形式可能是

UNTIL <condition> DO <statement>

UNTIL <condition> DO
  BEGIN
    <statements>
  END

,但这样解释和说服语言用户只有在块至少执行一次之后才会检查条件,这太令人困惑了。所以,沃斯没有这样做是件好事。

关于尝试除了; end - 这不是来自原始的 Pascal 语言设计和规范,这是由某些实现者(Borland?FreePascal?)事后添加的,所以难怪它是不一致的 - 这个想法更多与总体规范设计相比,“我可以在不破坏现有程序的情况下做到这一点吗”。上面的答案中给出了语言扩展的另一个例子 - case 开关中的默认子句 else - 虽然我发现这非常有用并且在过去的日子里使用过它Turbo Pascal - 这与 if 结构中使用 else 非常不一致。因此,我找到了我见过并使用得更好的另一个实现 - otherwise: 后跟每个 : 情况中的单个语句。

You are partly correct - on the repeat <stmts> until <expr> statement.

It feels a bit of a cheat that you don't need BEGIN-END for compound statement consistency but this is to avoid undue suffering. Because you see in all other cases you need the begin-end bracketing effect to show where the part of the code to which then or else or loops do apply to. REPEAT-UNTIL is the only Pascal statement i can think of that necessitates a far-removed second part - because it makes sense the condition for loop exit to be textually where it will be checked - after the loop body. An alternative form could have been

UNTIL <condition> DO <statement>

UNTIL <condition> DO
  BEGIN
    <statements>
  END

but then it would be way too confusing to explain and persuade the language users that the condition will be checked only after the block is executed at least once. So it's a good thing Wirth did not do it this way.

In regards to try <stmts> except <stmts> end - this is not from the original Pascal language design and specification, this has been slapped in as after-thought by some implementor (Borland? FreePascal?), so it's no wonder it is inconsistent - the thought has been more to the lines of "can i do it without breaking existing programs" than overall specification design. Another example of language extension was given in answer above - the default clause else in the case switch - and while i find this very useful and had used it back in the days in Turbo Pascal - this is horribly inconsistent with the use of else in the if construct. Thus i find another implementation i have seen and used better - otherwise: followed by a single statement as in each <value>: case.

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