Anonymous user
History variables: Difference between revisions
m
→{{header|Elena}}
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.
<
LEA HistoryVar+4,A0
Line 48:
jsr PrintHex32
mov D2,D0
jsr PrintHex32</
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:
<
generic
type Item_Type (<>) is private;
Line 98:
History: Vectors.Vector;
end record;
end History_Variables;</
The implementation of "History_Variables":
<
-- set and get
Line 136:
end Undo;
end History_Variables;</
===Sample 1: The History of an Integer Variable===
<
procedure Test_History is
Line 172:
Ada.Text_IO.Put_Line(Integer'Image(Sum));
end Test_History;</
{{out}}
Line 181:
===Sample 2: The History of a String===
<
procedure Test_History is
Line 212:
Ada.Text_IO.Put_Line(Integer'Image(Sum));
end Test_History;</
{{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.
<
% 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.</
{{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):
<
{
private Object value;
Line 293 ⟶ 357:
{
}
}</
Aspect (HistoryHandling.aj):
<
import java.util.HashMap;
import java.util.LinkedList;
Line 337 ⟶ 401:
private Map<HistoryVariable, Deque<Object>> history = new HashMap<>();
}</
Usage:
<
{
public static void main(final String[] args)
Line 355 ⟶ 419:
System.out.println(hv.toString());
}
}</
{{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}}
<
HV.var := 1
HV.var := 2
Line 383 ⟶ 447:
Return this[1]
}
}</
=={{header|C sharp}}==
<
using System.Collections;
using System.Collections.Generic;
Line 454 ⟶ 518:
}
}
}</
{{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.
<
(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>
{{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.
<
`(list ,value))
Line 514 ⟶ 653:
(undo-hvar v)
(format t "Restored value = ~a~%" (get-hvar v)))
</syntaxhighlight>
{{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'.
<
/// A history variable.
Line 586 ⟶ 725:
s = "goodby";
writefln("%(%s\n%)", s.history);
}</
{{out|Sample Output}}
<pre>2013-Jan-19 23:04:55.1660302; 1
Line 598 ⟶ 737:
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
<syntaxhighlight lang="delphi">
program History_variables;
Line 710 ⟶ 849:
readln;
end.</
{{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.
<
(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>
=={{header|Elena}}==
ELENA
<
import system'collections;
import system'routines;
Line 805 ⟶ 944:
console.printLine(o);
o.forEach
o.undo().undo().undo();
console.printLine(o.Value ?? "nil")
}</
{{out}}
<pre>
Line 841 ⟶ 980:
=={{header|Factor}}==
<
1 <history> {
Line 852 ⟶ 991:
[ go-back ]
[ value>> "Restored value: %u\n" printf ]
} cleave</
{{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.
<
: 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 ! ;</
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.
<
import (
Line 999 ⟶ 1,138:
fmt.Println(rv)
}
}</
{{out}}
<pre>
Line 1,017 ⟶ 1,156:
There are no native Haskell history variables, but they are simple to implement.
<
newtype HVar a = HVar (IORef [a])
Line 1,048 ⟶ 1,187:
undoHVar var
undoHVar var
undoHVar var</
=={{header|J}}==
Line 1,054 ⟶ 1,193:
J does not natively support "history variables", but the functionality is easy to add:
<
set_hist_=:4 :0
V=.varref x
Line 1,065 ⟶ 1,204:
)
length_hist_=: #@getall
get_hist_=: _1 {:: getall</
Example use:
<
9
'x' set_hist_ 10
Line 1,082 ⟶ 1,221:
┌─┬──┬──┐
│9│10│11│
└─┴──┴──┘</
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.
===
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).
<
import java.util.LinkedList;
import java.util.List;
Line 1,168 ⟶ 1,307:
}
}
</syntaxhighlight>
Test Program:
<
public static void main(String[] args) {
Line 1,194 ⟶ 1,333:
}
}</
{{out}}
Line 1,210 ⟶ 1,349:
</pre>
===
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).
Test Program using a "String with History":
<
import java.util.LinkedList;
import java.util.List;
Line 1,290 ⟶ 1,428:
}
}
</syntaxhighlight>
{{out}}
<pre>
Line 1,308 ⟶ 1,446:
=={{header|Julia}}==
Julia currently does not support overloading the assignment "=" operator.
<
num::Number
history::Vector{Number}
Line 1,323 ⟶ 1,461:
println("Past history of variable x: $(x.history). Current value is $(x.num)")
</
=={{header|Kotlin}}==
<
class HistoryVariable<T>(initialValue: T) {
Line 1,353 ⟶ 1,491:
v.showHistory()
println("\nCurrentvalue is ${v.currentValue}")
}</
{{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===
<
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())</
{{out}}
<pre>defined: table: 0000000000939240
Line 1,410 ⟶ 1,548:
===Via closure===
If a desire is to keep history private and immutable, then..
<
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())</
{{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">
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>
So now lets see the code:
<syntaxhighlight lang="m2000 interpreter">
Module CheckHistoryVariables {
Class History {
Line 1,682 ⟶ 1,820:
}
CheckStringHistoryVariables
</syntaxhighlight>
=={{header|Nim}}==
Line 1,688 ⟶ 1,826:
As Nim is statically typed, we define history variable type in a generic way.
<
hist: seq[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()</
{{out}}
Line 1,751 ⟶ 1,889:
=={{header|Oberon-2}}==
<
MODULE HVar;
IMPORT Out, Conv;
Line 1,931 ⟶ 2,069:
ShowVal(history.Undo());
END HVar.
</syntaxhighlight>
=={{header|OCaml}}==
The easiest solution is to use the Stack module coming with OCaml's standard library:
<
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>
{{out}}
Line 1,966 ⟶ 2,104:
=={{header|OxygenBasic}}==
Simple history class for fixed length types that do not contain volatile pointer members.
<
'============
class History
Line 2,025 ⟶ 2,163:
del hv
</syntaxhighlight>
=={{header|PARI/GP}}==
<
1+7
sin(Pi)
Line 2,037 ⟶ 2,175:
\a2
\a3
[%1, %2, %3] \\ or any other command using these values</
=={{header|Peloton}}==
<
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</@></
Same code, Simplified Chinese dialect
<
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</#> </
{{out}}
Line 2,081 ⟶ 2,219:
=={{header|Perl}}==
Implemented via tie (and what's the usefulness of this?)
<
sub TIESCALAR {
Line 2,120 ⟶ 2,258:
History::off($x);
print "\$x is: $x\n";</
{{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</
=={{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:
<!--<
<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>
<!--</
{{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):
<!--<
<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>
<!--</
And use it like this
<!--<
<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>
<!--</
Same output. Of course test2 does not ''have'' to be a constant, but it may help.
=={{header|PicoLisp}}==
<
(when (val "Var")
(with "Var"
Line 2,193 ⟶ 2,331:
(de restoreH ("Var")
(set "Var" (pop (prop "Var" 'history))) )</
Test:
<pre>: (setH 'A "Hello world")
Line 2,223 ⟶ 2,361:
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
declare t float controlled;
Line 2,233 ⟶ 2,371:
put (t); free t;
end;
</syntaxhighlight>
=={{header|PureBasic}}==
<
Structure historyint
Line 2,285 ⟶ 2,423:
Debug "undo, x = "+Str(x\value())
Next
</syntaxhighlight>
{{out}}
Line 2,304 ⟶ 2,442:
=={{header|Python}}==
<
HIST = {}
Line 2,337 ⟶ 2,475:
sys.settrace(trace)
main()</
{{out}}<syntaxhighlight lang="text">c: 4 -> undo x3 -> 1
HIST: {'a': [10, 20], 'i': [0, 1, 2, 3, 4], 'c': [0, 1], 'name': ['c']}</
Line 2,375 ⟶ 2,513:
Racket does not come with history variables, but they can be provided as a library as follows:
<
#lang racket
Line 2,405 ⟶ 2,543:
(hvar-undo! hv)
(check-equal? (hvar-current hv) 0)
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.03}}
<syntaxhighlight lang="raku"
has @.history;
has $!var handles <Str gist FETCH Numeric>;
Line 2,427 ⟶ 2,565:
.say for foo.history;
say "Current value: {foo}";</
{{out}}
<pre>[Instant:1523396079.685629 (Any)]
Line 2,441 ⟶ 2,579:
<br><br>The history list part of the  ' '''varSet''' subroutine could be separated into its
<br>own if you wanted to keep the subroutine's function pure.
<
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. */</
'''output'''
<pre>
Line 2,476 ⟶ 2,614:
===Version 2===
<
/* 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>
=={{header|Ruby}}==
This uses trace_var, which only works for global variables:
<
trace_var(:$foo){|v| foo_hist.unshift(v)}
Line 2,529 ⟶ 2,667:
p foo_hist # => ["banana", "pear", "apple"]
</syntaxhighlight>
=={{header|Rust}}==
<
struct HVar<T> {
history: Vec<T>,
Line 2,574 ⟶ 2,712:
println!("{:?}", var.revert());
println!("{:?}", var.get());
}</
{{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.)
<
override def self = !this
override def toString = "HVar(" + !this + ")"
Line 2,603 ⟶ 2,741:
v
}
}</
Usage:
<
h: HVar[Int] = HVar(3)
Line 2,625 ⟶ 2,763:
scala> h.undo
res36: Int = 3</
=={{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:
<
properties
history: [], -- a list of all historical values
Line 2,643 ⟶ 2,781:
return it
end rollback
</syntaxhighlight>
Here is an example how this could be used (note that variables in SenseTalk may hold any type of value):
<
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>
{{out}}
<pre>
Line 2,680 ⟶ 2,818:
=={{header|Sidef}}==
Implemented as a class:
<
has history = []
Line 2,707 ⟶ 2,845:
say "History: #{foo.history}"
say "Current value: #{foo}"</
{{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":
<
instanceVariableNames:'values'
classVariableNames:''
Line 2,752 ⟶ 2,890:
x value.
x history.
</syntaxhighlight>
=={{header|Swift}}==
Swift does not support history variables. However, you can add a watcher that can track when the variable will change.
<
var history:Int = 0 {
willSet {
Line 2,767 ⟶ 2,905:
history = 4
println(historyOfHistory)
</syntaxhighlight>
another approach, using generics:
plug this code into a Playground to see the output
{{works with|Swift|2.x+}}
<
struct History <T> {
Line 2,813 ⟶ 2,951:
h.undo() // outputs "First"
</syntaxhighlight>
=={{header|Tcl}}==
Though Tcl's variables don't have history by default, it can be added easily through the use of traces:
<
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]
}</
Demonstrating how to use it:
<
histvar foo start
set foo {a b c d}
Line 2,863 ⟶ 3,001:
histvar foo undo
puts $foo
histvar foo stop</
{{out}}
<pre>
Line 2,876 ⟶ 3,014:
{{trans|Kotlin}}
Not built in but we can soon make a suitable class.
<
construct new(initValue) {
_history = [initValue]
Line 2,894 ⟶ 3,032:
v.currentValue = 3
v.showHistory()
System.print("\nCurrent value is %(v.currentValue)")</
{{out}}
Line 2,908 ⟶ 3,046:
=={{header|zkl}}==
No native support, here is a something that can be done with a class:
<
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 }
}</
<
hv+4;
hv.set("Shuttle prepared for liftoff");
hv+": orbit achived";
hv.history.concat("\n").println();
hv.get(3).println("<-- value two changes ago");</
{{out}}
<pre>
|