The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,835 other subscribers

No, the Delphi IfThen functions do perform do lazy evaluation

Posted by jpluimers on 2026/07/30

Ever since introduction of the IfThen functions introduced in Delphi Delphi 2007 in both the Math and StrUtils units (see WayBack radstudio2007 HUpdate4 EN delphivclwin32.pdf ¹), I have been telling people that these do not perform lazy evaluation of the then and else parts which the if/then/else statement provides.

The newly introduced if/then/else ternary conditional operator in Delphi 13 ² (of which I am not a fan, not even of the generic workaround³) – despite the unlucky number – luckily also provides lazy evaluation of the then and else parts.

Statements and operations can be subject of optimisation by means of lazy evaluation; method arguments for function calls are always evaluated in full before calling.

Use of a ternary conditional operator results in seemingly shorter code (for Delphi not so much because the existing keywords have been re-used), but the brevity can lead to far less readable code.

The brevity usually does not lead to more optimal code generation, as most (with the exception of Delphi) language compilers can optimise from

See the example in [Wayback/Archive] Lazy Evaluation on the New Ternary Operator – Delphi 265 – YouTube – the first method has lazy evaluation, the second does not:

procedure TForm48.btnTernaryClick(Sender: TObject);
begin
  var s := 'My String';
  var sNew :=
    if CheckBox1.Checked then
      Reverse2(s)
    else
      UpperCase2(s);
  ShowMessage(sNew);
end;

procedure TForm48.btnIFThenClick(Sender: TObject);
begin
  var s := 'My String';
  var sNew :=
    IfThen(CheckBox1.Checked, Reverse2(s), UpperCase2(s));
    ShowMessage(sNew);
end;

function TForm48.Reverse2 (const s: string): string;
begin
  Result := ReverseString(s);
end;

function TForm48.Uppercase2(const s: string): string;
begin
  Result := UpperCase(s);
end;

Yay, naming conventions!
/s

It would be even clearer if there had been UI elements that would signal when Reverse2 and Uppercase2 had been called.

Via [Wayback/Archive] Post by @scipastips.bsky.social — Bluesky.

--jeroen

¹ Embarcadero killed old docs site with Delphi 2007 and 2009, but some of them are downloadable: see the Wayback Machine search links for the Delphi 2007 documentation I mentioned in Wayback Machine search string for either docwiki, Delphi 2007 or Delphi 2009 docs.

² the ternary operator has been asked for since ages – see the QC report below, but now that it’s there library developers likely will hesitate to adopt it as it breaks compatibility with less recent Delphi versions, see

Both the Stack Overflow and QC entry propose the ternary conditional operator with the ?: syntax. Delphi 13 implemented it with the if/then/else syntax (basically making the if into an operator that return a value)

³ the stack Over flow entry has this remark by Vivian to which I very much agreed and still agree, despite the current syntax reusing the if/then/else keywords.

  • Vivian:

    Personally I would rather not see a conditional operator (i.e. ?:) introduced in Delphi as I prefer the readability of Delphi/Pascal over C and it derivative languages. I would prefer to see more innovative Delphi type solutions to something like this than to implement more C-isms.

  • Me:

    mini-rant: I have seen very unreadable code with even very small usage of the ? ternary operator in C-like languages. The main cause is that it is yet another symbol being used, and most people using it forget to add parentheses or indentation for readability. The speed improvements that it can bring are hardly reached: most usage is just a replacement of a single if/then/else, whereas real improvement only can be gained in complex expressions that few people can maintain.

In the same entry, Wouter gives an answer that works in all Delphi versions supporting generics. Not fast, but it supports lazy evaluation:

Ok. WTF code of the day :)

How to get something that mostly acts like a ternary/conditional function.

program Project107;
{$APPTYPE CONSOLE}

uses SysUtils;

type
  TLazyIfThen<T:record>=record
    class function IfThen(aCondition:Boolean;aIfTrue, aIfFalse:TFunc<T>):T; static;
  end;

  class function TLazyIfThen<T>.IfThen(aCondition:Boolean;aIfTrue, aIfFalse:TFunc<T>):T;
  begin
    if aCondition then
      Result := aIfTrue
    else
      Result := aIfFalse
  end;

begin
  WriteLn(
    TLazyIfThen<Integer>.IfThen(
      True,
      function:Integer begin result := 0 end,
      function:Integer begin result := 1 end
    )
  );
  ReadLn;
end.

Yeah, it’s more or less useless, but it shows that it can be done.


[Wayback/Archive] Lazy Evaluation on the New Ternary Operator – Delphi 265 – YouTube

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.