![]() |
Forum Index : Microcontroller and PC projects : OOP (object oriented programming) in MMBASIC (kind of)
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
Yes, Fixed length records for RANDOM files are a typical use-case. Another use case would be a struct that combines the label (as a string), the numeric value, and the unit (as a string) of a measured value, which is then passed to a Subs for "drawing" GUI elements ("Forms"). It would be optimal to store the struct's data internally as a fixed-size "BLOB," as is done in C/C++. In this case, PEEK(VARADDR structVar) should return the address of the BLOB. One would have to live with the restriction that string members in the struct would then have a fixed size — or, if a pointer type were introduced, then a pointer to a variable-size string would be allowed. Greetings, bfwolf |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
Or, of course, you could program in C/C++ instead of spending many programming hours adding stuff to MMBasic that only 1% of users will ever touch. :) Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
Sure, you could program the Pi-Pico(2) in C/C++ – like with the Arduino framework, for example – but that wouldn't have the charm and advantages of an interpreter – like being able to simply abort a program with Ctrl-C and view variables and quickly modify the code if necessary. ![]() Also: Of course, MMBasic on the Pico is already really great – especially with its convenient support for hardware such as displays and sensors – but what's wrong with making a good thing even better? ![]() bfwolf |
||||
PeteCotton![]() Guru ![]() Joined: 13/08/2020 Location: CanadaPosts: 527 |
Wait... what? I didn't know we could use '.' characters in variable names! That presents a very easy solution that doesn't require any changes to MMBasic. DIM INTEGER Ship.Id(100), Ship.X(100),Ship.Y(100) DIM STRING Ship.Name$(100) And then when we want to use a value we just go with FOR T = 1 TO 100 IF Ship.X(T)<100 AND Ship.Y(T)< 100 THEN PRINT "In play area" NEXT Not quite as neat as having a struct, but pretty close. I'm going to change my Trek game to use this format. Edited 2025-03-24 05:53 by PeteCotton |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
DIM INTEGER Ship.Id(100), Ship.X(100),Ship.Y(100) DIM STRING Ship.Name$(100) FOR T = 1 TO 100 IF Ship.X(T)<100 AND Ship.Y(T)< 100 THEN PRINT "In play area" NEXT Yes - this appears "similar" but doesn't have the advantage of the informations belonging together being combined to a "bundle" and can be passed as a single expression to subs and functions. Also it requires extra effort to e.g. write them to RANDOM access type files etc. It's a less ugly "würgaround".. ![]() |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
But this is a BASIC interpreter, not a compiler. It's running on a pretty small microcontroller. If everything that people thought was a good idea had been followed up from the beginning then the project would never have got off the ground. The fact that structures can even be simulated is pretty much a miracle. I know they are used in C/C++ all the time, but that's partly because C/C++ isn't a high level language and they are necessary to some extent. I know Visual Basic supports them, but that isn't known for being a compact interpreter. ;) Please don't consider turning MMBasic into some sort of bastardized C. That is already a language of its own and there's no need to produce a second cousin that no-one will look at because it's so slow and they may as well learn C. Python has already gone that way. As far as users go, if there was a choice between incorporating structures or a new graphics mode I suspect that 90% would choose the latter - and it would get used. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
toml_12953 Guru ![]() Joined: 13/02/2015 Location: United StatesPosts: 390 |
But you still lack the ability to treat the entire structure as a record. For example to write a list of students and their data to a random file, instead of using field statements, you can do this: TYPE Student Name AS STRING * 30 DOB AS STRING * 8 Address AS STRING * 50 City AS STRING * 20 END TYPE NumStudents = 200 DIM StudentRecord(NumStudents) AS Student FOR I=1 TO NumStudents READ StudentRecord(I).Name,StudentRecord(I).DOB,StudentRecord(I).Address,StudentRecord(I).City NEXT I OPEN "StudentFile" AS #1 FOR RANDOM FOR I=1 TO NumStudents PUT #I, StudentRecord(I) NEXT I ' DATA LINES FOLLOW FOR EACH STUDENT DATA "JONES, JOHN", 12/17/86, 4 WALLOBY WAY, PARIS : : : |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
It appears, you are hard to convince.. ![]() Don't know your age, but do you know, about what we are talking, when we have a RP2040 or RP2350? ![]() ![]() An example for a "pretty small microcontroller" may be an ATMEGA or MSP430 or Cortex-M micro clocked at 16MHz having few kB of RAM.. ![]() bfwolf |
||||
PeteCotton![]() Guru ![]() Joined: 13/08/2020 Location: CanadaPosts: 527 |
While I agree 100% with this comment - I don't think structs are the gateway drug into OOP. BBC Basic - widely regarded as one of the best BASIC implementations of the 80's, had structs. Having said that, I think the workaround we have come up with works well, and I for one am happy with things staying just as they are. MMBasic is already insanely powerful compared to the 80's Basics. I think it can rest on it's laurels. I get that it's not the same as passing them into Subroutines etc., but I define those sort of variables globally anyway, so at best your just passing an integer index into subroutines and functions. |
||||
Amnesie Guru ![]() Joined: 30/06/2020 Location: GermanyPosts: 529 |
Wow! There are a lot of ideas from you.I've hoped that this question bring up one or two ideas, instead it brought up a lot of ideas! Thank you for this inspiration. Volhout, I will try this! Currently I am on a business travel... so this has to wait a bit. But yes , I don't want a full blown OOP, but I think the scruct idea is nice. Greetings Daniel |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10064 |
There are various tricks that would allow things of the sort DefineType mytype integer x(4) y(2,2) s As string newvar% End DefineType Type mytype atype(4),btype print atype(2).y(1,1),btype.new But this is a different order of magnitude to passing structures to a function or things like print #1,btype IMHO you are never going to see the latter. Certainly I'm not going to do it and as Tom says the impact of trying would likely be to de-stabilise MMbasic for an extended period. MMBasic is a robust environment for playing and lots of real-world applications. Trying to make it something it isn't is almost certainly counterproductive. Go program in Rust or whatever other language is the current fashion if you want to be "modern" but bastardizing MMBasic isn't likely a happy process However, the PicoMite source is freely available so if you want to have a go...... I don't know when structures appeared in BBC Basic. Was it ever on real H/W, if so what, or only on BBC Basic for Windows? Certainly,they aren't on the BBC B. |
||||
PeteCotton![]() Guru ![]() Joined: 13/08/2020 Location: CanadaPosts: 527 |
In fairness, after a quick google it looks like my memory has failed me. I might be getting confused with Pascal. Senility is creeping on me it seems ![]() |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
The concept of "structures" wasn't present in C at first - it's older and was already part of PASCAL from 1970, where structures were named "RECORD"s. Even unions (as named in C) were present in PASCAL, where they just were "variant records". Structures are in fact a "high level" concept of data processing! And PASCAL was really a well designed high level programming language with a "runtime system" that trapped most errors. Most implementations of PASCAL were compilers - a lot of them compiled for a virtual machine to be interpreted - but there existed (and still exist) completely interpreted implementations. https://en.wikipedia.org/wiki/Pascal_(programming_language) The later follower designed by N. Wirth, Modula2, was even better - looked like PASCAL, but was even more clean and allowed access to "low level things" and breaking large programs up to beautiful understandable modules. Modula2 was able to completely replace C. Modula2 was always a compiler to machine code - AFAIK.. https://en.wikipedia.org/wiki/Modula-2 I'm really NO Mcrosoft fan, just to say ![]() Type mytype integer x(4) y(2,2) s As string newvar% End Type DIM atype(4) As mytype, btype As mytype print atype(2).y(1,1), btype.newvar% would be "more understandable".. Let UDTs just trat as "ordinary types".. ![]() But as told before - let us play with ideas perhaps for a future version 7.x of MMBasic.. ![]() bfwolf |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3998 |
Pretty much anything could be added. With serious re-writing. Inevitably using more memory (ROM & RAM) and slower. I like OOP, I've always liked structures. I don't fancy the re-write, the larger memory wastage, the slowness. Would a garbage collector be more or less forced to be added? (Not trivial if close to real-time is still wanted.) But... if someone makes the changes, great, I can use the larger memory & faster chips. Not so great for those who really don't want to or for some reason can't do that, e.g. need small, fast, low power/sleep. The workarounds are "good enough" for me :) John |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7499 |
I would like to volunteer bfwolf and PeteCotton to write MMPascal. ;) As many on here will know, I'm no fan of C/C++. :) I program in BASIC because *it isn't* C/C++. If I wanted those I'd be using Arduino, not PicoMite. If I wanted Python (which I have used a little) I'd probably be using a Raspberry Pi (although I've also tried it on the Pico). I came across Pascal on the Nascom many years ago. I tried that and hated it from day one as it was so foreign to my way of thinking. :) I actually found Z80 assembler easier... I never tried Modula2 as I didn't have anything to try it on at the time. My Nascom hardware was too underpowered for something like that without a lot of expensive expansion. It was also very expensive IIRC (this would have been around 1979ish so it was pretty new. I still had a Nascom-1.). Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 3998 |
I'd defend Pascal as a pretty good teaching language. It's a bit of a pain to use for systems stuff but hey you can use anything if you put enough effort in - even FORTRAN. It wasn't aimed at what Picos etc are mainly used for, of course, and I for one would much rather have MMBasic than Pascal on a Pico. (I'd rather have python than Pascal for that matter.) If I wanted to do things even closer to the hardware I'd use C (not C++). (Or with MMBasic a CSUB.) Choice of language is quite a personal issue... In terms of changes to MMBasic, changing it to have a tiny OS layer would be great but it's "good enough" now, and good enough wins a lot. John |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Honestly I don't see struct support significantly adding to the size of MMBasic and a performance impact of only 1-3%, so probably irrelevant on the RP2350 and even more so on any likely successor, assuming someone is still porting MMBasic at that point. C manages without and TBH I wasn't contemplating adding dynamic creation of structs, only creating them as global or local variables and passing them (by reference) to functions. If they were allowed as returned value I rather assumed they would be copied into a variable in the caller, in as much as I had thought about it at all. I don't imagine Pascal would be "that difficult" if you could steal gratuitously from MMBasic's near-metal code. Not that I'm volunteering, or that I have any particular desire to work in Pascal, or any particular loathing for it either. I have two Modula-X stories: 1. They taught Modula-3 to us for my CompSci MSc presumably on the basis of levelling the playing field since no bu**er would have used it before (or after). I've never made use of it outside that course but the "manual" was very well written and I still have it on my shelf instead of in the "box of shame" mouldering in the atic. 2. When I started my first (and still only) job a significant proportion of the code-base was written in Modula-2 (because someone had persuaded the boss that it was the future ... and later persuaded him that CORBA was the future too). However the only Modula-2 compiler we had ran on exactly one SunOS machine (precursor to Solaris) and we didn't even sell on SunOS, so to create what we actually sold we transpiled it all into the worst C you've ever seen (almost incomprehensible due to the transpiler having to handle different calling conventions, some byref vs. byval issue I can not longer recall the details of). It was a happy day when we got shot of that legacy and replaced it with clean C/C++ ... we still haven't quite got rid of the last lingering stench of CORBA though. Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
bfwolf Regular Member ![]() Joined: 03/01/2025 Location: GermanyPosts: 72 |
What I really didn't like about Pascal back then were the annoying "BEGIN .. END" orgies. ![]() ![]() IF x>3 THEN BEGIN y := 5; z := x+1; END; WHILE val < 100 DO BEGIN val := val + 1; draw(val); END; N. Wirth probably realized this too and then abolished it in Modula-2. ![]() IF x>3 THEN y := 5; z := x+1; END; WHILE val < 100 DO val := val + 1; draw(val); END; The only "BEGIN" that survived in Modula-2 was the one, that leads the 1st instruction of any procedure or function after the declarations. Modula-2 was very popular on the Amiga and generated programs that lead to the dreaded "Guru Meditation Alerts" much less frequently than programs written in assembly or C. ![]() ![]() N. Wirth was appointed to the Ada Consortium at the time, which was tasked with defining the "safe programming language" Ada fore "safety critical systems". After failing to agree on anything practical within about 10 years, he left the consortium in frustration and returned to ETH Zurich. In just a few weeks, he defined the Modula-2 language himself, which implemented the important aspects of Ada, and shortly thereafter published a working compiler. ![]() @Mixtel90: Nascom-1 did run CP/M, true? ![]() ![]() http://www.retroarchive.org/cpm/cdrom/CPM/TURBOM2/ http://www.retroarchive.org/cpm/lang/lang.htm And nowadays there exists "GNU M2".. https://www.nongnu.org/gm2/12/features.html "can be built as a cross compiler (for embedded microprocessors such as the AVR and the ARM)." Perhaps, one day if I'm bored and have plenty of spare time, I'll try it.. ![]() bfwolf |
||||
PeteCotton![]() Guru ![]() Joined: 13/08/2020 Location: CanadaPosts: 527 |
![]() I did always like Fortran though - very similar to BASIC. I'm not a fan either - and I use C a lot in work. It's good enough language for low level coding - but I've just never been hugely enthusiastic about it. I love C# - mainly because it takes all of the good bits of C and ignores the bad. They are very different beasts, and both have their place in the programming world - but give me C# over C any day. But C# comes with a tonne of baggage as well (different .Net versions, cross platform confusion, requiring an operating system etc.) - but it uses the unbelievable power of a modern desktop PC to hide all of it's short comings and just brute forces it's way to a solution. There's very little need for optimization. If I was being philosophical, C# (and all modern languages) are about getting results (i.e. writing products, games, phone apps) as quickly as possible. They do this well, but in doing so, they distance you from the actual computer hardware. MMbasic (on hardware) is a delight - because it's just you and the processor. No libraries, no operating system. If a loop takes 100ms today, it will take 100ms tomorrow - and you can tweak that loop and get it down to 50ms and feel a great sense of achievement. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10064 |
Strange that since it ran the London International Financial Futures exchange with 100s of thousand transactions a day hitting a relational database on a DEC Vax cluster. Most of my real programming was in Pascal in that environment |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |