GSoC 2020: Final Submission

Published 8/20/20

Project Summary

For the summer of 2020 I did a GSoC internship with MIT App Inventor. App Inventor is a browser-based application for building Android apps, which includes a block-based coding editor built on Blockly.

An interesting thing about App Inventor's blocks editor is that many of the blocks are not specified directly in JS, but are instead specified via Java Annotations. These annotations are read by an AnnotationProcessor which creates a special JSON file which is used to "create" the blocks using Blockly mutations.

My project for the summer had two goals:

  1. Add dropdown blocks to the App Inventor blocks editor.

    These blocks would replace existing constants inside App Inventor, which usually represented states such as VerticalAlignment(1:top, 2:center, 3:bottom).

    Old vertical alignment blocks versus new vertical alignment blocks

    Dropdown blocks are advantageous because they are internationalizable, they reduce invalid value errors, and they make working with the blocks editor more efficient.

    There were also some less-than-intuitive constants that we wanted to "abstract away". For example the constants HorizontalAlignment(1:right, 2:left, 3:center). Having center be associated with 3 can be confusing, so a goal was to remove the need for novices remember that (and similar constants).

  2. Allow enums to be used as parameters to Java functions.

    These enums would then get translated into dropdown blocks. Using an enum to define the dropdown block is advantageous because it is intuitive, and increases the type safety of App Inventor's Java-side code.

    For example a concrete function definition like this:

    @SimpleProperty
    public void AlignVertical(int align) {
      if (align > 0 && align <= 3) {
        this.alignVertical = align;
      } else {
        this.dispatchErrorOccurred();
      }
    }

    Turns into a type-safe function definition like this:

    @SimpleProperty
    public void AlignVertical(VerticalAlignment align) {
      this.alignVertical = align;
    }

Demo

Here is a demo of how a student developer might have written code in the past, and how they can now use dropdown blocks to make their code more readable.

You can also try out the changes I made by checking out my test server.

Old alignment blocks versus new alignment blocks. Old screen blocks versus new screen blocks. Old direction and asset blocks versus new direction and asset blocks. Old Lego NXT blocks versus new Lego NXT blocks.

The Code

I decided to work inside of my own fork of App Inventor to complete this project. All pull requests were made against an soc/develop branch, which will eventually be merged into the main repo.

There were some demo and proof-of-concept pull requests, but the following PRs are the ones that were actually merge-worthy. If you follow the link, each PR includes a more detailed description of what it accomplished.

Additionally I also put up some PRs into the main repo, when it seemed appropriate:

I believe that these 20+ pull requests represent a feature-complete project.

Design

But this was not just an implementation project, this was also a design project. The high level goals given above were laid out in the beginning of the project, but the particulars of behavior had to be designed, analyzed, and decided by my mentor and me.

This project had two initial design documents. One was my GSoC application document, which had several misconceptions and hardly any information about annotation processing, a huge part of this project. The second design document fixed many of these misconceptions, and included more information about annotation processing. It was also meant to be more user-focused so it provided examples of what the front-end behavior would look like. These were very useful, but the bulk of the design work was not included in these documents.

After I began the implementation at the beginning of June, my mentor and I recognized that there was a gap in the design. The dev team at App Inventor wanted these new dropdown blocks to act very abstractly (basically like Java enums) but to be backwards compatible they had to act very concretely (like integers, able to be used in primitive operations).

I attempted to flesh out this design space by creating a YAIL and Java Communication of Enums document (YAIL is the underlying text language the blocks "transpile" to). This document laid out 3 approaches to communication that allowed for varying levels of abstraction, while still being backwards compatible. The goal was to share this document with the dev team to help us come to a decision. But after discussing it with my mentor this document seemed too narrowly focused.

Next I began work on a final design document that laid out ~5 alternative designs for the system, including not only the communication of values but also block definitions, component definitions, component processing, pro-con lists, etc; as well as all of the context and for decisions we had made up to this point. This document was so comprehensive that I didn't believe I would be able to complete it by the end of the summer. As such we decide to have a meeting in mid July to decide which approach to take, even though the document was not completed.

