Jump to content

BASIC 2? Why not get BASIC 7?


Recommended Posts

970257422_Screenshotfrom2021-03-1306-34-31.thumb.png.99482c2789115d65a56548c01db2b05a.png

I think it looks neater with indents and everything lower case (except quoted strings). I have a workflow and an actual working game 🙂 albeit not the most complicated one in the world, but it's all done with text commands ....  inkey$() has been added since I wrote this test game (I forgot ...). Code size is about 10k, but it's chopped up into about a dozen modules which are designed to be paged, and the largest module "main", the core, is under 6k and that's not likely to grow much, as the assembler has its own module (though that's not written  yet), and anything system specific goes in another module.

Spot the bug 😉

Edited by paulscottrobson
Duplication
Link to comment
Share on other sites

18 hours ago, rje said:

My "transpiler" isn't even that.  It's a two-pass thing that looks for patterns and does some simple substitutions.  It doesn't care about syntax at all.

Yeah, that's largely how this one works, but since I wanted the short variable naming to be automatic, I needed to know the text of all the reserved words. That way I didn't try to shorten "FOR" or "THEN". 

I've also got some additional syntax rules, compared to BASIC 2. Among other things, a space between keywords and variable names is required. So no FORT=1TO100. That would cause the parser to think FORT is a word, and it would try to shorten it to FO. I plan to include packing in a fourth pass, so the final output might indeed look like that, but the input definitely cannot. 🙂

 

  • Like 1
Link to comment
Share on other sites

11 hours ago, paulscottrobson said:

I think it looks neater with indents ...

Quoted For Metaphysical Truth.   I indent the for-blocks in my transpiled fake-BASIC thing, and it's refreshing.

I've thought about adding inkey$ as a cipher for 

get a$: if a$="" <then_try_again_until_there's_something_there_to_worry_about>

P.S. I like the defproc syntax.

The overall result looks sorta like Pascal with C-style assignment.

Edited by rje
Link to comment
Share on other sites

9 hours ago, rje said:

Quoted For Metaphysical Truth.   I indent the for-blocks in my transpiled fake-BASIC thing, and it's refreshing.

I've thought about adding inkey$ as a cipher for 


get a$: if a$="" <then_try_again_until_there's_something_there_to_worry_about>

P.S. I like the defproc syntax.

The overall result looks sorta like Pascal with C-style assignment.

I think it looks a good bit like Algol, from which C and Pascal descend, but with fewer parentheses.

  • Like 1
Link to comment
Share on other sites

18 hours ago, TomXP411 said:

Yeah, that's largely how this one works, but since I wanted the short variable naming to be automatic, I needed to know the text of all the reserved words. That way I didn't try to shorten "FOR" or "THEN". 

I've also got some additional syntax rules, compared to BASIC 2. Among other things, a space between keywords and variable names is required. So no FORT=1TO100. That would cause the parser to think FORT is a word, and it would try to shorten it to FO. I plan to include packing in a fourth pass, so the final output might indeed look like that, but the input definitely cannot. 🙂

Oh my goodness yes ... even in a hosted Basic transpiler, 80 columns and 30ish rows is enough that there is no reason to have crunched source.

Also, on indents, while eight column tabstops is the traditional 80s standard for programming and five column tabstops the standard for text editing, to my eye either three or four column tabstops work fine. When working on BMW, my pure text character line editor for & in Forth, I had a first line tabstop define, where if the first line was a comment line:

\ -+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

or

\ --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

... would give three or four column tabstopping, respectively. The test for a tabstop line was "Does it start with the string Comment character, space, - character? If so, skip any additional - characters, is the next character a +? If so, this is a tabstop comment, store it in the tabstop definition buffer". The indent out and indent back routines are the only ones that have to read the tabstop definition buffer, since they set the current tab indent column and that value is what the line display routine uses. There was no need for a tabstop setting command, since, eg, loading file consisting of nothing but a tabstop comment with 8 column tabstops would "set" the tabstop to 8 columns. Loading it into the copy and paste buffer rather than the main file buffer could set it after the file was loaded.

A similar thing can be done in the editor for any language that has a single character, single character plus space, or double character comment symbol, to support arbitrary regular column tabstops from 3 columns on up.

Edited by BruceMcF
Link to comment
Share on other sites

On 3/13/2021 at 8:29 PM, BruceMcF said:

Oh my goodness yes ... even in a hosted Basic transpiler, 80 columns and 30ish rows is enough that there is no reason to have crunched source.

