|
Hey Yakubin, Co-creator of Javis.jl here!
As adgjlsfhk1 said, there is an implicit global scope here!
This comes from a historic artifact from Cairo (which is what Javis is using deep within its tooling stack) which utilizes this sort of approach. Here is an ELI5 that may help about the flow of a Javis animation: imagine Javis as a magical artist sitting at a table.
The artist is a bit peculiar as they can draw anything you want but will not draw anything until you finish telling them everything you want to see.
When you create a `Video` object, the artist grabs an empty notebook and opens it up.
If you create a `Background` object, basically you are telling the artist that you want the background of each page in the notebook to be, in this case, black for pages 1 - 200.
As you keep telling the artist what you want, the artist listens to how you want it ordered, how objects should appear and animate, etc.
Finally, when you tell the artist to `render` this animation, Javis springs to work and flips through all the different pages, drawing backgrounds, objects, etc. to match what you asked.
Then, when Javis is all done, the artist gives you the notebook that when you open it up, it will magically flip through all the pages (i.e. at a given frame rate) showing you your requested animation. I know this ELI5 doesn't really get into the internals, but at a high level, that is what is happening with the start of the `Video` object.
Happy to give more details if desired.
We are trying to move to a v1.0.0 release very soon and in v2.0.0 we want to experiment with different syntax - perhaps a more implicit syntax similar to manim and Processing.
Out of curiosity, for you, do you find it necessary to know more about Javis's approach to use Javis or was this more of a question that you had?
Reason why I ask is perhaps we could add a "How Javis Works" section to the documentation if that could help more folks. Thanks! |
The reason I asked is because when I saw Background(1:200, ground), I did not know what made Javis use this background. To me it looked like creating an object and immediately discarding it. Global state explains it, but by default I'd assume that I can e.g. create two animations simultaneously (not necessarily meaning parallelism or concurrency, just multiple animation objects coexisting in memory at the same time, with code applying modifications to one in line N and to the other in line M e.g.) In that case I don't know how Javis would distinguish which background should be applied to which animation, as the code doesn't explicitly show any connection between the video variable and the Background(1:200, ground). From your explanation I assume you can only create one animation at a time. It makes sense. It makes it similar to creating plots in gnuplot. Keep in mind that I don't program in Julia (I'm considering learning it though), so I may still be totally off the mark in my understanding.
When I learn a library, tracing how data flows through example programs is the guide I use. When I don't see the explicit connection facilitating this flow of data, the library feels a bit less predictable to me and I need to rely more on copy-pasting ready-made examples to get something working through trial-and-error instead of relying on an accurate mental model of what happens. I know that such explicitness can feel verbose sometimes, but there are methods of escaping the verbosity without losing explicitness. Two examples: iterator pipelines in Rust/streams in Java, builder pattern in any language with method call syntax. In the first example, usually the pipeline starts with the name of the source of data and is followed by transformations connected by dots, e.g.:
The important thing here is that the dots signal that all those operations are applied to the result of the previous operations in pipeline (yet you don't need to name all the intermediate results). It's both terse and explicit.Builder pattern is similar: you have an object with methods which modify this object and return self/this, so that you don't need to repeat the name of the object being created in every line setting something in this object. E.g. I have this code in one of my Rust project using the clap library to parse CLI arguments:
I think the builder pattern could be a good fit for Javis. But that's just a complete outsider's opinion who doesn't even program in Julia, so don't take that too seriously. I think the API being a bit more like gnuplot is just fine for Javis' apparent purpose.To answer your question more directly, yes, I do think that knowing a bit about internals helps me understand how I should be using it.
Cheers