【问题标题】:Control structures beyond standard conditionals and loops?超出标准条件和循环的控制结构?
【发布时间】:2011-07-31 03:04:44
【问题描述】:

结构化编程语言通常具有一些控制结构,例如 whileiffordoswitchbreakcontinue,用于表示高级源代码中的结构。

但是,多年来提出的许多其他控制结构尚未进入现代编程语言。例如,在 Knuth 的论文“Structured Programming with Go To Statements”第 275 页中,他引用了一个看起来像是异常处理的精简版的控制结构:

loop until event1 or event2 or ... eventN
   /* ... */
   leave with event1;
   /* ... */
repeat;
then event1 -> /* ... code if event1 occurred ... */
     event2 -> /* ... code if event2 occurred ... */
     /* ... */
     eventN -> /* ... code if eventN occurred ... */
fi;

这似乎是一个有用的结构,但除了标准异常处理的特殊情况之外,我还没有看到任何语言实际实现它。

同样,Edsger Dijkstra 经常使用一种控制结构,在该结构中,许多代码片段中的一个片段根据一组可能为真的条件以非确定性方式执行。你可以在其他地方看到这个on page 10 of his paper on smoothsort。示例代码可能如下所示:

do
    /* Either of these may be chosen if x == 5 */
    if x <= 5 then y = 5;
    if x >= 5 then y = 137; 
od;

我知道在历史上 C 影响了许多现代语言,如 C++、C# 和 Java,我们今天使用的许多控制结构都是基于 C 提供的小集合。但是,as evidenced by this other SO question,我们程序员喜欢思考我们希望拥有但许多编程语言不支持的替代控制结构。

我的问题是 - 目前使用的通用语言是否支持与我上面提到的 C 风格控制结构完全不同的控制结构?这样的控制结构不一定是什么东西无法使用标准 C 结构表示 - 几乎任何东西都可以用这种方式编码 - 但理想情况下,我想要一个示例,它可以让您以与 C 模型所允许的完全不同的方式处理某些编程任务。

不,“函数式编程”并不是真正的控制结构。

【问题讨论】:

  • 只是一个小注解:多年来我一直想要一个“for...else”结构,而就在几个月前我发现它可以在 Python 中实现。
  • @Radagaisus:什么是“for...else”?
  • @Mehrdad:如果循环自然终止(而不是中断),则执行 for-else 循环中的 else 块。无论迭代多少次(甚至为零),这都适用。
  • 它按照 BoltClock 所说的去做。使用var found = false 编写循环时,我总是觉得过于冗长。 More info.
  • @BoltClock:啊,我明白了……很奇怪,哈哈。

标签: programming-languages control-structure structured-programming


【解决方案1】:
  • 由于 Haskell 是 lazy每个函数调用本质上都是一个控制结构。
  • ML 派生语言中的Pattern-matching 将分支、变量绑定和解构对象合并到一个控制结构中。
  • Common Lisp 的conditions 就像可以重新启动的异常。
  • 方案和其他语言支持continuations,让您可以随时暂停、恢复或重新启动程序。

【讨论】:

    【解决方案2】:

    也许不是“完全不同”但“异步”的控制结构是相当新的。

    异步允许并行执行非阻塞代码,一旦完成,控制权就会返回到主程序流。尽管使用嵌套回调也可以实现相同的效果,但以这种方式做任何不平凡的事情都会导致代码非常糟糕。

    例如,在即将发布的 C#/VB 版本中,Async 允许调用异步 API,而无需将代码拆分为多个方法或 lambda 表达式。 IE。没有更多的回调。 “await” 和 “async” 关键字使您能够编写异步方法,这些方法可以在不消耗线程的情况下暂停执行,然后再从中断处继续。

    // C#
    async Task<int> SumPageSizesAsync(IList<Uri> uris)
    {
        int total = 0;
        var statusText = new TextBox();
    
        foreach (var uri in uris)
        {
            statusText.Text = string.Format("Found {0} bytes ...", total);
            var data = await new WebClient().DownloadDataTaskAsync(uri);
            total += data.Length;
        }
    
        statusText.Text = string.Format("Found {0} bytes total", total);
        return total;
    }
    

    (来自http://blogs.msdn.com/b/visualstudio/archive/2011/04/13/async-ctp-refresh.aspx

    对于 Javascript,http://tamejs.org/ 允许您编写如下代码:

    var res1, res2;
    await {
        doOneThing(defer(res1));
        andAnother(defer(res2));
    }
    thenDoSomethingWith(res1, res2);
    

    【讨论】:

      【解决方案3】:

      C#/Python 迭代器/生成器

      def integers():
          i = 0
          while True:
              yield i
              i += 1
      

      【讨论】:

      • 这很像惰性求值。例如,在 Haskell 中:take 2 [1,2,3,4] -> [1,2]
      • @Radagaisus:不,不是。它更像协程——一个完全不同的概念(即在执行过程中暂停/恢复函数)。它“延迟”的事实与此无关。
      【解决方案4】:

      (我对这个主题了解不多,所以我将其标记为 wiki)

      Haskell's Pattern Matching.

      简单示例:

      sign x |  x >  0        =   1
             |  x == 0        =   0
             |  x <  0        =  -1
      

      或者说,斐波那契,它看起来几乎与数学方程相同:

      fib x | x < 2       = 1
            | x >= 2      = fib (x - 1) + fib (x - 2)
      

      【讨论】:

        猜你喜欢
        • 2021-04-09
        • 1970-01-01
        • 2012-06-24
        • 2013-07-06
        • 2018-03-11
        • 2015-02-12
        • 2023-01-11
        • 2011-12-01
        • 1970-01-01
        相关资源
        最近更新 更多