List Commands Library for 50g
08-23-2017, 12:00 PM
Post: #81
 John Keith Senior Member Posts: 794 Joined: Dec 2013
RE: List Commands Library for 50g
(08-23-2017 02:58 AM)DavidM Wrote:  So may I assume that you would be in support of specialized commands in the ListExt library to delete multiple instances of indexed elements?

To all, some considerations to ponder...

This would seem like a good candidate for a command with an overloaded argument scenario. The first would be:

2: { list of objects }
1: number (index of element to delete)

A second option:
2: { list of objects }
1: { list of indices to delete }

Those sound good to me!

(08-23-2017 02:58 AM)DavidM Wrote:  Other considerations:

What is the appropriate result for the following scenarios?
• Index list is empty
• Index list contains a 0
• Index list contains non-numeric elements
• Index list contains negative/fractional numbers
• Index list contains numbers greater than the number of elements in SL2 list

What would be an appropriate name for such a command?

Then there's mostly the same considerations for a command that would remove a list of matching elements (as opposed to indexed).

If the index list is empty, the command should return the original list unaltered. For the other scenarios, I would prefer that it exit with a "Bad Argument Value" error, since this would be consistent with built-in RPL commands that deal with lists.

I can see the advantage of having the command be able to "massage" non-integer or out-of-range values but I believe that consistency across commands is more important.

As to the name I would suggest REMOV or LRMOV but I'm sure there will be other good ideas.

John
08-23-2017, 05:30 PM
Post: #82
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
Re: Command Names and Library Menus

There have been some ideas bounced around lately about changing some existing command names and the ramifications of doing so. This prompted me to look a bit closer at the mechanism behind the library menus and the options that might exist for different treatments of the menus.

One suggestion was to see if it was possible to have the menu display something other than the actual command names (perhaps an abbreviated form of the name). It turns out there is a way to do that when the user selects the library menu using the RS-2 (LIB) command, but it won't work if the user shows the menu with "1423 MENU". Generally speaking, I can also see where this could be confusing, especially if some of the "alternate" menu labels are too close to existing commands (ROLL, POS, etc.). I'm still open to the idea, but with reservations about how it might be presented.

Others have expressed concerns about command names which are longer than can be shown in the menu, but start with the same 5 characters as other commands (thus showing in the menu as identical commands). I share those concerns, and would thus not support doing that. I believe each library command should have a unique representation in the menus.

Command Aliases?

This brings me to another possibility that I wasn't aware of until I started looking into this, and would like to hear other's thoughts on the concept. It's possible to create "alias" commands to existing ones, and those aliases need not show up in the menu. In other words, you can define multiple command names that all point to the same internal code in the library. Pressing the menu key shown will either execute the command or enter the name shown on the key if you are editing a program. But if you are typing in the command with an editor, you could use either the formal name or any of its aliases interchangeably.

An example of using a command alias could be something like the following:

