⭐ 🌚 Grayson’s Song:
Three Languages, One Night Sky
The same professionally documented animation — named constants, modular functions, and JSDoc comments — in JavaScript (p5.js), Java Processing, and Python Processing, side by side.
Seven Concepts at Work in Every Version
The Processing vocabulary is the same in all three languages. What changes is how each language handles constants, state, transforms, and function scope.
Every magic number is replaced by a named constant. How each language declares an immutable value differs: JS uses const, Java requires final type, and Python uses UPPER_CASE by convention only.
randomSeed(STAR_SEED) resets the generator each frame so star positions never change. Adding ndx to the sin() argument shifts each star to a unique phase — 400 independent twinkles from one formula.
colorMode(HSB, 360, 100, 100, 100) is identical in all three versions. Named constants like SKY_H = 235 make the color palette self-documenting and easy to change across any language.
A crescent is made without arcs: draw a full circle in moon color, then overlay a smaller circle in sky color offset to the right. The sky-colored circle erases part of the moon. The technique is identical in all three versions.
The central star uses translate, rotate, and scale simultaneously. JS uses push()/pop() to isolate the transforms. Java and Python Processing require pushMatrix()/popMatrix().
The custom star function alternates between outer and inner vertices at angles derived from dividing TWO_PI by n. -HALF_PI puts the first point at 12 o’clock. The math is identical in all three.
vertex(cos(a) * r2, sin(a) * r2)
Mutable state (moonX, starHue) is kept separate from constants. JS uses let. Java declares typed class-level variables. Python uses module-level variables and requires global inside functions that modify them.
All Three Versions, Side by Side
Yellow paper = JavaScript • Blue paper = Java • Green paper = Python. Each panel scrolls independently. Use the Copy button to copy clean source into your IDE.
What Changes Across the Three Versions
The core Processing vocabulary is identical in all three: background(), fill(), circle(), ellipse(), text(), rotate(), randomSeed(), random(), sin(), map(), TWO_PI, HALF_PI, and colorMode(HSB, 360, 100, 100, 100). Every constant name and every scene function name is the same in all three sketches.
The interesting language differences: JavaScript uses const for block-scoped immutable bindings; Java requires final type NAME with an explicit type for every constant; Python uses UPPER_CASE as a convention — the runtime does not enforce immutability. Java additionally requires a settings() method (Processing 3+) to call size() with named constants — setup() only accepts integer literals there. Python requires a global declaration for any module-level variable modified inside a function (moon_x, star_hue); JavaScript and Java handle this automatically. And Java’s draw_moon() modifies the class-level moonX float without any special declaration.
Push/pop: JavaScript uses push()/pop(); both Java and Python Processing require the older pushMatrix()/popMatrix(). The net effect is identical: the transform stack is saved before and restored after the central star’s translate/rotate/scale, so the moon, hills, and text are unaffected.
One sketch, three dialects. The named constants make the night sky the same in every classroom. • Chat Log documents the decisions that produced this comparison.