Recent

Author Topic: how to break out early of a case ?  (Read 66569 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: how to break out early of a case ?
« Reply #165 on: December 07, 2021, 01:53:23 pm »
Once we have support for compile time functions (the current term for them is “pure functions”) you can add that yourself ;)

:-) OTOH I'd suggest that that specific case might be worth examining whenever anybody complains that his desired initialisation can't be coded... I'm not suggesting that some implementation be added prematurely, only that it might turn out to be a common "pattern".

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: how to break out early of a case ?
« Reply #166 on: December 07, 2021, 02:05:45 pm »
Once we have support for compile time functions (the current term for them is “pure functions”) you can add that yourself ;)

:-) OTOH I'd suggest that that specific case might be worth examining whenever anybody complains that his desired initialisation can't be coded... I'm not suggesting that some implementation be added prematurely, only that it might turn out to be a common "pattern".

No, it's not worth examining, because then the next one will come with the next function and so on. Better focus this into a more general approach.

Also if all you need is the size in bits then you can always use BitSizeOf.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: how to break out early of a case ?
« Reply #167 on: December 07, 2021, 02:07:48 pm »
No, it's not worth examining, because then the next one will come with the next function and so on. Better focus this into a more general approach.

Also if all you need is the size in bits then you can always use BitSizeOf.

I didn't mean examining as in "we'll add a function" but as in "if you did it like this you wouldn't be asking us to add a function" :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Kaller

  • Jr. Member
  • **
  • Posts: 73
Re: how to break out early of a case ?
« Reply #168 on: December 19, 2023, 10:47:05 pm »
Grave digging here but in simple cases where the condition is not deeply embedded then

Code: Pascal  [Select][+][-]
  1. case I of
  2.   somevalue :
  3.   begin
  4.     statement ...
  5.     statement...
  6.  
  7.     if someconditionhere then
  8.    begin
  9.      ; // Do nothing
  10.    else
  11.   begin
  12.     // Carry on
  13.   end;
  14.  
  15.     statement ...
  16.     statement....
  17.   end;
  18.  
  19.   <more cases here>
  20. end; { case }
  21.  

Otherwise you could do something using functions, and/or raise an exception to the same effect.

« Last Edit: December 19, 2023, 10:56:25 pm by Kaller »

440bx

  • Hero Member
  • *****
  • Posts: 4029
Re: how to break out early of a case ?
« Reply #169 on: December 20, 2023, 12:05:52 am »
After asking the question I figured a very simple way that is even more powerful and flexible than the C switch.  Something like this:

Code: Pascal  [Select][+][-]
  1. while TRUE do
  2. begin
  3.   case SelectorVariable of
  4.     1 :
  5.     begin
  6.       <statement>
  7.       <statement>
  8.  
  9.       if somecondition then break;  { exits the case early }
  10.  
  11.       <statement>
  12.  
  13.       SelectorVariable := 2; { to cause fall through as in C }
  14.     end;
  15.  
  16.     2 :  
  17.     begin
  18.       <bunch of statements here>
  19.  
  20.       break; { exit case statement }
  21.     end;
  22.  
  23.     <more cases if needed >
  24.  
  25.     otherwise
  26.     begin
  27.       <statements>
  28.  
  29.       break;
  30.     end;
  31.   end; { case }
  32. end; { while }
  33.  

Note that instead of using TRUE, the while loop could use the SelectorVariable too and exit when it becomes a specific value, this could make some executions simpler.

As shown above, any case can carry out any test it wants and execute "break" which will end the loop, therefore the "case" too since they are now tied together.

The first case shows how to accomplish the C fall through.  Using the while loop enables full control of the execution of the each case, the sequence in which they are executed, fall through and, the number of time each case is executed.

Move over C switch, go to the corner and talk to Beethoven.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: how to break out early of a case ?
« Reply #170 on: December 20, 2023, 08:47:57 am »
Code: Pascal  [Select][+][-]
  1.       SelectorVariable := 2; { to cause fall through as in C }
  2.     end;
  3.  
  4.     2 :  
  5.  

Does that actually work, and is it documented behaviour? My understanding was that the selector was evaluated only at the head of the case statement.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Eugene Loza

  • Hero Member
  • *****
  • Posts: 674
    • My games in Pascal
Re: how to break out early of a case ?
« Reply #171 on: December 20, 2023, 09:21:58 am »
the selector was evaluated only at the head of the case statement.
Indeed, that's my understanding too, and that's how it works for me in objfpc mode:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. var
  4.   A: Integer;
  5. begin
  6.   A := 1;
  7.   case A of
  8.     1: begin
  9.          WriteLn('1');
  10.          A := 3;
  11.        end;
  12.     2: WriteLn('2');
  13.     3: begin
  14.          WriteLn('3');
  15.          A := 2;
  16.       end;
  17.   end;
  18.   WriteLn('Done');
  19.   ReadLn;
  20. end.  
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

