pytchlang / pytch-vm

Pytch: Core language and runtime
Other
3 stars 7 forks source link

Can we auto-register classes? #5

Open bennorth opened 4 years ago

bennorth commented 4 years ago

Currently, there is some boilerplate required in a Pytch project, along the lines of

import pytch                          # All this is
from pytch import (                   # boilerplate.
    Stage,                            #
    Sprite,                           # 
    Project,                          #
)                                     #

# Useful code goes here: Define class 'Bat', etc.

project = Project()                   # This is
project.register_sprite_class(Bat)    # boilerplate
project.go_live()                     # as well.

It could be useful to not have to write this boilerplate. Should we always create a Project instance? Can we scan the module for classes derived from Sprite or Stage and automatically register them with that Project?

There is the explicit is better than implicit doctrine, so some thought is required as to the right approach here. Maybe just a warning if there are Sprite-derived classes which have not been registered? Generate that boilerplate in a non-editable section of the code pane?

gdstrong commented 4 years ago

Some thoughts:

The import could just be from pitch import *

Python metaclasses can in theory do the registration - it's an explicit use case for them in the documentation. Skulpt doesn't support them at time of writing (it's a todo in Sk.misceval.buildClass), though. I have looked at class declarators for this, but haven't found a way to pull it off yet.

Creating/exporting a project instance within the Pitch library should be simple enough?

the go_live() is the trickiest to cleanly automate. We might be able to do something with the __import__ hook, but a cheat of a way to do it would be to tweak the way we use Sk.eval(); if we import the users "main" module into a hidden module of our own that contains only this final piece of boilerplate, assuming the sprites are auto-registered, that might work.

bennorth commented 4 years ago

Merged in functionality to do auto-registration and auto-go-live in f4cc987e1509.

The remaining part of this issue is whether it's desirable to avoid from pytch import (X, Y, Z). Leaving that question open for now.

bennorth commented 4 years ago

We could encourage the from pytch import * approach, if we use __all__ to limit the list of top-level names to what we consider the 'user-level' ones. E.g., we shouldn't expose play_sound because that is designed to be used internally by the user-level start_sound() and play_sound_until_done() methods. A candidate list for __all__ could be:

bennorth commented 4 years ago

Or should we adopt the practice of starting a project's code with just

import pytch

meaning that you have to say

class Spaceship(pytch.Sprite):
    # etc.

instead of class Spaceship(Sprite)? There are arguments both ways.

gdstrong commented 4 years ago

I'm trying a few approaches while developing tutorials. Right now I'm tending towards a simple "import pytch", but I'm not 100% sure yet.

Will complete a few more tutorials and then we can discuss it.