At this meeting we decided on a 3-staged approach to implementing this project which would remain entirely backwards compatible, but give us more abstraction at each stage. A more comprehensive discussion of the specific challenges we ran into, as well as the final decision, can be found in my Operation Options: A Story of Language Design document.

Documentation

I also completed 3 documents explaining to developers (not users) how to use the new system.

The Adding New Types of Helper Blocks to the Blocks Editor document explains to App Inventor sources developers how to add new kinds of helper blocks (like the dropdown blocks) to the editor, using the Helper Blocks system I designed.

The Adding Helper Blocks to a Component document explains to component and extension developers how to add helper blocks to their components. This will act as a living document that gets updated whenever a new kind of helper block is created.

And lastly the How to Add a Dropdown Block to a Component document explains to component and extension developers how to define their own dropdown blocks in more detail.

My Growth

Before starting this project I already had a lot of experience with professional-grade development due to my work on the Google Blockly project. I also had community management experience due to some previous volunteer positions.

As such I decided that the focus of my summer would be on gaining more academic knowledge about computer science, computer science education, and programming language design.

SICP Course

To further my goal of learning about computer science, at the beginning of the summer I completed the SICP lecture series (aka "The Scheme Course"). Prof. Hal Abelson, who is the head of the MIT App Inventor project, is a co-creator of this course. SICP was recommended to me by my GSoC mentor Franklyn Turbak.

Through this course I learned a lot about what makes a program elegant and modular. In particular I learned about the power of first-class functions, and how they allow you to create powerful abstractions. It also impressed upon me the importance of thinking of programming as creating layers of abstraction, rather than decomposing a problem into sub-problems.

CS Education Research

Throughout the summer I read deeply about CS education, and education in general. I also took the time to detail many of these readings, and my thoughts about them, on my blog. For example my blog post about different kinds of thinking.

This process gave me a much deeper understanding of many things related to education, including: the way that kids learn, different kinds of learning, different school systems, and how all of this affects learning about computer science. I found my exposure to Seymour Papert's Mindstorms, as well as Radia Perlman's writings about TORTIS particularly interesting. I hope to continue this work after the summer.

Programming Language Design

But I believe my most important experience from this summer was my exposure to programming language design through my mentor Franklyn Turbak, author of Design Concepts in Programming Languages.

Throughout the summer we had many lively conversations about concepts related to first class functions, inheritance vs subtyping, and subtyping vs polymorphism; just to name a few. Discussing these things has given me a greater appreciation for the different ideas you can express in different languages. It has also given me a better understanding of the trade-offs related to programming language design, and how different elements of a language interact with each other.

Actually, my entire project for this summer was a great lesson in exactly these trade-offs in language design, specifically with regard to backwards compatibility. I go over this in more detail in my Operation Options: A Story of Language Design document document. In our case we were trying to make a very concrete blocks-based language into a more abstract language, which caused many backwards compatibility problems.

I think it is interesting that this problem of adding abstraction to a concrete language is also something Java ran into in its development. In Java's case they were trying to add support for "generics", which allow you to operate on values without knowing their exact types. While in our case we were trying to add support for enums.

It excites me that I was able to work on a problem that parallels problems faced in developing professional-grade programming languages!

Conclusion

I feel like this summer project gave me a great opportunity to grow as a programmer. I have learned so much about elegant program design, and elegant programming language design. Plus I was able to complete a fun project that I hope will lead other people to learn about these things!

I feel particularly lucky that I was assigned a mentor who could facilitate my growth in areas besides systems-knowledge, and who was willing to go outside the normal bounds of GSoC to do so.

This summer was a great asset to me! And I hope to continue down the path it has set me on long after it is completed =)

Other Summer Activities

I would also like to detail some of the other things I did this summer which were related to GSoC.

References

Structure and Interpretation of Computer Programs. Harold Abelson and Gerald Jay Sussman. 1985

Design Concepts in Programming Languages. Franklyn Turbak. 2008

Mindstorms: Children, Computers, and Powerful Ideas. Seymour A. Papert. 1993

TORTIS: Toddler's Own Recursive Turtle Interpreter System. Radia Paulman. 1974