Recent

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

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: how to break out early of a case ?
« Reply #105 on: November 29, 2021, 09:13:38 pm »
Aren't managed variables like strings initialised to guaranteed minimum length as well?

Afaik that is considered an implementation detail, and to keep compatible with shortstrings, it was advised not to abuse that, so that string code could be swapped betwixt them.

Thanks for that. This is a bit like chess: if somebody had said that (non-shortstring) strings were minified (? :-) I'd have cited this

Code: Pascal  [Select][+][-]
  1. type
  2.   TPortDescription= record
  3.                       baseName: string;   (* This field is mandatory, e.g. ttyS *)
  4.                       idVendor: string;   (* Not tested if blank                *)
  5.                       idProduct: string;  (* Not tested if blank                *)
  6.                       driverName: string; (* Non-presence is ignored if blank   *)
  7.                       manufacturer: string; (* Non-presence is ignored if blank *)
  8.                       product: string;    (* Non-presence is ignored if blank   *)
  9.                       serial: string      (* Non-presence is ignored if blank   *)
  10.                     end;
  11. ...
  12. const
  13.   descriptionTemplate: TPortDescription= (
  14.                          baseName: 'ttyUSB';
  15.                          idVendor: '';
  16.                          idProduct: '';
  17.                          driverName: 'usb-serial/drivers/pl2303';
  18.                          manufacturer: 'Prolific Technology Inc.';
  19.                          product: 'USB-Serial Controller';
  20.                          serial: '';
  21.                        );
  22.  

and asked why those fields had to be explicitly initialised if their state was known.

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

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: how to break out early of a case ?
« Reply #106 on: November 29, 2021, 09:20:08 pm »
Well, I have been using TP, BP, Delphi and FPC for 35 years, and I learned something new today. But I think I do have an excellent grasp of it.

I have been programming in C and C++ almost as long, and while C isn't that hard in small bites, it can become really hard when you get to identifiers like this:

Code: [Select]
**(*((*SomeIdentifier)*)*)
And I doubt you can truly understand C++. Too much special cases and most of what you can do, you really shouldn't.
« Last Edit: November 29, 2021, 09:21:45 pm by SymbolicFrank »

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: how to break out early of a case ?
« Reply #107 on: November 29, 2021, 09:24:46 pm »
and asked why those fields had to be explicitly initialised if their state was known.

MarkMLl
To make it easier to understand?

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: how to break out early of a case ?
« Reply #108 on: November 29, 2021, 09:30:47 pm »
And I doubt you can truly understand C++. Too much special cases and most of what you can do, you really shouldn't.

Agreed. I'm slowly reading through the Rust documentation: they appear to be making a genuine attempt at asking what's really needed in the core language to support more complex stuff built on top.

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

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: how to break out early of a case ?
« Reply #109 on: November 29, 2021, 09:37:59 pm »
Which perfectly demonstrates that allowing one shorthand only needs to the next.
That reply of yours is an excellent example of your tendency to present useful features as if they were programming platitudes.

Being able to specify a group of variables to be of the same type by making it a single declaration is hardly a simple shorthand.  Without that "shorthand", there is no indication that those variables must be of the same type (an important fact to be aware of when maintaining the program.) It's the same thing with group variable initialization.

As I stated previously, I believe you know this.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: how to break out early of a case ?
« Reply #110 on: November 29, 2021, 10:03:48 pm »
Being able to specify a group of variables to be of the same type by making it a single declaration is hardly a simple shorthand.   

So what else is there to a group of variables then?

What is the concrete difference between

Code: [Select]
var a,b: integer;

vs

Code: [Select]
var a: integer;
     b: integer;

?

The "group of variables" only exists to justify the need for the initialization shorthand. It isn't a real thing.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: how to break out early of a case ?
« Reply #111 on: November 29, 2021, 10:19:47 pm »
The "group of variables" only exists to justify the need for the initialization shorthand. It isn't a real thing.

Everybody, please. I'm certainly not here to try to knock the core team, but neither am I here to dismiss every possible enhancement: particularly when well-argued.

(Or, as in an advert many years ago, "I come to bury C, sir, not to praise it" :-)

The "group of variables" is basically what is discussed in the FP Reference Guide, section 3.5, where it explicitly says

The referenced type should be introduced later in the same Type block. No other block may come between the definition of the pointer type and the referenced type.

So there's already strong precedent for considering types or variables declared together being in some way related to a greater extent than if they'd been declared separately. I believe that that was subsequently tightened up in Modula-2.

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

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: how to break out early of a case ?
« Reply #112 on: November 29, 2021, 10:22:29 pm »
What is the concrete difference between

Code: Pascal  [Select][+][-]
  1. var a,b: integer;
  2.  

vs

Code: Pascal  [Select][+][-]
  1. var a: integer;
  2.      b: integer;
  3.  

?
The concrete difference between those two is that, if used properly, the first construct informs the programmer that the two variables in the declaration should be of the same type. 

The second declaration doesn't do that.  If there is a need for the two variables to be of the same type then, it's very likely that in a maintenance cycle, a programmer will decide to change the type of the first variable and omit changing the type of the second because the impression is that they are  two totally unrelated variables or vice-versa, of course.

That's the concrete difference.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: how to break out early of a case ?
« Reply #113 on: November 29, 2021, 10:23:40 pm »
Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c: integer = 0;
  3.   s1, s2: string;
  4. begin
  5. //..
  6. end;