LSPLT would be the "formal" name of that existing command, but you could also have LSPLIT, LISTSPLIT, LSplit, ListSplit, etc. defined as aliases which all execute the same code (but don't show up in the menu). Only the command's names are replicated, so they don't take up much space in the library.

The downside to this, however, is that creating aliases in this way could make it more difficult for others to make meaningful names with their own commands (or any kind of object IDs) in the future. Once those aliases are defined in the library, anyone installing that library can't use any of the aliases as an identifier for something else. Reserving multiple IDs for a single command can thus be a "greedy" step that needlessly limits what users may want to do with their calculators. It could also make it harder for developers to come up with meaningful command names for similar/enhanced commands.

That said, I do think minimal application of aliases for the ListExt library may make sense. Some possibilities:

LRLLD - LROLLD
LSPLT - LSPLIT (and/or LSPLITL?)
LRSPL - LSPLITR
LCASE - LOCASE
UCASE - UPCASE

Also, I'm thinking the following commands should probably just be renamed:
LRLL to LROLL
LDST to LDIST
LSHF to LSHUF (my brain keeps seeing "LSHIFT" without the "U")
LSWP to LSWAP

08-23-2017, 05:41 PM (This post was last modified: 08-23-2017 05:42 PM by Luigi Vampa.)
Post: #83
 Luigi Vampa Member Posts: 262 Joined: Dec 2015
RE: List Commands Library for 50g
1 +
One alias per command is more than justifiable for the sake of clarity, IMHO.
Thanks for improving this library, David.

Saludos Saluti Cordialement Cumprimentos MfG BR + + + + +
Luigi Vampa +
Free42 '<3' I + +
08-23-2017, 06:40 PM
Post: #84
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
It strikes me that one possible use of the "alternate menu" option in my previous post would be to present a menu hierarchy, ie. similarly grouped commands in submenus.

Examples:
- DOCOMB, DOPERM in a "COMB" submenu
- LCLLT, LDIST, LGRP, LRPCT, LSDIV, LSPLT, LRSPL (others) in a "GROUP" submenu
- LROLL, LROLLD, LROT, LSWAP, LSHUF in an "ARNG" submenu
- LEQ, LPOS, LPOSL in a "TEST" submenu
- All String commands in a "STRNG" submenu
...others as identified/agreed upon

There would inevitably be commands that didn't fit into any group, and they could be at the top level I suppose.

The extra maintenance required would seem minimal compared to the value of quicker command selection. But maybe there are folks who don't like navigating menu trees? Provided the tree depth is kept minimal, it seems like this would be a benefit.
08-23-2017, 08:24 PM (This post was last modified: 08-23-2017 08:25 PM by pier4r.)
Post: #85
 pier4r Senior Member Posts: 2,111 Joined: Nov 2014
RE: List Commands Library for 50g
I agree to everything, especially the remove commands. And nice to have the creator so engaged!

edit: @John Keith . Thanks for the info, but I'd really like to see a command optimized for lists, rather than converting objects to strings.

Wikis are great, Contribute :)
08-24-2017, 08:23 PM
Post: #86
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
(08-13-2017 03:16 PM)John Keith Wrote:  The only other name that comes to mind is LPOS. I would prefer the name MPOS (as in Multiple POS) because it seems more descriptive of the difference between POS and LPOS. Another (self-interested) reason for the name MPOS is that I would really like to have that command work for strings as well as lists.

Given that POS already works with lists, I see the logic in this. And it shouldn't be too difficult to have an overloaded string version that simply applies the function of S→SL before processing.

08-24-2017, 10:25 PM (This post was last modified: 08-25-2017 07:30 AM by Gilles59.)
Post: #87
 Gilles59 Member Posts: 136 Joined: Jan 2017
RE: List Commands Library for 50g
(08-13-2017 04:59 PM)DavidM Wrote:
(08-13-2017 04:22 PM)Werner Wrote:  { {7, "longest"} {6 "longer"} {4 "long"} }
SORT

returns

{ {4 "long"} {6 "longer"} {7, "longest"} }

Combining the two lists:
Code:
{ "longest" "longer" "long" } { 7 6 4 }
into the needed format is simple enough with:
Code:
DUP SIZE LSDIV SWAP ADD

...which then leaves it to the user to choose which sort they want to use. After sorting, the combined list elements can be easily separated again if needed:
Code:
LCLLT 2 LSDIV LRLL EVAL

With gofer list you can do

Zip SORT Unzip

Code:
 Zip        xs ys -> xss        { 1 2 3 } { A B C } Zip                     -> { { 1 A } { 2 B } { 3 C } } Unzip        xss -> xs ys        { {1 A} {2 B} {3 C} } Unzip                     -> { 1 2 3 } { A B C }

There are also Zip3 and Unzip3 (but no ZipN)

There is also a Sort command in GoferList with the syntax :
{ my list } << how to sort >> Sort
but if the idea seems goods it is not stable at all and crash easily the system. In our exemple could be
{ "longest" "longer" "long" } << SIZE >> Sort
But this dont work and crash badly : DONT TRY THIS
But you can easily write your own command for this syntax in User RPL. Idea :

Code:
« { "longest" "long" "longer" }     DUP « SIZE » DOLIST SWAP Zip SORT Unzip NIP »

I imagine a DOSORT command :
{ list to sort } << How to sort>> DOSORT

Internally The DOSORT program could use the native SORT

example

