Proposal for a 'listlib' library

Discussions related to the code libraries supplied with BB4W & BBCSDL
Hated Moron

Proposal for a 'listlib' library

Post by Hated Moron »

In another thread, comparing BBC BASIC with Python (hiss!), one of the claimed advantages of Python is its support for lists. Lists differ from arrays in the following key ways:
  • Lists can contain a mixture of data types: numbers, strings and sub-lists (which themselves can have sub-sub-lists etc).
  • Lists don't have to be statically declared in advance, they can grow and shrink dynamically.
Not being one to take criticism of BBC BASIC lightly, I propose to create a new library listlib to support the functionality of lists in BBC BASIC, as far as is possible. Of course a library can never offer the elegance and brevity of a native language feature, but so long as its performance is good enough it can go a long way to meet the criticism.

As a proof-of-principle I have written a tiny proto-library which has some of the most basic functionality needed: it can create a list, it can append elements to the list, and it can return elements from the list. Here is an example of what it can already do:

Code: Select all

      REM Create a new (empty) list:
      PROC_listcreate(mylist())

      REM Append a number and a string to the list:
      PROC_listappend(mylist(), PI)
      PROC_listappend(mylist(), FN_sv("A string"))

      REM Note that the list length is now two:
      PRINT "Number of elements = "; FN_listlen(mylist())

      REM Create another list, but this time as an initialised list:
      DIM child(1)
      child() = FN_sv("Hello "), FN_sv("world!")

      REM Append the 'child' list to the parent list:
      PROC_listappend(mylist(), FN_lv(child()))

      REM Note that the list length is now three:
      PRINT "Number of elements = "; FN_listlen(mylist())

      REM Print the first two elements of the parent list:
      PRINT mylist(0) TAB(15) FN_vs(mylist(1))

      REM Extract the third element:
      PROC_vl(mylist(2), temp())

      REM Print the contents of that list:
      PRINT FN_vs(temp(0)) FN_vs(temp(1))

      REM Clean up and free memory:
      PROC_listdiscard(mylist())

      END
Which prints:

Code: Select all

Number of elements = 2
Number of elements = 3
3.14159265     A string
Hello world!
Hated Moron

Re: Proposal for a 'listlib' library

Post by Hated Moron »

On 02/12/2023 22:57, Andrew Cool wrote (cross-posted from the Discussion Group):
How does one copy and paste code listing on this forum direct into the BBC BASIC editor (BB4W in my case) without just getting one enormously long line of code with truncate errors?
It should 'just work', I've never encountered any problems such as you have described. I used copy-and-paste to transfer the code from the initial post of this thread into both BB4W and BBCSDL (SDLIDE) editors and it worked fine.

You're not, by any chance, trying to copy-and-paste from the Discussion Group a code listing which originated here at the Forum and was automatically cross-posted via the Atom feed, are you? As I have discussed before, there's a bug in phpBB which means that code blocks get converted to one long line in the #feed!

If it's that, I can't do anything about it. I reported the problem at the phpBB Bug Tracker but they seem to feel it is so unimportant that nothing is going to be done about it. I even offered a monetary incentive, as it was suggested that might help, but no joy.

But in practice it's easily resolved by copying-and-pasting directly from here (the Forum) rather than from the #feed received by the Discussion Group. All the posts forwarded via the #feed contain a link to the original.
User avatar
hellomike
Posts: 184
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Proposal for a 'listlib' library

Post by hellomike »

The functionality offered by the proposed library could really be useful.
Just my opinion of course.

Regards,

Mike
Hated Moron

Re: Proposal for a 'listlib' library

Post by Hated Moron »

hellomike wrote: Sun 03 Dec 2023, 12:37 The functionality offered by the proposed library could really be useful.
Thank you for the feedback. Needless to say the library won't provide any 'new' functionality, that's impossible, but it may make the functionality somewhat more accessible, especially if you have some prior knowledge of Python lists.

In case I've misunderstood something fundamental about Python lists, which is entirely possible, I will pause development of the library now until I've received some feedback from an expert (e.g. DDRM) to confirm that my approach is sound.

One area where I won't be able to come close to Python's functionality is in respect of slicing, there is no mechanism in BBC BASIC for representing a subset of the elements of a list as another list, other than by copying.
Hated Moron

Re: Proposal for a 'listlib' library

Post by Hated Moron »

Hated Moron wrote: Sun 03 Dec 2023, 23:44 In case I've misunderstood something fundamental about Python lists, which is entirely possible, I will pause development of the library now until I've received some feedback from an expert (e.g. DDRM) to confirm that my approach is sound.
Just a reminder that I've paused development pending some feedback.
DDRM

Re: Proposal for a 'listlib' library

Post by DDRM »

Hi Richard,

Just done my last bit of coursework, so I'll try to get to this over the next couple of days. It's a shame about slicing - it's really powerful feature. Is there any chance it could be provided "out of sight", even if that means making a copy? I can see that if there isn't a simple way of freeing memory that is rapidly going to become a problem with big/multidimensional lists...

Best wishes,

D
Hated Moron

Re: Proposal for a 'listlib' library

Post by Hated Moron »

DDRM wrote: Thu 14 Dec 2023, 08:43 It's a shame about slicing - it's really powerful feature. Is there any chance it could be provided "out of sight", even if that means making a copy?
I'm not too sure what you mean by "out of sight". I do not believe it is possible, without changes to the interpreter, to implement slicing without copying.

My intention is for the library to provide two procedures: PROC_getslice() and PROC_putslice(). The former would create a new list containing the contents of the specified slice of the source list (copied); the latter would replace the specified slice with the supplied sub-list (copied).

Functionally I don't see that there is a great deal of difference. It must surely be quite common for list slicing in Python to be 'read only', in other words for the source list not to be modified; in that case my proposed PROC_getslice() is equivalent except that since it returns a new list that would have to be discarded later.

Only when slicing is used to modify the source list (by modifying the slice) would it be necessary to call PROC_putslice() after modifications to the slice have been carried out. If that doesn't meet your objectives I will need to think again; it's not that I totally rule out any changes to the interpreter but they would be difficult, risky (especially in my current state of health) and need to be done to both the assembler and C versions.
Hated Moron

Re: Proposal for a 'listlib' library

Post by Hated Moron »

Hated Moron wrote: Thu 14 Dec 2023, 13:47 it's not that I totally rule out any changes to the interpreter but they would be difficult, risky (especially in my current state of health) and need to be done to both the assembler and C versions.
I've demonstrated, experimentally, that a modification to the interpreter to enable true list slicing (but not to implement it, that would still be by means of BASIC code in a library) is possible. It would in principle allow code like the following:

Code: Select all

DIM parent(9)
parent() = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

PROC_listslice(parent(), child(), 3, 5)
child() = 11, 12, 13
which would actually modify elements 3, 4 and 5 of parent().

So the question is whether the complication and risk of changing the interpreter is worth it for the benefit of being able to create a 'true' (read/write) slice rather than a 'copied' (read-only) slice.
Hated Moron

Re: Proposal for a 'listlib' library

Post by Hated Moron »

Hated Moron wrote: Sat 16 Dec 2023, 23:10 So the question is whether the complication and risk of changing the interpreter is worth it for the benefit of being able to create a 'true' (read/write) slice rather than a 'copied' (read-only) slice.
I should add that the 'copying' (read-only) approach could support the Python 'IndexJump' option, whereby the 'child' list extracts non-contiguous (even reversed) elements from the 'parent' list.

The 'true' slice approach can't, it can only set the child list to map to contiguous (ascending) elements of the parent list. Of course one could support both, it's not necessarily a choice of one or the other.

Incidentally do you happen to know why, to specify a list slice in Python, the 'start' index is inclusive but the 'end' index is exclusive? A mathematician might like it, but it doesn't seem very 'friendly'.
DDRM

Re: Proposal for a 'listlib' library

Post by DDRM »

Hi Richard,

I suspect it's related to the decision made for "range", and is all consistent with using 0-based numbering. If you write something like

for x in range(10):
<Block>

It will execute the block 10 times - but x will run from 0 to 9. Similarly, the index of the first character in a string (which is also just a list of characters) is string[0], As you (but maybe not some others) know, that has advantages in terms of using modular arithmetic to address multi-dimensional arrays.

Range has more sophisticated forms to run between two integers, with an integer step, but it has to be consistent with this usage, so

for x in range(2,10,2):

will run through x values of 2,4,6,8, but not 10. List slicing is essentially an extension of this. As you say, it's logical, but takes a bit of learning!

Best wishes,

D