Also, on indents, while eight column tabstops is the traditional 80s standard for programming and five column tabstops the standard for text editing, to my eye either three or four column tabstops work fine. When working on BMW, my pure text character line editor for & in Forth, I had a first line tabstop define, where if the first line was a comment line:

I go with 4 column tabs, as this gives a clear indent, but doesn't walk the text all the way across the screen. If I find I've indented more than 20 columns, that means I've got too many nested blocks, and I probably need a procedure, CASE statement, or more complex IF predicates. 

And I've never appreciated the habit of the Commodore community to write crunched code... while it's often necessary from a performance of space standpoint, don't do it while explaining things to other people. I've seen people give example code like FORI=1TO20STEP3 to new programmers, and I always have to stop and say something. It's fine to crunch code when you know what you're doing and need the bytes, but never, ever give crunched code in an example. (Unless the topic is "how to crunch code.") 

 

  • Like 2
Link to comment
Share on other sites

Progress update, at about 4 weeks as of v0.17 (very alpha)

So far :

  • 32 bit integer and string types (hooks for floating point)
  • long variable names.
  • Integer and string functions and operators, BBC Basic style indirection.
  • While/Repeat/For/Multilevel Ifs
  • Procedures
  • Locals/Parameters
  • VPEEK/VPOKE and VDEEK/VDOKE because there are so many 16 bit values.
  • Inline 65C02 assembler
  • Multidimensional Arrays
  • Tokenising / Detokenising, interactive editing, Load and Save from the console.
  • Text I/O functions, Timer function, Event function.
  • Usable Python workflow

Next up:

  • Some Sprite commands (X16 specific)
  • Links to the OS drawing commands .... when I can figure out exactly how they work 🙂
  • Write a couple of games as a test of the BASIC, the individual tests are somewhat limited.
  • Something like AMAL for the Amiga, a sort of simple scripting language to animate stuff in the background with low resource usage.
  • Floating Point

Current module usage. Each module runs through a single link, so it should be possible for example to load it into 2 or 3 pages of $A000 RAM and link it through page switching code without much of a performance hit.

Section "header"         $1000-$102d (45 bytes)
Section "assembler"      $102d-$138b (862 bytes) (inline assembler)
Section "device"         $138b-$14e0 (341 bytes) (I/O virtualisation)
Section "error"          $14e0-$1815 (821 bytes) (Error messages, multiple languages)
Section "extension"      $1815-$1924 (271 bytes) (X16 specific stuff)
Section "floatingpoint"  $1924-$1929 (5 bytes) (floating point routines)
Section "interaction"    $1929-$1b0b (482 bytes) (the console I/O stuff, program editing etc.)
Section "main"           $1b0b-$31a8 (5789 bytes) (core interpreter)
Section "string"         $31a8-$3458 (688 bytes) (string functions/string memory management)
Section "tokeniser"      $3458-$3c50 (2040 bytes) (tokenise/detokenise program lines)
Section "variable"       $3c50-$401a (970 bytes) (variables and arrays)
Section "footer"         $401a-$4100 (230 bytes)

Approximate total 12544 bytes.

 

 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

I developed RatBAS2 in order to generate large BASIC v.2 programs from C-like source code:
https://github.com/mobluse/ratbas2

RatBAS2 is similar to RatFOR (Rational Fortran). I discovered that RatFOR could be used to generate BASIC since it is similar to Fortran 66 and modern RatFOR has a disabled Fortran 66 mode that I could enable.

RatBAS uses only IF...GOTO, but BASIC does have FOR...NEXT loops, ON...GOTO, GOSUB, and ON...GOSUB also. Unfortunately the program that turns a program in BASIC with labels into BASIC with line numbers doesn't handle the ON... constructs. FOR... NEXT is probably faster than using IF...GOTO.

Link to comment
Share on other sites

On 3/13/2021 at 9:29 PM, BruceMcF said:

.. there is no reason to have crunched source..

For 'old school' Commodore, crunching was habit both because of that 80 character max on a line limit, and the speed benefit (both because a : between two things done in sequence was faster than doing the exact same two things on two subsequent lines, (ah, linked lists... thanks Bill Gates!) and the spaces themselves slowed things down). 

But as BASIC is still an interpreted language,  I would presume that is the case even with the transpilers or the like.   An interpreter has to step through every byte and ask "what is this thing" as it goes.    Bill Gates stuck the CHRGET code (the core of BASIC parsing) into Zeropage on the C64 because it was so important to speed.   

