Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 有用的替代控制结构?_Loops_Programming Languages_Control Structure - Fatal编程技术网

Loops 有用的替代控制结构?

Loops 有用的替代控制结构?,loops,programming-languages,control-structure,Loops,Programming Languages,Control Structure,有时在编程时,我发现某些特定的控制结构对我非常有用,但在我的编程语言中并不直接可用。我认为我最常见的愿望是“分手”(我不知道该怎么称呼这个): 此代码的语义是始终运行foo(),然后检查条件。如果为true,则运行bar(),然后返回第一个块(因此再次运行foo(),以此类推)。多亏了,我知道Donald E.Knuth在他的论文中写到了这种结构(见第279页) 您认为哪些替代控制结构是组织计算的有效方法? 我在这里的目标是给我自己和其他人新的思考代码结构的方法,以改进分块和推理 注意:我不是问

有时在编程时,我发现某些特定的控制结构对我非常有用,但在我的编程语言中并不直接可用。我认为我最常见的愿望是“分手”(我不知道该怎么称呼这个):

此代码的语义是始终运行
foo()
,然后检查条件。如果为true,则运行
bar()
,然后返回第一个块(因此再次运行
foo()
,以此类推)。多亏了,我知道Donald E.Knuth在他的论文中写到了这种结构(见第279页)

您认为哪些替代控制结构是组织计算的有效方法?

我在这里的目标是给我自己和其他人新的思考代码结构的方法,以改进分块和推理

注意:我不是问如何概括所有可能的控制结构,无论是使用
jne
if
/
goto
,Lisp宏,continuations,monad,combinator,quark还是其他什么。我想问的是,在描述代码时,哪些专门化是有用的

{
    foo();
} split_while( condition ) {
    bar();
}
使用常规的
,您可以非常轻松地完成此任务,而

while (true) {
    foo();
    if (!condition) break;
    bar();
}
我现在经常这样做,因为我已经克服了我对使用(lisp风格)宏、尾部调用和延续的
break

的非理性厌恶。所有这些都很奇怪

对于宏,如果标准的控制流构造对于给定的应用程序来说是不够的,程序员可以编写自己的(等等)。它只需要一个简单的宏来实现您作为示例给出的构造

if (cond)
   //do something
else (cond)
   //do something
else (cond)
   //do something
first
   //do something
then
   //do something
else (cond)
   //do something
else
   //do something
end
通过尾部调用,可以将复杂的控制流模式(如实现状态机)分解为函数

Continuations是一个强大的控制流原语(try/catch是它们的受限版本)。结合尾部调用和宏,复杂的控制流模式(回溯、解析等)变得直截了当。此外,它们在web编程中很有用,因为使用它们可以反转控制反转;您可以使用一个函数,要求用户进行一些输入、进行一些处理、要求用户进行更多输入等


为了解释Scheme标准,您不应该在您的语言中添加更多的功能,而应该设法消除使其他功能显得必要的限制。

还要注意,许多控件结构在一元上下文中获得了新的含义,这取决于特定的一元-查看mapM、filterM、whileM、,Haskell中的sequence等。

如果您查看Haskell,尽管各种控制结构都有特殊的语法,但控制流通常由类型捕获。最常见的此类控件类型是单子、箭头和应用程序函子。因此,如果您想要一种特殊类型的控制流,它通常是某种高阶函数,您可以自己编写,也可以在Haskells package database(Hackage)中找到一个,它相当大

这类函数通常位于控制命名空间中,您可以在其中找到用于并行执行以进行错误处理的模块。过程语言中的许多控制结构通常都有一个对应于control.Monad的函数,其中包括循环和if语句。If-else在haskell中是一个关键字表达式,If-without-else在表达式中没有意义,但在monad中完全有意义,因此函数
when
会捕获If-without-else语句,除非


另一种常见情况是在更一般的上下文中执行列表操作。函数式语言非常喜欢
折叠
,专门的版本有
map
filter
。如果你有一个单子,那么它有一个自然的扩展
fold
。这被称为
foldM
,因此也有你能想到的任何专门版本的fold的扩展,比如
mapM
filterM
这有点开玩笑,但是你可以得到你想要的行为,就像这样:

#include <iostream>
#include <cstdlib>

int main (int argc, char *argv[])
{
  int N = std::strtol(argv[1], 0, 10); // Danger!
  int state = 0;
  switch (state%2) // Similar to Duff's device.
  {
    do {
      case 1: std::cout << (2*state) << " B" << std::endl;
      case 0: std::cout << (2*state+1) << " A" << std::endl; ++state;
    } while (state <= N);
      default: break;
  }

  return 0;
}
forever {
  // ...
}
foreach (index i) (var item in list) {
  // ...
}
        foreach(var val in dataSource)
        groupon(val.CustomerID)
        {            
            startgroup
            {
                WriteHeader(val);
            }
            endgroup
            {
                WriteFooter(val)
            }
        }
        each
        {
            WriteRow(val);
        }
withControlBreaks (x, y, z : readSortedRecords()) {
  first (x) :     { emitHeader(x); subcount = 0; }
  first (x, y) :  { emitSubheader(x, y); zTotal = 0; }
  all (x, y, z) : { emitDetail(x, y, z); ztotal += z; }
  last (x, y) :   { emitSubfooter(x, y, zTotal); ++subCount; }
  last (x) :      { emitFooter(x, subcount); }
}
#包括
#包括
int main(int argc,char*argv[])
{
int N=std::strtol(argv[1],0,10);//危险!
int state=0;
开关(状态%2)//类似于达夫的设备。
{
做{

案例1:std::cout一个非常常见的是无限循环。我想这样写:

#include <iostream>
#include <cstdlib>

int main (int argc, char *argv[])
{
  int N = std::strtol(argv[1], 0, 10); // Danger!
  int state = 0;
  switch (state%2) // Similar to Duff's device.
  {
    do {
      case 1: std::cout << (2*state) << " B" << std::endl;
      case 0: std::cout << (2*state+1) << " A" << std::endl; ++state;
    } while (state <= N);
      default: break;
  }

  return 0;
}
forever {
  // ...
}
foreach (index i) (var item in list) {
  // ...
}
        foreach(var val in dataSource)
        groupon(val.CustomerID)
        {            
            startgroup
            {
                WriteHeader(val);
            }
            endgroup
            {
                WriteFooter(val)
            }
        }
        each
        {
            WriteRow(val);
        }
withControlBreaks (x, y, z : readSortedRecords()) {
  first (x) :     { emitHeader(x); subcount = 0; }
  first (x, y) :  { emitSubheader(x, y); zTotal = 0; }
  all (x, y, z) : { emitDetail(x, y, z); ztotal += z; }
  last (x, y) :   { emitSubfooter(x, y, zTotal); ++subCount; }
  last (x) :      { emitFooter(x, subcount); }
}

有时,我需要一个带有索引的foreach循环。它可以这样写:

#include <iostream>
#include <cstdlib>

int main (int argc, char *argv[])
{
  int N = std::strtol(argv[1], 0, 10); // Danger!
  int state = 0;
  switch (state%2) // Similar to Duff's device.
  {
    do {
      case 1: std::cout << (2*state) << " B" << std::endl;
      case 0: std::cout << (2*state+1) << " A" << std::endl; ++state;
    } while (state <= N);
      default: break;
  }

  return 0;
}
forever {
  // ...
}
foreach (index i) (var item in list) {
  // ...
}
        foreach(var val in dataSource)
        groupon(val.CustomerID)
        {            
            startgroup
            {
                WriteHeader(val);
            }
            endgroup
            {
                WriteFooter(val)
            }
        }
        each
        {
            WriteRow(val);
        }
withControlBreaks (x, y, z : readSortedRecords()) {
  first (x) :     { emitHeader(x); subcount = 0; }
  first (x, y) :  { emitSubheader(x, y); zTotal = 0; }
  all (x, y, z) : { emitDetail(x, y, z); ztotal += z; }
  last (x, y) :   { emitSubfooter(x, y, zTotal); ++subCount; }
  last (x) :      { emitFooter(x, subcount); }
}
(我不是特别喜欢这种语法,但你知道了)

怎么样

alternate {
    statement 1,
    statement 2,
    [statement 3,...]
}
用于循环浏览每个连续过程中的可用语句

编辑:琐碎的例子

table_row_color = alternate(RED, GREEN, BLUE);

player_color = alternate(color_list); // cycles through list items

alternate(
    led_on(),
    led_off()
);
编辑2:在上面的第三个示例中,语法可能有点混乱,因为它看起来像一个函数。事实上,每次传递只计算一条语句,而不是两条语句。更好的语法可能是

alternate {
    led_on();
}
then {
    led_off();
}
不过,我很喜欢这样的想法,即如果需要,可以使用which ever调用的结果(如颜色示例中所示)。

如果没有:

unless (condition) {
  // ...
}
虽然不是:

until (condition) {
  // ...
}

忽略
-忽略特定代码块中发生的异常

try {
  foo()
} catch {
  case ex: SomeException => /* ignore */
  case ex: SomeOtherException => /* ignore */
}
使用
忽略
控件构造,您可以更简洁易懂地编写它,如下所示:

ignoring(classOf[SomeException], classOf[SomeOtherException]) {
  foo()
}
[Scala在其标准库中,在
util.control
package中提供了这个(以及许多其他异常处理控件构造)。]

与else循环:

while (condition) {
  // ...
}
else {
  // the else runs if the loop didn't run
}

如果您主要使用非函数式语言,那么Python中的生成器真的很新颖。更一般的情况是:延续、协同例程、惰性列表。

这可能不算,但在Python中,我对没有do循环感到不安


为了确保我的答案不会被否决,我在任何一段时间内都会对我所使用的任何一种语言感到恼火,因为这些语言都缺少goto's。

标记的循环是我发现自己缺少的一些东西
for int i := 0 [down]to UpperBound() [step 2]
bool found = false;
for (int i = 0; i < N; i++) {
  if (hasProperty(A[i])) {
    found = true;
    DoSomething(A[i]);
    break;
  }
}
if (!found) {
  ...
}
for (int i = 0; i < N; i++) {
  if (hasProperty(A[i])) {
    DoSomething(A[i]);
    break;
  }
} ifnotinterrupted {
  ...
}
        int lastValue = 0;

        foreach (var val in dataSource)
        {
            if (lastValue != val.CustomerID)
            {                    
                WriteFooter(lastValue);
                WriteHeader(val);
                lastValue = val.CustomerID;
            }
            WriteRow(val);
        }
        if (lastValue != 0)
        {
            WriteFooter(lastValue);
        }
        foreach(var val in dataSource)
        groupon(val.CustomerID)
        {            
            startgroup
            {
                WriteHeader(val);
            }
            endgroup
            {
                WriteFooter(val)
            }
        }
        each
        {
            WriteRow(val);
        }
{$ forEach n var in (condition) sort-order $}
... text which appears for each item ....
{$ between $}
.. text which appears between each two items ....
{$ odd $}
.. text which appears for every other item, including the first ....
{$ even $}
.. text which appears for every other item, starting with the second ....
{$ else $}
.. text which appears if there are no items matching condition ....
{$ before $}
..text which appears before the loop, only if there are items matching condition
{$ after $}
..text which appears after the loop, only of there are items matching condition
{$ next $}
withControlBreaks (x, y, z : readSortedRecords()) {
  first (x) :     { emitHeader(x); subcount = 0; }
  first (x, y) :  { emitSubheader(x, y); zTotal = 0; }
  all (x, y, z) : { emitDetail(x, y, z); ztotal += z; }
  last (x, y) :   { emitSubfooter(x, y, zTotal); ++subCount; }
  last (x) :      { emitFooter(x, subcount); }
}
(cond
   ((evenp a) a)        ;if a is even return a
   ((> a 7) (/ a 2))    ;else if a is bigger than 7 return a/2
   ((< a 5) (- a 1))    ;else if a is smaller than 5 return a-1
   (t 17))              ;else return 17
cond 
    (a % 2 == 0): 
        a;     break;
    (a > 7):
        a / 2; break;
    (a < 5):
        a - 1; break;
    default:
        17;    break;