History variables: Difference between revisions
Content deleted Content added
Adds Clojure solution |
m {{out}} |
||
Line 1: | Line 1: | ||
{{task}} |
{{task}} |
||
''Storing the history of objects in a program is a common task. |
''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. |
''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: |
[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 [http://lambda-the-ultimate.org/node/3111 LtU] and [http://www.patents.com/us-7111283.html Patents.com]. |
Concept also discussed on [http://lambda-the-ultimate.org/node/3111 LtU] and [http://www.patents.com/us-7111283.html Patents.com]. |
||
Line 17: | Line 20: | ||
* recall the three values. |
* recall the three values. |
||
For extra points, if the language of choice does not support history variables, |
For extra points, if the language of choice does not support history variables, |
||
demonstrate how this might be implemented. |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Line 23: | Line 27: | ||
Ada does not natively support history variables -- we have to implement them. |
Ada does not natively support history variables -- we have to implement them. |
||
Furthermore, Ada is a strongly typed language -- that means, we would need |
Furthermore, Ada is a strongly typed language -- that means, we would need |
||
to write a history variable type for every basic item type. |
|||
Instead, we write a single generic package "History_Variables" that works for any item type. |
|||
Line 139: | Line 145: | ||
end Test_History;</lang> |
end Test_History;</lang> |
||
{{out}} |
|||
The program generates the following output: |
|||
<pre> 3 7 9 |
<pre> 3 7 9 |
||
19</pre> |
19</pre> |
||
Line 180: | Line 185: | ||
end Test_History;</lang> |
end Test_History;</lang> |
||
{{out}} |
|||
This time, the output is: |
|||
<pre>one oneone three |
<pre>one oneone three |
||
14</pre> |
14</pre> |
||
Line 275: | Line 279: | ||
}</lang> |
}</lang> |
||
{{out}} |
|||
'''Sample Output''' |
|||
<pre>foobar <- foo <- 5 |
<pre>foobar <- foo <- 5 |
||
</pre> |
</pre> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Clojure does not have history variables, but it can be accomplished |
Clojure does not have history variables, but it can be accomplished |
||
via a watcher function that can track changes on a variable. |
|||
<lang clojure> |
<lang clojure> |
||
Line 544: | Line 548: | ||
} |
} |
||
}</lang> |
}</lang> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
History of variable h: |
History of variable h: |
||
Line 931: | Line 935: | ||
History::off($x); |
History::off($x); |
||
print "\$x is: $x\n";</lang> |
print "\$x is: $x\n";</lang> |
||
{{out}}<lang>History: a b c d |
|||
undo 1, current value: c |
undo 1, current value: c |
||
undo 2, current value: b |
undo 2, current value: b |
||
Line 997: | Line 1,002: | ||
sys.settrace(trace) |
sys.settrace(trace) |
||
main()</lang> |
main()</lang> |
||
{{out}}<lang>c: 4 -> undo x3 -> 1 |
|||
HIST: {'a': [10, 20], 'i': [0, 1, 2, 3, 4], 'c': [0, 1], 'name': ['c']}</lang> |
HIST: {'a': [10, 20], 'i': [0, 1, 2, 3, 4], 'c': [0, 1], 'name': ['c']}</lang> |
||
Line 1,076: | Line 1,082: | ||
Turn history off <# 定义变量史>__off</#> </lang> |
Turn history off <# 定义变量史>__off</#> </lang> |
||
{{out}} |
|||
Sample output |
|||
<pre>Turn history on |
<pre>Turn history on |
||
Notify Protium we are interested in the variable mv |
Notify Protium we are interested in the variable mv |
||
Line 1,141: | Line 1,147: | ||
</lang> |
</lang> |
||
{{out}} |
|||
'''output''' |
|||
<pre style="overflow:scroll"> |
<pre style="overflow:scroll"> |
||
x history: |
x history: |
||
Line 1,219: | Line 1,225: | ||
end /*?j*/ |
end /*?j*/ |
||
return ?j-1 /*return the num of assignments. */</lang> |
return ?j-1 /*return the num of assignments. */</lang> |
||
{{out}} |
|||
'''output''' |
|||
<pre style="overflow:scroll"> |
<pre style="overflow:scroll"> |
||
fluid= -2.5 |
fluid= -2.5 |
||
Line 1,420: | Line 1,426: | ||
puts $foo |
puts $foo |
||
histvar foo stop</lang> |
histvar foo stop</lang> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
quick brown fox |
quick brown fox |