Nitorami

  • Sr. Member
  • ****
  • Posts: 496
Re: how to break out early of a case ?
« Reply #172 on: December 20, 2023, 09:25:53 am »
You are right, that puzzled me as well because the code of 440bx does work, surprisingly. The trick is in the "while true" loop which repeats the case selection.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: how to break out early of a case ?
« Reply #173 on: December 20, 2023, 09:38:21 am »
You are right, that puzzled me as well because the code of 440bx does work, surprisingly. The trick is in the "while true" loop which repeats the case selection.

The problem is that he's changing the selector, then implying that it falls straight into 2: in the style of C. I agree that wrapping the case in a while works (which is, after all, standard state-machine practice) but I'm very dubious about that claimed fallthrough.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Zoran

  • Hero Member
  • *****
  • Posts: 1830
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: how to break out early of a case ?
« Reply #174 on: December 20, 2023, 12:10:52 pm »
You are right, that puzzled me as well because the code of 440bx does work, surprisingly. The trick is in the "while true" loop which repeats the case selection.

The problem is that he's changing the selector, then implying that it falls straight into 2: in the style of C. I agree that wrapping the case in a while works (which is, after all, standard state-machine practice) but I'm very dubious about that claimed fallthrough.

MarkMLl

You didn't understand the point -- in case "1", the selector variable is set to "2", then while loop continues and case "2" is executed in next iteration -- that is emulated fall-through; and that is what 440bx meant, not a real fall-through.

Zoran

  • Hero Member
  • *****
  • Posts: 1830
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: how to break out early of a case ?
« Reply #175 on: December 20, 2023, 12:25:51 pm »
Actually, I realize that I used a very similar trick (currently lines 148-182) to what 440bx shows, though I have never thought about it as a kind of "fall-through".
« Last Edit: December 20, 2023, 12:56:53 pm by Zoran »

Joanna

  • Hero Member
  • *****
  • Posts: 760
Re: how to break out early of a case ?
« Reply #176 on: December 20, 2023, 12:47:40 pm »
This discussion seems very long  :D

I think having a lot of code inside a case statement can get kind of messy. Here is what I would do. I would move the code out of case into procedures.
Code: Pascal  [Select][+][-]
  1. Case condition of
  2. 1:procedure1;
  3. 2:procedure2;
  4. End;
  5.  

Procedures are easy to break out of and doing so would make you exit the case statement as well.
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: how to break out early of a case ?
« Reply #177 on: December 20, 2023, 01:06:20 pm »
You didn't understand the point -- in case "1", the selector variable is set to "2", then while loop continues and case "2" is executed in next iteration -- that is emulated fall-through; and that is what 440bx meant, not a real fall-through.

Well he ought to write what he means then (no disrespect intended). A constant stream of "of course Pascal can do that..." statements which turn out to be not quite accurate does nothing to promote the language when read by the broader community.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 6686
Re: how to break out early of a case ?
« Reply #178 on: December 20, 2023, 01:11:13 pm »
This discussion seems very long  :D

I think having a lot of code inside a case statement can get kind of messy. Here is what I would do. I would move the code out of case into procedures.
Code: Pascal  [Select][+][-]
  1. Case condition of
  2. 1:procedure1;
  3. 2:procedure2;
  4. End;
  5.  

Procedures are easy to break out of and doing so would make you exit the case statement as well.

That's fine in theory but not in practice. Consider the situation where the case statement is in a loop, and each case can do one of

* exit the current procedure

* break the loop

* continue at the head of the loop

* continue at the end of the case statement

As soon as you have to accommodate those you're back at the situation of having multiple lines of code in each case, you've really gained nothing except a few lines of boilerplate elsewhere.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Joanna

  • Hero Member
  • *****
  • Posts: 760
Re: how to break out early of a case ?
« Reply #179 on: December 20, 2023, 01:36:32 pm »
i tried this and the continue seems to work fine from inside case
Code: Pascal  [Select][+][-]
  1. h:= 1;
  2.   while h < 5 do
  3.        begin
  4.        case h of
  5.             1:begin ShowMessage('continue'); continue; end;
  6.             2:break;
  7.            END;
  8.        inc(h);
  9.        END;  

do you have any code examples to illustrate what you are saying ?
✨ 🙋🏻‍♀️ More Pascal enthusiasts are needed on IRC .. https://libera.chat/guides/ IRC.LIBERA.CHAT  Ports [6667 plaintext ] or [6697 secure] channel #fpc  Please private Message me if you have any questions or need assistance. 💁🏻‍♀️

 

TinyPortal © 2005-2018