hackworthltd / primer

A pedagogical functional programming language.
GNU Affero General Public License v3.0
13 stars 1 forks source link

Animations #1173

Open georgefst opened 7 months ago

georgefst commented 7 months ago

In #1164 we add proof-of-concept support for creating animations with Primer. We have a new ADT, Picture, representing 2D images, and a primitive function animate : Integer → (Integer → Picture) → Animation, where Animation is a new primitive type. The arguments are a duration, in seconds, and a description of how to render each frame. This is inspired by the API of pure functional animation libraries such as Haskell's Gloss.

This issue outlines the work that remains. Some of these points will be expanding in to their own issues in due course.

(I've folded in one or two important points from @brprice's notes on this topic, but there's more there on inspirations, alternative APIs and example animations we'd like to support)

Implementation

The one major current limitation is around the kinds of functions which we can pass as the second argument to animate without the evaluator getting stuck. This is explained further in #1169.

We implement Animation internally as a base-64 encoding of a GIF, for ease of use by clients. The conversion from List Picture to GIF is implemented via the diagrams library with the Rasterific backend. This is probably not what we want to use beyond the prototyping stage:

We may well be better off leaving interpretation up to clients, e.g. implement a renderer in JS for primer-app. This slightly contradicts our "dumb frontend" philosophy, but it shouldn't be too bad, since mapping from Primer's Picture ADT to SVG is very straightforward in principle.

Some more minor issues have been left out of the initial PR due its proof-of-concept nature (and particularly the hope that we might ditch the new primitives completely in favour of the projections-based approach discussed below):

Student-facing API

Alternative approach via projections

After the initial work on #1164 was completed, we discussed the possibility of dropping the primitive Animation type in favour of a projections system, which we have long wanted anyway for lists and text. Our output would then just be an alternative view of List Picture. It would also be useful to be able to project a single Picture as a static output.

This feels more principled than the current, rather ad-hoc approach where we have a primitive type with no support for directly creating it (i.e. it only appears as the result of a primitive function), and special support for displaying it (whereas every other type at least looks like a normal tree node).

The fact that we'd require no primitive function or type at all to support animations would also actually solve several implementation issues, particularly #1169.

A few open questions:

dhess commented 7 months ago

Thanks for writing this up. I do feel pretty strongly that leaving Primer as a pure language and writing interpreters in frontends is probably the best approach of the ideas discussed thus far. The only drawback is that we'd likely need to implement those interpreters in TypeScript, but on the other hand, that probably makes sense anyway, as there are many amazing libraries for writing animations, games, etc. in the JavaScript/web ecosystem.

dhess commented 7 months ago

See #1186, which removes diagrams, as that is blocking Wasm support.

I think the next step in this process is to change the Animation type from a primitive to just an ordinary algebraic type, which presumably will obviate any need to solve #1169.

dhess commented 2 months ago

I just found out about this project, which may provide some inspiration:

https://gitlab.com/TristanCacqueray/animation-fractal