On the X16 emulator, I just did this on the command line, with and without spaces (represented as [] below):

    TI=0: FOR[]I[]=[]1[]to[]10000[]:[]A[]=[]1[]:[]NEXT:?TI 

With the spaces the result was that elapsed TI was 266.

Without the spaces, elapsed TI was 258

That's a 3% performance loss for a very routine bunch of "stuff people do in basic."    (To be fair, I think leaving spaces in was closer to 4 or 5% hit on the C64, so our CX16 wizards are already ahead of the game).  

For those of you guys doing the  'modern' BASICs, are you still doing a run time interpreter?   How are you optimizing to deal with spaces compared with how the original '64 might have done?    I envision there still needing to be some mechanism to _scan_ through the BASIC, execute commands, parse variables, perform jumps etc; although, it occurs to me that with modern speed and memory it might be possible to hold some sort of optimized runtime embodiment (tokens, no-non-operating bytes outside of structure, operators, variables, etc) and even to have direct memory pointers substituted for variable names etc, sort of a real time version of what the old basic compilers did. 

Interesting projects, which I'll follow with interest for sure.   

Link to comment
Share on other sites

31 minutes ago, Snickers11001001 said:

For 'old school' Commodore, crunching was habit both because of that 80 character max on a line limit, and the speed benefit (both because a : between two things done in sequence was faster than doing the exact same two things on two subsequent lines, (ah, linked lists... thanks Bill Gates!) and the spaces themselves slowed things down). 

But as BASIC is still an interpreted language,  I would presume that is the case even with the transpilers or the like.   An interpreter has to step through every byte and ask "what is this thing" as it goes.    Bill Gates stuck the CHRGET code (the core of BASIC parsing) into Zeropage on the C64 because it was so important to speed.   

On the X16 emulator, I just did this on the command line, with and without spaces (represented as [] below):

    TI=0: FOR[]I[]=[]1[]to[]10000[]:[]A[]=[]1[]:[]NEXT:?TI 

With the spaces the result was that elapsed TI was 266.

Without the spaces, elapsed TI was 258

That's a 3% performance loss for a very routine bunch of "stuff people do in basic."    (To be fair, I think leaving spaces in was closer to 4 or 5% hit on the C64, so our CX16 wizards are already ahead of the game).  

For those of you guys doing the  'modern' BASICs, are you still doing a run time interpreter?   How are you optimizing to deal with spaces compared with how the original '64 might have done?    I envision there still needing to be some mechanism to _scan_ through the BASIC, execute commands, parse variables, perform jumps etc; although, it occurs to me that with modern speed and memory it might be possible to hold some sort of optimized runtime embodiment (tokens, no-non-operating bytes outside of structure, operators, variables, etc) and even to have direct memory pointers substituted for variable names etc, sort of a real time version of what the old basic compilers did. 

Interesting projects, which I'll follow with interest for sure.   

That's an excellent point about the overhead of reading the extra characters just to skip whitespace. Many probably already realize it, but when evaluating an expression, BASIC has to parse numbers every time. So using this little example:

10 TI = 0
20 FOR I = 1 TO 1000
30 A = 200*300*500*700
40 NEXT I
50 PRINT TI

Running that took 1290 jiffies through the loop. Adding a line 15 and modifying line 30:

15 W=200:X=300:Y=500:Z=700
30 A = W*X*Y*Z

Running that only takes 716 jiffies (45% faster by not having to parse four digit sequences to floating point numbers each time through the loop).

I think there are many ways to approach a "better" BASIC interpreter, but the things that will always take more time are interpreting the human readable form of code (such as infix expressions) into something the computer can work with (converting digit sequences, applying operator precedence, and so on).

I think it would be interesting to write an interpreter that tokenizes the lines more than just replacing keywords with tokens. Actually pre-evaluate digit strings into the equivalent binary formats. Convert the infix notation to postfix notation so that the interpreter didn't have to redo it every time. Replace constant expressions with their equivalent values. Other optimizations could be done. Those are things a compiler does, but a compiler also (generally, usually) discards the original text of the line afterward as it is of no value to the computer. An interpreter that is intended to be used to both edit and run code would need to keep some information about the original format of the text so that it could be "listed" for humans.

Perhaps these ideas belong in a different topic...

Link to comment
Share on other sites

6 hours ago, Scott Robison said:

