History variables: Difference between revisions

m
m (→‎{{header|Phix}}: added syntax colouring, marked p2js compatible)
imported>Arakov
 
(6 intermediate revisions by 5 users not shown)
Line 28:
The 68000 can use push/pop commands on any address register, not just the hardware stack pointer.
 
<langsyntaxhighlight lang="68000devpac">HistoryVar equ $100200 ;assume this is work ram.
 
LEA HistoryVar+4,A0
Line 48:
jsr PrintHex32
mov D2,D0
jsr PrintHex32</langsyntaxhighlight>
 
Whether this constitutes a single variable at this point is debatable, because at a hardware level anything you write to a memory address permanently erases what was there, with no way to get it back unless you saved it somewhere else. So storing three values at the same memory location won't maintain the history.
Line 65:
Specification:
 
<langsyntaxhighlight Adalang="ada">private with Ada.Containers.Indefinite_Vectors;
generic
type Item_Type (<>) is private;
Line 98:
History: Vectors.Vector;
end record;
end History_Variables;</langsyntaxhighlight>
 
The implementation of "History_Variables":
 
<langsyntaxhighlight Adalang="ada">package body History_Variables is
 
-- set and get
Line 136:
end Undo;
 
end History_Variables;</langsyntaxhighlight>
 
 
===Sample 1: The History of an Integer Variable===
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, History_Variables;
 
procedure Test_History is
Line 172:
Ada.Text_IO.Put_Line(Integer'Image(Sum));
 
end Test_History;</langsyntaxhighlight>
 
{{out}}
Line 181:
===Sample 2: The History of a String===
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, History_Variables;
 
procedure Test_History is
Line 212:
Ada.Text_IO.Put_Line(Integer'Image(Sum));
 
end Test_History;</langsyntaxhighlight>
 
{{out}}
Line 221:
Algol W does not have history variables as standard, as with other languages here, we can add them using a simple linked list.
<br>As Algol W does not have generic types, a separate history variable type would be required for each type of variable.
<langsyntaxhighlight lang="algolw">begin
% implements integer history variables %
% similar history types could be defined for other types of variable %
Line 255:
write( "Sum of the historic values: ", s )
end
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 261:
Sum of the historic values: 6
</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="arturo">define :history [][
init: [
this\record: @[0]
]
]
assign: function [historyVar,newValue][
historyVar\record: historyVar\record ++ newValue
]
 
alias.infix {'-->} 'assign
 
records: function [historyVar][
historyVar\record
]
 
retrieve: function [historyVar][
result: last historyVar\record
historyVar\record: chop historyVar\record
return result
]
 
current: function [historyVar][
return last historyVar\record
]
 
do [
h: to :history []
 
print "Assigning three values: 1, 2, 3..."
h --> 1
h --> 2
h --> 3
 
print "\nHistory (oldest values first):"
print [">" records h]
 
print ["\nCurrent value is:" current h]
 
print "\nRecalling the three values..."
loop 1..3 'x ->
print ["- Recalled:" retrieve h]
 
print "\nHistory:"
print [">" records h]
]</syntaxhighlight>
 
{{out}}
 
<pre>Assigning three values: 1, 2, 3...
 
History (oldest values first):
> [0 1 2 3]
 
Current value is: 3
 
Recalling the three values...
- Recalled: 3
- Recalled: 2
- Recalled: 1
 
History:
> [0] </pre>
 
=={{header|AspectJ}}==
AspectJ implementation for Java 7.
Type of the history variable (Java class):
<langsyntaxhighlight lang="java">public class HistoryVariable
{
private Object value;
Line 293 ⟶ 357:
{
}
}</langsyntaxhighlight>
Aspect (HistoryHandling.aj):
<langsyntaxhighlight lang="java">import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
Line 337 ⟶ 401:
 
private Map<HistoryVariable, Deque<Object>> history = new HashMap<>();
}</langsyntaxhighlight>
Usage:
<langsyntaxhighlight lang="java">public final class Main
{
public static void main(final String[] args)
Line 355 ⟶ 419:
System.out.println(hv.toString());
}
}</langsyntaxhighlight>
 
{{out}}
Line 369 ⟶ 433:
AutoHotkey records a history of your keypresses, but not your variables. The closest you can come is with a class:
{{works with|AutoHotkey 1.1}}
<langsyntaxhighlight lang="ahk">HV := new HistoryVariable
HV.var := 1
HV.var := 2
Line 383 ⟶ 447:
Return this[1]
}
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="c sharp">using System;
using System.Collections;
using System.Collections.Generic;
Line 454 ⟶ 518:
}
}
}</langsyntaxhighlight>
 
