Ideas regarding flow control and loops

Bruce Adams tortoise_74 at yeah.who.co.uk
Mon Nov 5 15:12:48 PST 2007


BCS Wrote:

> Bruce Adams wrote:
> >BCS Wrote:
> >>Reply to Bruce,
> >>>BCS Wrote:
> >>>
> > 
> > Right. So what you really want is something that runs when the scope ends naturally but not on a break.
> > 
> > for(int i=5;i>0;i--)
> > {
> >   ...
> >   break;
> > }
> > if (i<=0) ThisNeverRuns();
> >  
> > 
> 
> that has the same behavior but duplicates the end condition check. This 
> can be both a performance hit and can be really bad when the condition 
> changes or if it has side effects.
>
The performance and side effects problems can't be avoided with your sugar either. Is this not what your syntactic sugar is supposed to alias to? If not, then what? Repeating code that changes is as always an issue but if its a complex condition it could (arguably should) be a function instead.
 
> > 
> >>>scope(skip):  - saves you one conditional - not very useful
> >>>
> >>>if (!cond)
> >>>DoIfCondNeverPasses();
> >>>else do
> >>>{
> >>>...
> >>>}
> >>>while(cond);
> >>>
> >>
> >>mine looks better (IMHO)
> >>
> > 
> > It doesn't justify a syntax change (IMHO)
> >  
> 
> IIRC scope is totally redundant to begin with, your counter argument 
> apply to it's existing functionality but people still like it.
>
I see I needed to RTFM. I see you are suggesting an extension to existing syntax I missed. Still it makes me uneasy. Overuse of this feature will make for very hard to read code. scope(exit) serves a very particular purpose to replace RAII where destructors can't be used because of GC. I don't actually get scope(success) and scope(failure) yet (have to RTFM some more). success and failure of what exactly? The page eplicitly says scope doesn't catch exceptions. Its only for replacing the finaly of a try catch finally.
 
> > 
> >>>scope(break): - saves you a function call or two.
> >>>
> >>>while(cond)
> >>>{
> >>>...
> >>>if (cond2) DoOnBreak(); break;
> >>>...
> >>>if (cond3) DoOnBreak(); break;
> >>>...
> >>>}
> >>
> >>you prove half of my point and don't address the other half
> >>
> > 
> > What was the other half again?
> >  
> > 
> 
> Below
> 
> >>while(cond)
> >>{
> >>...
> >>if (cond2)
> >>  DoOnBreak();
> >>break;
> >>...   // this never runs
> >>if (cond3)
> >>  DoOnBreak();
> >>
> >>break;
> >>...
> >>}
> >>
> >>If you didn't get it correct in this case, what are the chances of making 
> >>an error in a more complicated case
> >>
> > 
> > Harsh.  I was writing at 2am or thereabouts. Also you missed a semi-colon in 
> your for loop above does that render anything moot?
> > Personally I try to keep the body of a loop and in particular the control flow simple. I try to avoid breaks and put anything too large separate functions where possible.
> > 
> 
> Have you ever written real code at 2AM? 

Frequently.

> I'd like to have a language that 
>   helps me not make mistakes. We're all human.
>
I use unit tests, design by contract, lint and -Wall but every little helps.
But you prove my point. At 2am reading code with multiple complex paths of control flow is painful.
 
> > 
> >>The other part is that it is very easy to forget to add the DoOnBreak to 
> >>one of the breaks (you try finding them all in old code) or adding it to 
> >>every new one (Now what needs to be done on break this time).
> >>
> >>Also, it will work with mixin(string) when you can't get to the string.
> >>
> > 
> > That might be a more valid use. Care to post an example? I think we have to be careful with mixin's. They could easily be as abused as macros. There's no reason you couldn't write with a style that has an exit condition specified in the mixin. I don't like the idea of having a mixin with a break or return hidden in it (that goes beyond the scope of the mixin itself). That could make it very hard to follow the control flow.
> >  
> > 
> 
> agreed, mixin can make for some nasty code.

I'd still like to see a real worldish example where new syntax helps significantly.

> > 
> > I'm more worried about the programmer having to maintain code using bizarre constructs. The compiler can be clever out of sight.
> > 
> 
> It's not about the compiler being clever, it about the code having fewer 
> internal dependencies.
> 
> I like the scope solution because it states stuff where it makes a 
> difference, not where it needs to be done. Also it states stuff in a way 
> that make the intention of the code more clear. "do this then" rather 
> than "when that, do this" or even worse "do this now" in several places.
> 
> I'll concede it is a style issue.

I like the idea of "do this then" versus "do this now". Its breaks out of in the procedural (and even message passing OO style) where pretty much everything is now but I'm not entirely convinced this is the best way to express it. The body of a loop should have stuff to do with its body only. A finally block is in the right place, at the end for example (that's not to imply I like the earlier suggestion of adding finally blocks to loops either).

Regards,

Bruce.




More information about the Digitalmars-d mailing list