{ 1. 123 "xyz" "abc" 'y=a*x*+b' } << TYPE >> DOSORT
{ -1 5 66 -89 33 } << ABS >> DOSORT
{ "Z" "a" "B" "d" } << UPCASE >> DOSORT

etc.
08-25-2017, 12:36 PM
Post: #88
 John Keith Senior Member Posts: 794 Joined: Dec 2013
RE: List Commands Library for 50g
(08-24-2017 08:23 PM)DavidM Wrote:
(08-13-2017 03:16 PM)John Keith Wrote:  The only other name that comes to mind is LPOS. I would prefer the name MPOS (as in Multiple POS) because it seems more descriptive of the difference between POS and LPOS. Another (self-interested) reason for the name MPOS is that I would really like to have that command work for strings as well as lists.

Given that POS already works with lists, I see the logic in this. And it shouldn't be too difficult to have an overloaded string version that simply applies the function of S→SL before processing.

The problem with that method is that lists require a lot more memory and processing time than strings. I routinely work with strings of 10000 - 20000 characters. Commands such as POS, SUB, and SREPL process such strings in a fraction of a second. A list of 20000 characters requires 120KB of memory which is impractical on the HP 50.

What I was wishing for is an analog of SREPL which, instead of modifying the string, would return a list of indexes where the pattern was found.

Example:

"the cat in the hat"
"he"
-> { 2 11 }

I realize that your library is primarily a list library rather than a string library but I can see the need for an expanded suite of string functions as well.

John
08-25-2017, 01:48 PM
Post: #89
 John Keith Senior Member Posts: 794 Joined: Dec 2013
RE: List Commands Library for 50g
(08-24-2017 10:25 PM)Gilles59 Wrote:
(08-13-2017 04:59 PM)DavidM Wrote:  Combining the two lists:
Code:
{ "longest" "longer" "long" } { 7 6 4 }
into the needed format is simple enough with:
Code:
DUP SIZE LSDIV SWAP ADD

...which then leaves it to the user to choose which sort they want to use. After sorting, the combined list elements can be easily separated again if needed:
Code:
LCLLT 2 LSDIV LRLL EVAL

With gofer list you can do

Zip SORT Unzip

Code:
 Zip        xs ys -> xss        { 1 2 3 } { A B C } Zip                     -> { { 1 A } { 2 B } { 3 C } } Unzip        xss -> xs ys        { {1 A} {2 B} {3 C} } Unzip                     -> { 1 2 3 } { A B C }

There are also Zip3 and Unzip3 (but no ZipN)

There is also a Sort command in GoferList with the syntax :
{ my list } << how to sort >> Sort
but if the idea seems goods it is not stable at all and crash easily the system. In our exemple could be
{ "longest" "longer" "long" } << SIZE >> Sort
But this dont work and crash badly : DONT TRY THIS
But you can easily write your own command for this syntax in User RPL. Idea :

Code:
« { "longest" "long" "longer" }     DUP « SIZE » DOLIST SWAP Zip SORT Unzip NIP »

I imagine a DOSORT command :
{ list to sort } << How to sort>> DOSORT

Internally The DOSORT program could use the native SORT

example

{ 1. 123 "xyz" "abc" 'y=a*x*+b' } << TYPE >> DOSORT
{ -1 5 66 -89 33 } << ABS >> DOSORT
{ "Z" "a" "B" "d" } << UPCASE >> DOSORT

etc.

The reason GoferLists' Sort command crashes in this case is that it is meant to work in a slightly different manner. The program used by your code is an objective function whereas the program required by Sort is a comparison operator. If you use the program \<< SIZE SWAP SIZE > \>> Sort will function correctly. Of course Sort should not crash the calculator under any circumstances and it is also quite slow.

Coincidentally, I have written a short program that is similar to yours which I call GSORT as in General-purpose sort. It uses commands from the ListEx library rather than GoferLists, and works exactly like your proposed DOSORT command:

Code:
\<< \-> p     \<< DUP 2.         \<<p EVAL SWAP 2. \->LIST \>>         DOLIST SORT LCLLT 2 LSDIV 2. GET     \>> \>>