{{out}}
<pre>foobar <- foo <- 5
</pre>
 
=={{header|C++}}==
C++ does not have history variables, but they can easily by implemented with a generic class.
<syntaxhighlight lang="c++">
#include <deque>
#include <iostream>
#include <string>
 
template <typename T>
class with_history {
public:
with_history(const T& element) {
history.push_front(element);
}
 
T get() {
return history.front();
}
 
void set(const T& element) {
history.push_front(element);
}
 
std::deque<T> get_history() {
return std::deque<T>(history);
}
 
T rollback() {
if ( history.size() > 1 ) {
history.pop_front();
}
return history.front();
}
 
private:
std::deque<T> history;
};
 
int main() {
with_history<double> number(1.2345);
std::cout << "Current value of number: " << number.get() << std::endl;
 
number.set(3.4567);
number.set(5.6789);
 
std::cout << "Historical values of number: ";
for ( const double& value : number.get_history() ) {
std::cout << value << " ";
}
std::cout << std::endl << std::endl;
 
with_history<std::string> word("Goodbye");
word.set("Farewell");
word.set("Hello");
 
std::cout << word.get() << std::endl;
word.rollback();
std::cout << word.get() << std::endl;
word.rollback();
std::cout << word.get() << std::endl;
word.rollback();
std::cout << word.get() << std::endl;
word.rollback();
}
</syntaxhighlight>
{{ out }}
<pre>
Current value of number: 1.2345
Historical values of number: 5.6789 3.4567 1.2345
 
Hello
Farewell
Goodbye
Goodbye
</pre>
 
Line 464 ⟶ 603:
via a watcher function that can track changes on a variable.
 
<langsyntaxhighlight lang="clojure">
(def a (ref 0))
(def a-history (atom [@a])) ; define a history vector to act as a stack for changes on variable a
(add-watch a :hist (fn [key ref old new] (swap! a-history conj new)))
</syntaxhighlight>
</lang>
 
{{out|Sample Output}}
Line 491 ⟶ 630:
In Lisp the list is a natural and simple data structure for representing variables with history. By adding some simple macros we can make a small DSL that hides the list and makes it look like a history variable is it's own special thing.
 
