Useful alternative control structures?

2019-03-08 02:01发布

Sometimes when I am programming, I find that some particular control structure would be very useful to me, but is not directly available in my programming language. I think my most common desire is something like a "split while" (I have no idea what to actually call this):

{
    foo();
} split_while( condition ) {
    bar();
}

The semantics of this code would be that foo() is always run, and then the condition is checked. If true, then bar() is run and we go back to the first block (thus running foo() again, etc). Thanks to a comment by reddit user zxqdms, I have learned that Donald E. Knuth writes about this structure in his paper "Structured programming with go to statements" (see page 279).

What alternative control structures do you think are a useful way of organizing computation?

My goal here is to give myself and others new ways of thinking about structuring code, in order to improve chunking and reasoning.

Note: I'm not asking about how to generalize all possible control structures, whether by using jne, if/goto, Lisp macros, continuations, monads, combinators, quarks, or whatever else. I'm asking what specializations are useful in describing code.

28条回答
兄弟一词,经得起流年.
2楼-- · 2019-03-08 02:24

This is a bit of a joke, but you can get the behavior you want like this:

#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;
}

p.s. formatting this was a bit difficult and I'm definitely not happy with it; however, emacs does even worse. Anyone care to try vim?

查看更多
3楼-- · 2019-03-08 02:29

If you look at Haskell, although there is special syntax for various control structures, control flow is often captured by types. The most common kind of such control types are Monads, Arrows and applicative functors. So if you want a special type of control flow, it's usually some kind of higher-order function and either you can write it yourself or find one in Haskells package database (Hackage) wich is quite big.

Such functions are usually in the Control namespace where you can find modules for parallel execution to errorhandling. Many of the control structures usually found in procedural languages have a function counterpart in Control.Monad, among these are loops and if statements. If-else is a keyworded expression in haskell, if without an else doesn't make sense in an expression, but perfect sense in a monad, so the if statements without an else is captured by the functions when and unless.

Another common case is doing list operation in a more general context. Functional languages are quite fond of fold, and the Specialized versions like map and filter. If you have a monad then there is a natural extension of fold to it. This is called foldM, and therefor there are also extensions of any specialized version of fold you can think of, like mapM and filterM.

查看更多
相关推荐>>
4楼-- · 2019-03-08 02:31

How about iterating with a moving window (of n elements instead of 1) through a list? This is tangentially related @munificent's answer, I think.

Something like

#python
#sum of adjacent elements
for x,y in pairs(list):
    print x + y

def pairs(l):              
    i=0                    
    while i < len(l)-1:    
        yield (l[i],l[i+1])
        i+=1               

It is useful for certain types of things. Don't get me wrong, this is easy to implement as a function, but I think a lot of people try to bring out for and while loops when there are more specific/descriptive tools for the job.

查看更多
狗以群分
5楼-- · 2019-03-08 02:31

if not:

unless (condition) {
  // ...
}

while not:

until (condition) {
  // ...
}
查看更多
一纸荒年 Trace。
6楼-- · 2019-03-08 02:32

Loop with else:

while (condition) {
  // ...
}
else {
  // the else runs if the loop didn't run
}
查看更多
聊天终结者
7楼-- · 2019-03-08 02:33

How about PL/I style "for" loop ranges? The VB equivalent would be:

' Counts 1, 2, ... 49, 50, 23, 999, 998, ..., 991, 990
  For I = 1 to 50, 23, 999 to 990 Step -1

The most common usage I can see would be to have a loop run for a list of indices, and then throw in one more. BTW, a For-Each usage could also be handy:

' Bar1, Bar2, Bar3 are an IEnum(Wazoo); Boz is a Wazoo
  For Each Foo as Wazoo in Bar1, Bar2, Enumerable.One(Boz), Bar3

This would run the loop on all items in Bar1, all items in Bar2, Boz, and Bar3. Linq would probably allow this without too much difficulty, but intrinsic language support might be a little more efficient.

查看更多
登录 后发表回答