Note that either program will work with LSORT provided that the list you are sorting does not contain a mix of exact integers and reals.

John
08-25-2017, 04:23 PM
Post: #90
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
(08-25-2017 12:36 PM)John Keith Wrote:  The problem with that method is that lists require a lot more memory and processing time than strings. I routinely work with strings of 10000 - 20000 characters. Commands such as POS, SUB, and SREPL process such strings in a fraction of a second. A list of 20000 characters requires 120KB of memory which is impractical on the HP 50.

What I was wishing for is an analog of SREPL which, instead of modifying the string, would return a list of indexes where the pattern was found.

Example:

"the cat in the hat"
"he"
-> { 2 11 }

I realize that your library is primarily a list library rather than a string library but I can see the need for an expanded suite of string functions as well.

John

The nature of a string being a "specialized list of characters" is the rationale I've used in my head to justify the string functions that I've already included. I can still see including this functionality with the "new" MPOS, but the scope as you have described obviously changes the needed approach. Not just in terms of the size of the objects in question, but also in its consideration of substrings of varying length.

You regularly deal with strings of 10-20K characters on your calculator? That's a paradigm shift for me. I wouldn't have ever considered using the 50g for that kind of processing. Thanks for clarifying!
08-25-2017, 06:53 PM
Post: #91
 pier4r Senior Member Posts: 2,111 Joined: Nov 2014
RE: List Commands Library for 50g
(08-25-2017 12:36 PM)John Keith Wrote:  The problem with that method is that lists require a lot more memory and processing time than strings. I routinely work with strings of 10000 - 20000 characters. Commands such as POS, SUB, and SREPL process such strings in a fraction of a second. A list of 20000 characters requires 120KB of memory which is impractical on the HP 50.

Uh, I did not think that the string functions on the 50g where that fast. I thought that, being strings (and not number or containers for numbers) they would be the slowest functions of the library.

Wikis are great, Contribute :)
08-25-2017, 07:20 PM
Post: #92
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
(08-25-2017 06:53 PM)pier4r Wrote:  Uh, I did not think that the string functions on the 50g where that fast. I thought that, being strings (and not number or containers for numbers) they would be the slowest functions of the library.

I can see where you might come to that conclusion, but it turns out not to be the case. Lists are generally slower in RPL than strings for similar functions, mostly due to two things:

- List elements aren't indexed (internally they are always accessed sequentially)
- List elements can be any object (including other lists), so no assumptions can be made about their size or contents

In contrast, strings have:
- A built-in count
- Fixed-length elements
- Elements of only one type

...so writing code to process them efficiently is much easier. There's usually no floating point considerations when manipulating strings, so the code lends itself well to assembly language implementations as well. This makes the possibility of fast manipulation of strings much more likely than lists, at least in RPL contexts.
08-25-2017, 09:07 PM
Post: #93
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
(08-23-2017 12:00 PM)John Keith Wrote:  I can see the advantage of having the command be able to "massage" non-integer or out-of-range values but I believe that consistency across commands is more important.

This brings up an interesting consideration, and it's one that I haven't actually looked at in depth before.

For most commands that expect numbers that are implied integers as arguments (indices, counts, etc.), the ListExt code simply takes the integer part of the number if a real is provided.

I just checked a couple of built-in list commands (SUB and GET), and it looks like they both perform a rounding function on the arguments instead of taking the integer part (likely due to COERCE being used to convert those reals into System Binary Integers). For example:
Code:
{ 1 2 3 4 5 } 1.1 GET
returns 1

whereas

Code:
{ 1 2 3 4 5 } 1.8 GET
returns 2

SUB treats real arguments in a similar fashion to GET.

My personal feeling is that IP is more appropriate than rounding, but that makes the ListExt commands different than SUB and GET (and probably others, too).

I'm interested in seeing others' opinions on this. How should non-integer real numbers be treated when they are used to designate something that is intended to be an integer?
08-26-2017, 05:05 AM (This post was last modified: 08-26-2017 05:06 AM by pier4r.)
Post: #94
 pier4r Senior Member Posts: 2,111 Joined: Nov 2014
