Check-in [21f784d0d3]

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Editorial pass for TIP 523
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 21f784d0d36e603630feac23f76c6209e7214830648d228ff589936e2946ba00
User & Date: dkf 2018-10-27 17:28:10
Context
2018-10-28
07:13
Updated text of tip495 check-in: 4188e0f58f user: hypnotoad tags: trunk
2018-10-27
17:28
Editorial pass for TIP 523 check-in: 21f784d0d3 user: dkf tags: trunk
17:08
Tidy up 523 check-in: de82360011 user: pspjuth tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to tip/523.md.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
Add a command to efficiently remove an element from a list.

# Rationale

Stacks and queues are common structures to use lists, and thus adding
and removing elements are common operations.
Adding has a direct command through lappend, while removing has less
obvious commands, which also needs tricks like K to avoid performance
problems.

A single command to both retrieve the value and remove it is simpler.

	set x [lpop stack]

vs.

................................................................................
	set stack [lrange $stack 0 end-1]

or even

	set stack [lrange [K $stack [set stack {}]] 0 end-1]

To support both queue and stack the pop end needs to be chosen, and the easiest
way is to have an index argument. This trivially extends the functionality to
remove any element.

Further, making it use multiple indices in the same way as lindex and lset does
gives more symmetry. Together with lset's ability to add to a sublist,
doing push/pop on a sublist becomes feasible.
The ability in lset and lindex to get an index list is not supported since
argument expansion covers that usage.

Since deleting last is rather common (stack) and also the cheapest operation,
that is selected as default when no index is given.

# Specification

A new command is added to the core with the following format.

	lpop listVar ?index ...?

The given indices are resolved to an element in the same way as lindex/lset
does, except an index list is not supported, just plain index arguments.
The return value is the element at index, and the list is modified to
remove that element.
If no index is given, the default is "end".
An out of range index is an error.

# Discussion

## Name

Many alternative command names have been proposed.

lpop, ltake, lremove, ltrunc, (Hunter Green #355E3B)

No name will ever fully explain what it does or match all users' expectations
of what that name means. "lpop" is close enough and short.

## Error

Should an out of range index be an error or a no-op returning ""?

Empty, for symmetry with lindex.

"It has always seemed wrongheaded to me that commands like lindex return
the empty string when no element exists"

Lpop is not just reading like lindex, it is also removing and there the
symmetry is not evident. Lreplace gives an error for too high indices.

## Pop Multiple

It was proposed to be able to pop more than one element.
This could be an index list in last index, or an option:

	lpop listVar ?index ...? {0 1)
	lpop -n 2 listVar
	lpop -gather {0 3 7} listVar

This should take careful consideration since having a command that sometimes
returns a list and sometimes an element should not be taken lightly.
Any of the above versions are possible extensions to the current TIP.


# Copyright

This document has been placed in the public domain.






|
|
|







 







|


|
|

|











|

|

|








|


|



|

|

|
|

|
|












|
>




14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
Add a command to efficiently remove an element from a list.

# Rationale

Stacks and queues are common structures to use lists, and thus adding
and removing elements are common operations.
Adding has a direct command through **lappend**, while removing has less
obvious commands, which also needs tricks like
**[K](https://wiki.tcl-lang.org/page/K)** to avoid performance problems.

A single command to both retrieve the value and remove it is simpler.

	set x [lpop stack]

vs.

................................................................................
	set stack [lrange $stack 0 end-1]

or even

	set stack [lrange [K $stack [set stack {}]] 0 end-1]

To support both queue and stack the pop end needs to be chosen, and the easiest
way is to have an _index_ argument. This trivially extends the functionality to
remove any element.

Further, making it use multiple indices in the same way as **lindex** and **lset** does
gives more symmetry. Together with **lset**'s ability to append to a sublist,
doing push/pop on a sublist becomes feasible.
The ability in **lset** and **lindex** to get an index list is not supported since
argument expansion covers that usage.

Since deleting last is rather common (stack) and also the cheapest operation,
that is selected as default when no index is given.

# Specification

A new command is added to the core with the following format.

	lpop listVar ?index ...?

The given indices are resolved to an element in the same way as **lindex**/**lset**
does, except an index list is not supported, just plain index arguments.
The return value is the element at _index_, and the list is modified to
remove that element.
If no index is given, the default is "`end`".
An out of range index is an error.

# Discussion

## Name

Many alternative command names have been proposed.

`lpop`, `ltake`, `lremove`, `ltrunc`, (the bikeshed is Hunter Green #355E3B)

No name will ever fully explain what it does or match all users' expectations
of what that name means. "`lpop`" is close enough and short.

## Error

Should an out of range index be an error or a no-op returning the empty string?

Empty, for symmetry with **lindex**.

 > "It has always seemed wrongheaded to me that commands like lindex return
   the empty string when no element exists"

Moreover, **lpop** is not just reading like lindex, it is also removing and there the
symmetry is not evident. By comparison, **lreplace** gives an error for too high indices.

## Pop Multiple

It was proposed to be able to pop more than one element.
This could be an index list in last index, or an option:

	lpop listVar ?index ...? {0 1)
	lpop -n 2 listVar
	lpop -gather {0 3 7} listVar

This should take careful consideration since having a command that sometimes
returns a list and sometimes an element should not be taken lightly.
Any of the above versions are possible extensions to the current TIP, but are
outside its scope.

# Copyright

This document has been placed in the public domain.