<langsyntaxhighlight lang="lisp">(defmacro make-hvar (value)
`(list ,value))
 
Line 514 ⟶ 653:
(undo-hvar v)
(format t "Restored value = ~a~%" (get-hvar v)))
</syntaxhighlight>
</lang>
{{out}}
<pre>Initial value = 1
Line 524 ⟶ 663:
D does not have history variables. The following implementation provides a generic HistoryVariable that protects the historical values by defining them as 'const'.
 
<langsyntaxhighlight lang="d">import std.stdio, std.array, std.string, std.datetime, std.traits;
 
/// A history variable.
Line 586 ⟶ 725:
s = "goodby";
writefln("%(%s\n%)", s.history);
}</langsyntaxhighlight>
{{out|Sample Output}}
<pre>2013-Jan-19 23:04:55.1660302; 1
Line 598 ⟶ 737:
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program History_variables;
 
Line 710 ⟶ 849:
 
readln;
end.</langsyntaxhighlight>
{{out}}
<pre>History of variable values:
Line 727 ⟶ 866:
=={{header|EchoLisp}}==
No native support. We implement an anonymous stack associated with the variable, and a few syntax rules to define the needed operations.
<langsyntaxhighlight lang="lisp">
(define-syntax-rule (make-h-var name) (define name (stack (gensym))))
(define-syntax-rule (h-get name) (stack-top name))
Line 750 ⟶ 889:
(h-undo x) → 42
(h-undo x) → ❌ error: no more values x
</syntaxhighlight>
</lang>
 
=={{header|Elena}}==
ELENA 56.0x :
<langsyntaxhighlight lang="elena">import extensions;
import system'collections;
import system'routines;
Line 805 ⟶ 944:
console.printLine(o);
o.forEach:(printingLn);
o.undo().undo().undo();
console.printLine(o.Value ?? "nil")
}</langsyntaxhighlight>
{{out}}
<pre>
Line 841 ⟶ 980:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: accessors combinators formatting kernel models.history ;
 
1 <history> {
Line 852 ⟶ 991:
[ go-back ]
[ value>> "Restored value: %u\n" printf ]
} cleave</langsyntaxhighlight>
{{out}}
<pre>
Line 862 ⟶ 1,001:
=={{header|Forth}}==
Forth does not have history variables, but it is trivial to define them. This one uses a linked list. The history variable is initialized to zero to avoid expensive sanity checks in ''H@''. ''H--'' undoes the assignment of a value and effectively returns a history variable to its former state.
<langsyntaxhighlight lang="forth">: history create here cell+ , 0 , -1 , ;
: h@ @ @ ;
: h! swap here >r , dup @ , r> swap ! ;
: .history @ begin dup cell+ @ -1 <> while dup ? cell+ @ repeat drop ;
: h-- dup @ cell+ @ dup -1 = if abort" End of history" then swap ! ;</langsyntaxhighlight>
 
A sample session:
Line 887 ⟶ 1,026:
=={{header|Go}}==
We're all in this for the extra points. Mallon and Takota seem happy with sequences, but time and timestamps were mentioned on LtU. Beyond a separate sequence for each history variable, timestamps enable multiple variables to be seen in a common temporal sequence. In Go, with it's attention to concurrency, this might be done with flexibility for proper handling of shared variables, and efficient handling of variables limited to a single thread.
<langsyntaxhighlight lang="go">package main
 
import (
Line 999 ⟶ 1,138:
fmt.Println(rv)
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,017 ⟶ 1,156:
There are no native Haskell history variables, but they are simple to implement.
 
<langsyntaxhighlight lang="haskell">import Data.IORef
 
newtype HVar a = HVar (IORef [a])
Line 1,048 ⟶ 1,187:
undoHVar var
undoHVar var
undoHVar var</langsyntaxhighlight>
 
=={{header|J}}==
Line 1,054 ⟶ 1,193:
J does not natively support "history variables", but the functionality is easy to add:
 
<langsyntaxhighlight lang="j">varref_hist_=:'VAR','_hist_',~]
set_hist_=:4 :0
V=.varref x
Line 1,065 ⟶ 1,204:
)
length_hist_=: #@getall
get_hist_=: _1 {:: getall</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight lang="j"> 'x' set_hist_ 9
9
'x' set_hist_ 10
Line 1,082 ⟶ 1,221:
┌─┬──┬──┐
│9│10│11│
└─┴──┴──┘</langsyntaxhighlight>
 
Note that each value is contained in a box, so different values do not need to be type compatible with each other. If this is considered a defect then assertions could be added to enforce type compatibility across assignments.
Line 1,093 ⟶ 1,232:
Java does not support history variables, but they are easy to implement using the lists that come with Java's Collections framework.
 
==={{header|Java Integer with History}}===
This implementation does not allow the History Variable to be "empty". It can be assigned one or multiple "nulls", but it can never have an undefined value (such as being created and not initialized).
<langsyntaxhighlight Javalang="java">import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
Line 1,168 ⟶ 1,307:
}
}
</syntaxhighlight>
</lang>
Test Program:
<langsyntaxhighlight Javalang="java">public class TestIntegerWithHistory {
 
public static void main(String[] args) {
Line 1,194 ⟶ 1,333:
 
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,210 ⟶ 1,349:
</pre>
 
==={{header|Java History for "any class" using Generics}}===
This implementation does not allow the History Variable to be "empty". It can be assigned one or multiple "nulls", but it can never have an undefined value (such as being created and not initialized).
<lang java></lang>
Test Program using a "String with History":
<langsyntaxhighlight lang="java">import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
Line 1,290 ⟶ 1,428:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,308 ⟶ 1,446:
=={{header|Julia}}==
Julia currently does not support overloading the assignment "=" operator.
<langsyntaxhighlight Julialang="julia">mutable struct Historied
num::Number
history::Vector{Number}
Line 1,323 ⟶ 1,461:
 
println("Past history of variable x: $(x.history). Current value is $(x.num)")
</langsyntaxhighlight>{{output}}<pre>Past history of variable x: Number[1, 3, 5]. Current value is 4</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.4
 
class HistoryVariable<T>(initialValue: T) {
Line 1,353 ⟶ 1,491:
v.showHistory()
println("\nCurrentvalue is ${v.currentValue}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,368 ⟶ 1,506:
Lua does not natively support history variables. However, as with other languages here, something roughly equivalent could be implemented with a "stack wrapper". The only complicated issue might be how to treat nil's (null values). The implementation below allows initial nil's, and allows undo()'s back to nil, but does <i>not</i> consider nil as part of the "history".
===Via metatable===
<langsyntaxhighlight lang="lua">-- History variables in Lua 6/12/2020 db
local HistoryVariable = {
new = function(self)
Line 1,397 ⟶ 1,535:
hv:undo(); print("undo() to:", hv:get())
hv:undo(); print("undo() to:", hv:get())
hv:undo(); print("undo() to:", hv:get())</langsyntaxhighlight>
{{out}}
<pre>defined: table: 0000000000939240
Line 1,410 ⟶ 1,548:
===Via closure===
If a desire is to keep history private and immutable, then..
<langsyntaxhighlight lang="lua">-- History variables in Lua 6/12/2020 db
local function HistoryVariable()
local history = {}
Line 1,443 ⟶ 1,581:
hv.undo(); print("undo() to:", hv.get())
hv.undo(); print("undo() to:", hv.get())
hv.undo(); print("undo() to:", hv.get())</langsyntaxhighlight>
{{out}}
<pre>defined: table: 0000000000a59500
Line 1,459 ⟶ 1,597:
First we see how we work with Stack (each module/function see a "current stack", we can make pointers to new stacks, but we can't get pointer of current stack). There are some statement no demonstrate here, such as Shift and ShiftBack (move top to a place, and move back to top), and Over (make new items by copying items).
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Flush ' empty curtrent stack
\\ a is a pointer to a new stack object
Line 1,498 ⟶ 1,636:
b=stackitem(z, 2)
Print stackitem(b, 4)=1000
</syntaxhighlight>
</lang>
 
So now lets see the code:
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckHistoryVariables {
Class History {
Line 1,682 ⟶ 1,820:
}
CheckStringHistoryVariables
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
Line 1,688 ⟶ 1,826:
As Nim is statically typed, we define history variable type in a generic way.
 
<langsyntaxhighlight Nimlang="nim">type HistoryVar[T] = object
hist: seq[T]
 
ffuncfunc initHistoryVar[T](value: T = T.default): HistoryVar[T] =
## Initialize a history variable with given value.
result.hist.add value
Line 1,733 ⟶ 1,871:
 
echo "History (note that initial value can never be removed):"
h.showHistory()</langsyntaxhighlight>
 
{{out}}
Line 1,751 ⟶ 1,889:
 
=={{header|Oberon-2}}==
<langsyntaxhighlight lang="oberon2">
MODULE HVar;
IMPORT Out, Conv;
Line 1,931 ⟶ 2,069:
ShowVal(history.Undo());
END HVar.
</syntaxhighlight>
</lang>
 
=={{header|OCaml}}==
The easiest solution is to use the Stack module coming with OCaml's standard library:
<langsyntaxhighlight lang="ocaml">
open Stack
(* The following line is only for convenience when typing code *)
Line 1,952 ⟶ 2,090:
hs |> H.pop |> Printf.printf "%d\n";
hs |> H.pop |> Printf.printf "%d\n"
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,966 ⟶ 2,104:
=={{header|OxygenBasic}}==
Simple history class for fixed length types that do not contain volatile pointer members.
<langsyntaxhighlight lang="oxygenbasic">
'============
class History
Line 2,025 ⟶ 2,163:
 
del hv
</syntaxhighlight>
</lang>
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">default(histsize, 1000) \\ or some other positive number to suit
1+7
sin(Pi)
Line 2,037 ⟶ 2,175:
\a2
\a3
[%1, %2, %3] \\ or any other command using these values</langsyntaxhighlight>
 
=={{header|Peloton}}==
<langsyntaxhighlight lang="sgml">Turn history on <@ DEFHST>__on</@>
Notify Protium we are interested in the variable mv
<@ DEFHST>mv</@>
Line 2,050 ⟶ 2,188:
Undo once: <@ ACTUNDVAR>mv</@><@ SAYVAR>mv</@>
Undo twice: <@ ACTUNDVAR>mv</@><@ SAYVAR>mv</@>
Turn history off <@ DEFHST>__off</@></langsyntaxhighlight>
 
Same code, Simplified Chinese dialect
<langsyntaxhighlight lang="sgml">Turn history on <# 定义变量史>__on</#>
Notify Protium we are interested in the variable mv
<# 定义变量史>mv</#>
Line 2,063 ⟶ 2,201:
Undo once: <# 运行撤消变量>mv</#><# 显示变量>mv</#>
Undo twice: <# 运行撤消变量>mv</#><# 显示变量>mv</#>
Turn history off <# 定义变量史>__off</#> </langsyntaxhighlight>
 
{{out}}
Line 2,081 ⟶ 2,219:
=={{header|Perl}}==
Implemented via tie (and what's the usefulness of this?)
<langsyntaxhighlight Perllang="perl">package History;
 
sub TIESCALAR {
Line 2,120 ⟶ 2,258:
 
History::off($x);
print "\$x is: $x\n";</langsyntaxhighlight>
{{out}}<syntaxhighlight lang="text">History: a b c d
undo 1, current value: c
undo 2, current value: b
undo 3, current value: a
$x is: a</langsyntaxhighlight>
 
=={{header|Phix}}==
No native support, but trivial to implement.<br>
If you only need the history for a single variable, you can just do this, though it does not work under pwa/p2js:
<!--<langsyntaxhighlight Phixlang="phix">-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (desktop/Phix only)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">history</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
Line 2,144 ⟶ 2,282:
<span style="color: #0000FF;">?{</span><span style="color: #008000;">"current"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">test</span><span style="color: #0000FF;">}</span>
<span style="color: #0000FF;">?{</span><span style="color: #008000;">"history"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">history</span><span style="color: #0000FF;">}</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 2,152 ⟶ 2,290:
Multiple history variables would require that routines must be invoked to create, update, and inspect them, and would be pwa/p2js compatible.<br>
Writing this as a separate reusable component (but omitting destroy/freelist handling for simplicity):
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- history.e</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">histories</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
Line 2,172 ⟶ 2,310:
<span style="color: #008080;">return</span> <span style="color: #000000;">histories</span><span style="color: #0000FF;">[</span><span style="color: #000000;">hv</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</langsyntaxhighlight>-->
And use it like this
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">include</span> <span style="color: #000000;">history</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 2,182 ⟶ 2,320:
<span style="color: #0000FF;">?{</span><span style="color: #008000;">"current"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_hv</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test2</span><span style="color: #0000FF;">)}</span>
<span style="color: #0000FF;">?{</span><span style="color: #008000;">"history"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_hv_full_history</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test2</span><span style="color: #0000FF;">)}</span>
<!--</langsyntaxhighlight>-->
Same output. Of course test2 does not ''have'' to be a constant, but it may help.
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de setH ("Var" Val)
(when (val "Var")
(with "Var"
Line 2,193 ⟶ 2,331:
 
(de restoreH ("Var")
(set "Var" (pop (prop "Var" 'history))) )</langsyntaxhighlight>
Test:
<pre>: (setH 'A "Hello world")
Line 2,223 ⟶ 2,361:
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
declare t float controlled;
 
Line 2,233 ⟶ 2,371:
put (t); free t;
end;
</syntaxhighlight>
</lang>
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">; integer history variable
 
Structure historyint
Line 2,285 ⟶ 2,423:
Debug "undo, x = "+Str(x\value())
Next
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,304 ⟶ 2,442:
=={{header|Python}}==
 
<langsyntaxhighlight Pythonlang="python">import sys
 
HIST = {}
Line 2,337 ⟶ 2,475:
 
sys.settrace(trace)
main()</langsyntaxhighlight>
{{out}}<syntaxhighlight lang="text">c: 4 -> undo x3 -> 1
HIST: {'a': [10, 20], 'i': [0, 1, 2, 3, 4], 'c': [0, 1], 'name': ['c']}</langsyntaxhighlight>
 
 
Line 2,375 ⟶ 2,513:
Racket does not come with history variables, but they can be provided as a library as follows:
 
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 2,405 ⟶ 2,543:
(hvar-undo! hv)
(check-equal? (hvar-current hv) 0)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
<syntaxhighlight lang="raku" perl6line>class HistoryVar {
has @.history;
has $!var handles <Str gist FETCH Numeric>;
Line 2,427 ⟶ 2,565:
 
.say for foo.history;
say "Current value: {foo}";</langsyntaxhighlight>
{{out}}
<pre>[Instant:1523396079.685629 (Any)]
Line 2,441 ⟶ 2,579:
<br><br>The history list part of the &nbsp' '''varSet''' &nbsp; subroutine could be separated into its
<br>own if you wanted to keep the subroutine's function pure.
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates a method to track history of assignments to a REXX variable.*/
varSet!.=0 /*initialize the all of the VARSET!'s. */
call varSet 'fluid',min(0,-5/2,-1) ; say 'fluid=' fluid
Line 2,462 ⟶ 2,600:
say 'history entry' ?j "for var" ?z":" varSet!.?J.?x
end /*?j*/
return ?j-1 /*return the number of assignments. */</langsyntaxhighlight>
'''output'''
<pre>
Line 2,476 ⟶ 2,614:
 
===Version 2===
<langsyntaxhighlight lang="rexx">
/* REXX ***************************************************************
* Demonstrate how the history of assignments can be kept and shown
Line 2,517 ⟶ 2,655:
end
Return varset.0.varu /*return the number of assignments. */
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
This uses trace_var, which only works for global variables:
<langsyntaxhighlight lang="ruby">foo_hist = []
trace_var(:$foo){|v| foo_hist.unshift(v)}
 
Line 2,529 ⟶ 2,667:
 
p foo_hist # => ["banana", "pear", "apple"]
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
<langsyntaxhighlight Rustlang="rust">#[derive(Clone, Debug)]
struct HVar<T> {
history: Vec<T>,
Line 2,574 ⟶ 2,712:
println!("{:?}", var.revert());
println!("{:?}", var.get());
}</langsyntaxhighlight>
{{out}}
<pre>([0, 1], 2)
Line 2,584 ⟶ 2,722:
=={{header|Scala}}==
Scala doesn't have a native support for history variables, but it's quite easy to implement them. The following class uses same conventions as ML's mutable reference cells. (i.e. <code>!</code> as accessor, and <code>:=</code> as mutator.)
<langsyntaxhighlight lang="scala">class HVar[A](initialValue: A) extends Proxy {
override def self = !this
override def toString = "HVar(" + !this + ")"
Line 2,603 ⟶ 2,741:
v
}
}</langsyntaxhighlight>
Usage:
<langsyntaxhighlight lang="scala">scala> val h = new HVar(3)
h: HVar[Int] = HVar(3)
 
Line 2,625 ⟶ 2,763:
 
scala> h.undo
res36: Int = 3</langsyntaxhighlight>
 
=={{header|SenseTalk}}==
SenseTalk does not have native support for history variables, but here is a simple object that can be instantiated to provide a history:
<langsyntaxhighlight lang="sensetalk">// HistoryVariable.script
properties
history: [], -- a list of all historical values
Line 2,643 ⟶ 2,781:
return it
end rollback
</syntaxhighlight>
</lang>
Here is an example how this could be used (note that variables in SenseTalk may hold any type of value):
<langsyntaxhighlight lang="sensetalk">set x to be a new HistoryVariable
 
tell x to set "Hello"
Line 2,665 ⟶ 2,803:
put "Rolling back:" && x.rollback -- remove the last value
put "After rollback, x is now" && x
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,680 ⟶ 2,818:
=={{header|Sidef}}==
Implemented as a class:
<langsyntaxhighlight lang="ruby">class HistoryVar(v) {
 
has history = []
Line 2,707 ⟶ 2,845:
 
say "History: #{foo.history}"
say "Current value: #{foo}"</langsyntaxhighlight>
{{out}}
<pre>
Line 2,717 ⟶ 2,855:
Smalltalk doesn't have native support for history variables. It could be implemented using (implementation dependent) tracing facilities, or by changing the code generator (which is part of the library and open for change).
The following implementation is portable and in the spirit of the Lisp implementation above, and defines a new "assignment operator":
<langsyntaxhighlight lang="smalltalk">Object subclass:'HVar'
instanceVariableNames:'values'
classVariableNames:''
Line 2,752 ⟶ 2,890:
x value.
x history.
</syntaxhighlight>
</lang>
 
=={{header|Swift}}==
Swift does not support history variables. However, you can add a watcher that can track when the variable will change.
<langsyntaxhighlight Swiftlang="swift">var historyOfHistory = [Int]()
var history:Int = 0 {
willSet {
Line 2,767 ⟶ 2,905:
history = 4
println(historyOfHistory)
</syntaxhighlight>
</lang>
 
another approach, using generics:
plug this code into a Playground to see the output
{{works with|Swift|2.x+}}
<langsyntaxhighlight lang="swift">
 
struct History <T> {
Line 2,813 ⟶ 2,951:
h.undo() // outputs "First"
 
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
Though Tcl's variables don't have history by default, it can be added easily through the use of traces:
<langsyntaxhighlight lang="tcl"># Define the history machinery
proc histvar {varName operation} {
upvar 1 $varName v ___history($varName) history
Line 2,849 ⟶ 2,987:
upvar 1 $varName v ___history($key) history
set v [lindex $history end]
}</langsyntaxhighlight>
Demonstrating how to use it:
<langsyntaxhighlight lang="tcl"># Enable history for foo
histvar foo start
set foo {a b c d}
Line 2,863 ⟶ 3,001:
histvar foo undo
puts $foo
histvar foo stop</langsyntaxhighlight>
{{out}}
<pre>
Line 2,876 ⟶ 3,014:
{{trans|Kotlin}}
Not built in but we can soon make a suitable class.
<langsyntaxhighlight ecmascriptlang="wren">class HistoryVariable {
construct new(initValue) {
_history = [initValue]
Line 2,894 ⟶ 3,032:
v.currentValue = 3
v.showHistory()
System.print("\nCurrent value is %(v.currentValue)")</langsyntaxhighlight>
 
{{out}}
Line 2,908 ⟶ 3,046:
=={{header|zkl}}==
No native support, here is a something that can be done with a class:
<langsyntaxhighlight lang="zkl">class HistoryVar{
var [private] _v, _history=List(), maxSz;
fcn init(v,maxEntries=3){ maxSz=maxEntries; set(v) }
Line 2,925 ⟶ 3,063:
fcn{ _history.pump(List,fcn([(t,v)]){ T(Time.Date.ctime(t),v) }) };
fcn __opAdd(x){ set(_v + x); self }
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">hv:=HistoryVar(123);
hv+4;
hv.set("Shuttle prepared for liftoff");
hv+": orbit achived";
hv.history.concat("\n").println();
hv.get(3).println("<-- value two changes ago");</langsyntaxhighlight>
{{out}}
<pre>
Anonymous user