RE: List Commands Library for 50g
(08-25-2017 07:20 PM)DavidM Wrote:  I can see where you might come to that conclusion, but it turns out not to be the case. Lists are generally slower in RPL than strings for similar functions, mostly due to two things:

- cut-

Thanks for sharing! I should create also the "programming challenge processing strings!" then.

(08-25-2017 09:07 PM)DavidM Wrote:  I'm interested in seeing others' opinions on this. How should non-integer real numbers be treated when they are used to designate something that is intended to be an integer?

In my opinion clear documentation and consistency triumph overall. Therefore: I'd prefer to raise an error.

Wikis are great, Contribute :)
08-26-2017, 01:28 PM
Post: #95
 John Keith Senior Member Posts: 794 Joined: Dec 2013
RE: List Commands Library for 50g
(08-25-2017 09:07 PM)DavidM Wrote:
(08-23-2017 12:00 PM)John Keith Wrote:  I can see the advantage of having the command be able to "massage" non-integer or out-of-range values but I believe that consistency across commands is more important.

This brings up an interesting consideration, and it's one that I haven't actually looked at in depth before.

For most commands that expect numbers that are implied integers as arguments (indices, counts, etc.), the ListExt code simply takes the integer part of the number if a real is provided.

I just checked a couple of built-in list commands (SUB and GET), and it looks like they both perform a rounding function on the arguments instead of taking the integer part (likely due to COERCE being used to convert those reals into System Binary Integers). For example:
Code:
{ 1 2 3 4 5 } 1.1 GET
returns 1

whereas

Code:
{ 1 2 3 4 5 } 1.8 GET
returns 2

SUB treats real arguments in a similar fashion to GET.

My personal feeling is that IP is more appropriate than rounding, but that makes the ListExt commands different than SUB and GET (and probably others, too).

I'm interested in seeing others' opinions on this. How should non-integer real numbers be treated when they are used to designate something that is intended to be an integer?

I had not noticed that behavior of SUB and GET myself. I agree that IP seems more "natural" than rounding but I also feel it is important that new commands work in a manner consistent with built-in ones.

John
08-26-2017, 01:52 PM
Post: #96
 John Keith Senior Member Posts: 794 Joined: Dec 2013
RE: List Commands Library for 50g
(08-26-2017 05:05 AM)pier4r Wrote:  Thanks for sharing! I should create also the "programming challenge processing strings!" then.

Please do! Here's a suggestion: Dissociated Press aka Travesty is one of my favorite programs. I translated the Pascal program from the Byte Magazine article linked on the Wikipedia page into HP-71 BASIC but it is very slow. I thought of re-writing it in RPL but never did so because it would be at least as slow as the HP-71 version.

The Travesty program (and others like it) was my impetus for requesting the MPOS command for strings. Having such a command would make a Travesty program on the HP 50 practical.

John
08-26-2017, 03:04 PM
Post: #97
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
(08-26-2017 05:05 AM)pier4r Wrote:  In my opinion clear documentation and consistency triumph overall. Therefore: I'd prefer to raise an error.

I'm a bit confused by the above. I get the clear documentation part, but I'm not sure how raising an error for non-integer arguments would be consistent -- the built-in routines I've checked don't seem to, and ListExt routines don't either. So what would that be consistent with? Or are you referring to non-numeric arguments (as opposed non-integer)? Those should definitely raise errors in my opinion.

Also, part of the original impetus for both GoferLists and ListExt was "working around" some inherent quirks that were the hallmarks of the built-in functions (returning no results, not working with empty lists come to mind). I'm not opposed to "going against the grain" if there's a meaningful reason to do so, but I'm not sure if "IP vs. Round" has enough value to warrant a change from the norm. While I prefer IP over rounding, it doesn't seem like it would come up as an issue very often since the calculations leading up to these argument's use is likely to result in integers anyway.
08-26-2017, 05:32 PM (This post was last modified: 08-26-2017 07:02 PM by pier4r.)
Post: #98
 pier4r Senior Member Posts: 2,111 Joined: Nov 2014
