Skip to content

Pyret Blocks (tracking issue) #501

Open

Description

@schanzer

Now that the pcardune-blocks branch has been merged into horizon, we need a tracking issue to keep tabs on the remaining work.

  • include and import need to work correctly, with snap's string-handling being a bit of an obstacle
  • do we want to support dragging a block into the interactions area?
  • we need to be able to share source locations (from error messages) with the block highlighter

Activity

  1. changed the title [-]Snap Blocks (tracking issue)[/-] [+]Pyret Blocks (tracking issue)[/+] on Jan 17, 2024
  2. self-assigned this
    on Jan 17, 2024
  3. asolove commented on Jan 21, 2024

    @asolove
    Contributor

    For item 3, highlighting error locations, see: #502

  4. asolove commented on Jan 21, 2024

    @asolove
    Contributor

    A couple other topics:

    • The current Pyret blocks are mostly expression-oriented, while Pyret has for loops and multi-line statement contexts that don't seem to be supported yet in blocks. I assume there's some work on our side to tell Snap which holes support that and to add more block types?

    • Hiding Pyret syntax: the blocks environment ends up not looking a lot like Pyret syntax (there's no end, quotation around strings is omitted, etc.). So it seems like there are a few options:

      • accept such differences and have teachers learn full Pyret so they can help students?
      • keep the blocks syntax as-is, and migrate anything that shows "normal" Pyret to instead show the blocks syntax (docs, instructional material and error messages)
      • try to make the blocks syntax more like Pyret (with explicit quotes, "end", etc.).
  5. shriram commented on Jan 21, 2024

    @shriram
    Member

    As an aside, note that Pyret for loops are not actually statements! They're genuine expressions. E.g.:

    squares = for map(i from range(0, 5)): i * i end
    check:
      squares is [list: 0, 1, 2 * 2, 3 * 3, 4 * 4]
    end
    

    In Pyret, for is just a very fancy and roundabout way of writing lambda, sorry-not-sorry. (-:

  6. asolove commented on Jan 21, 2024

    @asolove
    Contributor

    Of course, and thank you for the callout as I was being very imprecise with my language.

    What I mean to say is not about semantics but instead:

    • lexical syntax: what are we going to do about line breaks and indentation?
    • syntax: will we allow multiple statements inside a single hole?

    Lexical syntax
    As expressions get longer, Blocks world shows them on a single line until it runs out of space, at which point it breaks the line and indents just enough to leave the expression inside the circle of its parent:
    image

    The question here is whether this automatic line breaking is sufficient and understandable to the intended audience as you make more and more complex nested expressions for things like the flag assignment.

    Syntax:

    But more importantly, each of the "holes" today only accepts a single expression, and there is no equivalent of Scheme's begin (which is implicit in many contexts in Pyret), so making local definitions and then using them is impossible, whereas it is frequently used in Pyret:
    image

    This problem maybe does not arise: is blocks for a subset of Pyret that doesn't need nested definitions or the other cases where you want implicit begin?

    --

    PS: incidentally, two other things that may need adding: today in blocks world, functions can only take a single argument and there is no support for infix operators like is.

  7. schanzer commented on Jan 23, 2024

    @schanzer
    ContributorAuthor

    Adam, I so appreciate your thoughtful approach to design. A few responses:

    1. Yes, I do think that blocks are for a subset of Pyret that doesn't need nested definitions. Bootstrap doesn't nest definitions at all, and that's our primary use-case for blocks.
    2. Bootstrap uses only fixed-arity functions, so when Dorai and I designed the block language it was also fixed-arity. But that's definitely not a limitation of Snap! Snap blocks can be defined such that they contain an arbitrary number of holes.
    3. The question of how much "real Pyret syntax" we allow to leak through to blocks is a good one. Snap is shockingly flexible, but it wasn't hard to arrive at Pyret syntax that we couldn't reproduce. The best we could do was create blocks that have all the right syntax, but not in the right place. When I was spec'ing this out, I got stuck on which is worse: blocks looking nothing like Pyret syntax, or blocks looking like badly-indented Pyret syntax.

    (3a - keep in mind that it's always easier to add a feature than remove or change it, so I decided to punt on adding Pyret syntax for the first release.)

  8. asolove commented on Feb 29, 2024

    @asolove
    Contributor

    Emmanuel sent over this file as a benchmark for all the bits of Pyret that need to work in blocks world for it to be demoable.

    I spent some time tonight auditing everything in that file and figuring out which bits of it do and don't work in blocks today, so we have a checklist on what is left to figure out.

    Things that definitely work

    • image-url
    • scale(n, img)
    • if and nested elses (but note that these continue nesting visually, instead of staying at a single level like the else if, and don't allow alignment, so they're not quite as easy to understand as the text)
      image
      image

    Things I couldn't test

    • use context shared-gdrive: this seems to work, but locally I can't access files on real gdrive.
      • we could test this for real if the latest version were deployed to the live site, with the new version of Snap that allows shared-drive to work even when its arguments start with digits
    • load-spreadsheet (it relies on that file)

    Things that need some work

    • Definitions: there's no block for setting the value of a variable, which the sample file does a lot of (e.g. cat_row = row-n(...)). I think this might be straightforward to add to the language definition.
    • Map lookup: there's no block for var["key"], which the sample file does a lot (e.g. r["species"] == "dog")
    • load-table: all args are treated as strings, which is not what we need.
      • The "from" and "of" are treated as literal strings when we need them to refer to variables sometimes.
      • And the "naming columns" argument is interpreted as one big string ("a, b, c"), whereas we actually want a list of symbols (a, b, c). (I think this is fixable in the language definitions.)
        This block is translated into the below code:
        image
      load-table: "a, b, c"
                 source: "b".sheet-by-name("a", true)
               end
      
    • image-scatter-plot and other of the image functions have a similar issue where arguments are interpreted as strings rather than values, so you can't refer to variables. (I think this is fixable in the language definition.) This block is translated into the below code:
      image
      image-scatter-plot("a","b","d",animal-img)
    • Not used in this file, but possibly a problem: there's no way to make functions that have any number of arguments other than 1. You can't remove (only rename) the initial argument, and you can't add others. (Forget the "new math", maybe we should teach currying to 5th graders)

    Questions

    • How do we want the blocks in the sidebar to interact with their dependence on the loaded context? In this example, row-n and many other functions are available in the sidebar globally, even though they aren't defined unless you use the right context file. In a perfect world, perhaps we would detect the context file and its exports and only show the blocks for functions that are actually available. For now, do we want any kind of handling, like nicer error messages, if you pull out one of the sidebar blocks but it isn't defined in the context you loaded?

    Next steps

    • It would be great if we could launch the latest snap upgrade in to production so we can try out gdrive contexts.
    • @schanzer: can you teach me how you generated the language definitions in transpile.xml? I'm not sure if I should edit those directly or if they're auto-generated and I should edit them from elsewhere.
  9. jpolitz commented on Feb 29, 2024

    @jpolitz
    Member

    If you want to deploy I'm happy to merge to horizon and you can test with the Google keys + setup at https://pyret-horizon.herokuapp.com

  10. schanzer commented on Feb 29, 2024

    @schanzer
    ContributorAuthor

    @asolove from inside the snap submodule, you should be able to run a (full-featured) snap instance without Pyret at all. Dragging transpile.xml into the block palette will load the transpiler, and you can edit, add, or remove features as you see fit. Once you're done, you'll want to export the blocks back to XML.

    I found it most useful to keep the original file open in one window, then compare it to the exported transpiler and manually copy over what I wanted. There are some subtleties to the machine-generated XML that will bite you if you replace the file whole-cloth. ;)

    Happy to sit down on Zoom with you, if you like!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions