richpl / PyBasic

Simple interactive BASIC interpreter written in Python
GNU General Public License v3.0
170 stars 46 forks source link

Input is too fragile #19

Closed JiFish closed 3 years ago

JiFish commented 3 years ago

At the moment if you ask for a numeric input and the user mistypes their response, it will halt execution. This same applies if an incorrect number of inputs is provided. This is quite inconvenient as there's no way for your program to internally deal with bad user input and continue.

What do you think of the following alternatives?

Option A: Redo from start

Classic 8-bit BASIC variants dealt with this by printing "REDO FROM START" and offering the input prompt again, until the user enters a valid input. This solves the problem nicely. However the message is not customisable in your program and this isn't multi-lingual friendly.

Option B: Default value

If an input missing or invalid, set some default value instead. Probably 0 or -1 for numeric. Strings would be empty: ""

Option C: Don't assign values

If an input missing or invalid, don't even attempt to assign the value. It looks like PyBasic used to work close to this... The advantage is your can specify any default you want by pre-setting the variable before passing it in to INPUT. The downside is if you don't pre-set it, you are opening yourself to errors later in your code. This isn't my favourite, but I do think it's better than how things currently are.

Option D: Change INPUT syntax

Only allow collection of one variable at a time. That would also leave space for optional parameters that tell INPUT how to act when given invalid numeric input. e.g. customise the default value, or goto a line number on failure etc.

Option E: Keep current behaviour and document pitfalls

My least favourite approach. At minimum, the manual ought to tell you that the only safe INPUT is a single string. As anything else may cause your program to fall over depending on what the user enters.

richpl commented 3 years ago

Thanks Joe, let me think about this. Having to start getting into the code again for the first time in a couple of years!

JiFish commented 3 years ago

I did a bit of follow up research to see how other BASIC variants commonly deal with this issue. It seems that almost universally they use Option A: Redo from start. The justification here seems to be if the "redo from start" functionality is undesirable, you should instead collect a single string and deal with the conversion yourself.

QB64 uses Option B.

Some modern "functional"-inspired BASICs simply do not allow collection of numerics at all. Only an INPUT$ function is provided and you are expected to VAL(INPUT$()) or similar.

richpl commented 3 years ago

Hi again Joe. Things have been a bit hectic of late but I've finally had a bit of a think. Option A seems to be the cleanest and most robust approach. I'll look at implementing that over Easter and will upload a new version. Thanks for the feedback.

Like Artemis by the way.

richpl commented 3 years ago

I've implemented option A, hopefully this is a bit more robust.

richpl commented 3 years ago

Ah, I haven't fixed it fully! Will try again ...

richpl commented 3 years ago

That's better

JiFish commented 3 years ago

Thanks for this. I'll push the changes up to my fork.