RE: List Commands Library for 50g
(08-26-2017 03:04 PM)DavidM Wrote:  I'm a bit confused by the above. I get the clear documentation part, but I'm not sure how raising an error for non-integer arguments would be consistent -- the built-in routines I've checked don't seem to, and ListExt routines don't either. So what would that be consistent with? Or are you referring to non-numeric arguments (as opposed non-integer)? Those should definitely raise errors in my opinion.

Sorry, I clarify. If for my library I decide that I accept only integers as subscripts and I state it properly, then I keep doing this (unless otherwise stated for some particular commands).

It does not matter, for me, that the built in commands accept also decimals, the library should be consistent with its documentation, not (necessarily) with other commands, built in or popular.

So I would be completely ok if you say "look, please provide integers or reals without decimal parts".

I actually don't know why GET and SUB would work with reals with decimal part. It can surely produce some nice "tricks" but looks dirty in my opinion.

edit: I'll do the "processing strings!" thread. I need to find the proper set of challenges though (the start should be small but interesting) I will think about it.

Wikis are great, Contribute :)
08-26-2017, 06:59 PM
Post: #99
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
(08-26-2017 05:32 PM)pier4r Wrote:  I actually don't know why GET and SUB would work with reals with decimal part. It can surely produce some nice "tricks" but looks dirty in my opinion.

I doubt it was by design, and more likely just a consequence of how a particular SysRPL command works (COERCE). After looking at a couple of the built-in routines, it appears that they used COERCE to convert the given number into what is referred to as a "System Binary" (or BINT), which is what most internal routines use when integers are in context.

COERCE can be thought of as "move the given real to its closest BINT counterpart", which of course implies the rounding which happens. BINTs are unsigned, so the closest BINT to a negative real is 0. BINTs are only 5 nibbles, so the maximum real (integer) that can be represented is (2^20-1) or 1048575, which is represented by a BINT with the hex digits FFFFF. Any greater value real is "pinned" to that BINT in the same way that negative reals all convert to 0.

I tested SUB a little further and was reminded of something else I had forgotten, which is that it is very "forgiving" of out-of-bounds indices. This is actually documented in the fine print of the AUR for SUB, which states "Values of n less than 1 are treated as 1; values of n exceeding the length of the string or list are treated as that length." So there's already precedent for inconsistencies in how indices are treated with the built-in commands. GET definitely doesn't work that way.

Example: if you execute
Code:
"ABC" -2.3 -999 SUB
the 50g will happily give you "A" as the result.

Likewise,
Code:
"ABC" 1.2 20.8 SUB
results in "ABC".
08-30-2017, 03:20 PM (This post was last modified: 09-10-2017 02:22 PM by DavidM.)
Post: #100
 DavidM Senior Member Posts: 873 Joined: Dec 2013
RE: List Commands Library for 50g
I had originally planned to have a 1.0 release of the library as the next official update, but several very good requests for commands prompted me to add those and a couple other simple ones to the set. There's been enough change in this one to warrant a ".1" version change as well. I'll add the usual notes at the bottom of this post, but here's some more specific comments about the newer commands:

LPUSH

LHDTL was a simple (but very convenient) function that Pier had suggested some time back. In my mind, I came to think of it as a "POP" command, as it pops the first element of a list and leaves the rest behind. After becoming aware of the ability to have command aliases, I thought this would be a good time to rename LHDTL to LPOP and keep an alias of LHDTL active for the same function. LPOP would be lonely without LPUSH, so I went ahead and added that command to balance it out.

LRSPL

aka LSPLITR. Like its counterpart LSPLT, this simply splits a list into two parts based on the argument you supply. Instead of counting from the left, though, LRSPL counts from the right. This command was actually the inspiration for LLAST, which in turn needed LFRST to balance it out...

LFRST, LLAST

Returns a list containing the first/last <n> elements of the original list provided as an argument.

LPICK

BruceH suggested this one, and I knew as soon as I saw it that it was a great idea. I think this is actually a very powerful addition, as it nicely combines both a "selection" and an "ordering" function into one command.

LRMOV

"List Remove". This one was actually a little trickier to implement than I thought it would be. There's several possible approaches, but the hard part was getting it to perform reasonably well with large lists. This version features a couple of custom Saturn routines to minimize the iteration of list contents as the target indicies are being validated.

KSORT

