Page 1 of 1

Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 08, 2019 10:16 am
by Richard Russell
The following has appeared at the BBC BASIC forum:
Would something like the following be hard to implement in BBCSDL?

Code: Select all

      FOR I% OF 3, 22, -9
      NEXT
      FOR Day$ OF "Mon", "Fri", "Sun"
      NEXT
Just wondering as it would be so powerful to an already extremely powerful programming language.
My immediate reaction is that it would be a nice extension to the language and quite 'in keeping with' the general BBC BASIC philosophy (and doesn't need any new keywords!). What do you think?

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 08, 2019 10:23 am
by dhg2
Looks nice. It reminds me of 'foreach' from Tcl.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 08, 2019 10:25 am
by flaxcottage
I like it, Richard.

BITD Pascal used to have something similar; their example used cheese names I believe. :lol:

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 08, 2019 3:46 pm
by Soruk
I like it. Similar to 'for' in the bash shell.

(I wonder how hard that'll be to implement in Matrix Brandy)

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 08, 2019 4:17 pm
by markdryan
I've been thinking about this sort of thing a bit lately, mainly with the goal of eliminating bounds checks on arrays.

Would you also support 1d array and string variables? For example,

Code: Select all

FOR I% OF A%()
NEXT

FOR I% OF A$
NEXT

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 08, 2019 5:03 pm
by Richard Russell
markdryan wrote:
Fri Nov 08, 2019 4:17 pm
Would you also support 1d array and string variables?

Code: Select all

FOR I% OF A%()
NEXT
FOR I% OF A$
NEXT
I think my current feeling is that they can be so readily and elegantly implemented with a conventional FOR loop that the benefit wouldn't justify the complication:

Code: Select all

FOR P% = 0 TO DIM(A%(),1)
  I% = A%(P%)
NEXT
FOR P% = 1 TO LEN(A$)
  I% = ASCMID$(A$,P%)
NEXT
In the array case there's also the argument that iterating through the entire array (rather than just a limited range of indices) would be inflexible, especially as BBC BASIC supports only zero-based-index arrays.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sat Nov 09, 2019 3:02 pm
by julie_m
This is basically iterating over an anonymous enumerable, to use modern object-oriented parlance.

In a clunky old language that didn't let you apply methods directly to an anonymous constructor, you could always emulate it by initialising a new object and applying an iterator to that. Some would say that is ugly, because there need only ever be one reference to that list in the whole program.

Someone more used to PHP or Perl might expect it to look a bit more like

Code: Select all

10 FOR ("HELLO", "BBC", "FANS") AS WORD$
and then to work with an array in between the brackets:

Code: Select all

10 FOR (A%(10 TO 19)) AS Z%
I guess the important thing is, can the extension be introduced in a way that doesn't break pre-existing code (therefore, no new reserved words) while not being so counter-intuitive as to prevent it being useful?

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sat Nov 09, 2019 3:43 pm
by Richard Russell
julie_m wrote:
Sat Nov 09, 2019 3:02 pm
Someone more used to PHP or Perl might expect it to look a bit more like

Code: Select all

10 FOR ("HELLO", "BBC", "FANS") AS WORD$
To me that feels a less comfortable 'fit' with existing BBC BASIC syntax than what the OP proposed; why should the affected variable come first in the case of the conventional FOR statement but last here? And, as you imply, the introduction of a new keyword (especially a short one like AS) has the potential to break existing programs where it has been used as a variable name.

Anyway, I've received an 'over my dead body' kind of response at the BBC BASIC forum so there are evidently some strongly held views that such an extension should not be contemplated. I must admit that not being a user of one of those languages that support the construct I haven't really missed it myself; I'd be interested to see an example of some code that significantly benefits.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sat Nov 09, 2019 7:05 pm
by julie_m
I could be mixing up my BASICs here; if AS isn't a reserved word in any version of post-8-bit BBC BASIC then I agree, it doesn't make good sense to add it for fear of introducing incompatibilities. The actual PHP construct to which I was alluding is

Code: Select all

foreach($hash as $index=>$value) {
    # statements
}
where, inside the loop between the posh brackets, $index is the hash index -- always a scalar value -- and $value is the value, which may be a scalar, array, hash or object, to which it points.

I suppose, when all is said and done, BASIC is one of those clunky, old languages; and that is part of its charm. There is a danger of losing some of that under too many layers of syntactic sugar. (One of the USPs of BASIC always was that there were few constructs to learn before you could start programming in it.)

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 12:53 am
by jgharston
Richard Russell wrote:
Fri Nov 08, 2019 10:16 am

Code: Select all

      FOR I% OF 3, 22, -9
      NEXT
      FOR Day$ OF "Mon", "Fri", "Sun"
      NEXT
My immediate reaction is that it would be a nice extension to the language and quite 'in keeping with' the general BBC BASIC philosophy (and doesn't need any new keywords!). What do you think?
It's the sort of thing I've implemented as

Code: Select all

FOR A%=1 TO 7
Day$=MID$("SunMonTueWedThuFriSat",A%*3-2,3)
...
NEXT
FOR A%=1 TO 3
I%=VALMID$("  3 22 -9",A%*3-2,3)
...
NEXT
I can see how I'd implement it, the FOR control block would have a sort-of "invisible" variable which would be an index/offset into the visible values. In 6502/32K/ARM BASIC it would have the same memory-use issues the string allocator has if you re-use the index variable with different limits, eg:
FOR I% OF 2,4,8,16:NEXT I%
FOR I% OF 1,3,5,7,11,13,17,19,21:NEXT I%

One thing I accidently put in PDP BASIC was IF A$ THEN was interpreted as IF LEN(A$) THEN, which is actually quite useful, but I removed it as it broke the least-surprise paradigm of the IF syntax being IF <numeric_expression>. A typing error with the variable would accidently be valid syntax, whereas the above FOR extension wouldn't suffer from that, you wouldn't accidently type FOR a=something TO as FOR a OF item_list.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 2:38 am
by sweh
Richard Russell wrote:
Fri Nov 08, 2019 10:16 am

Code: Select all

      FOR I% OF 3, 22, -9
 
My initial preference would be to use "IN" instead of "OF". Because we're talking about selecting elements IN a set and it matches the math :-) Or maybe "FROM". "IN" shows we iterating amonst the elements a set. "FROM" to show we're selecting elements from a set. In my mind "IN" maintains order, but FROM wouldn't. So I prefer "IN".

"OF" doesn't match any mental model I have and so wouldn't be syntax that makes sense.

Advanced: Allow for optional (...)

So

Code: Select all

  FOR I% IN (3,22,-9)
But maybe this is my Unix shell scripting bias:

Code: Select all

  for a in 10 20 30 40
  do
    echo $a
  done

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 4:44 am
by Richard Russell
sweh wrote:
Sun Nov 10, 2019 2:38 am
My initial preference would be to use "IN" instead of "OF"... Or maybe "FROM".
They suffer from the same objection as 'AS', namely that they involve the introduction of a new keyword and hence risk breaking compatibility with existing programs. Admittedly I have added new keywords myself (EXIT and PRIVATE) but that was many years ago and I felt that the capabilities that they provided were of such high value that the risk was acceptable (and a few programs did indeed break).

But here we are talking about a relatively esoteric extension which confers no extra functionality, as such, but simply provides a more elegant syntax. My opinion is firmly that potentially breaking compatibility with existing programs is too high a price to pay, hence limiting us to existing keywords like OF.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 8:28 am
by BigEd
(In case anyone else was as confused as I was, OF is part of CASE)

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 9:10 am
by 1024MAK
BBC BASIC may not use IN as a reserved word, but some other BASICs do where it is a function that returns the (8 bit) value from a 8080/8085/Z80 I/O port address. Although it’s use is not universal as some BASICs use INP instead.

I’m sure I have seen ‘AS’ used (as a reserved word) in a BASIC somewhere, but I may be misremembering. But if it’s not already used in BBC BASIC, that's all that matters.

Mark

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 10:16 am
by Richard Russell
1024MAK wrote:
Sun Nov 10, 2019 9:10 am
BBC BASIC may not use IN as a reserved word... I’m sure I have seen ‘AS’ used (as a reserved word) in a BASIC somewhere...
I was of course referring to BBC BASIC (more specifically BBC BASIC for Windows, BBC BASIC for SDL 2.0 and Matrix Brandy BASIC which are the only ones to which the proposed language extension is likely to be relevant). AS and IN are valid variable names in those dialects and a program using them as such would break if they were tokenised (not helped by both BB4W and BBCSDL supporting optional lowercase keywords). OF has been a keyword in BBC BASIC for about 35 of its 38 years existence!

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 12:53 pm
by julie_m
There's no need to introduce any new reserved words if you just extend the parser to accept constructs such as:

Code: Select all

FOR J% = 2, 3, 5, 7
    R% = K% MOD J%
    REM ... statements ...
NEXT J%
which would just throw an error in earlier versions. There is no reason why you could not iterate over lists of strings:

Code: Select all

FOR A$ = "Hello", "BBC", "Micro", "Fans"
    PRINT TAB(10, 31); A$'
NEXT A$
and even make the special case where a single string (variable or literal, but not a one-element array) is given to decompose it into its individual characters, so

Code: Select all

FOR A$ = "Hello BBC Micro Fans"
would be treated as equivalent to

Code: Select all

FOR A$ = "H", "e", "l", "l", "o", " ", "B", "B", "C", "M", "i", "c", "r", "o", " ", "F", "a", "n", "s"
The real question is, does it do anything for the language? Does it solve a real problem? (Probably a yes, since there have been various proposals for ways to emulate such functionality.) Is it easier to understand than any of the workarounds that have been used to date? Does the complexity introduced by the additional functionality slow the interpreter down?

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sun Nov 10, 2019 3:34 pm
by Richard Russell
julie_m wrote:
Sun Nov 10, 2019 12:53 pm
There's no need to introduce any new reserved words if you just extend the parser to accept constructs such as:

Code: Select all

FOR J% = 2, 3, 5, 7
To be pedantic BBC BASIC is interpreted and doesn't have a "parser", but I take your point. You'd have to ask the person who originally proposed the syntax what his thinking was.
There is no reason why you could not iterate over lists of strings... and even make the special case where a single string...
"No reason"? I can think of several: it's more work, it's more code, it might have more impact on the performance of the normal FOR...NEXT loop. Perhaps you're not looking at it from the perspective of the poor sod who has to implement it (i.e. probably me)!
The real question is, does it do anything for the language? Does it solve a real problem?
Indeed it is, and as somebody who has never used one of the languages which has this construct I personally don't miss it. I'd still like to see a small example of its use in a 'mocked up' BBC BASIC program that does something useful.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Mon Nov 11, 2019 3:30 pm
by Soruk
Soruk wrote:
Fri Nov 08, 2019 3:46 pm
I like it. Similar to 'for' in the bash shell.

(I wonder how hard that'll be to implement in Matrix Brandy)
Cross-posting my reply in the other forum:
Right now there's a lot going on in the real world that precludes me spending a lot of time on something that might be used a little, if at all, to implement it it Matrix Brandy. On the flip-side, there is only one implementation to worry about (C) so don't have to worry about a second, parallel implementation in assembler or something else!

(And since LIST is a keyword, I'd have thought FOR x% LIST 4, 65, -2 might make more readable sense, unless it's impossible to use the LIST token in a program line; as a command it's limited to immediate mode only and thus likely removed from BBCSDL).

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Mon Nov 11, 2019 3:53 pm
by Richard Russell
Soruk wrote:
Mon Nov 11, 2019 3:30 pm
unless it's impossible to use the LIST token in a program line; as a command it's limited to immediate mode only and thus likely removed from BBCSDL.
As you surmise, LIST has been removed as a keyword from BBCSDL (and its original 8-bit token of &C9 reallocated to WHEN). From time to time somebody bemoans the loss of commands like DELETE and LIST and RENUMBER from BBCSDL's immediate mode, but if they were ever to be reinstated I don't think I'd bother to tokenise them at all.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Mon Nov 11, 2019 6:08 pm
by jgharston
And 'OF' semantically matches what it's doing, and matches how you verbalise* the equivalent mathematic action:

for all X of {a, b, f, g, w, cat, trombone}

*well, we did at my school. ;)

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Thu Nov 14, 2019 12:14 am
by BeebMaster
It's a nice idea, and the ability to loop with string variables rather than numeric variables does sound like it would be very handy, but I am still trying to think of an actual programming use for this FOR extension.

It could be used where sequences of data have a recognisable numeric value but irregular string values, like days of the week, months, presidents of the USA, countries in the order they joined the Commonwealth etc, or even the spelling of numbers.

So whereas we might print what day it is using something like:

Code: Select all

DIM Day$(7)
FOR A=1TO7
READ Day$(A)
NEXT
dayofweek=FNgetdayfromRTC
PRINT"Today is ";Day$(dayofweek)

...
DATA Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday

we could perhaps optimise the code significantly by using a FOR list with the days of the week in the list:

Code: Select all

FOR Day$ = Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
....
But actually I can't even think how that would work in order to finish this example!

Worse than that, and after a few days of genuinely trying to reconcile myself to this new idea, I do think that it breaks our whole conception of how we use FOR...NEXT loops in programming - in my view they are sequential and predictable: we go from the first value to the second value incrementing or decrementing by the value in STEP, if used.

We use a FOR..NEXT loop to repeat the same code a number of times. It might be as straightforward as doing exactly the same thing x times; but much more likely is that we do the same thing x times but making use of the incrementing or decrementing value of x on each pass of the loop. If there is no predictability to the change in value of x between passes then the whole purpose of FOR...NEXT is destroyed.

If we want to repeat the same code using a random set of variables, which a FOR list would allow, I would say we are just as well off calling the code explicitly several times with the "random" variable value each time, or find another way of passing the "random" variable:

A FOR list would let us do:

Code: Select all

FOR IceCreamFlavour$ = Book-End,Pumice Stone,West Germany
PROC SunshineDesserts(IceCreamFlavour$)
NEXT
which could be achieved with:

Code: Select all

PROC SunshineDesserts("Book-End")
PROC SunshineDesserts("Pumice Stone")
PROC SunshineDesserts("West Germany")
or using our READ...DATA friend:

Code: Select all

DIM IceCreamFlavour$(3)
FOR A=1 TO 3
READ IceCreamFlavour$(A)
NEXT
....
DATA Book-End,Pumice Stone,West Germany
....
FOR A=1 TO 3
PROC SunshineDesserts(IceCreamFlavour$(A))
NEXT
To answer the original question, then, I think on reflection that I wouldn't be pushing for this extension to be implemented, as I'm not convinced that it really is within the spirit of BBC BASIC and I don't think it has a proven real-world use.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Thu Nov 14, 2019 9:26 am
by Richard Russell
BeebMaster wrote:
Thu Nov 14, 2019 12:14 am
So whereas we might print what day it is using something like:

Code: Select all

DIM Day$(7)
FOR A=1TO7
READ Day$(A)
NEXT
...
DATA Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
In BBC BASIC V and later I would be more inclined to do this rather than use READ/DATA:

Code: Select all

DIM Day$(7)
Day$() = "","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"
I do think that it breaks our whole conception of how we use FOR...NEXT loops in programming - in my view they are sequential and predictable
My difficulty with that argument is that several other 'modern' languages do use FOR to indicate general iteration rather than just a sequence:

Python:

Code: Select all

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  print(x)
Java:

Code: Select all

    int arr[]={12,23,44,56,78};
    for(int i:arr){  
        System.out.println(i);
        }
I'm not a user of any of those languages myself, so I share your uncertainty of its value, but I can see the argument that if it's useful in them it should be in BBC BASIC too.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Thu Nov 14, 2019 11:47 am
by BigEd
Richard Russell wrote:
Thu Nov 14, 2019 9:26 am

Code: Select all

Day$() = "","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"
Hadn't seen that syntax before, but what it says to me is that if we have one of these we should have both:

Code: Select all

FOR A$ IN Day$()
FOR A$ IN "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"
In other words, there's such a thing as a list, and such a thing as a list expression, and we want to be able to iterate over a list expression.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Thu Nov 14, 2019 12:50 pm
by Richard Russell
BigEd wrote:
Thu Nov 14, 2019 11:47 am
Hadn't seen that syntax before
As far as I know it was in ARM BBC BASIC (BASIC V) from the very start, 35 years ago or thereabouts. Just one of the many 'whole array' operations supported by BBC BASIC.

I remember wanting to implement a 'shift register' in an array (whereby each element is shifted along one place into the next element); this is how I did it, in one statement:

Code: Select all

DIM sr(10)
sr() = newdata, sr(0), sr(1), sr(2), sr(3), sr(4), sr(5), sr(6), sr(7), sr(8), sr(9)
but what it says to me is that if we have one of these we should have both:

Code: Select all

FOR A$ IN Day$()
FOR A$ IN "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"
I'm inclined to agree (with OF or = instead of IN) but the OP didn't suggest it in his original proposal. Inevitably it adds considerable complication (effectively there are now three different kinds of FOR statement).

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 15, 2019 10:22 pm
by Coeus
Richard Russell wrote:
Thu Nov 14, 2019 9:26 am
My difficulty with that argument is that several other 'modern' languages do use FOR to indicate general iteration rather than just a sequence:
I think in many languages in which this appears you could say that this is syntactic sugar in that it does not enable you to do anything that you could not do previously, it just makes is easier to express certain constructs. I think the advantage is greater where there are non-sequential collections. As an example, neither C++ or Java have a built-in associative arrays but allow classes to be defined that do. In order to iterate over the keys in such an associative array the class can define an iterator and the language then provides the syntax to work that iterator in an easy to read way.

BTW, on the question of DATA statements I always wondered about these - why would one write them when the same effect could always be achieved by writing assignments into the body of the program. It occurred to me that this may have something to do with punch cards. One could write the program and submit it for processing more than once each time with a different deck of DATA cards immediately after it.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Fri Nov 15, 2019 11:15 pm
by Richard Russell
Coeus wrote:
Fri Nov 15, 2019 10:22 pm
I think in many languages in which this appears you could say that this is syntactic sugar in that it does not enable you to do anything that you could not do previously, it just makes is easier to express certain constructs.
Indeed, but if such "syntactic sugar" wasn't appropriate for BBC BASIC we wouldn't have the CASE statement, which can equivalently be expressed using IF..THEN..ENDIF! There are probably other examples.
BTW, on the question of DATA statements I always wondered about these - why would one write them when the same effect could always be achieved by writing assignments into the body of the program.
I assume it's primarily for space-saving. If you've got thousands of data items, it will require considerably less code to read them from DATA statements than to assign them individually. Even if you're using the whole-array assignment syntax there's still a saving (and more so when you remember that strings needn't be enclosed in quotes in DATA statements). Also, apart from in my BASICs which have a line-continuation operator, the whole-array assignment has to fit in a single program line.

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sat Nov 16, 2019 2:28 am
by sweh
Richard Russell wrote:
Fri Nov 15, 2019 11:15 pm
Coeus wrote:
Fri Nov 15, 2019 10:22 pm
I think in many languages in which this appears you could say that this is syntactic sugar in that it does not enable you to do anything that you could not do previously, it just makes is easier to express certain constructs.
Indeed, but if such "syntactic sugar" wasn't appropriate for BBC BASIC we wouldn't have the CASE statement, which can equivalently be expressed using IF..THEN..ENDIF! There are probably other examples.
A lot of these "syntactic sugar" commands are to make expression of ideas and comprehension of these ideas easier. After all, Turing theory says that any Turing machine can run any other Turing machine's algorithms... but it doesn't mean it's as easy to understand. The CASE command is a perfect example of "sugar" making code easier to write _and_ read. Similarly, iterating over some list can make code easier to understand.

I'm all in favour of extensions that make code easier to write and read.

But I'm also a big fan of compatibility; "you need version xx.yy.zz or newer to run this code"... well, I guess that works OK in the enthusiasts world, but it can cause a barrier; "last time I looked at this I only had aa.bb.cc; now I've got 20 yaks to shave before I can do what I want to do...?". Yak shaving isn't anyone's favourite pass time.

So the question always come back to "is this new sugar worth the potential incompatibilities"...

Re: Proposal for BBC BASIC 'FOR lists'

Posted: Sat Nov 16, 2019 10:05 am
by Richard Russell
sweh wrote:
Sat Nov 16, 2019 2:28 am
But I'm also a big fan of compatibility; ...
So the question always come back to "is this new sugar worth the potential incompatibilities"...
I couldn't agree more. With BBC BASIC at its current degree of maturity and stability, I wouldn't contemplate any extension that could cause existing programs to fail. But, with my preferred syntax, the proposed extension would result in a 'No TO' or 'Missing TO' error from current interpreters. So to cause an incompatibility a program would need to be expecting this error to occur and to fail if it doesn't! That is a vanishingly improbable scenario.