为什么Perl 6的循环变量声明在外部范围内?

bri*_*foy 8 loops for-loop perl6

在Perl 6中,在for-style中声明的变量loop位于外部作用域中.这有效并且有记录.

loop ( my $n = 0; $n < 3; $n++ ) {
    put $n;
    }

say "Outside: $n";
Run Code Online (Sandbox Code Playgroud)

$n是该块的外部可见:

0
1
2
Outside: 3
Run Code Online (Sandbox Code Playgroud)

这里是否存在激励技巧,使其与Perl 6的祖先所期望的不同?我没有在设计文档中看到这一点(但尝试在某个时候搜索"循环").我无法想出一个可以让事情变得更容易的例子.

在Perl 5中,同样的事情是严格的错误:

use v5.10;
use strict;

for ( my $n = 0; $n < 3; $n++ ) {
    put $n;
    }

say "Outside: $n";  # Nope!
Run Code Online (Sandbox Code Playgroud)

而且,在C(那些让你这样做),这是一个类似的错误:

#include <stdio.h>

int main () {

   for( int a = 10; a < 20; a = a + 1 ){
      printf("value of a: %d\n", a);
   }

   printf("value of a: %d\n", a);  /* Nope! */

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

像往常一样,我的问题,我对解决方法不感兴趣.我知道怎么做.


正如我在评论中所指出的,概要4推动实现仅在它们出现的块内声明词法.

$n在之前出现{,所以它不是"内部"的块.

然而,尖头块怎么样?

-> $a { put "a is $a" }
Run Code Online (Sandbox Code Playgroud)

并且,子程序签名?

sub ( $a ) { put "a is $a" }
Run Code Online (Sandbox Code Playgroud)

这些变量首先在之前输入{.

我并不特别关心这一点,但如果我必须通过说你必须在你将使用它们的块中声明词法变量来解释传统的这种突破,有人可以指出这些情况.

Bra*_*ert 6

您可以将其视为块是创建词法范围的原因.

if (1) {
  my $a = 1;
}
$a;  # error
Run Code Online (Sandbox Code Playgroud)
if (my $a = 1) {
}
$a;  # no error
Run Code Online (Sandbox Code Playgroud)
loop (my $a = 1; $a == 1; ++$a) {
}
$a;  # no error
Run Code Online (Sandbox Code Playgroud)

只是其他类似C语言的特殊情况(C风格)for循环,而Perl 6设计的特殊情况尽可能少.

因此,如果某个地方的某些东西非常有用,那么它的设计应该可以在任何地方使用.


例如,-1在数组中索引.
而不仅仅是将@a[*-1]特殊语法限制为数组索引,*-1只是一种创建lambda /闭包的方法,您可以在任何想要简单lambda的地方使用它.

另一个例子是尖块不仅仅是一种在循环中声明迭代变量的方法for.

for @a -> $value {…}
Run Code Online (Sandbox Code Playgroud)

它们可用于任何类似的构造.

if $a.some-resource-expensive-op -> $result {…}
Run Code Online (Sandbox Code Playgroud)

代替

{
  # note that $result isn't read-only like it is above
  my $result = $a.some-resource-expensive-op;
  if $result {…}
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以将其用作创建lambda的另一种语法.

@a.sort: -> $value {…}
Run Code Online (Sandbox Code Playgroud)

为了使语言更容易理解,特殊情况需要拉动自己的权重,只有loop构造的参数,而没有其他构造,才能成为块的一部分.
如果它通常有用那么它会有所不同.

此外,该loop构造是少数几个与Perl 6的一般设计美学不相符的特征之一.我认为它可能更容易争论它的弃用和删除,而不是它更特殊的套装.
(没人争论要删除它)

  • @briandfoy可以考虑Perl 6的设计[*奇怪的一致*](http://strangelyconsistent.org/).一旦你意识到某个特定的特征与另一个特征是如何一致的,它就会更容易记住,即使有必要的陌生感也会使它略有不同. (3认同)