vs

Code: Pascal  [Select][+][-]
  1. var
  2.   a: integer = 0;
  3.   b: integer = 0;
  4.   c: integer = 0;
  5.   s1: string;
  6.   s2: string;
  7. begin
  8. //..
  9. end;

Who would prefer the second syntax if the first were available?
keep it simple

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: how to break out early of a case ?
« Reply #114 on: November 29, 2021, 10:28:01 pm »
Who would prefer the second syntax if the first were available?
Not to mention that there is no good reason not to have the first option.  It's the natural option.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11382
  • FPC developer.
Re: how to break out early of a case ?
« Reply #115 on: November 29, 2021, 10:43:54 pm »
The "group of variables" is basically what is discussed in the FP Reference Guide, section 3.5, where it explicitly says

The referenced type should be introduced later in the same Type block. No other block may come between the definition of the pointer type and the referenced type.

So there's already strong precedent for considering types or variables declared together being in some way related to a greater extent than if they'd been declared separately. I believe that that was subsequently tightened up in Modula-2.

Weak argumentation to lift an exception to limit the impact of forward type referencing to a general rule even for other blocks. IMHO not even remotely plausible, it is like arguing that all semi-colons should go away because the dangling else was fixed by omitting it.

Modula2 also added  "opague" forward references, which were looser, as the final type of the pointer was  only defined in the implementation, being primarily meant as handle type.  I don't remember what the rules were for non opague types.



MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: how to break out early of a case ?
« Reply #116 on: November 29, 2021, 10:48:08 pm »
Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c: integer = 0;
  3.   s1, s2: string;
  4. begin
  5. //..
  6. end;

Or even

Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c: integer = (0, 0, 0);
  3.   s1, s2: string;
  4. begin
  5. //..
  6. end;

I grant that this is less concise than some form of multiple or replicated assignment, but it does guarantee that the three variables can be considered to be the same type by the compiler.

And it appears to be that level of robustness that Rust is targetting...

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: 6676
Re: how to break out early of a case ?
« Reply #117 on: November 29, 2021, 10:51:12 pm »
Modula2 also added  "opague" forward references, which were looser,

I'd hardly call that looser. It was still a robust type check, albeit of a type which was not accessible external to the module.

MarkMLl

p.s. s/gue/que/g :-)
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

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: how to break out early of a case ?
« Reply #118 on: November 29, 2021, 10:51:41 pm »
Who would prefer the second syntax if the first were available?
Not to mention that there is no good reason not to have the first option.  It's the natural option.

I remember having this discussion before and if memory serves me well, the grouped initialization syntax cannot be easily implemented in FPC. While I haven't looked at the FPC source myself, I can imagine that if the parser feeds the syntax directly to a AST structure, the initialization may be a problem.

SharpBASIC doesn't do it like that. It collects all declarations with type and initialization (immediate) and adds them to the symbol table. After the stack frame is setup the symbol table (with initializations) is read out and the variables are initialized.

The following code:
Code: Text  [Select][+][-]
  1. sub test()
  2.   dim a, b, c: int = 0;
  3.   dim s1, s2: str;
  4. do
  5.  
  6. end;

would generate:
Code: ASM  [Select][+][-]
  1.         push    ebp
  2.         mov     ebp, esp
  3.         sub     esp, 20
  4. ; load immediate
  5.         movsx   eax, byte [_sb_refn]
  6. ; save a
  7.         mov     [ebp - 4], eax
  8. ; save b
  9.         mov     [ebp - 8], eax
  10. ; save c
  11.         mov     [ebp - 12], eax
  12. ; create local variable string 's1'
  13.         call    _sb_create_strdesc
  14. ; save descriptor address
  15.         mov     [ebp - 16], eax
  16.  
  17. ; create local variable string 's2'
  18.         call    _sb_create_strdesc
  19. ; save descriptor address
  20.         mov     [ebp - 20], eax

With or without grouped initialization, the output would be the same, but we have the compiler to do the dirty work for us, as it should be.  ;)
« Last Edit: November 30, 2021, 12:11:48 pm by munair »
keep it simple

440bx

  • Hero Member
  • *****
  • Posts: 3944
Re: how to break out early of a case ?
« Reply #119 on: November 29, 2021, 10:57:15 pm »
Code: Pascal  [Select][+][-]
  1. var
  2.   a, b, c: integer = (0, 0, 0);
  3.   s1, s2: string;
  4. begin
  5. //..
  6. end;
I would not be in favor of that one because transpositions are a common error.  That construction makes it too easy to inadvertently swap initial values.



ETA:

I remember having this discussion before and if memory serves me well, the grouped initialization syntax cannot be easily implemented in FPC. While I haven't looked at the FPC source myself, I can imagine that if the parser feeds the syntax directly to a AST structure, the initialization may be a problem.
Yes, I remember that too.  From memory and, if I understood what was said at the time, apparently there is some code that is shared with other portions of the compiler that would not welcome the minor changes required in parsing an initial value. 

SharpBASIC doesn't do it like that. It collects all declarations with type and initialization (immediate) and adds them to the symbol table. After the stack frame is setup the symbol table (with initializations) is read out and the variables are initialized.
That's the best way of doing it.  Much more powerful and flexible.
« Last Edit: November 29, 2021, 11:19:19 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018