Using discriminated records to return variable amount of data from function


Sometimes, you want to return different data from a function dependending on the given parameters and the program state. For example, when searching a container for a certain element, you either want to return "NOT_FOUND" information or the actual element.

One way to do this is to use discriminated (or variant) records

type Search_Result (Found : Boolean) is record
   case Found is
      when True =>
         Value : Integer;
      when False =>
         null;
   end case;
end record;

If 'Found' parameter is True, you also have 'Value' component in the record. And if 'Found' is 'False', you have nothing extra.

The search function itself could be

function Search_Numbers (Key : Integer) return Search_Result is
begin
   if Key = 99 then
      return Search_Result'(Found => True, Value => 101);
   else
      return Search_Result'(Found => False);
   end if;
end Search_Numbers;

And it can be used like this:

procedure Main is
   Res : Search_Result := Search_Numbers (99);
begin
   if Res.Found then
      Put_Line ("Found: " & Integer'Image (Res.Value));
   else
      Put_Line ("Not found");
   end if;
end Main;

If you try to access 'Value' component of the 'Res' variable when 'Found' is False, an exception is raised during runtime.