Hi! Blog post author here. I have heard the "Computer Graphics from Scratch" book before, but I haven't read it myself, so it would be quite hard for me to plagiarize it. I guess some similarities are expected when talking about a well-established topic.
It's true that it makes it more complicated on the GPU side in general, but specifically in this scenario everything works out just fine, mostly because all updates effectively ping-pong between flow & water height buffers, and you never change both in the same kernel.
It's not as much about experience as it is about trade-offs. I've worked a lot with Vulkan and it's an incredible API, but when you're working alone and you don't have the goal of squeezing 250% performance out of your GPU on dozens of different GPU architectures, your performance becomes pretty much independent of a specific graphics API (unless your API doesn't support some stuff like multi-draw-indirect, etc).
I'm using WebGPU as a nice modern graphics API that is at the same time much more user-friendly and easier to use compared to e.g. Vulkan. I'm using a desktop implementation of WebGPU called wgpu, via it's C bindings called wgpu-native.
My browser doesn't support WebGPU properly yet, so I don't really care about running this thing in browser.
That's for efficiency reasons: most streams have way more logic than just filling the array, which can hardly be represented in terms of "getting the next value", and loops are good for optimization by compiler, etc. In fact, the actual sine wave implementation looks exactly the way you describe: it handles a generating function to a helper class that just fills the array https://bitbucket.org/lisyarus/psemek/src/master/libs/audio/...