[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;
foo();
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
corrupted.
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