1struct::list(n) Tcl Data Structures struct::list(n)
2
3
4
5______________________________________________________________________________
6
8 struct::list - Procedures for manipulating lists
9
11 package require Tcl 8.4
12
13 package require struct::list ?1.8.4?
14
15 ::struct::list longestCommonSubsequence sequence1 sequence2 ?maxOccurs?
16
17 ::struct::list longestCommonSubsequence2 sequence1 sequence2 ?maxOc‐
18 curs?
19
20 ::struct::list lcsInvert lcsData len1 len2
21
22 ::struct::list lcsInvert2 lcs1 lcs2 len1 len2
23
24 ::struct::list lcsInvertMerge lcsData len1 len2
25
26 ::struct::list lcsInvertMerge2 lcs1 lcs2 len1 len2
27
28 ::struct::list reverse sequence
29
30 ::struct::list shuffle list
31
32 ::struct::list assign sequence varname ?varname?...
33
34 ::struct::list flatten ?-full? ?--? sequence
35
36 ::struct::list map sequence cmdprefix
37
38 ::struct::list mapfor var sequence script
39
40 ::struct::list filter sequence cmdprefix
41
42 ::struct::list filterfor var sequence expr
43
44 ::struct::list split sequence cmdprefix ?passVar failVar?
45
46 ::struct::list fold sequence initialvalue cmdprefix
47
48 ::struct::list shift listvar
49
50 ::struct::list iota n
51
52 ::struct::list equal a b
53
54 ::struct::list repeat size element1 ?element2 element3...?
55
56 ::struct::list repeatn value size...
57
58 ::struct::list dbJoin ?-inner|-left|-right|-full? ?-keys varname? {key‐
59 col table}...
60
61 ::struct::list dbJoinKeyed ?-inner|-left|-right|-full? ?-keys varname?
62 table...
63
64 ::struct::list swap listvar i j
65
66 ::struct::list firstperm list
67
68 ::struct::list nextperm perm
69
70 ::struct::list permutations list
71
72 ::struct::list foreachperm var list body
73
74______________________________________________________________________________
75
77 The ::struct::list namespace contains several useful commands for pro‐
78 cessing Tcl lists. Generally speaking, they implement algorithms more
79 complex or specialized than the ones provided by Tcl itself.
80
81 It exports only a single command, struct::list. All functionality pro‐
82 vided here can be reached through a subcommand of this command.
83
85 ::struct::list longestCommonSubsequence sequence1 sequence2 ?maxOccurs?
86 Returns the longest common subsequence of elements in the two
87 lists sequence1 and sequence2. If the maxOccurs parameter is
88 provided, the common subsequence is restricted to elements that
89 occur no more than maxOccurs times in sequence2.
90
91 The return value is a list of two lists of equal length. The
92 first sublist is of indices into sequence1, and the second sub‐
93 list is of indices into sequence2. Each corresponding pair of
94 indices corresponds to equal elements in the sequences; the se‐
95 quence returned is the longest possible.
96
97 ::struct::list longestCommonSubsequence2 sequence1 sequence2 ?maxOc‐
98 curs?
99 Returns an approximation to the longest common sequence of ele‐
100 ments in the two lists sequence1 and sequence2. If the maxOc‐
101 curs parameter is omitted, the subsequence computed is exactly
102 the longest common subsequence; otherwise, the longest common
103 subsequence is approximated by first determining the longest
104 common sequence of only those elements that occur no more than
105 maxOccurs times in sequence2, and then using that result to
106 align the two lists, determining the longest common subsequences
107 of the sublists between the two elements.
108
109 As with longestCommonSubsequence, the return value is a list of
110 two lists of equal length. The first sublist is of indices into
111 sequence1, and the second sublist is of indices into sequence2.
112 Each corresponding pair of indices corresponds to equal elements
113 in the sequences. The sequence approximates the longest common
114 subsequence.
115
116 ::struct::list lcsInvert lcsData len1 len2
117 This command takes a description of a longest common subsequence
118 (lcsData), inverts it, and returns the result. Inversion means
119 here that as the input describes which parts of the two se‐
120 quences are identical the output describes the differences in‐
121 stead.
122
123 To be fully defined the lengths of the two sequences have to be
124 known and are specified through len1 and len2.
125
126 The result is a list where each element describes one chunk of
127 the differences between the two sequences. This description is a
128 list containing three elements, a type and two pairs of indices
129 into sequence1 and sequence2 respectively, in this order. The
130 type can be one of three values:
131
132 added Describes an addition. I.e. items which are missing in
133 sequence1 can be found in sequence2. The pair of indices
134 into sequence1 describes where the added range had been
135 expected to be in sequence1. The first index refers to
136 the item just before the added range, and the second in‐
137 dex refers to the item just after the added range. The
138 pair of indices into sequence2 describes the range of
139 items which has been added to it. The first index refers
140 to the first item in the range, and the second index
141 refers to the last item in the range.
142
143 deleted
144 Describes a deletion. I.e. items which are in sequence1
145 are missing from sequence2. The pair of indices into se‐
146 quence1 describes the range of items which has been
147 deleted. The first index refers to the first item in the
148 range, and the second index refers to the last item in
149 the range. The pair of indices into sequence2 describes
150 where the deleted range had been expected to be in se‐
151 quence2. The first index refers to the item just before
152 the deleted range, and the second index refers to the
153 item just after the deleted range.
154
155 changed
156 Describes a general change. I.e a range of items in se‐
157 quence1 has been replaced by a different range of items
158 in sequence2. The pair of indices into sequence1 de‐
159 scribes the range of items which has been replaced. The
160 first index refers to the first item in the range, and
161 the second index refers to the last item in the range.
162 The pair of indices into sequence2 describes the range of
163 items replacing the original range. Again the first index
164 refers to the first item in the range, and the second in‐
165 dex refers to the last item in the range.
166
167
168
169 sequence 1 = {a b r a c a d a b r a}
170 lcs 1 = {1 2 4 5 8 9 10}
171 lcs 2 = {0 1 3 4 5 6 7}
172 sequence 2 = {b r i c a b r a c}
173
174 Inversion = {{deleted {0 0} {-1 0}}
175 {changed {3 3} {2 2}}
176 {deleted {6 7} {4 5}}
177 {added {10 11} {8 8}}}
178
179
180 Notes:
181
182
183 • An index of -1 in a deleted chunk refers to just before
184 the first element of the second sequence.
185
186 • Also an index equal to the length of the first sequence
187 in an added chunk refers to just behind the end of the
188 sequence.
189
190 ::struct::list lcsInvert2 lcs1 lcs2 len1 len2
191 Similar to lcsInvert. Instead of directly taking the result of a
192 call to longestCommonSubsequence this subcommand expects the in‐
193 dices for the two sequences in two separate lists.
194
195 ::struct::list lcsInvertMerge lcsData len1 len2
196 Similar to lcsInvert. It returns essentially the same structure
197 as that command, except that it may contain chunks of type un‐
198 changed too.
199
200 These new chunks describe the parts which are unchanged between
201 the two sequences. This means that the result of this command
202 describes both the changed and unchanged parts of the two se‐
203 quences in one structure.
204
205
206
207 sequence 1 = {a b r a c a d a b r a}
208 lcs 1 = {1 2 4 5 8 9 10}
209 lcs 2 = {0 1 3 4 5 6 7}
210 sequence 2 = {b r i c a b r a c}
211
212 Inversion/Merge = {{deleted {0 0} {-1 0}}
213 {unchanged {1 2} {0 1}}
214 {changed {3 3} {2 2}}
215 {unchanged {4 5} {3 4}}
216 {deleted {6 7} {4 5}}
217 {unchanged {8 10} {5 7}}
218 {added {10 11} {8 8}}}
219
220
221 ::struct::list lcsInvertMerge2 lcs1 lcs2 len1 len2
222 Similar to lcsInvertMerge. Instead of directly taking the result
223 of a call to longestCommonSubsequence this subcommand expects
224 the indices for the two sequences in two separate lists.
225
226 ::struct::list reverse sequence
227 The subcommand takes a single sequence as argument and returns a
228 new sequence containing the elements of the input sequence in
229 reverse order.
230
231 ::struct::list shuffle list
232 The subcommand takes a list and returns a copy of that list with
233 the elements it contains in random order. Every possible order‐
234 ing of elements is equally likely to be generated. The Fisher-
235 Yates shuffling algorithm is used internally.
236
237 ::struct::list assign sequence varname ?varname?...
238 The subcommand assigns the first n elements of the input se‐
239 quence to the one or more variables whose names were listed af‐
240 ter the sequence, where n is the number of specified variables.
241
242 If there are more variables specified than there are elements in
243 the sequence the empty string will be assigned to the superflu‐
244 ous variables.
245
246 If there are more elements in the sequence than variable names
247 specified the subcommand returns a list containing the unas‐
248 signed elements. Else an empty list is returned.
249
250
251 tclsh> ::struct::list assign {a b c d e} foo bar
252 c d e
253 tclsh> set foo
254 a
255 tclsh> set bar
256 b
257
258
259 ::struct::list flatten ?-full? ?--? sequence
260 The subcommand takes a single sequence and returns a new se‐
261 quence where one level of nesting was removed from the input se‐
262 quence. In other words, the sublists in the input sequence are
263 replaced by their elements.
264
265 The subcommand will remove any nesting it finds if the option
266 -full is specified.
267
268
269 tclsh> ::struct::list flatten {1 2 3 {4 5} {6 7} {{8 9}} 10}
270 1 2 3 4 5 6 7 {8 9} 10
271 tclsh> ::struct::list flatten -full {1 2 3 {4 5} {6 7} {{8 9}} 10}
272 1 2 3 4 5 6 7 8 9 10
273
274
275 ::struct::list map sequence cmdprefix
276 The subcommand takes a sequence to operate on and a command pre‐
277 fix (cmdprefix) specifying an operation, applies the command
278 prefix to each element of the sequence and returns a sequence
279 consisting of the results of that application.
280
281 The command prefix will be evaluated with a single word appended
282 to it. The evaluation takes place in the context of the caller
283 of the subcommand.
284
285
286
287 tclsh> # squaring all elements in a list
288
289 tclsh> proc sqr {x} {expr {$x*$x}}
290 tclsh> ::struct::list map {1 2 3 4 5} sqr
291 1 4 9 16 25
292
293 tclsh> # Retrieving the second column from a matrix
294 tclsh> # given as list of lists.
295
296 tclsh> proc projection {n list} {::lindex $list $n}
297 tclsh> ::struct::list map {{a b c} {1 2 3} {d f g}} {projection 1}
298 b 2 f
299
300
301 ::struct::list mapfor var sequence script
302 The subcommand takes a sequence to operate on and a tcl script,
303 applies the script to each element of the sequence and returns a
304 sequence consisting of the results of that application.
305
306 The script will be evaluated as is, and has access to the cur‐
307 rent list element through the specified iteration variable var.
308 The evaluation takes place in the context of the caller of the
309 subcommand.
310
311
312
313 tclsh> # squaring all elements in a list
314
315 tclsh> ::struct::list mapfor x {1 2 3 4 5} {
316 expr {$x * $x}
317 }
318 1 4 9 16 25
319
320 tclsh> # Retrieving the second column from a matrix
321 tclsh> # given as list of lists.
322
323 tclsh> ::struct::list mapfor x {{a b c} {1 2 3} {d f g}} {
324 lindex $x 1
325 }
326 b 2 f
327
328
329 ::struct::list filter sequence cmdprefix
330 The subcommand takes a sequence to operate on and a command pre‐
331 fix (cmdprefix) specifying an operation, applies the command
332 prefix to each element of the sequence and returns a sequence
333 consisting of all elements of the sequence for which the command
334 prefix returned true. In other words, this command filters out
335 all elements of the input sequence which fail the test the cmd‐
336 prefix represents, and returns the remaining elements.
337
338 The command prefix will be evaluated with a single word appended
339 to it. The evaluation takes place in the context of the caller
340 of the subcommand.
341
342
343
344 tclsh> # removing all odd numbers from the input
345
346 tclsh> proc even {x} {expr {($x % 2) == 0}}
347 tclsh> ::struct::list filter {1 2 3 4 5} even
348 2 4
349
350
351 Note: The filter is a specialized application of fold where the result
352 is extended with the current item or not, depending o nthe result of
353 the test.
354
355 ::struct::list filterfor var sequence expr
356 The subcommand takes a sequence to operate on and a tcl expres‐
357 sion (expr) specifying a condition, applies the conditionto each
358 element of the sequence and returns a sequence consisting of all
359 elements of the sequence for which the expression returned true.
360 In other words, this command filters out all elements of the in‐
361 put sequence which fail the test the condition expr represents,
362 and returns the remaining elements.
363
364 The expression will be evaluated as is, and has access to the
365 current list element through the specified iteration variable
366 var. The evaluation takes place in the context of the caller of
367 the subcommand.
368
369
370
371 tclsh> # removing all odd numbers from the input
372
373 tclsh> ::struct::list filterfor x {1 2 3 4 5} {($x % 2) == 0}
374 2 4
375
376
377 ::struct::list split sequence cmdprefix ?passVar failVar?
378 This is a variant of method filter, see above. Instead of re‐
379 turning just the elements passing the test we get lists of both
380 passing and failing elements.
381
382 If no variable names are specified then the result of the com‐
383 mand will be a list containing the list of passing elements, and
384 the list of failing elements, in this order. Otherwise the lists
385 of passing and failing elements are stored into the two speci‐
386 fied variables, and the result will be a list containing two
387 numbers, the number of elements passing the test, and the number
388 of elements failing, in this order.
389
390 The interface to the test is the same as used by filter.
391
392 ::struct::list fold sequence initialvalue cmdprefix
393 The subcommand takes a sequence to operate on, an arbitrary
394 string initial value and a command prefix (cmdprefix) specifying
395 an operation.
396
397 The command prefix will be evaluated with two words appended to
398 it. The second of these words will always be an element of the
399 sequence. The evaluation takes place in the context of the
400 caller of the subcommand.
401
402 It then reduces the sequence into a single value through re‐
403 peated application of the command prefix and returns that value.
404 This reduction is done by
405
406 1 Application of the command to the initial value and the
407 first element of the list.
408
409 2 Application of the command to the result of the last call
410 and the second element of the list.
411
412 ...
413
414 i Application of the command to the result of the last call
415 and the i'th element of the list.
416
417 ...
418
419 end Application of the command to the result of the last call
420 and the last element of the list. The result of this call
421 is returned as the result of the subcommand.
422
423
424
425 tclsh> # summing the elements in a list.
426 tclsh> proc + {a b} {expr {$a + $b}}
427 tclsh> ::struct::list fold {1 2 3 4 5} 0 +
428 15
429
430
431 ::struct::list shift listvar
432 The subcommand takes the list contained in the variable named by
433 listvar and shifts it down one element. After the call listvar
434 will contain a list containing the second to last elements of
435 the input list. The first element of the ist is returned as the
436 result of the command. Shifting the empty list does nothing.
437
438 ::struct::list iota n
439 The subcommand returns a list containing the integer numbers in
440 the range [0,n). The element at index i of the list contain the
441 number i.
442
443 For "n == 0" an empty list will be returned.
444
445 ::struct::list equal a b
446 The subcommand compares the two lists a and b for equality. In
447 other words, they have to be of the same length and have to con‐
448 tain the same elements in the same order. If an element is a
449 list the same definition of equality applies recursively.
450
451 A boolean value will be returned as the result of the command.
452 This value will be true if the two lists are equal, and false
453 else.
454
455 ::struct::list repeat size element1 ?element2 element3...?
456 The subcommand creates a list of length "size * number of ele‐
457 ments" by repeating size times the sequence of elements element1
458 element2 .... size must be a positive integer, elementn can be
459 any Tcl value. Note that repeat 1 arg ... is identical to list
460 arg ..., though the arg is required with repeat.
461
462 Examples:
463
464
465
466 tclsh> ::struct::list repeat 3 a
467 a a a
468 tclsh> ::struct::list repeat 3 [::struct::list repeat 3 0]
469 {0 0 0} {0 0 0} {0 0 0}
470 tclsh> ::struct::list repeat 3 a b c
471 a b c a b c a b c
472 tclsh> ::struct::list repeat 3 [::struct::list repeat 2 a] b c
473 {a a} b c {a a} b c {a a} b c
474
475
476 ::struct::list repeatn value size...
477 The subcommand creates a (nested) list containing the value in
478 all positions. The exact size and degree of nesting is deter‐
479 mined by the size arguments, all of which have to be integer
480 numbers greater than or equal to zero.
481
482 A single argument size which is a list of more than one element
483 will be treated as if more than argument size was specified.
484
485 If only one argument size is present the returned list will not
486 be nested, of length size and contain value in all positions.
487 If more than one size argument is present the returned list will
488 be nested, and of the length specified by the last size argument
489 given to it. The elements of that list are defined as the result
490 of Repeat for the same arguments, but with the last size value
491 removed.
492
493 An empty list will be returned if no size arguments are present.
494
495
496
497 tclsh> ::struct::list repeatn 0 3 4
498 {0 0 0} {0 0 0} {0 0 0} {0 0 0}
499 tclsh> ::struct::list repeatn 0 {3 4}
500 {0 0 0} {0 0 0} {0 0 0} {0 0 0}
501 tclsh> ::struct::list repeatn 0 {3 4 5}
502 {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}} {{0 0 0} {0 0 0} {0 0 0} {0 0 0}}
503
504
505 ::struct::list dbJoin ?-inner|-left|-right|-full? ?-keys varname? {key‐
506 col table}...
507 The method performs a table join according to relational alge‐
508 bra. The execution of any of the possible outer join operation
509 is triggered by the presence of either option -left, -right, or
510 -full. If none of these options is present a regular inner join
511 will be performed. This can also be triggered by specifying -in‐
512 ner. The various possible join operations are explained in de‐
513 tail in section TABLE JOIN.
514
515 If the -keys is present its argument is the name of a variable
516 to store the full list of found keys into. Depending on the ex‐
517 act nature of the input table and the join mode the output table
518 may not contain all the keys by default. In such a case the
519 caller can declare a variable for this information and then in‐
520 sert it into the output table on its own, as she will have more
521 information about the placement than this command.
522
523 What is left to explain is the format of the arguments.
524
525 The keycol arguments are the indices of the columns in the ta‐
526 bles which contain the key values to use for the joining. Each
527 argument applies to the table following immediately after it.
528 The columns are counted from 0, which references the first col‐
529 umn. The table associated with the column index has to have at
530 least keycol+1 columns. An error will be thrown if there are
531 less.
532
533 The table arguments represent a table or matrix of rows and col‐
534 umns of values. We use the same representation as generated and
535 consumed by the methods get rect and set rect of matrix objects.
536 In other words, each argument is a list, representing the whole
537 matrix. Its elements are lists too, each representing a single
538 rows of the matrix. The elements of the row-lists are the column
539 values.
540
541 The table resulting from the join operation is returned as the
542 result of the command. We use the same representation as de‐
543 scribed above for the input tables.
544
545 ::struct::list dbJoinKeyed ?-inner|-left|-right|-full? ?-keys varname?
546 table...
547 The operations performed by this method are the same as de‐
548 scribed above for dbJoin. The only difference is in the specifi‐
549 cation of the keys to use. Instead of using column indices sepa‐
550 rate from the table here the keys are provided within the table
551 itself. The row elements in each table are not the lists of col‐
552 umn values, but a two-element list where the second element is
553 the regular list of column values and the first element is the
554 key to use.
555
556 ::struct::list swap listvar i j
557 The subcommand exchanges the elements at the indices i and j in
558 the list stored in the variable named by listvar. The list is
559 modified in place, and also returned as the result of the sub‐
560 command.
561
562 ::struct::list firstperm list
563 This subcommand returns the lexicographically first permutation
564 of the input list.
565
566 ::struct::list nextperm perm
567 This subcommand accepts a permutation of a set of elements (pro‐
568 vided by perm) and returns the next permutatation in lexico‐
569 graphic sequence.
570
571 The algorithm used here is by Donal E. Knuth, see section REFER‐
572 ENCES for details.
573
574 ::struct::list permutations list
575 This subcommand returns a list containing all permutations of
576 the input list in lexicographic order.
577
578 ::struct::list foreachperm var list body
579 This subcommand executes the script body once for each permuta‐
580 tion of the specified list. The permutations are visited in lex‐
581 icographic order, and the variable var is set to the permutation
582 for which body is currently executed. The result of the loop
583 command is the empty string.
584
586 The longestCommonSubsequence subcommand forms the core of a flexible
587 system for doing differential comparisons of files, similar to the ca‐
588 pability offered by the Unix command diff. While this procedure is
589 quite rapid for many tasks of file comparison, its performance degrades
590 severely if sequence2 contains many equal elements (as, for instance,
591 when using this procedure to compare two files, a quarter of whose
592 lines are blank. This drawback is intrinsic to the algorithm used (see
593 the Reference for details).
594
595 One approach to dealing with the performance problem that is sometimes
596 effective in practice is arbitrarily to exclude elements that appear
597 more than a certain number of times. This number is provided as the
598 maxOccurs parameter. If frequent lines are excluded in this manner,
599 they will not appear in the common subsequence that is computed; the
600 result will be the longest common subsequence of infrequent elements.
601 The procedure longestCommonSubsequence2 implements this heuristic. It
602 functions as a wrapper around longestCommonSubsequence; it computes the
603 longest common subsequence of infrequent elements, and then subdivides
604 the subsequences that lie between the matches to approximate the true
605 longest common subsequence.
606
608 This is an operation from relational algebra for relational databases.
609
610 The easiest way to understand the regular inner join is that it creates
611 the cartesian product of all the tables involved first and then keeps
612 only all those rows in the resulting table for which the values in the
613 specified key columns are equal to each other.
614
615 Implementing this description naively, i.e. as described above will
616 generate a huge intermediate result. To avoid this the cartesian prod‐
617 uct and the filtering of row are done at the same time. What is re‐
618 quired is a fast way to determine if a key is present in a table. In a
619 true database this is done through indices. Here we use arrays inter‐
620 nally.
621
622 An outer join is an extension of the inner join for two tables. There
623 are three variants of outerjoins, called left, right, and full outer
624 joins. Their result always contains all rows from an inner join and
625 then some additional rows.
626
627 [1] For the left outer join the additional rows are all rows from
628 the left table for which there is no key in the right table.
629 They are joined to an empty row of the right table to fit them
630 into the result.
631
632 [2] For the right outer join the additional rows are all rows from
633 the right table for which there is no key in the left table.
634 They are joined to an empty row of the left table to fit them
635 into the result.
636
637 [3] The full outer join combines both left and right outer join. In
638 other words, the additional rows are as defined for left outer
639 join, and right outer join, combined.
640
641 We extend all the joins from two to n tables (n > 2) by executing
642
643
644 (...((table1 join table2) join table3) ...) join tableN
645
646
647 Examples for all the joins:
648
649
650 Inner Join
651
652 {0 foo} {0 bagel} {0 foo 0 bagel}
653 {1 snarf} inner join {1 snatz} = {1 snarf 1 snatz}
654 {2 blue} {3 driver}
655
656 Left Outer Join
657
658 {0 foo} {0 bagel} {0 foo 0 bagel}
659 {1 snarf} left outer join {1 snatz} = {1 snarf 1 snatz}
660 {2 blue} {3 driver} {2 blue {} {}}
661
662 Right Outer Join
663
664 {0 foo} {0 bagel} {0 foo 0 bagel}
665 {1 snarf} right outer join {1 snatz} = {1 snarf 1 snatz}
666 {2 blue} {3 driver} {{} {} 3 driver}
667
668 Full Outer Join
669
670 {0 foo} {0 bagel} {0 foo 0 bagel}
671 {1 snarf} full outer join {1 snatz} = {1 snarf 1 snatz}
672 {2 blue} {3 driver} {2 blue {} {}}
673 {{} {} 3 driver}
674
675
677 [1] J. W. Hunt and M. D. McIlroy, "An algorithm for differential
678 file comparison," Comp. Sci. Tech. Rep. #41, Bell Telephone Lab‐
679 oratories (1976). Available on the Web at the second author's
680 personal site: http://www.cs.dartmouth.edu/~doug/
681
682 [2] Donald E. Knuth, "Fascicle 2b of 'The Art of Computer Program‐
683 ming' volume 4". Available on the Web at the author's personal
684 site: http://www-cs-faculty.stanford.edu/~knuth/fasc2b.ps.gz.
685
687 This document, and the package it describes, will undoubtedly contain
688 bugs and other problems. Please report such in the category struct ::
689 list of the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist].
690 Please also report any ideas for enhancements you may have for either
691 package and/or documentation.
692
693 When proposing code changes, please provide unified diffs, i.e the out‐
694 put of diff -u.
695
696 Note further that attachments are strongly preferred over inlined
697 patches. Attachments can be made by going to the Edit form of the
698 ticket immediately after its creation, and then using the left-most
699 button in the secondary navigation bar.
700
702 Fisher-Yates, assign, common, comparison, diff, differential, equal,
703 equality, filter, first permutation, flatten, folding, full outer join,
704 generate permutations, inner join, join, left outer join, list, longest
705 common subsequence, map, next permutation, outer join, permutation, re‐
706 duce, repeating, repetition, reshuffle, reverse, right outer join,
707 shuffle, subsequence, swapping
708
710 Data structures
711
713 Copyright (c) 2003-2005 by Kevin B. Kenny. All rights reserved
714 Copyright (c) 2003-2012 Andreas Kupries <andreas_kupries@users.sourceforge.net>
715
716
717
718
719tcllib 1.8.4 struct::list(n)