The p5.js reference pages are bad
Analyze the fundamental flaw with p5's documentation. Learn why q5.js is better for beginners and CS educators.
(this article was originally published on Medium on December 1st, 2024)
Check out the new q5.js documentation pages!
The p5.js reference pages are bad…
… and not merely due to the garish color theming, empty pages, and sloppy formatting errors introduced in the recent website redesign.
They’ve always been bad.
Wait! Let me explain! 😅
Don’t get me wrong, I appreciate all the work that’s been done by p5's contributors over the years. Yet there’s a fundamental flaw with the documentation, and only I would have the audacity to fix it.
Can you tell what the big issue is just by reading this excerpt from the reference page for `draw`?
This is often called the “draw loop” because p5.js calls the code in draw() in a loop behind the scenes. By default, draw() tries to run 60 times per second. The actual rate depends on many factors. The drawing rate, called the “frame rate”, can be controlled by calling frameRate(). The number of times draw() has run is stored in the system variable frameCount().
Code placed within draw() begins looping after setup() runs. draw() will run until the user closes the sketch. draw() can be stopped by calling the noLoop() function. draw() can be resumed by calling the loop() function.
There are some minor mistakes here. Saying that draw()
, the function, tries to run 60 times per second is odd phrasing. Also frameCount
is not a function. But the big problem is… the whole excerpt is boring, lengthy exposition!
Surely there’s a better way for us Computer Science educators to present this info to beginners.
“Show don’t tell” is the golden rule of writing. So why not show readers what all these related functions do? Because each function has its own separate reference page… oof.
(Perhaps this choice was made due to perceived technical limitations, computers can’t handle running too many p5 sketches on one page. Although, that issue can be solved by pausing the draw loop of sketches that go offscreen, which is what I’ve done in q5.js, but I digress.)
p5 doc writers constantly trip themselves up, making variably false generalizations. Then editors transplant nuance and divulge every possible caveat to those previous statements.
If a page starts with “The sun shines on the earth”, it then goes on to say, “Except not as much when it’s cloudy, night time, or during a solar eclipse.” Woah woah woah, I just wanted to know what the sun does. How about we start with, “The sun shines”. Then if users want to learn about Earth’s climate and celestial events they can scroll down to that info.
I don’t remember it being like this when I was learning Java Processing as a kid. Yet, looking at the wayback machine, it seems the p5 documentation has always been this way.
Flaws with the single page per function mindset extend to code examples as well. Just look at this p5.js example for redraw
.
// Double-click the canvas to move the circle.
let x = 0;
function setup() {
createCanvas(100, 100);
// Turn off the draw loop.
noLoop();
describe(
'A white half-circle on the left edge of a gray square. The circle moves a little to the right when the user double-clicks.'
);
}
function draw() {
background(200);
// Draw the circle.
circle(x, 50, 20);
// Increment x.
x += 5;
}
// Run the draw loop when the user double-clicks.
function doubleClicked() {
redraw();
}
Notice how there’s five comments verbosely explaining what functions other than redraw
do. Imagine if you looked in a dictionary and each word had recursive definitions for all the words included in the definition!
With the mini code editors on the q5 Learn pages, users can hover over a function to see its documentation (big thanks to @Tezumie). What value then would comments like “Turn off the draw loop.” and “Draw a circle.” provide? Each example doesn’t need to be a stand-alone demo.
If you’d indulge me, subject yourself to all these p5.js reference pages on core functions:
Redundancy to this extent makes it harder to gain pertinent information. Who wants to read through all this? Do the p5.js Contributor Guidelines include a minimum word count requirement for these pages? I’m not just cherrypicking either.
Complaining to The Processing Foundation staff (they already loathe me for that) and begging for a complete rewrite of the documentation was not going to pan out. It took five months just for one of my PRs to be included in a release of p5.js!
But as Captain Jack Sparrow said, “It’ll all have to be redone. All of it! I have no sympathy for any of you feculent maggots and no more patience to pretend otherwise. Gentlemen, I wash my hands of this weirdness.”
Yes, I realize this idea sounds insane. How could I expect to do better than the combined efforts of hundreds of p5 contributors? By working smarter, not harder.
Mark Twain once wrote, “Sorry I didn’t have time to write a short letter”. Writing is an art! Concise writing takes a lot of effort and planning.
So my big plan for q5’s documentation was to group documentation for related functions into scrollable sections. Each function definition and code example can therefore be written as part of a sequence.
Here are the strategies I used when writing the code examples in q5.d.ts.
keep ’em short and sweet (9 lines or less)
avoid defining a
setup
function, usecreateCanvas
to start the sketch or only write adraw
functionavoid declaring and using variables
don’t add comments explaining other functions (users can hover for documentation)
use comments in the code only when necessary, don’t use the
describe
function in the code, all explanation should be given in the JSDocrequire only the simplest user interactions (moving the mouse, pressing left mouse button, or pressing the space key)
Here’s my q5 example code for redraw
, it retains the essence of the p5 example, but cuts it from 29 lines to just 8.
function draw() {
circle(frameCount * 5, 50, 20);
noLoop();
}
function mouseClicked() {
redraw();
}
Alright, had enough yapping? Check out the “core section” of q5’s documentation!
Note how the descriptions are not overly broad, to avoid pesky false generalizations. For example the description for draw
simply states “The draw function is run 60 times per second by default.” Putting “by default” makes it so I don’t have to account for any exceptions. If users want to change the default behavior, they’re inclined to read more: and that’s actually a good thing! Related functions are just a small scroll away.
q5’s core section documentation combines all the most pertinent info, strewn across a dozen separate pages in the p5 docs, and presents it in a more appealing, carefully worded, and dense form factor. It has code examples that act as simple visual aids and also interactive examples that get users to learn by doing.
Best part is: I’m making this resource 100% free!
Will you start using q5.js to teach Computer Science? What do you think of my approach to writing the documentation? If you like it please spread the word to other teachers!
Thanks for reading!
I agree that the p5.js website as well as documentation could be improved. But why not contribute to the original project instead of forking it?
When will you have FFT analysis in Q5?