[fpc-pascal] New feature: IfThen() intrinsic

Serguei TARASSOV serge at arbinada.com
Mon Feb 1 12:27:49 CET 2016


Hello,

I'm not afraid about existing uses of Math.IfThen ou StrUItils.IfThen 
because they will hide System.IfThen.
However, existing semantic of IfThen doesn't allow expressions like this

s := IfThen(Obj = nil, 'Unknown', Obj.Value); // raise AV when Obj is nil

As far as I understand, new System.IfThen accepts this kind of code. Good.
But suppose, we add later Math or StrUtils to same unit. This cancel 
immediately expected behavior and give AV for IfThen. The only solution 
is to specify System.IfThen explicitly (good style of coding but not 
used by the most of programmers).

In such case, I would like to propose at least to use other name for 
System.IfThen.
IMO, the best solution is don't use a function at all because of 
dependency on argument's processing order by compiler. The new operator 
will be safe:

s := iif Obj = nil : 'Unknown' : Obj.Value;

Regards,
Serguei


On 31/01/2016 16:20, fpc-pascal-request at lists.freepascal.org wrote:
> Message: 1
> Date: Sun, 31 Jan 2016 15:43:06 +0100
> From: Sven Barth<pascaldragon at googlemail.com>
> To: FPC-Pascal users discussions<fpc-pascal at lists.freepascal.org>
> Subject: [fpc-pascal] New feature: IfThen() intrinsic
> Message-ID:<56AE1D7A.5030009 at googlemail.com>
> Content-Type: text/plain; charset=utf-8
>
> Hello together!
>
> I've finally come around to add a feature that many people have asked
> for throughout the years: an inline if that works like the if-statement
> in that it only evaluates that expression that is indeed returned.
>
> After the discussion last year about the inline-if I've decided to add
> it as an intrinsic function instead of an extension of the language.
> Like all intrinsics it's part of the System unit and "declared" like this:
>
> === code begin ===
>
> function IfThen(Condition: Boolean; ThenExpr, ElseExpr: type): type;
>
> === code end ===
>
> Since it's declared in the System unit it won't interfere with the
> IfThen()s that are declared in the Math unit or other units, so they'll
> continue to work as before to avoid any surprises.
>
> An important point to note is that in general the result type is
> determined by the ThenExpr (there are a few usability exceptions
> regarding strings and chars).
>
> Examples:
>
> === code begin ===
>
> function A: LongInt;
> begin
>    A := 42;
> end;
>
> function B: LongInt;
>    B := 21;
> end;
>
> var
>    i, j: LongInt;
>    s: String;
> begin
>    i := 42;
>    j ;= IfThen(i < 32, 48, 21);
>
>    j := IfThen(True, 23, 49); // compiler will warn of unreachable code
>    j := IfThen(False, 23, 49); // compiler will warn of unreachable code
>
>    j := IfThen(i < 32, A, B); // in this case only B will be executed
>
>    //j := IfThen(i < 32, 32, '123'); // this will fail if there's no
> suitable conversion operator available
>
>    //s := IfThen(j < 32, #42, 'Foo'); // this will fail as a char is expected
>    s := IfThen(j < 32, #42, #3294); // this will work however and will
> result in a WideChar
>    s := IfThen(j < 32, 'Hello World', 'Hello'#3294'World'); // this will
> also work and will result in a WideString (and a warning as s is a
> Short-/AnsiString)
> end;
>
> === code end ===
>
> If there are any combinations of types that should work, but do not,
> please don't hesistate to report them athttp://bugs.freepascal.org/
>
> Regards,
> Sven




More information about the fpc-pascal mailing list