Internal organization of the list extension

Purpose: List and discuss technical decisions with regard to the official list extension in particular.

AK: Proposal: Use namespaces, the namespace is ::list.

AK: File organization: One file, more than one file ?

AK: Definitely use the package mechanism to simplify usage of the extension.

AK: Comments and coding: Follow the published style guide. Makes extraction of documentation harder, but not impossible.

RSeeger: Have both an pure Tcl version, and a compiled extension version. If people wish to compile, they can gain the speed of the binary version. If not (don't have access to a compiler, not allowed to, etc), they can use the pure Tcl version, at the cost of speed.

AK: Start with a tcl version, convert into C later (After TEA [L1 ]). Write the C version so that it is possible to either compile it as part of the kernel, or as loadable shared library.


OK. OK. OK. This has lain fallow for almost two months. I want this. And in the true spirit of collaborative development, "if it ain't there, then write it."

I think that you can do everything on the Chart of proposed list functionality with the exceptions of

  • Applying a script to a list and reducing the result to a single value. Too many ways to do this.
  • Existential qualifiers, other than a more flexible "search"
  • Set values at multiple points in a list, which can be accomplished cleanly with foreach and list::set

Please be tremendously critical - before a lot of code gets written.

-- RWT 5/18/99

"lain fallow": Guilty as charged. Thanks for taking over.

"Applying a script to a list and reducing ...": I disagree. The command gets a list, an initial value and the script. The script accepts two arguments, one of which is at first the initial value (and later its last result) and the current item of the list. The result for the last element is the final result of the command. This is enough. Especially as the script is able to store state information beyond the last result in additional arguments, variables, etc. See Lisp and SICP. Niceties in the interface to the script: Number of elements in the list, index of currently processed item.

-- AK 05/21/1999

OK by me. But I'm afraid that Lisp is a foreign language to me. What is SICP, and is there a real word that would be an appropriate function name? (I am assuming that this would be different from the ::list::apply which returns a list.) -- RWT 5/21/99

SICP = "Structure and Interpretation of Computer Programs". A 'must have' book for every computer scientist, IMHO. Authors: H. Abelson, G. J. Sussman & J. Sussman. After reading it I still maintained my opinion that longer LISP functions have a severe case of (p(a))r(e)nt((his)itis) but I began to appreciate the power of the language and of the underlying concepts.

They called this function 'accumulate'.

-- AK 05/25/1999


The list extension will be implemented in pure Tcl as a set of commands in the ::list namespace, using the conventions described in Will's Guide to Success with Namespaces and Packages. [L2 ]

The Tcl Style Guide [L3 ] will be followed as much as possible. Documentation will be written here in the Wiki, and later converted to the emerging XML format.

Some of the list extension functionality will duplicate what is already available in the core functions. Most of the list extension functions will also have greater capability. In all cases, the internal Tcl core support for list objects will be employed. -- AK: Employment of TclX might be a good idea too, if present.


LV in the case where the ::list function happens to be equivalent to an existing Tcl function, will that function be used without replicating it in Tcl?


Some brave soul may eventually make convert part or all of the list extension into C. Good luck.

In the following synopsis of functions, several conventions will be used.

Indices

Many functions operate on elements specified by index value. These are documented as index in the synopsis. You can include switches in a list of indices. Indices following -except are excluded from the operation. Indices following -including are included in the operation.

Ranges

Many functions operate on ranges of elements within the lists. These are documented as first last in the synopsis. end may specify one or both ranges, and the last value may be optional. Just to be really cool, we will support expressions for the range indices, including things like "end-1"

In-place

Some functions have the ability to modify a list "in place", as opposed to the typical behavior in the core which returns copies of lists. This will be specified by an optional switch -in before the list argument. If the -in switch is specified, then the list argument is the name of the list to be modified, instead of the value of a list.


Function List

These are in the order I typed them.


::list::create ?arg arg ...?

Core list function.


::list::insert ?-in? list index element ?element element ...?

Like the core linsert function, but can insert in-place.


::list::append ?-in? list ?value value value ...?

Like the core lappend function, but can also return a value. (The core always operates in-place.)


::list::set ?-in? list index value ?index value ...?

Sets the specified list element(s) to the specified values.


::list::concat ?arg arg ...?

Similar to the core concat function, but treats the arguments as lists without converting them into their string representations. (See Jeff Hobbs' c.l.t posting titled "concat support for list objects" on 19-May-1999).


::list::element list index ?index index ...?

Like the core lindex function, but returns a list of elements.


::list::length list

Core llength function.


::list::range ?-indices? list first last

Like the core lrange function. Can also return the enumerated indices from the list.


::list::replace ?-in? list first last ?element element ...?

Like the core lreplace function, but can operate on a list in-place.


::list::search ?switches? list pattern ?pattern pattern ...?

Similar to the core lsearch function. Returns a list of matches. Supports modes -exact -glob and -regexp. Also supports the --nocase and -indices switches from regexp. Also supports the switch -first, which tells the function to return only one value, like the core lsearch function.


::list::sort ?options? ?-in? list

Like the core lsort function, but also supports the -in switch for in-place sorting.


::list::remove ?-in? list index ?index index ...?

Removes items from the list. Note that the indices could come from a call to ::list::search -indices or ::list::range -indices.


::list::reverse ?-in? list

Reverses the order of the elements in the list.


::list::longest list ::list::shortest list

Returns the length of the longest/shortest element in the list, when the elements are treates as strings.


::list::apply ?-in? list script ?index index ...?

Applys the script to the elements in the list. Either generates a new list or replaces elements in the existing list with the return value from the script. If the indices are supplied, the script will only be applied to those elements, and the remaining elements will be unchanged.

If the script contains the characters %s, then the value of the list element will be substitued using format. Otherwise the value of the list element will be appended to the script (like an argument to a proc call), and it will be evaluated.


::list::unique ?-in? list

Removes duplicates from the list.


ulis: why not ::list::depth?

Returns the deepest level in the list.

I need this for a language manipulating scripts and texts (they need to be stripped). - RS belatedly experimented with the depth of a list, but questions remain.