Storing the history of objects in a program is a common task. 
Maintaining the history of an object in a program has traditionally required programmers either to write specific code for handling the historical data, or to use a library which supports history logging.

History variables are variables in a programming language which store not only their current value, but also the values they have contained in the past. Some existing languages do provide support for history variables. However these languages typically have many limits and restrictions on use of history variables.
 

[http://www.bod.com/index.php?id=3435&objk_id=148050 "History Variables:
The Semantics, Formal Correctness, and Implementation of History Variables
in an Imperative Programming Language" by Mallon and Takaoka]

Concept also discussed on LtU and Patents.com.

Task
 
Demonstrate History variable support:

 enable history variable support (if needed) 
 define a history variable
 assign three values
 non-destructively display the history
 recall the three values. 

For extra points, if the language of choice does not support history variables,
demonstrate how this might be implemented.




 
program History_variables;
 
{$APPTYPE CONSOLE}
 
uses
  System.SysUtils;
 
type
  THistoryVarType = record
    value: variant;
    timestamp: TDateTime;
    function ToString: string;
  end;
 
  THistoryVar = record
    Fvalue: variant;
    FHistory: TArray<THistoryVarType>;
  private
    procedure SetValue(const Value: Variant);
    function GetTimestamp: TDateTime;
  public
    property History: TArray<THistoryVarType> read FHistory;
    constructor Init(val: variant);
    function Dump: string;
    function Recall(steps: Integer): variant; overload;
    function Recall(timestamp: TDateTime): variant; overload;
    property Timestamp: TDateTime read GetTimestamp;
    property Value: Variant read Fvalue write SetValue;
  end;
 
{ THistoryVar }
 
function THistoryVar.Dump: string;
begin
  Result := '';
  for var h in FHistory do
    Result := Result + h.ToString + #10;
end;
 
function THistoryVar.GetTimestamp: TDateTime;
begin
  if Length(FHistory) = 0 then
    exit(0);
  Result := FHistory[high(FHistory)].timestamp;
end;
 
constructor THistoryVar.Init(val: variant);
begin
  SetLength(Fhistory, 0);
  SetValue(val);
end;
 
function THistoryVar.Recall(timestamp: TDateTime): variant;
begin
  for var h in FHistory do
  begin
    if h.timestamp = timestamp then
      exit(h.value);
  end;
  result := Fvalue;
end;
 
function THistoryVar.Recall(steps: Integer): variant;
begin
  if (steps <= 1) or (steps >= Length(FHistory)) then
    exit(value);
 
  result := FHistory[Length(FHistory) - steps - 1].value;
end;
 
procedure THistoryVar.SetValue(const Value: Variant);
begin
  SetLength(FHistory, Length(FHistory) + 1);
  FHistory[High(FHistory)].Value := Value;
  FHistory[High(FHistory)].timestamp := now;
  Fvalue := Value;
end;
 
{ THistoryVarType }
 
function THistoryVarType.ToString: string;
var
  dt: string;
begin
  DateTimeToString(dt, 'mm/dd/yyyy hh:nn:ss.zzz', timestamp);
  Result := format('%s -  %s', [dt, Value]);
end;
 
begin
  var v := THistoryVar.Init(0);
  v.Value := True;
 
  Sleep(200);
  if v.Value then
    v.Value := 'OK';
 
  Sleep(100);
  if v.Value = 'OK' then
    v.Value := PI;
 
  writeln('History of variable values:'#10);
  Writeln(v.Dump);
 
  Writeln('Recall 2 steps');
  Writeln(v.Recall(2));
 
  var t := v.History[3].timestamp;
  Writeln(#10'Recall to timestamp ', datetimetostr(t));
  Writeln(v.Recall(t));
 
  readln;
end.