Jump to content
MarkShark

Thoughts on using begin end merely to limit inline var scope.

Recommended Posts

I realize that this is going to be very subjective, but what are people's thoughts on using begin end just to limit the scope of an inline variable?  For example:

 

... code
begin
  var LocalString := 'My String';
  ... Use LocalString for something
end;
... more code  

Are there any caveats to doing so?   I know that doing this can cause an implicit try-finally for managed types, so I can see that being a performance factor in a loop and something to be aware of. It also seems like they've fixed the issues with the debugger and inline vars in Delphi 11 (at least in the simple cases I've tried), which makes them more usable.

 

-Mark

 

Share this post


Link to post
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    var x:=5;
    inc(x, DayOfWeek(now));
    writeln(x);
    if x<5 then {break point here}
      writeln('x<5')
    else
      writeln('x>=5');

    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

The debugger will say: 'Symbol was eliminated by linker'. In my opinion it's still not solved in debug configuration. I am still going to wait for fully implemented inline variables.

 

Share this post


Link to post

In concept, it is great - but lack of support in the debugger is a problem.

If you have two blocks with var x := <whatever> it gets even more confused.

 

I love using inline vars for loops -> no use after the loop block and type inference saves you from having to declare the type.

 

Share this post


Link to post
19 minutes ago, Lars Fosdal said:

no use after the loop block and type inference saves you from having to declare the type.

Saves you from declaring the type when it's working (eg. Currency).

  • Sad 1

Share this post


Link to post

us C++ programmers have had this since the begining - it's very common to just use a pair { } and create a local variable that exists only for the extent of the braces

  • Like 2

Share this post


Link to post
11 hours ago, Fr0sT.Brutal said:

IMHO using blocks just for this purpose only adds visual noise and needlessly increases LOCs

When has an abundance of visual noise been a problem before with Pascal, the most verbose of languages!!! 

  • Haha 4

Share this post


Link to post

Until the tooling catches up, I wouldn't recommend inline variables.  Refactoring can break, code formatting breaks, debugger gets confused...

 

I really jumped into inline var usage and quickly hit a wall.  Now they are banned from my code.

 

Share this post


Link to post
2 hours ago, Darian Miller said:

Refactoring can break, code formatting breaks, debugger gets confused...

Sure, its only been what.. well under a decade 🙂

 

Share this post


Link to post

We use inline vars quite a bit.  For loops, in particular - as well as for temporary variables.

But, yes, the tooling is lagging behind.

Share this post


Link to post
10 hours ago, David Heffernan said:

When has an abundance of visual noise been a problem before with Pascal, the most verbose of languages!!! 

Looking at some " succinct " languages, I'd prefer verbosity...

Perl `sub deleteDoubleDots($) { while($_[0] = m/\.\./) { $_[0] = s/\/[^\/]*\/\.\.//; } }`

  • Like 1

Share this post


Link to post
9 minutes ago, Fr0sT.Brutal said:

Looking at some " succinct " languages, I'd prefer verbosity...

Perl `sub deleteDoubleDots($) { while($_[0] = m/\.\./) { $_[0] = s/\/[^\/]*\/\.\.//; } }`

Not wishing to defend Perl too much, but that function could be written more clearly with a named variable, but it would look much the same in any language. The regex wouldn't change. In fact the regex match and substitute syntax in Perl is actually very readable. I don't think the Delphi version would be clearer. 

Share this post


Link to post
5 hours ago, Fr0sT.Brutal said:

Looking at some " succinct " languages, I'd prefer verbosity...

Perl `sub deleteDoubleDots($) { while($_[0] = m/\.\./) { $_[0] = s/\/[^\/]*\/\.\.//; } }`

There are worse:

Software History

Share this post


Link to post
On 11/9/2021 at 2:12 PM, Bill Meyer said:

There are worse:

Software History

Oh yes! Remember Forth...

  • Haha 1

Share this post


Link to post

History teaches us that nothing is new under the moon. Limiting the scope of a varable to the begin/end block was invented long ago, just have a look at the PL/I specification from 1964:

Quote

A begin block is a sequence of statements headed by a BEGIN statement (see Section 8.2) and terminated by an END statement (see Section 8.3). In general, you can use a begin block wherever a single PL/I statement would be valid. In some contexts, such as an ON-unit, a begin block is the only way to perform several statements instead of one. A primary use of begin blocks is to localize variables. Because execution of a begin block causes a block activation, automatic variables declared within the begin block are local to it, and their storage disappears when the block completes execution.

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×