"Key Sort". I decided to implement this "sort helper" as follows: given a list and its corresponding list of keys, the two are combined and passed to either the internal SORT command, or a user program if provided (eg. « LSORT »). Allowing the optional user program also provides flexibility; the user program could further manipulate the interim list, save it for later use, or simply do nothing at all if it's determined that sorting isn't needed. If you don't supply a user program, the two lists are simply bundled/sorted/unbundled.

As always, see the command description document for full details. Thanks to everyone for your combined efforts at making this a useful collection of commands! Please give these newer ones a try. Those last three (LPICK, LRMOV, KSORT) probably need the most testing -- the others are just simple shortcuts.

Edit: The attachment has been deleted; see the first post in this thread for the latest version.
______________________________________________________________________________
ListExt Release Notes

Version 1.1.0d
2017-08-30

- Argument order for RPTCHR swapped (now: CHAR, COUNT).
- Updated the library description text to "ListExt Commands".
- Created a menu for the library commands that is activated either by the user function "MENU1423" or by selecting the "ListExt Commands" library directory from the LIB (RS-2) menu.
- Renamed commands: LHDTL to LPOP (kept LHDTL as alias), LDST to LDIST, LRLL to LROLL, LSHF to LSHUF, LSWP to LSWAP, LPOS to MPOS, LPOSL to MPOSL
- Command aliases added: LROLLD → LRLLD, LSPLIT → LSPLT, LOCASE → LCASE, UPCASE → UCASE
- MPOS now accepts two strings as arguments
- Bumped version to 1.1.0 and changed status to "d" (development) due to the nature of the updates in this release.

COMMAND SUMMARY

LSEQ - creates a list of <count> integers as a sequence from 1..<count>
LSEQR - creates a list of integers for the range specified
LMRPT - repeats list contents as indicated by count
LNDUP - creates a list by repeating an object as indicated by count

LDDUP - removes duplicates from a list
LPOP - retrieves the first element in a list while leaving the rest on the stack
LPUSH - adds object to front of list
LPICK - returns a list containing identified elements in specified order
LREPL - replaces list elements with a substitute object as indicated
LRMOV - removes 1 or more elements from a list as indicated

LFRST - returns the first <n> elements of a list
LLAST - returns the last <n> elements of a list
LRCL - recalls objects identified by variables in a list

LROLL - rolls the list (equivalent to 1 LROT)
LRLLD - "roll down" the list (equivalent to -1 LROT)
LROT - rotates list elements left or right as indicated by count
LSWAP - swaps the positions of two list elements
KSORT - Sorts a list based on keys from a separate list
LSHUF - shuffles the contents of a list

LCLLT - collates a list of sublists
LDIST - distributes list items into sublists (reciprocal of LCLLT)
LGRP - replaces repeated elements with a single instance
LRPCT - list with LGRP elements and another list of the count of each element
LSPLT - splits a list as indicated into two sublists
LRSPL - splits a list as indicated from the right into two sublists

LSDIV - subdivides a list into <count> sublists
LXIL - explodes inner sublists into individual elements (non-recursive)
LXILR - recursive version of LXIL

LCNT - counts objects in a list
LEQ - checks list items to see if any do not match
MPOS - returns a list of all positions of an object in a list, or a substring in a string
MPOSL - returns a list of all positions of an object in a list or its sublists

DOCOMB - feeds indicated combinations of a list to a user-supplied program
DOPERM - feeds indicated permutations of a list to a user-supplied program

LSUM - ΣLIST that also accepts lists with 0 or 1 element
LPROD - ΠLIST that also accepts lists with 0 or 1 element

CHR+ - adds an offset to the CHR value of each character of a string
LCASE - converts upper case characters in a string to lower case
UCASE - converts lower case characters in a string to upper case
RPTCHR - creates a string of repeated characters
I→NL - converts an integer to a list of numbers
NL→I - converts a list of numbers to an integer

S→NL - converts a string to a list of numbers
NL→S - converts a list of numbers to a string
S→SL - converts a string to a list of characters
SL→S - converts a list of characters to a string

Other Commands
About - Library short description and version information
Unins - Detaches and deletes the library

 « Next Oldest | Next Newest »