Previous | Table of Contents | Next |
6.2.9.3. Termination Dumps
If the value of the keyword &dump is nonzero when program execution terminates, whether normally or as the result of a runtime error, a dump of variable values at the time of termination is given. Here is an example:
Runtime error 103 File csgen.icn; Line 137 string expected offending value: &null Traceback: main(list_1 = []) subst(list_4 = [X,abc]) from line 127 in csgen.icn find(&null,X,&null,&null) from line 137 in csgen.icn Termination dump: coexpression_1 subst local identifiers: a = list_4 = [X,abc] main local identifiers: args = list_1 = [] line = X:10 goal = X count = 10 s = X opts = table_1(0) global identifiers: any = function any close = function close find = function find get = function get integer = function integer main = procedure main many = function many map = function map move = function move open = function open options = procedure options pos = function pos pull = function pull push = function push put = function put randomize = procedure randomize read = function read real = function real stop = function stop string = function string subst = procedure subst tab = function tab table = function table upto = function upto write = function write xlist = list_3 = [list_4(2),list_5(2),list_6(2), , list_8(2),list_9(2),list_10(2)] xpairs = procedure xpairs
Note that the functions used by the program are listed.
6.2.9.4. Tracing
Tracing of procedures occurs if the value of &trace is nonzero. (The initial value of &trace is 0.) The value of &trace is decremented for each trace message, so if &trace is set to a positive value, it turns off automatically, provided procedure activity continues long enough. Assigning a negative value to &trace, as in
&trace := 1
results in unlimited tracing. The value of &trace can, of course, be changed at any time during program execution.
Trace messages occur for the following:
Here is an example of tracing resulting from testing the procedure factorial() shown earlier:
ftest: 5 | factorial(5) ftest: 12 | | factorial(4) ftest: 12 | | | factorial(3) ftest: 12 | | | | factorial(2) ftest: 12 | | | | | factorial(1) ftest: 11 | | | | | factorial returned 1 ftest: 12 | | | | factorial returned 2 ftest: 12 | | | factorial returned 6 ftest: 12 | | factorial returned 24 ftest: 12 | factorial returned 120 ftest: 7 main failed
Each line of tracing shows the name of the source file in which procedure activity occurs (ftest.icn in the preceding example). Following a separating colon after the file name, the line number in the file where the activity occurred is given, followed by vertical bars that indicate the level of procedure call.
The rest of the line indicates the type of procedure activity with an associated value if the activity has one.
When learning a new natural language that is not familiar, it is typical to start by learning grammar and vocabulary and then translating mentally from the new language into a familiar one. To really master a new language, however, it is necessary to think in it.
The same situation exists in programming languages. The first steps are to learn the syntax and the computational repertoire. The computational repertoire involves more than just vocabulary; the semantics may be very different from familiar programming languages.
It is much more difficult to grasp how to program in a new languageto use it to formulate solutions to problems. As with natural languages, the first approach usually is to formulate programs in a familiar language and then try to translate them into the new language.
If the two languages are similar, this approach may be successful to a point. But to really take advantage of the features in a new programming language that a familiar programming language does not have, it is necessary to learn to think in the new language.
Since Icon has many features that are not found in other programming languages, translating from another language into Icon inevitably means that many features of Icon will not be used or not used as well as they might be. For example, if a programmer thinks in C and translates into Icon, generators and goal-directed evaluation cannot be used to their full advantage; C simply does not have the concepts.
One way to approach learning to think in a new programming language is to deliberately avoid thinking in a familiar language and translating to the new one. Although it may be difficult at the beginning to write even simple programs in an unfamiliar language, it pays off in the long run. Another approach is to concentrate on the essential features of the new language and see what can be done with them, independent of a preplanned project. Recreational topics work well because of their inherent interest.
In Icon, the most difficult concepts to master are related to expression evaluation: success, failure, and particularly generation.
If there is one single thing that most characterizes thinking in Icon, it is formulating solutions to problems in terms of sequences produced by generators. Because few programming languages have generators, and none have them in the style of Icon, thinking in terms of sequences produced by generators not only means thinking in Icon but also using a uniquely powerful programming tool.
Icon has subtleties in generators and the control structures related to them that are not described in preceding material. More aspects of these matters will be brought out in what follows, but many can be understood by deciding what is most natural and how specific features might be generalized.
Previous | Table of Contents | Next |