13 days have elapsed since I announced the Slubberdegulion project, looking for volunteers to commit to using it. Halfway through the trial period, only 7 people have stepped forward to volunteer — and three of them are really volunteering money, not their willingness to use the tool. It therefore seems unlikely that the Slubberdegullion project will proceed.
It gets worse. Realizing the likelihood that Slubberdegullion would fail, I decided to move ahead with my own person version of Slubberdegullion and build this project.
But I ran into a number of problems, and the latest problem appears to be a killer. First, some background.
I’ve always been a lone wolf and have learned how to teach myself almost anything. I taught myself how to fix my motorcycle when I was in my late teens. I taught myself how to fix my Volkswagen in my twenties. I also taught myself how to build electronic circuits, including digital circuits using TTL chips. I taught myself how to program and how to build extension boards for my KIM-1 computer. I taught myself how to program the Commodore PET, then the Atari 800, and then the Macintosh through its long and complex evolution. I taught myself FORTRAN, 6502 assembly language, BASIC, Pascal, Forth, C, C++, Java, HTML, CCS, Java, XML, Javascript, and JSON.
But as time passed, I found it more and more difficult to learn new languages, and I have now figured out why I have had so much difficulty: programming languages have changed in fundamental ways.
I’m not talking about changes arising from the evolution of programming language design theory. Here are the stages of programming concepts that I have successfully navigated:
Simple procedural languages with GOTO statements: FORTRAN, BASIC, and Assembly
Procedural languages without GOTO: Pascal, Forth, and C
Object-oriented languages: C++ and Java
“21st century languages”: Javascript
Over the last forty years, there have been a number of forces that have dramatically changed programming:
Increasing Computer Power
During the first generation of personal computers with 8-bit machines, all output went to televisions, with a screen resolution of 320h by 192v. All through the 1980s, monitors grew larger and, by 1990, color was standard. The typical monitor size in the early 90s was 640h x 480v, for 307K pixels with 8 bits of color.
The increase in size made it practical to have multiple windows open on the monitor. During the 1980s, monitors were so small that most programs needed to take the entire screen space available, making the use of multiple windows rather clumsy. That and the limited RAM available in most computers (1 to 4 MB) kept user interfaces rather simple. But as computers gained bigger monitors, more RAM, and bigger hard drives in the 1990s, it became practical to keep multiple windows open, which greatly complicated the user interfaces and the programming requirements for them.
Cross-Platform Languages
All through the 1980s, the Mac, the PC, and Linux systems were independent of each other. A program written for one of these platforms could not work on any other. This required a slow and expensive procedure known as “porting”. Typically, this would be done under contract by an independent company. I wrote my programs on the Mac; many of them were then ported to the PC.
There were a number of attempts to solve this problem in the 1990s with programs that had Mac and PC versions that both ran a common graphical language so that a programmer could write one program that would work on both platforms. I experimented with one of these and was not impressed. The first genuine solution to this came with Java, a programming language created by Oracle. This company was big enough to create a full-featured language capable of running on all three platforms. It had its own graphical user interface system that closely mimicked the systems in Macintosh and Windows. Later, the graphical system of Java was expanded with a package called “Swing”.
At first Java was scorned because, as an interpreted language, it ran slowly. This was a temporary problem; as computers grew faster, the complaints about Java’s speed evaporated.
However, Java’s initial graphical system was criticized by many advanced programmers for being unable to handle complex displays. This led to the developed of the Swing package, which is what I used during the nearly two decades that I used Java.
Swing is a powerful disaster. I never fully understood it. I was able to write software using Swing that worked, but I always felt that I had been lucky. I read books about Swing. I consulted websites offering help on Swing. I was able to bumble through, but I never felt that I grasped the complexities of Swing.
JavaScript is another cross-platform language. It was designed to operate on the web; as such it has a number of features specifically designed for the web. While Java has been found to have a number of vulnerabilities to hackers, Javascript was designed from the ground up to be hacker-proof. Javascript displays can be built that automatically adjust to fit properly into any size screen.
Basic Javascript is easy to understand; I taught myself how to use the language in about a month. But…
Social Programming
The most important change, I believe, came from the transition from individual programmers to teams of programmers. Very roughly speaking, that transition took place between 1990 and 2000. Before then, most programs were written by individuals. Big programs might have programmers working together, but team coordination was difficult, leading to many problems and hordes of bugs. There were all manner of schemes and protocols for team management, but these efforts seemed to slow down progress to a snail’s pace.
During the 1990s, the pieces fell together and the software community developed social protocols for effective team cooperation. Crucial to this effort was the internet, which not only permitted rapid communication between team members, but also encouraged cooperation on a much grander scale than previously possible.
The most salient expression of this newfound cooperation was the “help site” — a website dedicated to helping programmers deal with difficult problems. A programmer in Austria might post a question and within 24 hours receive answers from all over the globe. The programming community developed a powerful ethic of mutual assistance. Indeed, this ethic operated at multiple scales. The global community was augmented by a local community of programmers within the same group, building, or company.
No longer did a programmer need to master every element of the technology; the software community became rather like the Borg Collective, with expertise distributed throughout the entire community, readily accessible to any individual. The Collective can handle far more complex programming languages by sharing information — and languages grew in complexity to take full advantage of that capability.
Expanding Requirements
Computers nowadays operate in a vastly more complex technical environment. A modern computer must be able to handle complex displays with more pixels, more colors, more windows, more complicated user interfaces, more animation, more complex sounds, and of course, networking. Computers nowadays must be able to handle the complex Internet protocols as well as WiFi and Bluetooth. It is all too easy for us to underestimate the immense capabilities of this technology. Of course, to be able utilize these capabilities, programming languages must themselves become more complex.
Libraries
Programming languages cannot handle every possible technical capability without becoming massive memory-hogging monstrosities. They therefore are now equipped with library systems. These systems are rather like the various brushes that one can attach to a vacuum cleaner. Put on one brush for cleaning a carpet; another for a smooth linoleum floor; a third for reaching into corners. In like fashion, libraries permit a lean programming language to gain additional capabilities as required. These libraries can be readily shared over the Internet. They can be modified as needed on sites like GitHub. The flexibility and power provided by libraries has greatly increased our ability to cope with expanding requirements.
But!
This is all wonderful stuff — but it comes at a price. In order to enjoy the full benefits of the new programming ecosystem, one must become part of that ecosystem, joining a broad collection of social networks, one for each specialty one must be competent in. GitHub, Quora, Stack Overflow, Free Code Camp, Big Moose Saloon — the web teems with such places. If you’re plugged into this ecosystem of technical information and regularly participate in the discussions, you can stay ahead of all the latest technological developments.
But if you’re NOT engaging in all this social-technical chatter, then you’re out of luck. Modern programming languages are designed with the assumption that programmers can always get help on the Internet.
That’s my problem. I have always been self-taught. My whole approach to learning has been “figure it out for yourself”. I have asked for and gotten help many times on the Internet, but of late the problems I encounter involve a complex web of concepts that I just can’t handle. My problems cannot be solved by somebody providing a few dozen lines of code.
Specific: how to save a file in JavaScript
The specific problem that has befuddled me is so simple and basic that I am aghast that it cannot be simply solved. I have a JavaScript program in which the user creates some data. I want to save that data in a file. This is one of the most fundamental tasks in programming. Most old programming languages required just three commands to save data. The typical code might look something like this (I’m using italics to illustrate terms specific to the task):
FSOPEN(filename, read/write/both). // the read/write/both term is a numeric code
FSWRITE(variable_name). // variable_name is usually an array or object
FSCLOSE(filename)
That’s all it took. But in JavaScript saving a file is a major undertaking involving a great deal of complexity. I have examined dozens of web pages showing how to do this. Here are just a few of the pages I found:
https://stackoverflow.com/questions/13405129/create-and-save-a-file-with-javascript
https://www.tutorialspoint.com/how-to-create-and-save-text-file-in-javascript
https://code.tutsplus.com/how-to-save-a-file-with-javascript--cms-41105t
https://www.geeksforgeeks.org/javascript-program-to-write-data-in-a-text-file/
Here’s one of the solutions from the first URL (I have stripped out some code irrelevant to my problem):
// Function to download data to a file
function download(data, filename, type) {
var file = new Blob([data], {type: type});
var a = document.createElement("a”), url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
This confuses the hell out of me. Why in the world must we create an HTML anchor in line 3? And what’s this second element (“url = …”) attached with a comma? I’ve never seen that syntax before. Does the line “a.click()” trigger a click event? The documentation I read about the anchor element does not seem to say that. And that “setTimeout” function appears to delete the URL to the file. But what actually saves the file? I don’t see anything in this code that saves the file.
I later found another page presenting a similar solution, but this one works; it’s from the second URL I list above (tutorialspoint.com)
function saveButtonClick() {
const encounterJSON = JSON.stringify(encounters);
const link = document.createElement("a”);
var textBlob = new Blob([encounterJSON], {type: 'text/plain'});
link.href = URL.createObjectURL(textBlob);
link.download = "storyworld.txt”;
link.click();
URL.revokeObjectURL(link.href);
}
I have no idea how this code works. But it works, which is good enough. Now I have to figure out how to load a file. More pain.
There’s a reason for this: it is imperative that hackers not be able to take over a user’s machine using JavaScript. Of course, programmers figured out how to save files in JavaScript, and if regular programmers have solved the problem, you can be sure that the hackers have solved it, too. The end result is like a car equipped with a security system requiring the user to roll down the passenger window, turn the steering wheel as far to the right as possible, and press hard on the brake before turning the ignition key in order to start the car. It’s just enough security to make the task a royal pain in the butt, but not enough to actually secure the car.