This is the first in a series of articles on building a programming language called Wee and its tooling. Wee is an educational prgramming tool for beginners, bridging the gap between (visual) learning tools like Scratch, and professional environments like Java, Python, or C. You can learn more about my motivations on my old blog.
Almost exactly two years ago, I've played with the thought of creating a programming learning environment. As usual, life finds a way to interfer with your plans; the project was mostly gestating in my head. Time to change that.
A lot of research is available on how to teach programming (see the blog post above). However, having performed user studies in related areas myself, I feel that the causes and effects within a learning environment are not entirely scientifically quantifiable. What I do know is how I learned to program. And a lot of my peers seem to have very similar stories.
I thus work under the following (shaky) assumptions: by analyzing my own history, I can identify key elements that let me successfully learn how to program. Since my peers share similar stories, the key elements I find might be applicable not only to myself, but to a larger group of people.
It's not my plan to ignore the literature. But I want to augment it with my own experience.
I'd been saving up for a 486 DX 2 with 40Mhz, 8MB of RAM and a whopping 50MB HDD. As a dumb 10 year old on the country side, and without anything like the internet, I had no way of knowing the real cost of a PC. That my measly savings would only afford me a pocket calculator was not obvious to me. My parents saved up as well. In secret. Every week I'd ask mum if I'd saved enough. After two years of this Spiel, mum and dad solemnly announced "it is time!", strapped me into the car, and took me to the (now defunct) computer retailer Vobis in the big city. My parents let me put the money on the counter. I completed my first big transaction at the big boy age of 12.
That was in 1995. Years later I realized that my parents had ponied up about 99.99% of the asking price. That explained our somewhat rustic, short, annual vaccation. It also shed some light on why dad was coming home late at times: he'd earn some extra cash fixing cars and doing construction work after his regular job. The damn machine cost my mum and dad a considerable amount of their annual income. I can't express in words how much this meant and will forever mean to me.
So there I was, machine plugged in, display and keyboard connected. What to do? Play games of course! Naturally, I couldn't afford to buy games. A relative of mine had connections to a super secret underground channel that'd copy floppies for the cost of a lollipop. I had a lot of floppies. With labels in terrible hand-writing, reading "Prince of Persia", "DOOM", "Dune II", or "Monkey Island".
Getting games to work in MS-DOS was often hard work (shout-out to my peeps growing up with 80ies equipment. I know you had it rougher. No, I'm not getting off your lawn).
AUTOEXEC.BAT had to be infused with magic spells to go beyond 640kB of RAM. Crashes, and more annoyingly, unending hangs with super loud beeps were a daily occurance. The machine came with a manual for MS-DOS from which I could piece together the basics. My uncle would show me some tricks of the trade and provide me with aforementioned magic spells.
Within a year, I was able to afford a mouse and a double speed CD-ROM drive. Installing that CD-ROM drive was one of the most terrifying experiences in my life. The prospect of seeing this expensive machine go up in flames paralyzed me. And had I known of my parents' sacrifices, I would have been even more scared to death. It took me a week to take the drive out of its anti-static wrapper. I'd touch the radiator, touch the drive, then put it back in. Eventually, my dad got fed up. "Son, if you don't put it in there, I'm going to put it in there. Do you want a car mechanic to handle your computer?". Under tears (not kidding), I got myself a screw driver and went to work. I'm happy to report that everything went better than expected. Otherwise, you might not be reading these lines. Thanks, dad!
Unconciously, I learned how to use a PC. Not because I wanted to become a programmer, but so I could play all those amazing games.
This first year of owning a PC opened up a seemingly infinite amount of new worlds to me. PC games were fantastic in their diversity and quality. And sometimes they even managed to convey a great story. You had jaw droppers like DOOM and Duke Nuke 'Em, that'd punch you right in the face, story be damned. You had zen-like experiences with Myst or Lost Eden. The absurd humor of Day of the Tentacle or Sam and Max would give you mad giggles. Privateer would let you explore the galaxy on your own terms, and Master of Orion had you burn it all down. Slowly but surely, two questions formed in my punny brain: How did they do this? How can I do this?
Coincidentially, my school got their first PCs and (limited) internet access. There were quite a few sites dedicated to game programming, but everything was in English. Back then, that was to much of a language barrier for me. I had to find the answers to my questions elsewhere. Small aside: this was the beginning of me switching from consuming German media to consuming mostly English media. Again, not because I had an interest in the language or using it abroad, but because it was the only path way to learning how to write my own games.
Serendipitously, as internet "searches" were back then, I ended up on a site archiving listings of games written in various BASIC dialects. The listings were collected and digitized from computer magazines I could not buy in Austria. There wasn't much in the way of an explanation what it all meant, but it did include instructions on how to run the games. One such set of instructions explained that the game could be run with a program called QBasic that was included with MS-DOS 6.22. That's what I ran at home! I copied all listings for QBasic onto a floppy, and waited for the school day to end.
Back home, I booted my machine, copied the contents of the floppy to the HDD, and began searching for this mysterious
QBASIC.EXE the instructions mentioned. And so it began.
C:\GAMES\QBASIC.EXE /RUN NIBBLES.BAS
Running this magic spell resulted in instant gratification. The command would fire up the game Nibbles, an early variant of the game "Snake", which we all enjoyed on our Nokia phones.
Once I killed off enough Sammies, I hit
CTRL + BREAK, as pointed out by the listing instructions, and ended up in one of the most iconic programming tools of the nineties: QBasic.
The programm felt immediately familar. The
Edit menu items, as well as the editing area and scrollbars were the same as in
EDIT.EXE, the text editor I used to modify
CONFIG.SYS. Other portions of the program were more mysterious.
Microsoft was kind enough to give me some initial hints right there on the first screen.
SHIFT + F5 to restart the game.
F1 to show information about any keyword my cursor is on. The same information and more was repeated in the bottom bar. That bar would change depending on the context. A great on-boarding experience.
Scrolling through the source code, I was surprised that everything was extremely descriptive. It gave me the impression that this is something I can learn with some practice. What I'd later understand to be variable names, were words that I could immediately associated with aspects of the game I just played.
DO PlayNibbles NumPlayers, speed, diff$ LOOP WHILE StillWantsToPlay
NumPlayers I knew form the title screen of the game, that asked me to enter a number. The same for
diff$ didn't make sense. But
StillWantsToPlay in combination with
DO LOOP WHILE sort of made sense (after consulting a dictionary to look up 'loop' and other words).
Of course nothing really made sense at this point. I did as Microsoft told me, moved my cursor on top of
LOOP, and pressed
QBasic came with a full-blown contextual help system. Every keyword and command from the standard library had its own help page. The help pages included examples and were worded in a very beginner friendly way. When viewing the help for a token, QBasic also didn't just throw you into a separate full-screen. Instead, it kept the editor on screen, which meant there was no context switching.
All the examples given on the help pages where tiny, self-contained little programms, that you could just copy and paste into a blank
.BAS file, run, and fiddle with.
I remember wasting 2 nights just playing around with
LINE, then discovering
CIRCLE and friends. The simplicity of both the examples and the lack of ceremony to get them running, made for fast and instantly rewarding exploration.
What the integrated help system did not come with, was a beginner's guide. Luckily, the listings I downloaded earlier contained a tutorial series of small QBasic programms that iteratively introduced you to basic programming concepts, like variables, data types, control flow and finally procedures. I wished I still had the source code. Instead of an accompanying website, the tutorial text was part of the source code. Some comments would ask you to modify the line following them. Later parts of the tutorial would be incomplete, forcing you to apply what you've learned to solve small challenges. Speaking of challenges: the comments were of course in English. My German-English dictionary became my best friend, but could not help me with deciphering grammar constructs I did not encounter before.
Due to the PC experience I accumulated up until this point, I already was a somewhat proficient keyboard user. Still, syntax errors were a common occurance. QBasic's syntax was line-based. Every time you hit
ENTER, the line you just completed would be checked by the parser, and you would get immediate feedback on any syntax errors.
With more knowledge came bigger programs. And with bigger programs came the first bugs that were hard to reason about just by looking at the code. QBasic came with a capable debugger that would let you set breakpoints and evaluate expressions when the program was paused. QBasic's big brother QuickBasic additionally let you create up to 8 watchpoints consiting of arbitrary expressions. It even let you set conditional breakpoints. You could also modify the running program. All of that was packaged up in the simplest possible UI. The following video shows QuickBasic instead of QBasic.
Another crucial aspect of creating bigger and bigger programs: code navigation. QBasic had an interesting solution to this. A single
.BAS file constituted a module. All code outside of a procedure was module level code. When opening a
.BAS file, QBasic would only show the module level code. Procedures were shown on their own screen. QBasic also had some rudimentary search and refactoring functionality in form of text replacement.
Six months after opening QBasic for the first time, I became proficient enough to write little text adventures and simple graphical games. Any time a friend came over to my place, I'd proudly show off my creations. My friends were somewhat hard to impress though. They were used to higher quality on their GameBoy, SNES and other gaming devices. Why would they not see the brilliance of my little oeuvres?
I also couldn't convince any of them to learn programming. Only one of my friends had a PC, but he rather spent his time playing games. And while I offered everyone else to come to my place to learn, the prospect of spending time in front of a computer, and typing what must have seemed like hyroglyphs, didn't appeal to anyone. I felt alone. Worse, I hit somewhat of a knowledge ceiling.
Programming is not an inherently social activity. Yet, I was longing to share my thoughts and work with like minded people. At the end of 1997, aged 14, my parents granted me another long time wish: my first guitar. It was the cheapest spanish concert guitar money could buy, but it was mine! My parents already spent money on recorder lessons for my sister. Our deal was that they'd buy me a guitar, on the condition that I had to learn playing it without taking lessons. Challenge accepted.
My circle of friends had some older peers in it who already were proficient guitar players, and were happy to mentor me. I finally had people to hang out with, learn from, and share my work with. Something programming couldn't offer me. I would occasionally write the odd little program, but my focus shifted almost entirely towards music.
This changed when I entered 5th grade at the gymnasium I went to (somewhat like high school, but you stay around until you are 18). We had to choose electives that semester. I signed up for computer science. Which turnd out to be about Microsoft Office. I told my teacher I already knew all about Office (I didn't), and that instead of having to suffer through the regular lectures, it would be lovely if I could use the time to browse the internet for some programming information. I was lucky, my teacher was amazing.
She asked me to bring some of my programs to proof that I actually knew how to code. Excited, I copied my best creations (a star field simulator and a graphical text adventure) to a floppy and showed it to her before the next lecture. She was blown away and allowed me to essentially skip her class, and do whatever I wanted. In addition, she'd give me a key to the IT lab, so I could use the computers whenever I had down time at school. Jackpot.
Invigorated, I hit this new site called AltaVista I heard about. A big improvement on the old site directories I used to frequent! My head exploded when the first search result for "qbasic games" showed a seemingly unending list of websites and forums, chock-full with source code, programming tips, and most importantly, people.
jar xzf 3dLibQB.zip.
Feeling proficient enough with my English skills, I signed up to what appeared to be the biggest of all the forums, qb45.com. (This is a partial copy of the old site, sadly both the download section and the forums do not contain much stuff from that time anymore). I also submitted my best code for others to enjoy and dissect.
I had finally found a place of like-minded people and a swath of new information that let me break through my knowledge ceiling. Sharing and getting feedback on code was a fantastic way to improve and learn new concepts. After a while, I started helping others on the forum, which in turn helped me to better organize my own thoughts. I also had the good fortune of becoming friends with insanely talented individuals like Ali Mosavian, and Andre Victor (who would later create FreeBASIC). Ali introduced me to the wonderful world of assembly programming, an entirely new pandora's box to keep me up at night.
The internet community surrounding QBasic and MS-DOS game programming was thriving at the end of the 90ies. There was a seemingly unending influx of newcomers, thirsty to join the ranks of the old guard. And the old guard, even those that were now working with different technologies for their new projects, still stuck around to show beginners around. People were encouraged to write about their findings, which lead to an immense archive of knowledge. You can still find a lot of these articles on Phat Code.
In 2003, I started my brief university career, exposing me to a new set of ideas, including functional programming, compiler engineering and more theoretical aspects of computing. I wasn't fully formed as a programmer yet, but my exposure to a lot of low-level aspects of computing, forced on me by the sluggishness of QBasic, as well as working on mid-sized projects, gave me a great foundation to work from. While I moved on to new things and technologies, I stuck around the community in some form or another until 2006, the year I got my first job. The community somewhat dispersed, or found a new home in FreeBASIC.
I was extremely lucky to live through my formative years at the end of the 90ies. But I was even luckier to have all these supportive people in my life, from my loving parents, to my teacher and even random strangers on the internet, that ended up becoming friends for life. I hope I can pay it back in kind.
Avid readers may have already noticed the underlines in this essay. In the next installement, I'll try to distill my findings above into a set of key elements Wee should incorporate. I'll also take a closer look at QBasic the language, which has some surprising properties. No, I am not talking about
GOTO. I have already harassed Michael with my language design for Wee and hope to be able to share it soon as well.
Until then, I'm happy to hear about your nostalgic stories or any feedback you have! Send your thoughts through Twitter.
p.s.: As a non-native speaker that generally has a hard time with grammar in any language, I really appreciate pull requests.