I think it would be interesting to write an interpreter that tokenizes the lines more than just replacing keywords with tokens. Actually pre-evaluate digit strings into the equivalent binary formats. Convert the infix notation to postfix notation so that the interpreter didn't have to redo it every time. Replace constant expressions with their equivalent values. Other optimizations could be done. Those are things a compiler does, but a compiler also (generally, usually) discards the original text of the line afterward as it is of no value to the computer. An interpreter that is intended to be used to both edit and run code would need to keep some information about the original format of the text so that it could be "listed" for humans.

 

Some and some. Infix to Postfix would work, except that if you are (in this example) doing multiplies the 6502 time spent doing that tends to dwarf the time climbing the parse tree (which actually is fairly minimal). My Basic does most of these and it's probably only 40-50% quicker than Microsoft BASIC, much of which is down to 32 bit math being 32 bit math. The only thing that isn't tokenised is text in quoted strings, and that's stored with a precalculated length.

Link to comment
Share on other sites

2 minutes ago, paulscottrobson said:

Some and some. Infix to Postfix would work, except that if you are (in this example) doing multiplies the 6502 time spent doing that tends to dwarf the time climbing the parse tree (which actually is fairly minimal). My Basic does most of these and it's probably only 40-50% quicker than Microsoft BASIC, much of which is down to 32 bit math being 32 bit math. The only thing that isn't tokenised is text in quoted strings, and that's stored with a precalculated length.

I call 40 to 50% significant! 🙂

Link to comment
Share on other sites

3 minutes ago, paulscottrobson said:

It's worthwhile, but not enough to get out of writing assembler. If it was 4-5 times faster you could write 80s style arcade games pretty much entirely in BASIC.

Please note I'm not trying to denigrate your work at all. I'm just trying to think of ways to:

1. Write a native interpreter;

2. That does a more sophisticated tokenization / crunching process than v2 BASIC;

3. That still keeps around the original form of the source code so that it can be listed and edited;

What you've done is great from the perspective of having better tooling to emit BASIC compatible for the platform. My thoughts are more of an intermediary between v2 BASIC and assembly code. Something that could still give the programmer an interactive feeling of immediacy by typing and running their code, but that spends more time optimizing.

At this point it is just a thought exercise that I might never have the time to work on, but it is similar in spirit to what I did with PCBoard Programming Language. The source code was similar to BASIC without line numbers, and it went through a "compilation" phase to create tokenized form. So if you wanted a program like:

PRINTLN "2+3*4-6", 2+3*4-6

It would generate a tokenized form that looked like:

PRINTLN 2 "2+3*4-6" NUL 2 3 4 * + 6 - NUL

Where the first token indicated what statement, followed by a count of expressions, followed by postfix expressions terminated with NUL markers. Each of the tokens was just a reference to a variable table (even constants were stored as variables because I was young and inexperienced and it was the first compiler I ever wrote). Then the BBS had a runtime system / VM in it that knew how to parse the token stream.

My first thought when tokenizing code by this theoretical BASIC interpreter would be that it parses the line into compact tokens, then stores a copy of the human readable form of the token stream, then a copy of the "optimized" (not the best word) sequence of the tokens. So using the example above, maybe a serialized form of the line looks like (labels are for convenient reference, it really is more or less just an array of tokens in three sub-sections):

TOKEN_COUNT = 11
TOKEN_0 = SPACE CHARACTER
TOKEN_1 = PRINTLN
TOKEN_2 = "2+3*4-6"
TOKEN_3 = ,
TOKEN_4 = 2
TOKEN_5 = +
TOKEN_6 = 3
TOKEN_7 = *
TOKEN_8 = 4
TOKEN_9 = -
TOKEN_10 = 6
PRE_COUNT = 12
PRE_TOKENS = T1 T0 T2 T3 T0 T4 T5 T6 T7 T8 T9 T10
POST_COUNT = 12
POST_TOKENS = T1 T4 T2 NUL T4 T6 T8 T7 T5 T10 T9 NUL

This isn't extremely well thought through yet, just stream of consciousness ideas, but it could give one an interactive environment that allows listing and editing of existing statements, while eliminating a significant portion of the runtime cost. The PRE data includes the niceties of original spacing, intuitive expression order with order of operations support. The POST data has already processed the data to a greater extent than v2 BASIC did, so it can more efficiently process the tokenized form.

This can never be as good as a real compiler or assembler that discards the original program text after doing the same transformations, but maybe it could be enough of an enhancement to justify larger BASIC tokenized text in exchange for faster speed. Or maybe not.

Link to comment
Share on other sites

12 hours ago, Scott Robison said:

Please note I'm not trying to denigrate your work at all. I'm just trying to think of ways to:

1. Write a native interpreter;

2. That does a more sophisticated tokenization / crunching process than v2 BASIC;

3. That still keeps around the original form of the source code so that it can be listed and edited;

Oh, that's pretty much what it does. It just detokenises the tokenised code 🙂

There are two main handicaps. The first which we are stuck with is 32 bit (or 16 bit if you like) multiply and divide.  Float or Int, you have the same problem, it still has to be done. Short of having a hardware multiplier (can live without divide mostly) there isn't really an answer to it.

The second is accessing variables and other identifiers fast enough. Mine uses several techniques : A-Z are done seperately as on the BBC Micro. Rather than one linked list there's 8 linked liists accessed via hashes. Checks on hashes are done before checks on the full name, and the name itself is tokenised so it doesn't have to be parsed, it's easy to find the type and the end and so on. Whether doing what some of the semicompiling  BASICs do (have you ever looked at DAI Basic ?) in the way of storing identifier addresses inline in the code is worth the extra effort is debatable. You might get another 20-30% with such techniques (I wrote a language called RPL which is rather like a cross between BASIC and FORTH and does most of these things) its debatable whether it matters. The extra step to get the speed required isn't there. It's not even there if you compile to pseudocode. Compiling to assembler has the usual problems you have with the 6502 e.g. 16 bit operations are very verbose.

I don't think having RPN already available gains you an awful lot in processor time.

I always reckoned you could produce a fairly easy to use programming system if you had a fast CPU, or lots of directly available memory. At the moment you are stuck between two stools. If you generate 6502 code it's too long. If you generate p-code it's too slow. I did have an experimental compiler that did both, and could be switched on request following the 90/10 rule, but the language was quite limited and to expand that into a full programming language is quite a task. Even normally efficient things like FORTH do not have the speed they really need for this machine.

The other problem is if you store it in dual format you effectively halve the RAM, and there isn't that much of it unless you stick it in banked memory.

 

Edited by paulscottrobson
amend
Link to comment
Share on other sites

6 minutes ago, paulscottrobson said:

Oh, that's pretty much what it does. It just detokenises the tokenised code 🙂

The other problem is if you store it in dual format you effectively halve the RAM, and there isn't that much of it unless you stick it in banked memory.

 

Understood about detokenizing the tokenized code. That's how v2 BASIC already handles it. Also understood about reducing the amount of RAM, just contemplating ways to give people more efficient BASIC (or some other interpreted language) that is comfortable for people who don't have the desire or mindset to go assembly. It could only work with the idea of multiple banks of RAM (or with very simple programs that don't require much space).

Link to comment
Share on other sites

48 minutes ago, paulscottrobson said:

The other problem is if you store it in dual format you effectively halve the RAM, and there isn't that much of it unless you stick it in banked memory.

Though if it is stored in dual format "for editing and listing", the "for editing and listing" form can be stored on disk, since the SD card is not a bottleneck for any human-paced text mode activity along those lines.

Link to comment
Share on other sites

5 hours ago, BruceMcF said:

Though if it is stored in dual format "for editing and listing", the "for editing and listing" form can be stored on disk, since the SD card is not a bottleneck for any human-paced text mode activity along those lines.

Good idea 🙂 Mind you, I suppose that's getting close to a compiler again.

Link to comment
Share on other sites

5 hours ago, Scott Robison said:

Understood about detokenizing the tokenized code. That's how v2 BASIC already handles it. Also understood about reducing the amount of RAM, just contemplating ways to give people more efficient BASIC (or some other interpreted language) that is comfortable for people who don't have the desire or mindset to go assembly. It could only work with the idea of multiple banks of RAM (or with very simple programs that don't require much space).

I know what you mean. I've been contemplating this for a while myself, and I've concluded it's not actually possible - unless you don't have very much moving.  Pacman is probably about as far as  you can go - half a dozen active screen objects that move about.

Link to comment
Share on other sites

6 hours ago, paulscottrobson said:

Good idea 🙂 Mind you, I suppose that's getting close to a compiler again.

Yes, but if the edit of a line then results in the corresponding change to the interpreted runtime, it feels like its an interpreter. All the little clock driven automatic routines, to run the ADSR or to increment the position of a sprite along its commanded trajectory or whatever, are in an $A000-$BFFF segment, since when the currently visible part of the interpreter script is sitting in the $A000-$BFFF segment being edited and then scanned to generate the changes to the interpreted runtime, at that time those little clock driven automatic routines are not in use.

And perhaps it's not just the script, perhaps there things that don't need to be tracked when an optimizing intepreted runtime is ready to go that can make the editing and then fresh run more responsive. For instance, an optimizing Basic-like interpreted runtime can have pointers to the targets of GOTO that are initialized as NUL and the keyword proceeds to read the line number or label and then scan for the target ... but it then stores the address when it finds it, and the next GOTO doesn't have to read the line number / label. Re-initializing the ones to zero that are pointing to a line number / label after the first modified location is a lot faster if you keep a list of where they are ... but that list doesn't have to be in the interpreted runtime.

And of course, if variables are just referred to in the runtime as a 16bit index to the number of unique variable references that have been made, the variable names can reside in a data structure outside of the interpreted runtime.

Edited by BruceMcF
Link to comment
Share on other sites

  • 2 months later...
Posted (edited)

Going in the other direction, a couple utils I've seen here on this forum could take us in the better direction of Assembler For The Masses.

In short, Assembler with enough oomf or macro-goodness that you won't need anything else directly on the X16.

Thus, BASIC becomes the batch/boot language.

* * *

I think that may be why I was idly thinking about an AWK-like language for the X16.  Something that did things that just aren't done in a typical 3GL.  Presumably, for the purpose of file system management, but.... well is it worth bothering with on an 8 bit platform?

 

Edited by rje
  • Like 1
Link to comment
Share on other sites

On 2/10/2021 at 8:52 AM, paulscottrobson said:

almost no program structures , no long identifier names, no local variables.

Some other significant issues: BASIC is a dead end these days. Learning it doesn't give you any skills you can use elsewhere. But most of all: BASIC doesn't have functions (the way we're used to in modern languages).

Let me give you an example. I got a mechanical keyboard with replaceable switches some time ago, and that led me to write several keyboard testing tools, such as this web-based one. (I had a hard time writing one for the Amiga because unbuffered keyboard input in standard C was hard.) I also wrote one for the X16 using the emulator: kbdtest.prg

A big problem here was setting the cursor position. There is actually a KERNAL API interface for this, so you can just do:

9010 POKE781,VE:POKE782,HO:POKE783,0:SYS65520:RETURN

And then HO=10:VE=8:GOSUB9010 as needed.

It would have been so much better if I could have just created a function for this.

My takeaway: BASIC is just too limited, and has ended up being a dead end in the evolution of programming languages. So I'd rather do something like defining a subset of Python that provides the basic BASIC functionality, but in a more modern way, where someone who learned the Python subset has a head start learning "real" Python.

Link to comment
Share on other sites

1 hour ago, iljitsch said:

Some other significant issues: BASIC is a dead end these days. Learning it doesn't give you any skills you can use elsewhere. But most of all: BASIC doesn't have functions (the way we're used to in modern languages).

I believe you mean Microsoft 6502 V2 Basic doesn't have functions. QBasic had functions while the C64 was still on the market.

Link to comment
Share on other sites

14 minutes ago, BruceMcF said:

I believe you mean Microsoft 6502 V2 Basic doesn't have functions. QBasic had functions while the C64 was still on the market.

Yeah, MS-based 6502 BASICs of the time were limited. Not a limitation of the CPU, BBC Basic also had procedures and function (and built-in assembler) on the 6502 BBC Micro. 

Link to comment
Share on other sites

I may be in the minority, but Commodore BASIC v2 is responsible for getting me started! Sure, there are a lot of things missing WRT modern languages, but I firmly believe that learning any language is a useful exercise to get one to begin thinking in a programmer mindset. And the more languages you learn, the better off you are because you being to contemplate programming in the abstract (input, output, variables, conditionals, control structures) instead of the concrete (INPUT, PRINT, A$, IF X=Y THEN ...).

I know there are plenty of people who believe "avoid these toy languages because you'll learn bad habits" or other similar arguments. For learning the basics (pun not intended but apropos) of how to write a program to tell a computer what to do, BASIC is great.

Not every language must lead directly to a six figure income.

Then of course there is assembly / machine language. Talk about a language without modern first class features like functions! 🙂

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use