Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pyret Blocks (tracking issue) #501

Open
3 tasks
schanzer opened this issue Jan 17, 2024 · 8 comments
Open
3 tasks

Pyret Blocks (tracking issue) #501

schanzer opened this issue Jan 17, 2024 · 8 comments
Assignees

Comments

@schanzer
Copy link
Contributor

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
@schanzer schanzer changed the title Snap Blocks (tracking issue) Pyret Blocks (tracking issue) Jan 17, 2024
@schanzer schanzer self-assigned this Jan 17, 2024
@asolove
Copy link
Contributor

asolove commented Jan 21, 2024

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

@asolove
Copy link
Contributor

asolove commented Jan 21, 2024

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.).

@shriram
Copy link
Member

shriram commented Jan 21, 2024

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. (-:

@asolove
Copy link
Contributor

asolove commented Jan 21, 2024

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.

@schanzer
Copy link
Contributor Author

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.)

@asolove
Copy link
Contributor

asolove commented Feb 29, 2024

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.

@jpolitz
Copy link
Member

jpolitz commented Feb 29, 2024

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

@schanzer
Copy link
Contributor Author

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants