[fpc-pascal] Optional param modifier

Martin Frb lazarus at mfriebe.de
Sun Apr 14 18:04:08 CEST 2019

On 14/04/2019 16:05, Ryan Joseph wrote:
>> On Apr 14, 2019, at 3:15 AM, Sven Barth via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
>> Your idea requires exceptions as well. The compiler is not capable checking whether valid entries are passed in at compile time except for simple, constant cases, so runtime checks are needed and the only way to abort something is by exceptions.
> My idea didn’t require the procedure to exit so I don’t see where an exception would be needed. It just says if a param was flagged you would need to check for nil before dereferencing other you get a compile time error.
First of all the max you should get is a note (warning, maybe). But 
never a compile time error.

I have code like
   If a > 7 then
      (* If b = nil then *) b:= somedefault;
   if a = 8 then
      a := b;  // compiler claim b is not initialized     (* a := b.Foo *)

So if your request for a compile time error was implemented, and above 
was a pointer deref on the last line, the code would not compile. Yet it 
is safe.

Also see my previous comment.
What is the point, if the compiler checks for potential issues, but only 
if I insert a request for the check on top of the potential unsave code.

If I have to write "optional" so the compiler checks for "if assigned" 
then what good is it? I can write "if assigned " immediately and save 
myself the optional.

And please do not counter this with: "But it documents for the user that 
he can use nil". The documentation is a separate distinct issue, and it 
can be solved in other ways.
You proposed one keyword to archive 2 features, be prepared to discuss 
each of them separately.

> I like the idea (because it feels Pascalish) to make a code section that checks requirements but the exit condition is up for debate. I personally wouldn’t use the feature if it meant I need to start the tedious process of wrapping everything in try blocks and taking on what performance costs there are to exceptions (we can’t opt into exceptions via modeswitch so I don’t know what those things are doing and where they are).
There would be no need for try blocks.

It is the same as "assert". An assert raises an exception. But you do 
not write try except blocks for it.
An assert should never happen, therefore you do not handle it. An assert 
is a controlled crash of the app. Asserts are compiled into your app, if 
you test it. But you leave them out if you release.
Once you have tested (automatic test case), you no longer need the 
assert, because the case can never happen. (Or the third party using 
your code have to test, they follow the API. Or you allow nil for them, 
and you tested that it does work)

I understand that this is not the same you propose.
It is for cases where nil is NOT allowed, rather than for cases were nil 
is allowed. (as above, if nil is allowed, the code must be tested with 
nil. The compiler can never detect all cases, therefore the compiler can 
never enforce that you do "if assigned"... You may have done, without 
the compiler having noted)

> We have custom error systems in our code also so forcing everyone into exceptions would not be nice. I could imagine a bail condition that was jumped to but it would have to be in the code section. That’s usually how we do it now anyways so it shouldn’t be too strange.
> function MakeHero (name: string; hp: integer; level: integer): THero;
> require
>    name <> ‘’;
>    hp > 0;
>    (level > 0) and (level < 10);
> begin
>> bail
>    MyCustomErrorHandler(‘MakeHero() params are invalid’);
>    exit(THero.Invalid);
> end;
You do not need the exit. Because the purpose of the assert is to abort 
the entire application (controlled crash).

If you get a call with invalid param, you have to assume this is because 
something else went wrong before. So in this case you have to assume 
worst case, something like the entire memory of the application has been 
There no longer is a way to rescue the app. All you can do is make sure 
that it will not do further damage. So you exit the app.

The IDE for example uses Application.OnException.
It tells the user that it is now unstable. Save your work and exit.

More information about the fpc-pascal mailing list