Post Reply 
List API (G1CMZ): List Processing API
09-14-2018, 10:49 PM
Post: #14
RE: List API (G1CMZ): List Processing API
From here https://www.hpcalc.org/details/6529 you get a readme that is a txt.

anyway

Code:


GoferLists 1.0 (SysRPL version) for the HP-49G/49G+/50G
========== === ======= ======== === === ===============

Library Id: 1652

Copyright (c) 1994 by Jarno Peschier (http://www.jarno.demon.nl/hp48.htm)
Copyright (c) 2001 by Luis Morales Boisset (http://www.arrakis.es/~lboisset/)
Copyright (c) 2007 by Albert Graef (http://www.musikwissenschaft.uni-mainz.de/~ag/hp49)

GoferLists is a library of useful list processing functions mostly borrowed
from the Haskell programming language. The name comes from the popular Haskell
dialect and interpreter by Mark P. Jones, which was originally called Gofer
and is now known as Hugs ("Haskell User's Gofer System", see
http://www.haskell.org/hugs/).

RPL's built-in list processing facilities such as DOLIST and STREAM are quite
powerful, but can be awkward to work with because they do not treat the corner
cases such as empty input lists in a consistent fashion. GoferLists attempts
to fix that by providing user-friendly frontends to the built-in operations,
in the form of an elaborate collection of generic list processing functions
which are fairly standard in modern functional languages and have proven their
utility in countless applications. GoferLists is implemented in System RPL and
thus the provided operations are fairly efficient as well.

GoferLists was originally written by Jarno Peschier and later ported to SysRPL
for better performance by Luis Morales Boisset. The present version was put
together by Albert Graef who fixed a couple of minor bugs in the SysRPL
version and added a bunch of additional operations (see the revision history
in the following section for details).

See below for installation instructions and an overview of the functions
provided in this version of the library. Also see README.OLD for the original
documentation included with the 0.1b version. Please report bugs in the
present version to Albert Graef at Dr.Graef@t-online.de.


REVISION HISTORY
======== =======

1.0 Jan 24 2007

Bugfixes and new operations by Albert Graef.

- Head, Tail and Init now produce the appropriate dimension errors on an empty
  list.

- Copy now works with zero repeat count.

- Concat is now implemented in terms of Foldl.

- Nub was reimplemented in terms of ^AppendList instead of a (non-existing)
  lib 776 entry point.

- Foldl, Foldr now take args in reverse order ({} ob prog), to facilitate
  "currying", and now work with empty input lists.

- Subs now works with empty input lists.

- New functions: All, Any, Foldl1, Foldr1, Scanl, Scanr, Scanl1, Scanr1,
  Zip/Unzip and friends, Seq, ElemIndex, Find, FindIndex, Insert, Delete,
  Union/Diff/Intersect, Iterate, While, Until, Chars, Strcat, Sum, Product.
  This makes for a total of 56 operations now, hence the library menu was
  reordered alphabetically, to make it easier to find a particular function.

0.1b (2001)

Ported to System RPL by Luis Morales Boisset.

0.1 (1994)

Original User RPL version by Jarno Peschier (JPSOFT).


INSTALLATION
============

Transfer glsys49.lib to your calculator and store it in port 0, 1 or 2 (e.g.,
2 STO). Do a quick reboot with On+C, or just 1652 ATTACH, in order to attach
the library. After that the GoferLists function should be available via the
LIB menu or using the command 1652 MENU. For quicker access you might wish to
assign \<< 1652 MENU \>> to a key or include it in your custom menu.

IMPORTANT: GoferLists 1.0 is for the HP-49 series only, for the HP-48 series
calculators you'll have to go with the 0.1 UserRPL version still available at
http://www.hpcalc.org. This is BETA SOFTWARE, so please back up your
calculator before trying it! No warranty etc. etc.


OVERVIEW
========

Here is a brief rundown of the available functions. Most functions are named
after their Haskell counterparts (see, e.g., http://haskell.org/hoogle), but
some may take different arguments or take arguments in a different order, see
the notes below. Some functions don't exist in Haskell, but are provided here
for convenience. Other functions might work a bit different from their Haskell
counterparts, but still serve the same purpose.

Symbol legend: 0/1: truth value, s: string; n: integer (zint or real); x, y,
z: any object (sometimes also an arbitrary real or zint); xs, ys, zs: list;
xss, yss, zss: list of list; f: arbitrary program; p: predicate (program which
returns 0/1 to denote a truth value)

Function    Stack Diagram        Example
--------------  ----------------------  ------------------------------------
All        xs p -> 0/1        { 1 2 3 } \<< 0 > \>> All
                    -> 1.
Any        xs p -> 0/1        { 1 2 3 } \<< 0 < \>> Any
                    -> 0.
Chars        s -> xs            "abc" Chars
                    -> { "a" "b" "c" }
Concat        xss -> ys        { { 1 } { 2 3 } } Concat
                    -> { 1 2 3 }
Copy        xs n -> ys        { 1 2 3 } 3 Copy
                    -> { 1 2 3 1 2 3 1 2 3 }
Delete        xs x -> ys        { 1 2 3 } 2 Delete
                    -> { 1 3 }
Diff        xs ys -> zs        { 1 2 3 } { 3 4 5 } Diff
                    -> { 1 2 }
Drop        xs n -> ys        { 1 2 3 } 2 Drop
                    -> { 3 }
DropWhile    xs p -> ys        { 1 2 3 } \<< 2 < \>> DropWhile
                    -> { 2 3 }
Elem        xs x -> 0/1        { 1 2 3 } 2 Elem
                    -> 1.
ElemIndex    xs x -> n        { 1 2 3 } 2 ElemIndex
                    -> 2.
Filter        xs p -> ys        { 1 2 3 } \<< 1 > \>> Filter
                    -> { 2 3 }
Find        xs p -> x        { 1 2 3 } \<< 1 > \>> Find
                    -> 2
FindIndex    xs p -> n        { 1 2 3 } \<< 1 > \>> FindIndex
                    -> 2.
Foldl        xs x f -> ys        { 1 2 3 } 0 \<< + \>> Foldl
                    -> 6
Foldl1        xs f -> ys        { 1 2 3 } \<< + \>> Foldl1
                    -> 6
Foldr        xs x f -> ys        { 1 2 3 } 0 \<< + \>> Foldr
                    -> 6
Foldr1        xs f -> ys        { 1 2 3 } \<< + \>> Foldr1
                    -> 6
Head        xs -> x            { 1 2 3 } Head
                    -> 1
Init        xs -> ys        { 1 2 3 } Init
                    -> { 1 2 }
Inits        xs -> yss        { 1 2 3 } Inits
                    -> { { } { 1 } { 1 2 } { 1 2 3 } }
Insert        xs x -> ys        { 1 2 3 } 4 Insert
                    -> { 1 2 3 4 }
Intersect    xs ys -> zs        { 1 2 3 } { 3 4 5 } Intersect
                    -> { 3 }
Iterate        x f n -> xs        1 \<< 2 * \>> 10 Iterate
                    -> { 1 2 4 8 16 32 64 128 256 512 }
Last        xs -> x            { 1 2 3 } Last
                    -> 3
Length        xs -> n            { 1 2 3 } Length
                    -> 3.
Map        xs f -> ys        { 1 2 3 } \<< 3 ^ \>> Map
                    -> { 1 8 27 }
Nub        xs -> ys        { 1 2 2 3 2 3 3 } Nub
                    -> { 1 2 3 }
Null        xs -> 0/1        { 1 2 3 } Null
                    -> 0.
Product        xs -> x            { 1 2 3 } Product
                    -> 6
Repeat        x n -> xs        1 5 Repeat
                    -> { 1 1 1 1 1 }
Reverse        xs -> ys        { 1 2 3 } Reverse
                    -> { 3 2 1 }
Scanl        xs x f -> yss        { 1 2 3 } 0 \<< + \>> Scanl
                    -> { 0 1 3 6 }
Scanl1        xs f -> yss        { 1 2 3 } \<< + \>> Scanl1
                    -> { 1 3 6 }
Scanr        xs x f -> yss        { 1 2 3 } 0 \<< + \>> Scanr
                    -> { 6 5 3 0 }
Scanr1        xs f -> yss        { 1 2 3 } \<< + \>> Scanr1
                    -> { 6 5 3 }
Segs        xs -> yss        { 1 2 3 } Segs
                    -> { { } { 3 } { 2 } { 2 3 } { 1 }
                         { 1 2 } { 1 2 3 } }
Seq        x y z -> xs        1 10 2 Seq
                    -> { 1 3 5 7 9 }
Sort        xs p -> ys        { 1 3 2 } \<< < \>> Sort
                    -> { 1 2 3 }
Split        xs n -> ys zs        { 1 2 3 } 2 Split
                    -> { 1 2 } { 3 }
Strcat        xs -> s            { "a" "b" "c" } Strcat
                    -> "abc"
Subs        xs -> yss        { 1 2 3 } Subs
                    -> { { 1 2 3 } { 1 2 } { 1 3 } { 1 }
                         { 2 3 } { 2 } { 3 } { } }
Sum        xs -> x            { 1 2 3 } Sum
                    -> 6
Tail        xs -> ys        { 1 2 3 } Tail
                    -> { 2 3 }
Tails        xs -> yss        { 1 2 3 } Tails
                    -> { { 1 2 3 } { 2 3 } { 3 } { } }
Take        xs n -> ys        { 1 2 3 } 2 Take
                    -> { 1 2 }
TakeWhile    xs p -> ys        { 1 2 3 } \<< 2 < \>> TakeWhile
                    -> { 1 }
Union        xs ys -> zs        { 1 2 3 } { 3 4 5 } Union
                    -> { 1 2 3 4 5 }
Until        x f p -> y        1 \<< 2 * \>> \<< 1000 > \>> Until
                    -> 1024
Unzip        xss -> xs ys        { {1 A} {2 B} {3 C} } Unzip
                    -> { 1 2 3 } { A B C }
Unzip3        xss -> xs ys zs        { {1 A x} {2 B y} {3 C z} } Unzip3
                    -> { 1 2 3 } { A B C } { x y z }
While        x f p -> xs        1 \<< 2 * \>> \<< 1000 < \>> While
                    -> { 1 2 4 8 16 32 64 128 256 512 }
Zip        xs ys -> xss        { 1 2 3 } { A B C } Zip
                    -> { { 1 A } { 2 B } { 3 C } }
Zip3        xs ys zs -> xss        { 1 2 3 } { A B C } { x y z } Zip3
                    -> { { 1 A x } { 2 B y } { 3 C z } }
ZipWith        xs ys f -> xs'        { 1 2 3 } DUP \<< * \>> ZipWith
                    -> { 1 4 9 }
ZipWith3    xs ys zs f -> xs'    { 1 2 3 } DUP DUP \<< * * \>> ZipWith3
                    -> { 1 8 27 }

Notes:

1.  Chars and Strcat are provided to convert between strings and lists of
    single character strings. These are not available in Haskell (nor are they
    needed, since a string already is a list of characters in Haskell), but
    are provided here for your convenience so that you can manipulate strings
    using list processing. Note that Strcat can also be used to concatenate an
    arbitrary list of strings.

2.  Copy and Split should actually be named Cycle and SplitAt, respectively,
    but we retained those names for backward compatibility with previous
    GoferLists versions. Also note that the Diff function (meaning list
    difference) is implemented by an operator (\\) in Haskell.

3.  Copy (a.k.a. Haskell's cycle), Iterate and Repeat take an additional
    integer argument which specifies the number of repetitions or
    iterations. In Haskell these functions return infinite lists instead. This
    is possible because of Haskell's lazy evaluation, but of course this
    wouldn't work in an eager language like RPL.

4.  Foldl/Foldr now take their arguments in reverse order. This breaks
    backward compatibility with previous GoferLists versions, but is
    consistent with other generic list functions like Filter and Map, and
    makes it possible to "curry" these operations just like you would in
    Haskell. E.g., concatenating a list of lists can be done using {} << + >>
    Foldl, just as you'd define concat = foldl (++) [] in Haskell, where the
    "list of lists" parameter is implicit (the {} a.k.a. [] is the initial
    empty list from which the accumulation starts). Note that in order to make
    this work in RPL, the parameters have to be in reverse order, because of
    RPN. Other higher-order list functions like Filter, Find, Iterate, Map,
    Scanl/Scanr, Sort etc. work in an analogous fashion.

5.  Concat, Product, Sum and Strcat are all just special instances of Foldl.
    They could easily be defined in User RPL, but are already included in the
    library for your convenience.

6.  The Seg and Subs function are not in the Haskell library, but work in the
    same fashion as Inits and Tails. Seg returns the list of all consecutive
    sublists of a list, while Subs yields the list of *all* (2^N) sublists.

7.  The Seq function (which is just a simplified frontend for the builtin SEQ)
    provides a quick means to generate an arithmetic sequence, which can be
    used as a replacement for Haskell's [x,y..z] construct.

8.  The Sort function takes an additional order predicate as parameter, so
    that lists can be sorted according to different criteria. E.g., \<< < \>>
    Sort and \<< > \>> Sort sorts lists in ascending and descending order,
    respectively. (Haskell also provides a sortBy function for this purpose,
    but that function takes a special ordering function instead of a binary
    predicate as argument.)

9.  GoferLists also provides a number of operations which implement the usual
    set operations on lists. The Nub function removes duplicates from a list,
    so that the resulting list contains each of its members exactly once. The
    Elem, Insert/Delete, Union/Diff/Intersect functions provide the common set
    operations: membership test, insert/delete a member, set union, difference
    and intersection. The Find function works similar to Elem, but looks for
    an element satisfying the given predicate and returns that element if
    found, NOVAL otherwise. Both functions also have a variation, ElemIndex/
    FindIndex, which returns the index of the element in the list (0. if not
    found) instead.

10. Two additional functions are provided to iterate a function starting from
    an initial value. Until is not actually a list function but is provided
    for your convenience anyway. It iterates a function starting from the
    given value and returns the first of the computed values which satisfies
    the given predicate. E.g., 1 \<< 2 * \>> \<< 1000 > \>> Until returns the
    first power of 2 which is greater than 1000, i.e., 1024. The "dual" of the
    Until function is While which returns the list of all iterated values up
    to the point where the given predicate becomes false. Thus, e.g., 1 \<< 2
    * \>> \<< 1000 < \>> While returns the list of all powers of two below
    1000, { 1 2 4 8 16 32 64 128 256 512 }. This function is not actually part
    of the Haskell library, but is equivalent to a combination of Haskell's
    iterate and takeWhile functions.

11. Zip and Zip3 produce a list of lists instead of a list of tuples as in
    Haskell. The Unzip and Unzip3 functions return two or three result lists
    on the stack, respectively; in Haskell, these functions return a tuple of
    lists instead.


EXAMPLE
=======

Here is a quick and dirty implementation of Erathosthenes' sieve in RPL. This
makes use of GoferLists's Filter, Head, Tail and Seq functions. The central
routine here is SIEVE which just takes away the first list element P (which
already is a prime by virtue of the construction) and invokes itself
recursively on the rest of the list after multiples of P have been removed.

SIEVE:        \<< IF DUP Null NOT THEN DUP Head \-> P
              \<< Tail \<< P MOD 0 \=/ \>> Filter SIEVE    P SWAP + \>>
            END \>>

PRIMES:        \<< 2 SWAP 1 Seq SIEVE \>>

N PRIMES returns the list of prime numbers up to the given number N. For
instance: 50 PRIMES -> { 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 }


Enjoy. :)

Jan 26 2007
Albert Graef <Dr.Graef@t-online.de>

Wikis are great, Contribute :)
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: List API (G1CMZ): List Processing API - pier4r - 09-14-2018 10:49 PM



User(s) browsing this thread: 2 Guest(s)